diff options
author | Jan Beulich <jbeulich@novell.com> | 2006-01-06 00:11:48 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 08:33:34 -0800 |
commit | e43d674f44dc885a2476cab3537e639d9eaa31a9 (patch) | |
tree | 23bf53cc0752000ddee91b8f957181bfc5b70a4c /arch/i386 | |
parent | 7c4cb60e5b97677424e95baee9c29df54b26e6ba (diff) | |
download | op-kernel-dev-e43d674f44dc885a2476cab3537e639d9eaa31a9.zip op-kernel-dev-e43d674f44dc885a2476cab3537e639d9eaa31a9.tar.gz |
[PATCH] i386: don't blindly enable interrupts in die()
Rather than blindly re-enabling interrupts in die(), save their state
upon entry and then restore that state.
If the kernel is in really bad condition and faults with interrupts disabled,
re-enabling them in die() may cause even more trouble, implying more chances
of data corruption.
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/kernel/traps.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index ab0e943..bb36a98 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -306,14 +306,17 @@ void die(const char * str, struct pt_regs * regs, long err) .lock_owner_depth = 0 }; static int die_counter; + unsigned long flags; if (die.lock_owner != raw_smp_processor_id()) { console_verbose(); - spin_lock_irq(&die.lock); + spin_lock_irqsave(&die.lock, flags); die.lock_owner = smp_processor_id(); die.lock_owner_depth = 0; bust_spinlocks(1); } + else + local_save_flags(flags); if (++die.lock_owner_depth < 3) { int nl = 0; @@ -340,7 +343,7 @@ void die(const char * str, struct pt_regs * regs, long err) bust_spinlocks(0); die.lock_owner = -1; - spin_unlock_irq(&die.lock); + spin_unlock_irqrestore(&die.lock, flags); if (kexec_should_crash(current)) crash_kexec(regs); |