sh: Fix bogus regs pointer in do_IRQ().
SH-3 and SH-4 were trampling the register, and SH-2 wasn't even setting it in the first place. This ended up with some rather broken behaviour in the sysrq show_regs(). Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
parent
ffe1b4e9f4
commit
3afb209a43
@ -165,6 +165,7 @@ ENTRY(exception_handler)
|
|||||||
|
|
||||||
interrupt_entry:
|
interrupt_entry:
|
||||||
mov r9,r4
|
mov r9,r4
|
||||||
|
mov r15,r5
|
||||||
mov.l 6f,r9
|
mov.l 6f,r9
|
||||||
mov.l 7f,r8
|
mov.l 7f,r8
|
||||||
jmp @r8
|
jmp @r8
|
||||||
|
@ -514,13 +514,16 @@ skip_save:
|
|||||||
|
|
||||||
interrupt_exception:
|
interrupt_exception:
|
||||||
mov.l 1f, r9
|
mov.l 1f, r9
|
||||||
|
mov.l 2f, r4
|
||||||
|
mov.l @r4, r4
|
||||||
jmp @r9
|
jmp @r9
|
||||||
nop
|
mov r15, r5
|
||||||
rts
|
rts
|
||||||
nop
|
nop
|
||||||
|
|
||||||
.align 2
|
.align 2
|
||||||
1: .long do_IRQ
|
1: .long do_IRQ
|
||||||
|
2: .long INTEVT
|
||||||
|
|
||||||
.align 2
|
.align 2
|
||||||
ENTRY(exception_none)
|
ENTRY(exception_none)
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/kernel_stat.h>
|
#include <linux/kernel_stat.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/io.h>
|
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
@ -82,13 +81,9 @@ static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly;
|
|||||||
static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
|
static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
|
asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs)
|
||||||
unsigned long r6, unsigned long r7,
|
|
||||||
struct pt_regs __regs)
|
|
||||||
{
|
{
|
||||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
|
||||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||||
int irq;
|
|
||||||
#ifdef CONFIG_4KSTACKS
|
#ifdef CONFIG_4KSTACKS
|
||||||
union irq_ctx *curctx, *irqctx;
|
union irq_ctx *curctx, *irqctx;
|
||||||
#endif
|
#endif
|
||||||
@ -111,13 +106,7 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_HAS_INTEVT
|
irq = irq_demux(evt2irq(irq));
|
||||||
irq = evt2irq(ctrl_inl(INTEVT));
|
|
||||||
#else
|
|
||||||
irq = r4;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
irq = irq_demux(irq);
|
|
||||||
|
|
||||||
#ifdef CONFIG_4KSTACKS
|
#ifdef CONFIG_4KSTACKS
|
||||||
curctx = (union irq_ctx *)current_thread_info();
|
curctx = (union irq_ctx *)current_thread_info();
|
||||||
|
@ -94,8 +94,13 @@
|
|||||||
/*
|
/*
|
||||||
* Convert back and forth between INTEVT and IRQ values.
|
* Convert back and forth between INTEVT and IRQ values.
|
||||||
*/
|
*/
|
||||||
|
#ifdef CONFIG_CPU_HAS_INTEVT
|
||||||
#define evt2irq(evt) (((evt) >> 5) - 16)
|
#define evt2irq(evt) (((evt) >> 5) - 16)
|
||||||
#define irq2evt(irq) (((irq) + 16) << 5)
|
#define irq2evt(irq) (((irq) + 16) << 5)
|
||||||
|
#else
|
||||||
|
#define evt2irq(evt) (evt)
|
||||||
|
#define irq2evt(irq) (irq)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Simple Mask Register Support
|
* Simple Mask Register Support
|
||||||
|
Loading…
Reference in New Issue
Block a user