diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-05-08 13:31:59 +1000 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-05-09 09:42:21 +1000 |
commit | 56dfa7fa19e36db352a94be022243ed461710119 (patch) | |
tree | 37ea957522aa18a2d3f4fb62629e9e4ca0e7f38c /arch/powerpc/kernel/irq.c | |
parent | 810b4de25e53459323ff48957b0162b48d6cbd57 (diff) | |
download | linux-56dfa7fa19e36db352a94be022243ed461710119.tar.bz2 |
powerpc/irq: Fix bug with new lazy IRQ handling code
We had a case where we could turn on hard interrupts while
leaving the PACA_IRQ_HARD_DIS bit set in the PACA. This can
in turn cause a BUG_ON() to hit in __check_irq_replay() due
to interrupt state getting out of sync.
The assembly code was also way too convoluted. Instead, we
now leave it to the C code to do the right thing which ends
up being smaller and more readable.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/irq.c')
-rw-r--r-- | arch/powerpc/kernel/irq.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 43eb74fcedde..c6c6f3b7f8cd 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -260,11 +260,17 @@ EXPORT_SYMBOL(arch_local_irq_restore); * if they are currently disabled. This is typically called before * schedule() or do_signal() when returning to userspace. We do it * in C to avoid the burden of dealing with lockdep etc... + * + * NOTE: This is called with interrupts hard disabled but not marked + * as such in paca->irq_happened, so we need to resync this. */ void restore_interrupts(void) { - if (irqs_disabled()) + if (irqs_disabled()) { + local_paca->irq_happened |= PACA_IRQ_HARD_DIS; local_irq_enable(); + } else + __hard_irq_enable(); } #endif /* CONFIG_PPC64 */ |