[PATCH] x86_64: Switch to the interrupt stack when running a softirq in local_bh_enable()

This avoids some potential stack overflows with very deep softirq callchains.
i386 does this too.

TOADD CFI annotation

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Andi Kleen 2005-07-28 21:15:49 -07:00 committed by Linus Torvalds
parent 3829ee6b1b
commit ed6b676ca8
4 changed files with 35 additions and 2 deletions

View File

@ -918,3 +918,15 @@ ENTRY(machine_check)
ENTRY(call_debug)
zeroentry do_call_debug
ENTRY(call_softirq)
movq %gs:pda_irqstackptr,%rax
pushq %r15
movq %rsp,%r15
incl %gs:pda_irqcount
cmove %rax,%rsp
call __do_softirq
movq %r15,%rsp
decl %gs:pda_irqcount
popq %r15
ret

View File

@ -135,3 +135,22 @@ void fixup_irqs(cpumask_t map)
local_irq_disable();
}
#endif
extern void call_softirq(void);
asmlinkage void do_softirq(void)
{
__u32 pending;
unsigned long flags;
if (in_interrupt())
return;
local_irq_save(flags);
pending = local_softirq_pending();
/* Switch to interrupt stack */
if (pending)
call_softirq();
local_irq_restore(flags);
}
EXPORT_SYMBOL(do_softirq);

View File

@ -57,4 +57,6 @@ int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
extern void fixup_irqs(cpumask_t map);
#endif
#define __ARCH_HAS_DO_SOFTIRQ 1
#endif /* _ASM_IRQ_H */

View File

@ -86,7 +86,7 @@ asmlinkage void __do_softirq(void)
/* Reset the pending bitmask before enabling irqs */
local_softirq_pending() = 0;
local_irq_enable();
//local_irq_enable();
h = softirq_vec;
@ -99,7 +99,7 @@ asmlinkage void __do_softirq(void)
pending >>= 1;
} while (pending);
local_irq_disable();
//local_irq_disable();
pending = local_softirq_pending();
if (pending && --max_restart)