diff options
Diffstat (limited to 'arch/powerpc/kernel/smp.c')
-rw-r--r-- | arch/powerpc/kernel/smp.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index a90df6bf0940..8e3ca674d359 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -75,6 +75,8 @@ void smp_call_function_interrupt(void); | |||
75 | 75 | ||
76 | int smt_enabled_at_boot = 1; | 76 | int smt_enabled_at_boot = 1; |
77 | 77 | ||
78 | static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL; | ||
79 | |||
78 | #ifdef CONFIG_MPIC | 80 | #ifdef CONFIG_MPIC |
79 | int __init smp_mpic_probe(void) | 81 | int __init smp_mpic_probe(void) |
80 | { | 82 | { |
@@ -123,11 +125,16 @@ void smp_message_recv(int msg, struct pt_regs *regs) | |||
123 | /* XXX Do we have to do this? */ | 125 | /* XXX Do we have to do this? */ |
124 | set_need_resched(); | 126 | set_need_resched(); |
125 | break; | 127 | break; |
126 | #ifdef CONFIG_DEBUGGER | ||
127 | case PPC_MSG_DEBUGGER_BREAK: | 128 | case PPC_MSG_DEBUGGER_BREAK: |
129 | if (crash_ipi_function_ptr) { | ||
130 | crash_ipi_function_ptr(regs); | ||
131 | break; | ||
132 | } | ||
133 | #ifdef CONFIG_DEBUGGER | ||
128 | debugger_ipi(regs); | 134 | debugger_ipi(regs); |
129 | break; | 135 | break; |
130 | #endif | 136 | #endif /* CONFIG_DEBUGGER */ |
137 | /* FALLTHROUGH */ | ||
131 | default: | 138 | default: |
132 | printk("SMP %d: smp_message_recv(): unknown msg %d\n", | 139 | printk("SMP %d: smp_message_recv(): unknown msg %d\n", |
133 | smp_processor_id(), msg); | 140 | smp_processor_id(), msg); |
@@ -147,6 +154,17 @@ void smp_send_debugger_break(int cpu) | |||
147 | } | 154 | } |
148 | #endif | 155 | #endif |
149 | 156 | ||
157 | #ifdef CONFIG_KEXEC | ||
158 | void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *)) | ||
159 | { | ||
160 | crash_ipi_function_ptr = crash_ipi_callback; | ||
161 | if (crash_ipi_callback) { | ||
162 | mb(); | ||
163 | smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_DEBUGGER_BREAK); | ||
164 | } | ||
165 | } | ||
166 | #endif | ||
167 | |||
150 | static void stop_this_cpu(void *dummy) | 168 | static void stop_this_cpu(void *dummy) |
151 | { | 169 | { |
152 | local_irq_disable(); | 170 | local_irq_disable(); |