ia64/xen-unstable

annotate xen/arch/x86/crash.c @ 14181:d39dcdb9cca3

hvm: Only do hvm_disable() on HVM-enabled systems.

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