Skip to content

Commit

Permalink
[PATCH] x86_64: Switch to the interrupt stack when running a softirq …
Browse files Browse the repository at this point in the history
…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 <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Andi Kleen authored and Linus Torvalds committed Jul 29, 2005
1 parent 3829ee6 commit ed6b676
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 2 deletions.
12 changes: 12 additions & 0 deletions arch/x86_64/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -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

19 changes: 19 additions & 0 deletions arch/x86_64/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
2 changes: 2 additions & 0 deletions include/asm-x86_64/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
4 changes: 2 additions & 2 deletions kernel/softirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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)
Expand Down

0 comments on commit ed6b676

Please sign in to comment.