|
@@ -35,19 +35,34 @@ static int crashing_cpu;
|
|
|
#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
|
|
|
static atomic_t waiting_for_crash_ipi;
|
|
|
|
|
|
-static int crash_nmi_callback(struct notifier_block *self,
|
|
|
- unsigned long val, void *data)
|
|
|
+static void kdump_nmi_callback(int cpu, struct die_args *args)
|
|
|
{
|
|
|
struct pt_regs *regs;
|
|
|
#ifdef CONFIG_X86_32
|
|
|
struct pt_regs fixed_regs;
|
|
|
#endif
|
|
|
+
|
|
|
+ regs = args->regs;
|
|
|
+
|
|
|
+#ifdef CONFIG_X86_32
|
|
|
+ if (!user_mode_vm(regs)) {
|
|
|
+ crash_fixup_ss_esp(&fixed_regs, regs);
|
|
|
+ regs = &fixed_regs;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ crash_save_cpu(regs, cpu);
|
|
|
+
|
|
|
+ disable_local_APIC();
|
|
|
+}
|
|
|
+
|
|
|
+static int crash_nmi_callback(struct notifier_block *self,
|
|
|
+ unsigned long val, void *data)
|
|
|
+{
|
|
|
int cpu;
|
|
|
|
|
|
if (val != DIE_NMI_IPI)
|
|
|
return NOTIFY_OK;
|
|
|
|
|
|
- regs = ((struct die_args *)data)->regs;
|
|
|
cpu = raw_smp_processor_id();
|
|
|
|
|
|
/* Don't do anything if this handler is invoked on crashing cpu.
|
|
@@ -58,14 +73,8 @@ static int crash_nmi_callback(struct notifier_block *self,
|
|
|
return NOTIFY_STOP;
|
|
|
local_irq_disable();
|
|
|
|
|
|
-#ifdef CONFIG_X86_32
|
|
|
- if (!user_mode_vm(regs)) {
|
|
|
- crash_fixup_ss_esp(&fixed_regs, regs);
|
|
|
- regs = &fixed_regs;
|
|
|
- }
|
|
|
-#endif
|
|
|
- crash_save_cpu(regs, cpu);
|
|
|
- disable_local_APIC();
|
|
|
+ kdump_nmi_callback(cpu, (struct die_args *)data);
|
|
|
+
|
|
|
atomic_dec(&waiting_for_crash_ipi);
|
|
|
/* Assume hlt works */
|
|
|
halt();
|