ia64/xen-unstable

changeset 12677:2b43fb3afb3e

[XEN] Kexec / Kdump: Code shared between x86_32 and x86_64

This patch contains Kexec / Kdump code shared between x86_32 and x86_64.

Signed-Off-By: Magnus Damm <magnus@valinux.co.jp>
Signed-Off-By: Simon Horman <horms@verge.net.au>
author Ian Campbell <ian.campbell@xensource.com>
date Thu Nov 30 12:38:51 2006 +0000 (2006-11-30)
parents c988f781817d
children 5690d18637f5
files patches/linux-2.6.16.33/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch patches/linux-2.6.16.33/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch patches/linux-2.6.16.33/series xen/arch/x86/crash.c xen/arch/x86/machine_kexec.c xen/arch/x86/setup.c xen/arch/x86/traps.c xen/include/asm-x86/elf.h xen/include/asm-x86/fixmap.h xen/include/asm-x86/hypercall.h xen/include/asm-x86/kexec.h xen/include/asm-x86/x86_32/elf.h xen/include/asm-x86/x86_32/kexec.h xen/include/asm-x86/x86_64/elf.h xen/include/asm-x86/x86_64/kexec.h xen/include/public/kexec.h xen/include/xen/elfcore.h
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/patches/linux-2.6.16.33/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch	Thu Nov 30 12:38:51 2006 +0000
     1.3 @@ -0,0 +1,62 @@
     1.4 +From: Eric W. Biederman <ebiederm@xmission.com>
     1.5 +Date: Sun, 30 Jul 2006 10:03:20 +0000 (-0700)
     1.6 +Subject: [PATCH] machine_kexec.c: Fix the description of segment handling
     1.7 +X-Git-Tag: v2.6.18-rc4
     1.8 +X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=2a8a3d5b65e86ec1dfef7d268c64a909eab94af7
     1.9 +
    1.10 +[PATCH] machine_kexec.c: Fix the description of segment handling
    1.11 +
    1.12 +One of my original comments in machine_kexec was unclear
    1.13 +and this should fix it.
    1.14 +
    1.15 +Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
    1.16 +Cc: Andi Kleen <ak@muc.de>
    1.17 +Acked-by: Horms <horms@verge.net.au>
    1.18 +Signed-off-by: Andrew Morton <akpm@osdl.org>
    1.19 +Signed-off-by: Linus Torvalds <torvalds@osdl.org>
    1.20 +---
    1.21 +
    1.22 +--- a/arch/i386/kernel/machine_kexec.c
    1.23 ++++ b/arch/i386/kernel/machine_kexec.c
    1.24 +@@ -189,14 +189,11 @@ NORET_TYPE void machine_kexec(struct kim
    1.25 + 	memcpy((void *)reboot_code_buffer, relocate_new_kernel,
    1.26 + 						relocate_new_kernel_size);
    1.27 + 
    1.28 +-	/* The segment registers are funny things, they are
    1.29 +-	 * automatically loaded from a table, in memory wherever you
    1.30 +-	 * set them to a specific selector, but this table is never
    1.31 +-	 * accessed again you set the segment to a different selector.
    1.32 +-	 *
    1.33 +-	 * The more common model is are caches where the behide
    1.34 +-	 * the scenes work is done, but is also dropped at arbitrary
    1.35 +-	 * times.
    1.36 ++	/* The segment registers are funny things, they have both a
    1.37 ++	 * visible and an invisible part.  Whenever the visible part is
    1.38 ++	 * set to a specific selector, the invisible part is loaded
    1.39 ++	 * with from a table in memory.  At no other time is the
    1.40 ++	 * descriptor table in memory accessed.
    1.41 + 	 *
    1.42 + 	 * I take advantage of this here by force loading the
    1.43 + 	 * segments, before I zap the gdt with an invalid value.
    1.44 +--- a/arch/x86_64/kernel/machine_kexec.c
    1.45 ++++ b/arch/x86_64/kernel/machine_kexec.c
    1.46 +@@ -207,14 +207,11 @@ NORET_TYPE void machine_kexec(struct kim
    1.47 + 	__flush_tlb();
    1.48 + 
    1.49 + 
    1.50 +-	/* The segment registers are funny things, they are
    1.51 +-	 * automatically loaded from a table, in memory wherever you
    1.52 +-	 * set them to a specific selector, but this table is never
    1.53 +-	 * accessed again unless you set the segment to a different selector.
    1.54 +-	 *
    1.55 +-	 * The more common model are caches where the behide
    1.56 +-	 * the scenes work is done, but is also dropped at arbitrary
    1.57 +-	 * times.
    1.58 ++	/* The segment registers are funny things, they have both a
    1.59 ++	 * visible and an invisible part.  Whenever the visible part is
    1.60 ++	 * set to a specific selector, the invisible part is loaded
    1.61 ++	 * with from a table in memory.  At no other time is the
    1.62 ++	 * descriptor table in memory accessed.
    1.63 + 	 *
    1.64 + 	 * I take advantage of this here by force loading the
    1.65 + 	 * segments, before I zap the gdt with an invalid value.
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/patches/linux-2.6.16.33/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch	Thu Nov 30 12:38:51 2006 +0000
     2.3 @@ -0,0 +1,93 @@
     2.4 +From: Tobias Klauser <tklauser@nuerscht.ch>
     2.5 +Date: Mon, 26 Jun 2006 16:57:34 +0000 (+0200)
     2.6 +Subject: Storage class should be first
     2.7 +X-Git-Tag: v2.6.18-rc1
     2.8 +X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=2efe55a9cec8418f0e0cde3dc3787a42fddc4411
     2.9 +
    2.10 +Storage class should be first
    2.11 +
    2.12 +Storage class should be before const
    2.13 +
    2.14 +Signed-off-by: Tobias Klauser <tklauser@nuerscht.ch>
    2.15 +Signed-off-by: Adrian Bunk <bunk@stusta.de>
    2.16 +---
    2.17 +
    2.18 +--- a/arch/i386/kernel/machine_kexec.c
    2.19 ++++ b/arch/i386/kernel/machine_kexec.c
    2.20 +@@ -133,9 +133,9 @@ typedef asmlinkage NORET_TYPE void (*rel
    2.21 + 					unsigned long start_address,
    2.22 + 					unsigned int has_pae) ATTRIB_NORET;
    2.23 + 
    2.24 +-const extern unsigned char relocate_new_kernel[];
    2.25 ++extern const unsigned char relocate_new_kernel[];
    2.26 + extern void relocate_new_kernel_end(void);
    2.27 +-const extern unsigned int relocate_new_kernel_size;
    2.28 ++extern const unsigned int relocate_new_kernel_size;
    2.29 + 
    2.30 + /*
    2.31 +  * A architecture hook called to validate the
    2.32 +--- a/arch/powerpc/kernel/machine_kexec_32.c
    2.33 ++++ b/arch/powerpc/kernel/machine_kexec_32.c
    2.34 +@@ -30,8 +30,8 @@ typedef NORET_TYPE void (*relocate_new_k
    2.35 +  */
    2.36 + void default_machine_kexec(struct kimage *image)
    2.37 + {
    2.38 +-	const extern unsigned char relocate_new_kernel[];
    2.39 +-	const extern unsigned int relocate_new_kernel_size;
    2.40 ++	extern const unsigned char relocate_new_kernel[];
    2.41 ++	extern const unsigned int relocate_new_kernel_size;
    2.42 + 	unsigned long page_list;
    2.43 + 	unsigned long reboot_code_buffer, reboot_code_buffer_phys;
    2.44 + 	relocate_new_kernel_t rnk;
    2.45 +--- a/arch/ppc/kernel/machine_kexec.c
    2.46 ++++ b/arch/ppc/kernel/machine_kexec.c
    2.47 +@@ -25,8 +25,8 @@ typedef NORET_TYPE void (*relocate_new_k
    2.48 + 				unsigned long reboot_code_buffer,
    2.49 + 				unsigned long start_address) ATTRIB_NORET;
    2.50 + 
    2.51 +-const extern unsigned char relocate_new_kernel[];
    2.52 +-const extern unsigned int relocate_new_kernel_size;
    2.53 ++extern const unsigned char relocate_new_kernel[];
    2.54 ++extern const unsigned int relocate_new_kernel_size;
    2.55 + 
    2.56 + void machine_shutdown(void)
    2.57 + {
    2.58 +--- a/arch/s390/kernel/machine_kexec.c
    2.59 ++++ b/arch/s390/kernel/machine_kexec.c
    2.60 +@@ -27,8 +27,8 @@ static void kexec_halt_all_cpus(void *);
    2.61 + 
    2.62 + typedef void (*relocate_kernel_t) (kimage_entry_t *, unsigned long);
    2.63 + 
    2.64 +-const extern unsigned char relocate_kernel[];
    2.65 +-const extern unsigned long long relocate_kernel_len;
    2.66 ++extern const unsigned char relocate_kernel[];
    2.67 ++extern const unsigned long long relocate_kernel_len;
    2.68 + 
    2.69 + int
    2.70 + machine_kexec_prepare(struct kimage *image)
    2.71 +--- a/arch/sh/kernel/machine_kexec.c
    2.72 ++++ b/arch/sh/kernel/machine_kexec.c
    2.73 +@@ -25,8 +25,8 @@ typedef NORET_TYPE void (*relocate_new_k
    2.74 + 				unsigned long start_address,
    2.75 + 				unsigned long vbr_reg) ATTRIB_NORET;
    2.76 + 
    2.77 +-const extern unsigned char relocate_new_kernel[];
    2.78 +-const extern unsigned int relocate_new_kernel_size;
    2.79 ++extern const unsigned char relocate_new_kernel[];
    2.80 ++extern const unsigned int relocate_new_kernel_size;
    2.81 + extern void *gdb_vbr_vector;
    2.82 + 
    2.83 + /*
    2.84 +--- a/arch/x86_64/kernel/machine_kexec.c
    2.85 ++++ b/arch/x86_64/kernel/machine_kexec.c
    2.86 +@@ -149,8 +149,8 @@ typedef NORET_TYPE void (*relocate_new_k
    2.87 + 					unsigned long start_address,
    2.88 + 					unsigned long pgtable) ATTRIB_NORET;
    2.89 + 
    2.90 +-const extern unsigned char relocate_new_kernel[];
    2.91 +-const extern unsigned long relocate_new_kernel_size;
    2.92 ++extern const unsigned char relocate_new_kernel[];
    2.93 ++extern const unsigned long relocate_new_kernel_size;
    2.94 + 
    2.95 + int machine_kexec_prepare(struct kimage *image)
    2.96 + {
     3.1 --- a/patches/linux-2.6.16.33/series	Thu Nov 30 12:38:50 2006 +0000
     3.2 +++ b/patches/linux-2.6.16.33/series	Thu Nov 30 12:38:51 2006 +0000
     3.3 @@ -1,4 +1,6 @@
     3.4  kexec-generic.patch
     3.5 +git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch
     3.6 +git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch
     3.7  blktap-aio-16_03_06.patch
     3.8  device_bind.patch
     3.9  fix-hz-suspend.patch
     4.1 --- a/xen/arch/x86/crash.c	Thu Nov 30 12:38:50 2006 +0000
     4.2 +++ b/xen/arch/x86/crash.c	Thu Nov 30 12:38:51 2006 +0000
     4.3 @@ -1,10 +1,119 @@
     4.4 -#include <xen/lib.h>       /* for printk() used in stub */
     4.5 +/******************************************************************************
     4.6 + * crash.c
     4.7 + * 
     4.8 + * Based heavily on arch/i386/kernel/crash.c from Linux 2.6.16
     4.9 + *
    4.10 + * Xen port written by:
    4.11 + * - Simon 'Horms' Horman <horms@verge.net.au>
    4.12 + * - Magnus Damm <magnus@valinux.co.jp>
    4.13 + */
    4.14 +
    4.15 +#include <asm/atomic.h>
    4.16 +#include <asm/elf.h>
    4.17 +#include <asm/percpu.h>
    4.18 +#include <asm/kexec.h>
    4.19  #include <xen/types.h>
    4.20 -#include <public/kexec.h>
    4.21 +#include <xen/irq.h>
    4.22 +#include <asm/ipi.h>
    4.23 +#include <asm/nmi.h>
    4.24 +#include <xen/string.h>
    4.25 +#include <xen/elf.h>
    4.26 +#include <xen/elfcore.h>
    4.27 +#include <xen/smp.h>
    4.28 +#include <xen/delay.h>
    4.29 +#include <xen/perfc.h>
    4.30 +#include <xen/kexec.h>
    4.31 +#include <xen/sched.h>
    4.32 +#include <public/xen.h>
    4.33 +#include <asm/hvm/hvm.h>
    4.34 +
    4.35 +#ifdef CONFIG_SMP
    4.36 +static atomic_t waiting_for_crash_ipi;
    4.37 +
    4.38 +static int crash_nmi_callback(struct cpu_user_regs *regs, int cpu)
    4.39 +{
    4.40 +	/* Don't do anything if this handler is invoked on crashing cpu.
    4.41 +	 * Otherwise, system will completely hang. Crashing cpu can get
    4.42 +	 * an NMI if system was initially booted with nmi_watchdog parameter.
    4.43 +	 */
    4.44 +	if (cpu == crashing_cpu)
    4.45 +		return 1;
    4.46 +	local_irq_disable();
    4.47 +
    4.48 +    machine_crash_save_cpu();
    4.49 +	disable_local_APIC();
    4.50 +	atomic_dec(&waiting_for_crash_ipi);
    4.51 +	hvm_disable();
    4.52 +
    4.53 +    for ( ; ; )
    4.54 +        __asm__ __volatile__ ( "hlt" );
    4.55 +
    4.56 +	return 1;
    4.57 +}
    4.58 +
    4.59 +/*
    4.60 + * By using the NMI code instead of a vector we just sneak thru the
    4.61 + * word generator coming out with just what we want.  AND it does
    4.62 + * not matter if clustered_apic_mode is set or not.
    4.63 + */
    4.64 +static void smp_send_nmi_allbutself(void)
    4.65 +{
    4.66 +    cpumask_t allbutself = cpu_online_map;
    4.67 +
    4.68 +   	cpu_clear(smp_processor_id(), allbutself);
    4.69 +    send_IPI_mask(allbutself, APIC_DM_NMI);
    4.70 +}
    4.71 +
    4.72 +static void nmi_shootdown_cpus(void)
    4.73 +{
    4.74 +	unsigned long msecs;
    4.75 +
    4.76 +	atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
    4.77 +	/* Would it be better to replace the trap vector here? */
    4.78 +	set_nmi_callback(crash_nmi_callback);
    4.79 +	/* Ensure the new callback function is set before sending
    4.80 +	 * out the NMI
    4.81 +	 */
    4.82 +	wmb();
    4.83 +
    4.84 +	smp_send_nmi_allbutself();
    4.85 +
    4.86 +	msecs = 1000; /* Wait at most a second for the other cpus to stop */
    4.87 +	while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
    4.88 +		mdelay(1);
    4.89 +		msecs--;
    4.90 +	}
    4.91 +
    4.92 +	/* Leave the nmi callback set */
    4.93 +    disable_local_APIC();
    4.94 +}
    4.95 +#endif
    4.96 +
    4.97 +static void crash_save_xen_notes(void)
    4.98 +{
    4.99 +    crash_xen_info_t *info;
   4.100 +
   4.101 +    info = machine_crash_save_info();
   4.102 +
   4.103 +    info->dom0_pfn_to_mfn_frame_list_list = \
   4.104 +        dom0->shared_info->arch.pfn_to_mfn_frame_list_list;
   4.105 +}
   4.106  
   4.107  void machine_crash_shutdown(void)
   4.108  {
   4.109 -    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
   4.110 +	printk("machine_crash_shutdown: %d\n", smp_processor_id());
   4.111 +	local_irq_disable();
   4.112 +
   4.113 +#ifdef CONFIG_SMP
   4.114 +	nmi_shootdown_cpus();
   4.115 +#endif
   4.116 +
   4.117 +#ifdef CONFIG_X86_IO_APIC
   4.118 +    disable_IO_APIC();
   4.119 +#endif
   4.120 +    hvm_disable();
   4.121 +
   4.122 +    crash_save_xen_notes();
   4.123  }
   4.124  
   4.125  /*
     5.1 --- a/xen/arch/x86/machine_kexec.c	Thu Nov 30 12:38:50 2006 +0000
     5.2 +++ b/xen/arch/x86/machine_kexec.c	Thu Nov 30 12:38:51 2006 +0000
     5.3 @@ -1,26 +1,89 @@
     5.4 -#include <xen/lib.h>       /* for printk() used in stubs */
     5.5 +/******************************************************************************
     5.6 + * machine_kexec.c
     5.7 + * 
     5.8 + * Xen port written by:
     5.9 + * - Simon 'Horms' Horman <horms@verge.net.au>
    5.10 + * - Magnus Damm <magnus@valinux.co.jp>
    5.11 + */
    5.12 +
    5.13 +#include <xen/lib.h>
    5.14 +#include <asm/irq.h>
    5.15 +#include <asm/page.h>
    5.16 +#include <asm/flushtlb.h>
    5.17 +#include <xen/smp.h>
    5.18 +#include <xen/nmi.h>
    5.19  #include <xen/types.h>
    5.20 -#include <public/kexec.h>
    5.21 +#include <xen/console.h>
    5.22 +#include <xen/kexec.h>
    5.23 +#include <asm/kexec.h>
    5.24 +#include <xen/domain_page.h>
    5.25 +#include <asm/fixmap.h>
    5.26 +#include <asm/hvm/hvm.h>
    5.27  
    5.28  int machine_kexec_load(int type, int slot, xen_kexec_image_t *image)
    5.29  {
    5.30 -    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
    5.31 -    return -1;
    5.32 +    unsigned long prev_ma = 0;
    5.33 +    int fix_base = FIX_KEXEC_BASE_0 + (slot * (KEXEC_XEN_NO_PAGES >> 1));
    5.34 +    int k;
    5.35 +
    5.36 +    /* setup fixmap to point to our pages and record the virtual address
    5.37 +     * in every odd index in page_list[].
    5.38 +     */
    5.39 +
    5.40 +    for (k = 0; k < KEXEC_XEN_NO_PAGES; k++) {
    5.41 +        if ((k & 1) == 0) {               /* even pages: machine address */
    5.42 +            prev_ma = image->page_list[k];
    5.43 +        }
    5.44 +        else {                            /* odd pages: va for previous ma */
    5.45 +            set_fixmap(fix_base + (k >> 1), prev_ma);
    5.46 +            image->page_list[k] = fix_to_virt(fix_base + (k >> 1));
    5.47 +        }
    5.48 +    }
    5.49 +
    5.50 +  return 0;
    5.51  }
    5.52  
    5.53  void machine_kexec_unload(int type, int slot, xen_kexec_image_t *image)
    5.54  {
    5.55 -    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
    5.56  }
    5.57 +  
    5.58 +static void __machine_shutdown(void *data)
    5.59 +{
    5.60 +    xen_kexec_image_t *image = (xen_kexec_image_t *)data;
    5.61 +
    5.62 +    watchdog_disable();
    5.63 +    console_start_sync();
    5.64  
    5.65 -void machine_kexec(xen_kexec_image_t *image)
    5.66 -{
    5.67 -    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
    5.68 +    smp_send_stop();
    5.69 +
    5.70 +#ifdef CONFIG_X86_IO_APIC
    5.71 +    disable_IO_APIC();
    5.72 +#endif
    5.73 +    hvm_disable();
    5.74 +
    5.75 +    machine_kexec(image);
    5.76  }
    5.77 -
    5.78 +  
    5.79  void machine_shutdown(xen_kexec_image_t *image)
    5.80  {
    5.81 -    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
    5.82 +    int reboot_cpu_id;
    5.83 +    cpumask_t reboot_cpu;
    5.84 +
    5.85 +    reboot_cpu_id = 0;
    5.86 +
    5.87 +    if (!cpu_isset(reboot_cpu_id, cpu_online_map))
    5.88 +        reboot_cpu_id = smp_processor_id();
    5.89 +    
    5.90 +    if (reboot_cpu_id != smp_processor_id()) {
    5.91 +        cpus_clear(reboot_cpu);
    5.92 +        cpu_set(reboot_cpu_id, reboot_cpu);
    5.93 +        on_selected_cpus(reboot_cpu, __machine_shutdown, image, 1, 0);
    5.94 +        for (;;)
    5.95 +                ; /* nothing */
    5.96 +    }
    5.97 +    else
    5.98 +        __machine_shutdown(image);
    5.99 +    BUG();
   5.100  }
   5.101  
   5.102  /*
     6.1 --- a/xen/arch/x86/setup.c	Thu Nov 30 12:38:50 2006 +0000
     6.2 +++ b/xen/arch/x86/setup.c	Thu Nov 30 12:38:51 2006 +0000
     6.3 @@ -27,6 +27,7 @@
     6.4  #include <asm/shadow.h>
     6.5  #include <asm/e820.h>
     6.6  #include <acm/acm_hooks.h>
     6.7 +#include <xen/kexec.h>
     6.8  
     6.9  extern void dmi_scan_machine(void);
    6.10  extern void generic_apic_probe(void);
    6.11 @@ -273,6 +274,20 @@ static void srat_detect_node(int cpu)
    6.12          printk(KERN_INFO "CPU %d APIC %d -> Node %d\n", cpu, apicid, node);
    6.13  }
    6.14  
    6.15 +void __init move_memory(unsigned long dst, 
    6.16 +                          unsigned long src_start, unsigned long src_end)
    6.17 +{
    6.18 +#if defined(CONFIG_X86_32)
    6.19 +    memmove((void *)dst,  /* use low mapping */
    6.20 +            (void *)src_start,      /* use low mapping */
    6.21 +            src_end - src_start);
    6.22 +#elif defined(CONFIG_X86_64)
    6.23 +    memmove(__va(dst),
    6.24 +            __va(src_start),
    6.25 +            src_end - src_start);
    6.26 +#endif
    6.27 +}
    6.28 +
    6.29  void __init __start_xen(multiboot_info_t *mbi)
    6.30  {
    6.31      char __cmdline[] = "", *cmdline = __cmdline;
    6.32 @@ -284,6 +299,7 @@ void __init __start_xen(multiboot_info_t
    6.33      unsigned long nr_pages, modules_length;
    6.34      paddr_t s, e;
    6.35      int i, e820_warn = 0, e820_raw_nr = 0, bytes = 0;
    6.36 +    xen_kexec_reserve_t crash_area;
    6.37      struct ns16550_defaults ns16550 = {
    6.38          .data_bits = 8,
    6.39          .parity    = 'n',
    6.40 @@ -415,15 +431,8 @@ void __init __start_xen(multiboot_info_t
    6.41          initial_images_start = xenheap_phys_end;
    6.42      initial_images_end = initial_images_start + modules_length;
    6.43  
    6.44 -#if defined(CONFIG_X86_32)
    6.45 -    memmove((void *)initial_images_start,  /* use low mapping */
    6.46 -            (void *)mod[0].mod_start,      /* use low mapping */
    6.47 -            mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
    6.48 -#elif defined(CONFIG_X86_64)
    6.49 -    memmove(__va(initial_images_start),
    6.50 -            __va(mod[0].mod_start),
    6.51 -            mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
    6.52 -#endif
    6.53 +    move_memory(initial_images_start, 
    6.54 +                mod[0].mod_start, mod[mbi->mods_count-1].mod_end);
    6.55  
    6.56      /* Initialise boot-time allocator with all RAM situated after modules. */
    6.57      xenheap_phys_start = init_boot_allocator(__pa(&_end));
    6.58 @@ -471,6 +480,52 @@ void __init __start_xen(multiboot_info_t
    6.59  #endif
    6.60      }
    6.61  
    6.62 +    machine_kexec_reserved(&crash_area);
    6.63 +    if (crash_area.size > 0) {
    6.64 +        unsigned long kdump_start, kdump_size, k;
    6.65 +
    6.66 +        /* mark images pages as free for now */
    6.67 +
    6.68 +        init_boot_pages(initial_images_start, initial_images_end);
    6.69 +
    6.70 +        kdump_start = crash_area.start;
    6.71 +        kdump_size = crash_area.size;
    6.72 +
    6.73 +        printk("Kdump: %luMB (%lukB) at 0x%lx\n", 
    6.74 +               kdump_size >> 20,
    6.75 +               kdump_size >> 10,
    6.76 +               kdump_start);
    6.77 +
    6.78 +        if ((kdump_start & ~PAGE_MASK) || (kdump_size & ~PAGE_MASK))
    6.79 +            panic("Kdump parameters not page aligned\n");
    6.80 +
    6.81 +        kdump_start >>= PAGE_SHIFT;
    6.82 +        kdump_size >>= PAGE_SHIFT;
    6.83 +
    6.84 +        /* allocate pages for Kdump memory area */
    6.85 +
    6.86 +        k = alloc_boot_pages_at(kdump_size, kdump_start);
    6.87 +
    6.88 +        if (k != kdump_start)
    6.89 +            panic("Unable to reserve Kdump memory\n");
    6.90 +
    6.91 +        /* allocate pages for relocated initial images */
    6.92 +
    6.93 +        k = ((initial_images_end - initial_images_start) & ~PAGE_MASK) ? 1 : 0;
    6.94 +        k += (initial_images_end - initial_images_start) >> PAGE_SHIFT;
    6.95 +
    6.96 +        k = alloc_boot_pages(k, 1);
    6.97 +
    6.98 +        if (!k)
    6.99 +            panic("Unable to allocate initial images memory\n");
   6.100 +
   6.101 +        move_memory(k << PAGE_SHIFT, initial_images_start, initial_images_end);
   6.102 +
   6.103 +        initial_images_end -= initial_images_start;
   6.104 +        initial_images_start = k << PAGE_SHIFT;
   6.105 +        initial_images_end += initial_images_start;
   6.106 +    }        
   6.107 +
   6.108      memguard_init();
   6.109      percpu_guard_areas();
   6.110  
     7.1 --- a/xen/arch/x86/traps.c	Thu Nov 30 12:38:50 2006 +0000
     7.2 +++ b/xen/arch/x86/traps.c	Thu Nov 30 12:38:51 2006 +0000
     7.3 @@ -45,6 +45,7 @@
     7.4  #include <xen/iocap.h>
     7.5  #include <xen/nmi.h>
     7.6  #include <xen/version.h>
     7.7 +#include <xen/kexec.h>
     7.8  #include <asm/shadow.h>
     7.9  #include <asm/system.h>
    7.10  #include <asm/io.h>
    7.11 @@ -1633,6 +1634,7 @@ static void unknown_nmi_error(unsigned c
    7.12          printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
    7.13          printk("Dazed and confused, but trying to continue\n");
    7.14          printk("Do you have a strange power saving mode enabled?\n");
    7.15 +        machine_crash_kexec();
    7.16      }
    7.17  }
    7.18  
     8.1 --- a/xen/include/asm-x86/elf.h	Thu Nov 30 12:38:50 2006 +0000
     8.2 +++ b/xen/include/asm-x86/elf.h	Thu Nov 30 12:38:51 2006 +0000
     8.3 @@ -1,21 +1,15 @@
     8.4  #ifndef __X86_ELF_H__
     8.5  #define __X86_ELF_H__
     8.6  
     8.7 -#include <xen/lib.h>       /* for printk() used in stub */
     8.8 -
     8.9  typedef struct {
    8.10 -    unsigned long dummy;
    8.11 -} ELF_Gregset;
    8.12 -
    8.13 -typedef struct {
    8.14 -    unsigned long dummy;
    8.15 +    unsigned long cr0, cr2, cr3, cr4;
    8.16  } crash_xen_core_t;
    8.17  
    8.18 -extern inline void elf_core_save_regs(ELF_Gregset *core_regs, 
    8.19 -                                      crash_xen_core_t *xen_core_regs)
    8.20 -{
    8.21 -    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
    8.22 -}
    8.23 +#ifdef __x86_64__
    8.24 +#include <asm/x86_64/elf.h>
    8.25 +#else
    8.26 +#include <asm/x86_32/elf.h>
    8.27 +#endif
    8.28  
    8.29  #endif /* __X86_ELF_H__ */
    8.30  
     9.1 --- a/xen/include/asm-x86/fixmap.h	Thu Nov 30 12:38:50 2006 +0000
     9.2 +++ b/xen/include/asm-x86/fixmap.h	Thu Nov 30 12:38:51 2006 +0000
     9.3 @@ -16,6 +16,7 @@
     9.4  #include <asm/apicdef.h>
     9.5  #include <asm/acpi.h>
     9.6  #include <asm/page.h>
     9.7 +#include <xen/kexec.h>
     9.8  
     9.9  /*
    9.10   * Here we define all the compile-time 'special' virtual
    9.11 @@ -36,6 +37,9 @@ enum fixed_addresses {
    9.12      FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
    9.13      FIX_HPET_BASE,
    9.14      FIX_CYCLONE_TIMER,
    9.15 +    FIX_KEXEC_BASE_0,
    9.16 +    FIX_KEXEC_BASE_END = FIX_KEXEC_BASE_0 \
    9.17 +      + ((KEXEC_XEN_NO_PAGES >> 1) * KEXEC_IMAGE_NR) - 1,
    9.18      __end_of_fixed_addresses
    9.19  };
    9.20  
    10.1 --- a/xen/include/asm-x86/hypercall.h	Thu Nov 30 12:38:50 2006 +0000
    10.2 +++ b/xen/include/asm-x86/hypercall.h	Thu Nov 30 12:38:51 2006 +0000
    10.3 @@ -6,6 +6,7 @@
    10.4  #define __ASM_X86_HYPERCALL_H__
    10.5  
    10.6  #include <public/physdev.h>
    10.7 +#include <xen/types.h>
    10.8  
    10.9  extern long
   10.10  do_event_channel_op_compat(
   10.11 @@ -87,6 +88,10 @@ extern long
   10.12  arch_do_vcpu_op(
   10.13      int cmd, struct vcpu *v, XEN_GUEST_HANDLE(void) arg);
   10.14  
   10.15 +extern int
   10.16 +do_kexec(
   10.17 +    unsigned long op, unsigned arg1, XEN_GUEST_HANDLE(void) uarg);
   10.18 +
   10.19  #ifdef __x86_64__
   10.20  
   10.21  extern long
    11.1 --- a/xen/include/asm-x86/kexec.h	Thu Nov 30 12:38:50 2006 +0000
    11.2 +++ b/xen/include/asm-x86/kexec.h	Thu Nov 30 12:38:51 2006 +0000
    11.3 @@ -1,15 +1,11 @@
    11.4  #ifndef __X86_KEXEC_H__
    11.5  #define __X86_KEXEC_H__
    11.6  
    11.7 -#include <xen/lib.h>       /* for printk() used in stub */
    11.8 -#include <xen/types.h>
    11.9 -#include <public/xen.h>
   11.10 -#include <xen/kexec.h>
   11.11 -
   11.12 -static inline void machine_kexec(xen_kexec_image_t *image)
   11.13 -{
   11.14 -    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
   11.15 -}
   11.16 +#ifdef __x86_64__
   11.17 +#include <asm/x86_64/kexec.h>
   11.18 +#else
   11.19 +#include <asm/x86_32/kexec.h>
   11.20 +#endif
   11.21  
   11.22  #endif /* __X86_KEXEC_H__ */
   11.23  
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/xen/include/asm-x86/x86_32/elf.h	Thu Nov 30 12:38:51 2006 +0000
    12.3 @@ -0,0 +1,26 @@
    12.4 +#ifndef __X86_32_ELF_H__
    12.5 +#define __X86_32_ELF_H__
    12.6 +
    12.7 +#include <xen/lib.h>       /* for printk() used in stub */
    12.8 +
    12.9 +typedef struct {
   12.10 +    unsigned long dummy;
   12.11 +} ELF_Gregset;
   12.12 +
   12.13 +extern inline void elf_core_save_regs(ELF_Gregset *core_regs, 
   12.14 +                                      crash_xen_core_t *xen_core_regs)
   12.15 +{
   12.16 +    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
   12.17 +}
   12.18 +
   12.19 +#endif /* __X86_32_ELF_H__ */
   12.20 +
   12.21 +/*
   12.22 + * Local variables:
   12.23 + * mode: C
   12.24 + * c-set-style: "BSD"
   12.25 + * c-basic-offset: 4
   12.26 + * tab-width: 4
   12.27 + * indent-tabs-mode: nil
   12.28 + * End:
   12.29 + */
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/xen/include/asm-x86/x86_32/kexec.h	Thu Nov 30 12:38:51 2006 +0000
    13.3 @@ -0,0 +1,24 @@
    13.4 +#ifndef __X86_32_KEXEC_H__
    13.5 +#define __X86_32_KEXEC_H__
    13.6 +
    13.7 +#include <xen/lib.h>       /* for printk() used in stub */
    13.8 +#include <xen/types.h>
    13.9 +#include <public/xen.h>
   13.10 +#include <xen/kexec.h>
   13.11 +
   13.12 +static inline void machine_kexec(xen_kexec_image_t *image)
   13.13 +{
   13.14 +    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
   13.15 +}
   13.16 +
   13.17 +#endif /* __X86_32_KEXEC_H__ */
   13.18 +
   13.19 +/*
   13.20 + * Local variables:
   13.21 + * mode: C
   13.22 + * c-set-style: "BSD"
   13.23 + * c-basic-offset: 4
   13.24 + * tab-width: 4
   13.25 + * indent-tabs-mode: nil
   13.26 + * End:
   13.27 + */
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/xen/include/asm-x86/x86_64/elf.h	Thu Nov 30 12:38:51 2006 +0000
    14.3 @@ -0,0 +1,26 @@
    14.4 +#ifndef __X86_64_ELF_H__
    14.5 +#define __X86_64_ELF_H__
    14.6 +
    14.7 +#include <xen/lib.h>       /* for printk() used in stub */
    14.8 +
    14.9 +typedef struct {
   14.10 +    unsigned long dummy;
   14.11 +} ELF_Gregset;
   14.12 +
   14.13 +extern inline void elf_core_save_regs(ELF_Gregset *core_regs, 
   14.14 +                                      crash_xen_core_t *xen_core_regs)
   14.15 +{
   14.16 +    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
   14.17 +}
   14.18 +
   14.19 +#endif /* __X86_64_ELF_H__ */
   14.20 +
   14.21 +/*
   14.22 + * Local variables:
   14.23 + * mode: C
   14.24 + * c-set-style: "BSD"
   14.25 + * c-basic-offset: 4
   14.26 + * tab-width: 4
   14.27 + * indent-tabs-mode: nil
   14.28 + * End:
   14.29 + */
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/xen/include/asm-x86/x86_64/kexec.h	Thu Nov 30 12:38:51 2006 +0000
    15.3 @@ -0,0 +1,24 @@
    15.4 +#ifndef __X86_64_KEXEC_H__
    15.5 +#define __X86_64_KEXEC_H__
    15.6 +
    15.7 +#include <xen/lib.h>       /* for printk() used in stub */
    15.8 +#include <xen/types.h>
    15.9 +#include <public/xen.h>
   15.10 +#include <xen/kexec.h>
   15.11 +
   15.12 +static inline void machine_kexec(xen_kexec_image_t *image)
   15.13 +{
   15.14 +    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
   15.15 +}
   15.16 +
   15.17 +#endif /* __X86_64_KEXEC_H__ */
   15.18 +
   15.19 +/*
   15.20 + * Local variables:
   15.21 + * mode: C
   15.22 + * c-set-style: "BSD"
   15.23 + * c-basic-offset: 4
   15.24 + * tab-width: 4
   15.25 + * indent-tabs-mode: nil
   15.26 + * End:
   15.27 + */
    16.1 --- a/xen/include/public/kexec.h	Thu Nov 30 12:38:50 2006 +0000
    16.2 +++ b/xen/include/public/kexec.h	Thu Nov 30 12:38:51 2006 +0000
    16.3 @@ -40,6 +40,10 @@
    16.4  
    16.5  #include "xen.h"
    16.6  
    16.7 +#if defined(__i386__) || defined(__x86_64__)
    16.8 +#define KEXEC_XEN_NO_PAGES 17
    16.9 +#endif
   16.10 +
   16.11  /*
   16.12   * Prototype for this hypercall is:
   16.13   *  int kexec_op(int cmd, void *args)
   16.14 @@ -72,6 +76,9 @@
   16.15   */
   16.16   
   16.17  typedef struct xen_kexec_image {
   16.18 +#if defined(__i386__) || defined(__x86_64__)
   16.19 +    unsigned long page_list[KEXEC_XEN_NO_PAGES];
   16.20 +#endif
   16.21      unsigned long indirection_page;
   16.22      unsigned long start_address;
   16.23  } xen_kexec_image_t;
    17.1 --- a/xen/include/xen/elfcore.h	Thu Nov 30 12:38:50 2006 +0000
    17.2 +++ b/xen/include/xen/elfcore.h	Thu Nov 30 12:38:51 2006 +0000
    17.3 @@ -108,6 +108,9 @@ typedef struct {
    17.4      unsigned long xen_compile_date;
    17.5      unsigned long xen_compile_time;
    17.6      unsigned long tainted;
    17.7 +#ifdef CONFIG_X86
    17.8 +    unsigned long dom0_pfn_to_mfn_frame_list_list;
    17.9 +#endif
   17.10  } crash_xen_info_t;
   17.11  
   17.12  TYPEDEF_NOTE(crash_note_xen_info_t, XEN_STR_LEN, crash_xen_info_t);