diff options
author | David S. Miller <davem@davemloft.net> | 2010-04-14 05:04:29 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-14 05:04:29 -0400 |
commit | ec687886de00e1e63f3d821ccade9a61590408ed (patch) | |
tree | 093e303475754d30b679bd35ae9cc5522832057e /arch/sparc/kernel/irq_64.c | |
parent | 035df35d968323f6f463c8789553e8589efcbcd4 (diff) |
sparc64: Run NMIs on the hardirq stack.
Otherwise we can overflow the main stack with the function tracer
enabled.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/kernel/irq_64.c')
-rw-r--r-- | arch/sparc/kernel/irq_64.c | 19 |
1 files changed, 1 insertions, 18 deletions
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index 2b04c722cc3e..830d70a3e20b 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c | |||
@@ -47,6 +47,7 @@ | |||
47 | 47 | ||
48 | #include "entry.h" | 48 | #include "entry.h" |
49 | #include "cpumap.h" | 49 | #include "cpumap.h" |
50 | #include "kstack.h" | ||
50 | 51 | ||
51 | #define NUM_IVECS (IMAP_INR + 1) | 52 | #define NUM_IVECS (IMAP_INR + 1) |
52 | 53 | ||
@@ -713,24 +714,6 @@ void ack_bad_irq(unsigned int virt_irq) | |||
713 | void *hardirq_stack[NR_CPUS]; | 714 | void *hardirq_stack[NR_CPUS]; |
714 | void *softirq_stack[NR_CPUS]; | 715 | void *softirq_stack[NR_CPUS]; |
715 | 716 | ||
716 | static __attribute__((always_inline)) void *set_hardirq_stack(void) | ||
717 | { | ||
718 | void *orig_sp, *sp = hardirq_stack[smp_processor_id()]; | ||
719 | |||
720 | __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp)); | ||
721 | if (orig_sp < sp || | ||
722 | orig_sp > (sp + THREAD_SIZE)) { | ||
723 | sp += THREAD_SIZE - 192 - STACK_BIAS; | ||
724 | __asm__ __volatile__("mov %0, %%sp" : : "r" (sp)); | ||
725 | } | ||
726 | |||
727 | return orig_sp; | ||
728 | } | ||
729 | static __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp) | ||
730 | { | ||
731 | __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp)); | ||
732 | } | ||
733 | |||
734 | void __irq_entry handler_irq(int irq, struct pt_regs *regs) | 717 | void __irq_entry handler_irq(int irq, struct pt_regs *regs) |
735 | { | 718 | { |
736 | unsigned long pstate, bucket_pa; | 719 | unsigned long pstate, bucket_pa; |