From c5a9a020cfbc44833020007d6a77cd4200d7ced6 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sat, 25 Jun 2005 14:57:58 -0700 Subject: [PATCH] --- yaml --- r: 3327 b: refs/heads/master c: c4ac4263a019c791e906f284bb03891d3c25a845 h: refs/heads/master i: 3325: aad439061ad9ce556b8f4f39f15c936dcf485654 3323: 97aa55fd46cd1e7c84039c2ce181fceb016e9307 3319: 33dd10dd84f18c50e4917ade80afa0ae0c45b8ab 3311: 0c14f8f322e670f64b49502d7d2045b68aee21d1 3295: ff2490506aa8058cc67c5bf2bd372e0b38c863c2 3263: 96bd72e219eb08a3faf7e4dcd53ed972dab317d7 3199: 243006f54d2e9f1759ef8018dfe557300d40ee89 3071: 13184a57c9e4b0f41e5900a2f4e883f32b00e412 v: v3 --- [refs] | 2 +- trunk/arch/i386/kernel/crash.c | 56 ++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index b2e9a3365f40..a9d78122e0e9 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5033cba087f6ac773002123aafbea1aad4267682 +refs/heads/master: c4ac4263a019c791e906f284bb03891d3c25a845 diff --git a/trunk/arch/i386/kernel/crash.c b/trunk/arch/i386/kernel/crash.c index fa27a6c2abb6..882779c07874 100644 --- a/trunk/arch/i386/kernel/crash.c +++ b/trunk/arch/i386/kernel/crash.c @@ -23,12 +23,65 @@ #include #include #include +#include #define MAX_NOTE_BYTES 1024 typedef u32 note_buf_t[MAX_NOTE_BYTES/4]; note_buf_t crash_notes[NR_CPUS]; +#ifdef CONFIG_SMP +static atomic_t waiting_for_crash_ipi; + +static int crash_nmi_callback(struct pt_regs *regs, int cpu) +{ + local_irq_disable(); + atomic_dec(&waiting_for_crash_ipi); + /* Assume hlt works */ + __asm__("hlt"); + for(;;); + return 1; +} + +/* + * By using the NMI code instead of a vector we just sneak thru the + * word generator coming out with just what we want. AND it does + * not matter if clustered_apic_mode is set or not. + */ +static void smp_send_nmi_allbutself(void) +{ + send_IPI_allbutself(APIC_DM_NMI); +} + +static void nmi_shootdown_cpus(void) +{ + unsigned long msecs; + atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); + + /* Would it be better to replace the trap vector here? */ + set_nmi_callback(crash_nmi_callback); + /* Ensure the new callback function is set before sending + * out the NMI + */ + wmb(); + + smp_send_nmi_allbutself(); + + msecs = 1000; /* Wait at most a second for the other cpus to stop */ + while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) { + mdelay(1); + msecs--; + } + + /* Leave the nmi callback set */ +} +#else +static void nmi_shootdown_cpus(void) +{ + /* There are no cpus to shootdown */ +} +#endif + void machine_crash_shutdown(void) { /* This function is only called after the system @@ -39,4 +92,7 @@ void machine_crash_shutdown(void) * In practice this means shooting down the other cpus in * an SMP system. */ + /* The kernel is broken so disable interrupts */ + local_irq_disable(); + nmi_shootdown_cpus(); }