tree 753ea613ce334c41f835f6aac21074b137d24713
parent 3829ee6b1be03d5aa3005fe7d19f30088b539836
author Andi Kleen <[EMAIL PROTECTED]> Fri, 29 Jul 2005 11:15:49 -0700
committer Linus Torvalds <[EMAIL PROTECTED]> Fri, 29 Jul 2005 11:46:02 -0700

[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 <[EMAIL PROTECTED]>
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>

 arch/x86_64/kernel/entry.S |   12 ++++++++++++
 arch/x86_64/kernel/irq.c   |   19 +++++++++++++++++++
 include/asm-x86_64/irq.h   |    2 ++
 kernel/softirq.c           |    4 ++--
 4 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -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
+
diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c
--- a/arch/x86_64/kernel/irq.c
+++ b/arch/x86_64/kernel/irq.c
@@ -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);
diff --git a/include/asm-x86_64/irq.h b/include/asm-x86_64/irq.h
--- a/include/asm-x86_64/irq.h
+++ b/include/asm-x86_64/irq.h
@@ -57,4 +57,6 @@ int handle_IRQ_event(unsigned int, struc
 extern void fixup_irqs(cpumask_t map);
 #endif
 
+#define __ARCH_HAS_DO_SOFTIRQ 1
+
 #endif /* _ASM_IRQ_H */
diff --git a/kernel/softirq.c b/kernel/softirq.c
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -86,7 +86,7 @@ restart:
        /* Reset the pending bitmask before enabling irqs */
        local_softirq_pending() = 0;
 
-       local_irq_enable();
+       //local_irq_enable();
 
        h = softirq_vec;
 
@@ -99,7 +99,7 @@ restart:
                pending >>= 1;
        } while (pending);
 
-       local_irq_disable();
+       //local_irq_disable();
 
        pending = local_softirq_pending();
        if (pending && --max_restart)
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to