diff options
| -rw-r--r-- | arch/x86/kernel/crash.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 268553817909..60475422a51a 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c | |||
| @@ -35,19 +35,34 @@ static int crashing_cpu; | |||
| 35 | #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) | 35 | #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) |
| 36 | static atomic_t waiting_for_crash_ipi; | 36 | static atomic_t waiting_for_crash_ipi; |
| 37 | 37 | ||
| 38 | static int crash_nmi_callback(struct notifier_block *self, | 38 | static void kdump_nmi_callback(int cpu, struct die_args *args) |
| 39 | unsigned long val, void *data) | ||
| 40 | { | 39 | { |
| 41 | struct pt_regs *regs; | 40 | struct pt_regs *regs; |
| 42 | #ifdef CONFIG_X86_32 | 41 | #ifdef CONFIG_X86_32 |
| 43 | struct pt_regs fixed_regs; | 42 | struct pt_regs fixed_regs; |
| 44 | #endif | 43 | #endif |
| 44 | |||
| 45 | regs = args->regs; | ||
| 46 | |||
| 47 | #ifdef CONFIG_X86_32 | ||
| 48 | if (!user_mode_vm(regs)) { | ||
| 49 | crash_fixup_ss_esp(&fixed_regs, regs); | ||
| 50 | regs = &fixed_regs; | ||
| 51 | } | ||
| 52 | #endif | ||
| 53 | crash_save_cpu(regs, cpu); | ||
| 54 | |||
| 55 | disable_local_APIC(); | ||
| 56 | } | ||
| 57 | |||
| 58 | static int crash_nmi_callback(struct notifier_block *self, | ||
| 59 | unsigned long val, void *data) | ||
| 60 | { | ||
| 45 | int cpu; | 61 | int cpu; |
| 46 | 62 | ||
| 47 | if (val != DIE_NMI_IPI) | 63 | if (val != DIE_NMI_IPI) |
| 48 | return NOTIFY_OK; | 64 | return NOTIFY_OK; |
| 49 | 65 | ||
| 50 | regs = ((struct die_args *)data)->regs; | ||
| 51 | cpu = raw_smp_processor_id(); | 66 | cpu = raw_smp_processor_id(); |
| 52 | 67 | ||
| 53 | /* Don't do anything if this handler is invoked on crashing cpu. | 68 | /* 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, | |||
| 58 | return NOTIFY_STOP; | 73 | return NOTIFY_STOP; |
| 59 | local_irq_disable(); | 74 | local_irq_disable(); |
| 60 | 75 | ||
| 61 | #ifdef CONFIG_X86_32 | 76 | kdump_nmi_callback(cpu, (struct die_args *)data); |
| 62 | if (!user_mode_vm(regs)) { | 77 | |
| 63 | crash_fixup_ss_esp(&fixed_regs, regs); | ||
| 64 | regs = &fixed_regs; | ||
| 65 | } | ||
| 66 | #endif | ||
| 67 | crash_save_cpu(regs, cpu); | ||
| 68 | disable_local_APIC(); | ||
| 69 | atomic_dec(&waiting_for_crash_ipi); | 78 | atomic_dec(&waiting_for_crash_ipi); |
| 70 | /* Assume hlt works */ | 79 | /* Assume hlt works */ |
| 71 | halt(); | 80 | halt(); |
