ia64/xen-unstable

changeset 13029:6a28bfc1a940

[KEXEC] Clean up kexec code and fix panic-induced reboot when
kdump is not in use.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Thu Dec 14 15:06:22 2006 +0000 (2006-12-14)
parents 70155087efe8
children 664e762a10e8
files xen/arch/x86/crash.c xen/arch/x86/traps.c xen/common/kexec.c xen/drivers/char/console.c xen/include/xen/kexec.h
line diff
     1.1 --- a/xen/arch/x86/crash.c	Thu Dec 14 14:13:18 2006 +0000
     1.2 +++ b/xen/arch/x86/crash.c	Thu Dec 14 15:06:22 2006 +0000
     1.3 @@ -28,6 +28,7 @@
     1.4  #include <asm/hvm/hvm.h>
     1.5  
     1.6  static atomic_t waiting_for_crash_ipi;
     1.7 +static unsigned int crashing_cpu;
     1.8  
     1.9  static int crash_nmi_callback(struct cpu_user_regs *regs, int cpu)
    1.10  {
    1.11 @@ -39,7 +40,7 @@ static int crash_nmi_callback(struct cpu
    1.12          return 1;
    1.13      local_irq_disable();
    1.14  
    1.15 -    machine_crash_save_cpu();
    1.16 +    kexec_crash_save_cpu();
    1.17      disable_local_APIC();
    1.18      atomic_dec(&waiting_for_crash_ipi);
    1.19      hvm_disable();
    1.20 @@ -67,6 +68,8 @@ static void nmi_shootdown_cpus(void)
    1.21  {
    1.22      unsigned long msecs;
    1.23  
    1.24 +    crashing_cpu = smp_processor_id();
    1.25 +
    1.26      atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
    1.27      /* Would it be better to replace the trap vector here? */
    1.28      set_nmi_callback(crash_nmi_callback);
    1.29 @@ -86,18 +89,10 @@ static void nmi_shootdown_cpus(void)
    1.30      disable_local_APIC();
    1.31  }
    1.32  
    1.33 -static void crash_save_xen_notes(void)
    1.34 +void machine_crash_shutdown(void)
    1.35  {
    1.36      crash_xen_info_t *info;
    1.37  
    1.38 -    info = machine_crash_save_info();
    1.39 -
    1.40 -    info->dom0_pfn_to_mfn_frame_list_list = \
    1.41 -        dom0->shared_info->arch.pfn_to_mfn_frame_list_list;
    1.42 -}
    1.43 -
    1.44 -void machine_crash_shutdown(void)
    1.45 -{
    1.46      local_irq_disable();
    1.47  
    1.48      nmi_shootdown_cpus();
    1.49 @@ -106,7 +101,9 @@ void machine_crash_shutdown(void)
    1.50  
    1.51      hvm_disable();
    1.52  
    1.53 -    crash_save_xen_notes();
    1.54 +    info = kexec_crash_save_info();
    1.55 +    info->dom0_pfn_to_mfn_frame_list_list =
    1.56 +        dom0->shared_info->arch.pfn_to_mfn_frame_list_list;
    1.57  }
    1.58  
    1.59  /*
     2.1 --- a/xen/arch/x86/traps.c	Thu Dec 14 14:13:18 2006 +0000
     2.2 +++ b/xen/arch/x86/traps.c	Thu Dec 14 15:06:22 2006 +0000
     2.3 @@ -1665,7 +1665,7 @@ static void unknown_nmi_error(unsigned c
     2.4          printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
     2.5          printk("Dazed and confused, but trying to continue\n");
     2.6          printk("Do you have a strange power saving mode enabled?\n");
     2.7 -        machine_crash_kexec();
     2.8 +        kexec_crash();
     2.9      }
    2.10  }
    2.11  
     3.1 --- a/xen/common/kexec.c	Thu Dec 14 14:13:18 2006 +0000
     3.2 +++ b/xen/common/kexec.c	Thu Dec 14 15:06:22 2006 +0000
     3.3 @@ -24,7 +24,6 @@
     3.4  
     3.5  DEFINE_PER_CPU (crash_note_t, crash_notes);
     3.6  cpumask_t crash_saved_cpus;
     3.7 -int crashing_cpu;
     3.8  
     3.9  xen_kexec_image_t kexec_image[KEXEC_IMAGE_NR];
    3.10  
    3.11 @@ -58,38 +57,34 @@ custom_param("crashkernel", parse_crashk
    3.12  
    3.13  static void one_cpu_only(void)
    3.14  {
    3.15 -   /* Only allow the first cpu to continue - force other cpus to spin */
    3.16 +    /* Only allow the first cpu to continue - force other cpus to spin */
    3.17      if ( test_and_set_bit(KEXEC_FLAG_IN_PROGRESS, &kexec_flags) )
    3.18 -    {
    3.19 -        while (1);
    3.20 -    }
    3.21 +        for ( ; ; ) ;
    3.22  }
    3.23  
    3.24 -/* Save the registers in the per-cpu crash note buffer */
    3.25 -
    3.26 -void machine_crash_save_cpu(void)
    3.27 +/* Save the registers in the per-cpu crash note buffer. */
    3.28 +void kexec_crash_save_cpu(void)
    3.29  {
    3.30      int cpu = smp_processor_id();
    3.31      crash_note_t *cntp;
    3.32  
    3.33 -    if ( !cpu_test_and_set(cpu, crash_saved_cpus) )
    3.34 -    {
    3.35 -        cntp = &per_cpu(crash_notes, cpu);
    3.36 -        elf_core_save_regs(&cntp->core.desc.desc.pr_reg,
    3.37 -                           &cntp->xen_regs.desc.desc);
    3.38 +    if ( cpu_test_and_set(cpu, crash_saved_cpus) )
    3.39 +        return;
    3.40 +
    3.41 +    cntp = &per_cpu(crash_notes, cpu);
    3.42 +    elf_core_save_regs(&cntp->core.desc.desc.pr_reg,
    3.43 +                       &cntp->xen_regs.desc.desc);
    3.44  
    3.45 -        /* setup crash "CORE" note */
    3.46 -        setup_crash_note(cntp, core, CORE_STR, CORE_STR_LEN, NT_PRSTATUS);
    3.47 +    /* Set up crash "CORE" note. */
    3.48 +    setup_crash_note(cntp, core, CORE_STR, CORE_STR_LEN, NT_PRSTATUS);
    3.49  
    3.50 -        /* setup crash note "Xen", XEN_ELFNOTE_CRASH_REGS */
    3.51 -        setup_crash_note(cntp, xen_regs, XEN_STR, XEN_STR_LEN,
    3.52 -                         XEN_ELFNOTE_CRASH_REGS);
    3.53 -    }
    3.54 +    /* Set up crash note "Xen", XEN_ELFNOTE_CRASH_REGS. */
    3.55 +    setup_crash_note(cntp, xen_regs, XEN_STR, XEN_STR_LEN,
    3.56 +                     XEN_ELFNOTE_CRASH_REGS);
    3.57  }
    3.58  
    3.59 -/* Setup the single Xen specific info crash note */
    3.60 -
    3.61 -crash_xen_info_t *machine_crash_save_info(void)
    3.62 +/* Set up the single Xen-specific-info crash note. */
    3.63 +crash_xen_info_t *kexec_crash_save_info(void)
    3.64  {
    3.65      int cpu = smp_processor_id();
    3.66      crash_note_t *cntp;
    3.67 @@ -99,7 +94,7 @@ crash_xen_info_t *machine_crash_save_inf
    3.68  
    3.69      cntp = &per_cpu(crash_notes, cpu);
    3.70  
    3.71 -    /* setup crash note "Xen", XEN_ELFNOTE_CRASH_INFO */
    3.72 +    /* Set up crash note "Xen", XEN_ELFNOTE_CRASH_INFO. */
    3.73      setup_crash_note(cntp, xen_info, XEN_STR, XEN_STR_LEN,
    3.74                       XEN_ELFNOTE_CRASH_INFO);
    3.75  
    3.76 @@ -117,45 +112,34 @@ crash_xen_info_t *machine_crash_save_inf
    3.77      return info;
    3.78  }
    3.79  
    3.80 -void machine_crash_kexec(void)
    3.81 +void kexec_crash(void)
    3.82  {
    3.83      int pos;
    3.84 -    xen_kexec_image_t *image;
    3.85 +
    3.86 +    pos = (test_bit(KEXEC_FLAG_CRASH_POS, &kexec_flags) != 0);
    3.87 +    if ( !test_bit(KEXEC_IMAGE_CRASH_BASE + pos, &kexec_flags) )
    3.88 +        return;
    3.89  
    3.90      one_cpu_only();
    3.91 -
    3.92 -    machine_crash_save_cpu();
    3.93 -    crashing_cpu = smp_processor_id();
    3.94 -
    3.95 +    kexec_crash_save_cpu();
    3.96      machine_crash_shutdown();
    3.97  
    3.98 -    pos = (test_bit(KEXEC_FLAG_CRASH_POS, &kexec_flags) != 0);
    3.99 +    machine_kexec(&kexec_image[KEXEC_IMAGE_CRASH_BASE + pos]);
   3.100  
   3.101 -    if ( test_bit(KEXEC_IMAGE_CRASH_BASE + pos, &kexec_flags) )
   3.102 -    {
   3.103 -        image = &kexec_image[KEXEC_IMAGE_CRASH_BASE + pos];
   3.104 -        machine_kexec(image); /* Does not return */
   3.105 -    }
   3.106 +    BUG();
   3.107  }
   3.108  
   3.109  static void do_crashdump_trigger(unsigned char key)
   3.110  {
   3.111 -    int pos = (test_bit(KEXEC_FLAG_CRASH_POS, &kexec_flags) != 0);
   3.112 -    if ( test_bit(KEXEC_IMAGE_CRASH_BASE + pos, &kexec_flags) )
   3.113 -    {
   3.114 -        printk("'%c' pressed -> triggering crashdump\n", key);
   3.115 -        machine_crash_kexec();
   3.116 -    }
   3.117 -    else
   3.118 -    {
   3.119 -        printk("'%c' pressed -> no crash kernel loaded -- not triggering crashdump\n", key);
   3.120 -    }
   3.121 +    printk("'%c' pressed -> triggering crashdump\n", key);
   3.122 +    kexec_crash();
   3.123 +    printk(" * no crash kernel loaded!\n");
   3.124  }
   3.125  
   3.126  static __init int register_crashdump_trigger(void)
   3.127  {
   3.128 -	register_keyhandler('C', do_crashdump_trigger, "trigger a crashdump");
   3.129 -	return 0;
   3.130 +    register_keyhandler('C', do_crashdump_trigger, "trigger a crashdump");
   3.131 +    return 0;
   3.132  }
   3.133  __initcall(register_crashdump_trigger);
   3.134  
   3.135 @@ -303,7 +287,7 @@ static int kexec_exec(XEN_GUEST_HANDLE(v
   3.136          machine_reboot_kexec(image); /* Does not return */
   3.137          break;
   3.138      case KEXEC_TYPE_CRASH:
   3.139 -        machine_crash_kexec(); /* Does not return */
   3.140 +        kexec_crash(); /* Does not return */
   3.141          break;
   3.142      }
   3.143  
     4.1 --- a/xen/drivers/char/console.c	Thu Dec 14 14:13:18 2006 +0000
     4.2 +++ b/xen/drivers/char/console.c	Thu Dec 14 15:06:22 2006 +0000
     4.3 @@ -866,7 +866,7 @@ void panic(const char *fmt, ...)
     4.4  
     4.5      debugger_trap_immediate();
     4.6  
     4.7 -    machine_crash_kexec();
     4.8 +    kexec_crash();
     4.9  
    4.10      if ( opt_noreboot )
    4.11      {
     5.1 --- a/xen/include/xen/kexec.h	Thu Dec 14 14:13:18 2006 +0000
     5.2 +++ b/xen/include/xen/kexec.h	Thu Dec 14 15:06:22 2006 +0000
     5.3 @@ -5,8 +5,6 @@
     5.4  #include <asm/percpu.h>
     5.5  #include <xen/elfcore.h>
     5.6  
     5.7 -extern int crashing_cpu;
     5.8 -
     5.9  typedef struct xen_kexec_reserve {
    5.10      unsigned long size;
    5.11      unsigned long start;
    5.12 @@ -27,9 +25,9 @@ int machine_kexec_load(int type, int slo
    5.13  void machine_kexec_unload(int type, int slot, xen_kexec_image_t *image);
    5.14  void machine_kexec_reserved(xen_kexec_reserve_t *reservation);
    5.15  void machine_reboot_kexec(xen_kexec_image_t *image);
    5.16 -void machine_crash_kexec(void);
    5.17 -void machine_crash_save_cpu(void);
    5.18 -crash_xen_info_t *machine_crash_save_info(void);
    5.19 +void kexec_crash(void);
    5.20 +void kexec_crash_save_cpu(void);
    5.21 +crash_xen_info_t *kexec_crash_save_info(void);
    5.22  void machine_crash_shutdown(void);
    5.23  
    5.24  #endif /* __XEN_KEXEC_H__ */