ia64/xen-unstable

view xen/arch/x86/crash.c @ 13876:b50350fb0fde

[XEN] kexec: Remove asm/kexec.h. Move the single inline function into
arch specific machine_kexec.c with the other arch specific kexec
functions.

IA64 already had a stub in both kexec.h and machine_kexec.c.

Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
author Ian Campbell <ian.campbell@xensource.com>
date Thu Feb 08 11:03:29 2007 +0000 (2007-02-08)
parents 4c8f157a3a47
children d39dcdb9cca3
line source
1 /******************************************************************************
2 * crash.c
3 *
4 * Based heavily on arch/i386/kernel/crash.c from Linux 2.6.16
5 *
6 * Xen port written by:
7 * - Simon 'Horms' Horman <horms@verge.net.au>
8 * - Magnus Damm <magnus@valinux.co.jp>
9 */
11 #include <asm/atomic.h>
12 #include <asm/elf.h>
13 #include <asm/percpu.h>
14 #include <xen/types.h>
15 #include <xen/irq.h>
16 #include <asm/ipi.h>
17 #include <asm/nmi.h>
18 #include <xen/string.h>
19 #include <xen/elf.h>
20 #include <xen/elfcore.h>
21 #include <xen/smp.h>
22 #include <xen/delay.h>
23 #include <xen/perfc.h>
24 #include <xen/kexec.h>
25 #include <xen/sched.h>
26 #include <public/xen.h>
27 #include <asm/shared.h>
28 #include <asm/hvm/hvm.h>
30 static atomic_t waiting_for_crash_ipi;
31 static unsigned int crashing_cpu;
33 static int crash_nmi_callback(struct cpu_user_regs *regs, int cpu)
34 {
35 /* Don't do anything if this handler is invoked on crashing cpu.
36 * Otherwise, system will completely hang. Crashing cpu can get
37 * an NMI if system was initially booted with nmi_watchdog parameter.
38 */
39 if ( cpu == crashing_cpu )
40 return 1;
41 local_irq_disable();
43 kexec_crash_save_cpu();
44 disable_local_APIC();
45 atomic_dec(&waiting_for_crash_ipi);
46 hvm_disable();
48 for ( ; ; )
49 __asm__ __volatile__ ( "hlt" );
51 return 1;
52 }
54 /*
55 * By using the NMI code instead of a vector we just sneak thru the
56 * word generator coming out with just what we want. AND it does
57 * not matter if clustered_apic_mode is set or not.
58 */
59 static void smp_send_nmi_allbutself(void)
60 {
61 cpumask_t allbutself = cpu_online_map;
62 cpu_clear(smp_processor_id(), allbutself);
63 if ( !cpus_empty(allbutself) )
64 send_IPI_mask(allbutself, APIC_DM_NMI);
65 }
67 static void nmi_shootdown_cpus(void)
68 {
69 unsigned long msecs;
71 crashing_cpu = smp_processor_id();
73 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
74 /* Would it be better to replace the trap vector here? */
75 set_nmi_callback(crash_nmi_callback);
76 /* Ensure the new callback function is set before sending out the NMI. */
77 wmb();
79 smp_send_nmi_allbutself();
81 msecs = 1000; /* Wait at most a second for the other cpus to stop */
82 while ( (atomic_read(&waiting_for_crash_ipi) > 0) && msecs )
83 {
84 mdelay(1);
85 msecs--;
86 }
88 /* Leave the nmi callback set */
89 disable_local_APIC();
90 }
92 void machine_crash_shutdown(void)
93 {
94 crash_xen_info_t *info;
96 local_irq_disable();
98 nmi_shootdown_cpus();
100 disable_IO_APIC();
102 hvm_disable();
104 info = kexec_crash_save_info();
105 info->dom0_pfn_to_mfn_frame_list_list =
106 arch_get_pfn_to_mfn_frame_list_list(dom0);
107 }
109 /*
110 * Local variables:
111 * mode: C
112 * c-set-style: "BSD"
113 * c-basic-offset: 4
114 * tab-width: 4
115 * indent-tabs-mode: nil
116 * End:
117 */