From f2fb4e4f647dabf1177d3ce164988e73482d76b1 Mon Sep 17 00:00:00 2001 From: Stuart Menefy Date: Wed, 2 Jul 2008 17:51:23 +0900 Subject: sh: Conditionally re-enable IRQs in fault path. The current kernel behaviour is to reenable interrupts unconditionally when taking a page fault. This patch changes this to only enable them if interrupts were previously enabled. It also fixes a problem seen with this fix in place: the kernel previously flushed the vsyscall page when handling a signal, which is not only unncessary, but caused a possible sleep with interrupts disabled. Signed-off-by: Stuart Menefy Signed-off-by: Paul Mundt --- arch/sh/mm/fault_32.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'arch/sh/mm') diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c index d1fa275..0c776fd 100644 --- a/arch/sh/mm/fault_32.c +++ b/arch/sh/mm/fault_32.c @@ -37,16 +37,12 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, int fault; siginfo_t info; - trace_hardirqs_on(); - local_irq_enable(); - #ifdef CONFIG_SH_KGDB if (kgdb_nofault && kgdb_bus_err_hook) kgdb_bus_err_hook(); #endif tsk = current; - mm = tsk->mm; si_code = SEGV_MAPERR; if (unlikely(address >= TASK_SIZE)) { @@ -88,6 +84,14 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, return; } + /* Only enable interrupts if they were on before the fault */ + if ((regs->sr & SR_IMASK) != SR_IMASK) { + trace_hardirqs_on(); + local_irq_enable(); + } + + mm = tsk->mm; + /* * If we're in an interrupt or have no user * context, we must not take the fault.. -- cgit v1.1