2 * Architecture specific (i386) functions for kexec based crash dumps.
4 * Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
6 * Copyright (C) IBM Corporation, 2004. All rights reserved.
10 #include <linux/init.h>
11 #include <linux/types.h>
12 #include <linux/kernel.h>
13 #include <linux/smp.h>
14 #include <linux/irq.h>
15 #include <linux/reboot.h>
16 #include <linux/kexec.h>
17 #include <linux/irq.h>
18 #include <linux/delay.h>
19 #include <linux/elf.h>
20 #include <linux/elfcore.h>
22 #include <asm/processor.h>
23 #include <asm/hardirq.h>
25 #include <asm/hw_irq.h>
28 #define MAX_NOTE_BYTES 1024
29 typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
31 note_buf_t crash_notes[NR_CPUS];
34 static atomic_t waiting_for_crash_ipi;
36 static int crash_nmi_callback(struct pt_regs *regs, int cpu)
39 atomic_dec(&waiting_for_crash_ipi);
40 /* Assume hlt works */
47 * By using the NMI code instead of a vector we just sneak thru the
48 * word generator coming out with just what we want. AND it does
49 * not matter if clustered_apic_mode is set or not.
51 static void smp_send_nmi_allbutself(void)
53 send_IPI_allbutself(APIC_DM_NMI);
56 static void nmi_shootdown_cpus(void)
59 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
61 /* Would it be better to replace the trap vector here? */
62 set_nmi_callback(crash_nmi_callback);
63 /* Ensure the new callback function is set before sending
68 smp_send_nmi_allbutself();
70 msecs = 1000; /* Wait at most a second for the other cpus to stop */
71 while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
76 /* Leave the nmi callback set */
79 static void nmi_shootdown_cpus(void)
81 /* There are no cpus to shootdown */
85 void machine_crash_shutdown(void)
87 /* This function is only called after the system
88 * has paniced or is otherwise in a critical state.
89 * The minimum amount of code to allow a kexec'd kernel
90 * to run successfully needs to happen here.
92 * In practice this means shooting down the other cpus in
95 /* The kernel is broken so disable interrupts */