source: trunk/packages/xen-3.1/xen-3.1/xen/arch/x86/crash.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

File size: 2.7 KB
Line 
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 */
10
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/support.h>
29
30static atomic_t waiting_for_crash_ipi;
31static unsigned int crashing_cpu;
32
33static 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();
42
43    kexec_crash_save_cpu();
44    disable_local_APIC();
45    atomic_dec(&waiting_for_crash_ipi);
46    hvm_disable();
47
48    for ( ; ; )
49        __asm__ __volatile__ ( "hlt" );
50
51    return 1;
52}
53
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 */
59static 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}
66
67static void nmi_shootdown_cpus(void)
68{
69    unsigned long msecs;
70
71    crashing_cpu = smp_processor_id();
72
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();
78
79    smp_send_nmi_allbutself();
80
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    }
87
88    /* Leave the nmi callback set */
89    disable_local_APIC();
90}
91
92void machine_crash_shutdown(void)
93{
94    crash_xen_info_t *info;
95
96    local_irq_disable();
97
98    nmi_shootdown_cpus();
99
100    disable_IO_APIC();
101
102    hvm_disable();
103
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}
108
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 */
Note: See TracBrowser for help on using the repository browser.