WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 02/04] Kexec / Kdump: Code shared between x86_32 and

To: Keir Fraser <Keir.Fraser@xxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 02/04] Kexec / Kdump: Code shared between x86_32 and x86_64
From: Magnus Damm <magnus@xxxxxxxxxxxxx>
Date: Mon, 16 Oct 2006 17:33:34 +0900
Cc: Ian Pratt <m+Ian.Pratt@xxxxxxxxxxxx>, Kazuo Moriwaka <moriwaka@xxxxxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx, Akio Takebe <takebe_akio@xxxxxxxxxxxxxx>, magnus.damm@xxxxxxxxx, Isaku Yamahata <yamahata@xxxxxxxxxxxxx>, Magnus Damm <magnus@xxxxxxxxxxxxx>, Horms <horms@xxxxxxxxxxxx>
Delivery-date: Mon, 16 Oct 2006 09:37:15 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <20061016083319.7611.4399.sendpatchset@localhost>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20061016083319.7611.4399.sendpatchset@localhost>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
[PATCH 02/04] 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@xxxxxxxxxxxxx>
---

 Applies on top of xen-unstable-11760.

 patches/linux-2.6.16.29/series           |    2
 patches/linux-2.6.16.29/git-2a..f7.patch |   62 +++
 patches/linux-2.6.16.29/git-2e..11.patch |   93 +++++
 xen/arch/x86/x86_32/machine_kexec.c      |   26 +
 xen/arch/x86/x86_64/machine_kexec.c      |   27 +
 xen/include/asm-x86/elf.h                |   27 +
 xen/include/asm-x86/x86_32/elf.h         |   28 +
 xen/include/asm-x86/x86_32/kexec.h       |   48 ++
 xen/include/asm-x86/x86_64/elf.h         |   28 +
 xen/include/asm-x86/x86_64/kexec.h       |   33 +
 xen/arch/x86/crash.c                     |  178 +++++++++-
 xen/arch/x86/machine_kexec.c             |   72 +++-
 xen/arch/x86/setup.c                     |   73 +++-
 xen/arch/x86/traps.c                     |    3
 xen/arch/x86/x86_32/Makefile             |    1
 xen/arch/x86/x86_64/Makefile             |    1
 xen/include/asm-x86/fixmap.h             |    3
 xen/include/asm-x86/hypercall.h          |    5
 xen/include/asm-x86/kexec.h              |   13
 xen/include/public/kexec.h               |    7
 xen/include/xen/elfcore.h                |    3
 21 files changed, 706 insertions(+), 27 deletions(-)

--- /dev/null
+++ 
work/patches/linux-2.6.16.29/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch 
    2006-10-16 12:15:10.000000000 +0900
@@ -0,0 +1,62 @@
+From: Eric W. Biederman <ebiederm@xxxxxxxxxxxx>
+Date: Sun, 30 Jul 2006 10:03:20 +0000 (-0700)
+Subject: [PATCH] machine_kexec.c: Fix the description of segment handling
+X-Git-Tag: v2.6.18-rc4
+X-Git-Url: 
http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=2a8a3d5b65e86ec1dfef7d268c64a909eab94af7
+
+[PATCH] machine_kexec.c: Fix the description of segment handling
+
+One of my original comments in machine_kexec was unclear
+and this should fix it.
+
+Signed-off-by: Eric W. Biederman <ebiederm@xxxxxxxxxxxx>
+Cc: Andi Kleen <ak@xxxxxx>
+Acked-by: Horms <horms@xxxxxxxxxxxx>
+Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
+Signed-off-by: Linus Torvalds <torvalds@xxxxxxxx>
+---
+
+--- a/arch/i386/kernel/machine_kexec.c
++++ b/arch/i386/kernel/machine_kexec.c
+@@ -189,14 +189,11 @@ NORET_TYPE void machine_kexec(struct kim
+       memcpy((void *)reboot_code_buffer, relocate_new_kernel,
+                                               relocate_new_kernel_size);
+ 
+-      /* The segment registers are funny things, they are
+-       * automatically loaded from a table, in memory wherever you
+-       * set them to a specific selector, but this table is never
+-       * accessed again you set the segment to a different selector.
+-       *
+-       * The more common model is are caches where the behide
+-       * the scenes work is done, but is also dropped at arbitrary
+-       * times.
++      /* The segment registers are funny things, they have both a
++       * visible and an invisible part.  Whenever the visible part is
++       * set to a specific selector, the invisible part is loaded
++       * with from a table in memory.  At no other time is the
++       * descriptor table in memory accessed.
+        *
+        * I take advantage of this here by force loading the
+        * segments, before I zap the gdt with an invalid value.
+--- a/arch/x86_64/kernel/machine_kexec.c
++++ b/arch/x86_64/kernel/machine_kexec.c
+@@ -207,14 +207,11 @@ NORET_TYPE void machine_kexec(struct kim
+       __flush_tlb();
+ 
+ 
+-      /* The segment registers are funny things, they are
+-       * automatically loaded from a table, in memory wherever you
+-       * set them to a specific selector, but this table is never
+-       * accessed again unless you set the segment to a different selector.
+-       *
+-       * The more common model are caches where the behide
+-       * the scenes work is done, but is also dropped at arbitrary
+-       * times.
++      /* The segment registers are funny things, they have both a
++       * visible and an invisible part.  Whenever the visible part is
++       * set to a specific selector, the invisible part is loaded
++       * with from a table in memory.  At no other time is the
++       * descriptor table in memory accessed.
+        *
+        * I take advantage of this here by force loading the
+        * segments, before I zap the gdt with an invalid value.
--- /dev/null
+++ 
work/patches/linux-2.6.16.29/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch 
    2006-10-16 12:15:10.000000000 +0900
@@ -0,0 +1,93 @@
+From: Tobias Klauser <tklauser@xxxxxxxxxxx>
+Date: Mon, 26 Jun 2006 16:57:34 +0000 (+0200)
+Subject: Storage class should be first
+X-Git-Tag: v2.6.18-rc1
+X-Git-Url: 
http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=2efe55a9cec8418f0e0cde3dc3787a42fddc4411
+
+Storage class should be first
+
+Storage class should be before const
+
+Signed-off-by: Tobias Klauser <tklauser@xxxxxxxxxxx>
+Signed-off-by: Adrian Bunk <bunk@xxxxxxxxx>
+---
+
+--- a/arch/i386/kernel/machine_kexec.c
++++ b/arch/i386/kernel/machine_kexec.c
+@@ -133,9 +133,9 @@ typedef asmlinkage NORET_TYPE void (*rel
+                                       unsigned long start_address,
+                                       unsigned int has_pae) ATTRIB_NORET;
+ 
+-const extern unsigned char relocate_new_kernel[];
++extern const unsigned char relocate_new_kernel[];
+ extern void relocate_new_kernel_end(void);
+-const extern unsigned int relocate_new_kernel_size;
++extern const unsigned int relocate_new_kernel_size;
+ 
+ /*
+  * A architecture hook called to validate the
+--- a/arch/powerpc/kernel/machine_kexec_32.c
++++ b/arch/powerpc/kernel/machine_kexec_32.c
+@@ -30,8 +30,8 @@ typedef NORET_TYPE void (*relocate_new_k
+  */
+ void default_machine_kexec(struct kimage *image)
+ {
+-      const extern unsigned char relocate_new_kernel[];
+-      const extern unsigned int relocate_new_kernel_size;
++      extern const unsigned char relocate_new_kernel[];
++      extern const unsigned int relocate_new_kernel_size;
+       unsigned long page_list;
+       unsigned long reboot_code_buffer, reboot_code_buffer_phys;
+       relocate_new_kernel_t rnk;
+--- a/arch/ppc/kernel/machine_kexec.c
++++ b/arch/ppc/kernel/machine_kexec.c
+@@ -25,8 +25,8 @@ typedef NORET_TYPE void (*relocate_new_k
+                               unsigned long reboot_code_buffer,
+                               unsigned long start_address) ATTRIB_NORET;
+ 
+-const extern unsigned char relocate_new_kernel[];
+-const extern unsigned int relocate_new_kernel_size;
++extern const unsigned char relocate_new_kernel[];
++extern const unsigned int relocate_new_kernel_size;
+ 
+ void machine_shutdown(void)
+ {
+--- a/arch/s390/kernel/machine_kexec.c
++++ b/arch/s390/kernel/machine_kexec.c
+@@ -27,8 +27,8 @@ static void kexec_halt_all_cpus(void *);
+ 
+ typedef void (*relocate_kernel_t) (kimage_entry_t *, unsigned long);
+ 
+-const extern unsigned char relocate_kernel[];
+-const extern unsigned long long relocate_kernel_len;
++extern const unsigned char relocate_kernel[];
++extern const unsigned long long relocate_kernel_len;
+ 
+ int
+ machine_kexec_prepare(struct kimage *image)
+--- a/arch/sh/kernel/machine_kexec.c
++++ b/arch/sh/kernel/machine_kexec.c
+@@ -25,8 +25,8 @@ typedef NORET_TYPE void (*relocate_new_k
+                               unsigned long start_address,
+                               unsigned long vbr_reg) ATTRIB_NORET;
+ 
+-const extern unsigned char relocate_new_kernel[];
+-const extern unsigned int relocate_new_kernel_size;
++extern const unsigned char relocate_new_kernel[];
++extern const unsigned int relocate_new_kernel_size;
+ extern void *gdb_vbr_vector;
+ 
+ /*
+--- a/arch/x86_64/kernel/machine_kexec.c
++++ b/arch/x86_64/kernel/machine_kexec.c
+@@ -149,8 +149,8 @@ typedef NORET_TYPE void (*relocate_new_k
+                                       unsigned long start_address,
+                                       unsigned long pgtable) ATTRIB_NORET;
+ 
+-const extern unsigned char relocate_new_kernel[];
+-const extern unsigned long relocate_new_kernel_size;
++extern const unsigned char relocate_new_kernel[];
++extern const unsigned long relocate_new_kernel_size;
+ 
+ int machine_kexec_prepare(struct kimage *image)
+ {
--- 0003/patches/linux-2.6.16.29/series
+++ work/patches/linux-2.6.16.29/series 2006-10-16 12:15:09.000000000 +0900
@@ -1,4 +1,6 @@
 kexec-generic.patch
+git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch
+git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch
 blktap-aio-16_03_06.patch
 device_bind.patch
 fix-hz-suspend.patch
--- 0003/xen/arch/x86/crash.c
+++ work/xen/arch/x86/crash.c   2006-10-16 12:15:09.000000000 +0900
@@ -3,16 +3,188 @@
  * 
  * Created By: Horms
  *
- * Should be based heavily on arch/i386/kernel/crash.c from Linux 2.6.16
+ * Based heavily on arch/i386/kernel/crash.c from Linux 2.6.16
  */
 
-#include <xen/lib.h>       /* for printk() used in stub */
+#include <asm/atomic.h>
+#include <asm/elf.h>
+#include <asm/percpu.h>
+#include <asm/kexec.h>
 #include <xen/types.h>
+#include <xen/irq.h>
+#include <asm/ipi.h>
+#include <asm/nmi.h>
+#include <xen/string.h>
+#include <xen/elf.h>
+#include <xen/elfcore.h>
+#include <xen/smp.h>
+#include <xen/delay.h>
+#include <xen/perfc.h>
+#include <xen/kexec.h>
 #include <public/xen.h>
+#include <asm/hvm/hvm.h>
+
+static int crashing_cpu;
+
+static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
+                                                              size_t data_len)
+{
+       Elf_Note note;
+
+       note.namesz = strlen(name) + 1;
+       note.descsz = data_len;
+       note.type   = type;
+       memcpy(buf, &note, sizeof(note));
+       buf += (sizeof(note) +3)/4;
+       memcpy(buf, name, note.namesz);
+       buf += (note.namesz + 3)/4;
+       memcpy(buf, data, note.descsz);
+       buf += (note.descsz + 3)/4;
+
+       return buf;
+}
+
+static void final_note(u32 *buf)
+{
+       Elf_Note note;
+
+       note.namesz = 0;
+       note.descsz = 0;
+       note.type   = 0;
+       memcpy(buf, &note, sizeof(note));
+}
+
+static void crash_save_this_cpu(struct cpu_user_regs *regs, int cpu)
+{
+       ELF_Prstatus prstatus;
+       uint32_t *buf;
+
+       printk("crash_save_this_cpu: %d\n",  cpu);
+
+       if ((cpu < 0) || (cpu >= NR_CPUS))
+               return;
+
+       /* Using ELF notes here is opportunistic.
+        * A well defined structure format with tags is needed
+        * ELF notes happen to provide this and there is infastructure
+        * in the Linux kernel to supprot them. In order to make
+        * crash dumps produced by xen the same, the same
+        * technique is used here.
+        */
+
+       /* It should be safe to use per_cpu() here instead of per_cpu_ptr()
+        * (which does not exist in xen) as kexecing_lock must be held in
+        * order to get anywhere near here */
+       buf = (uint32_t *)per_cpu(crash_notes, cpu);
+       if (!buf) /* XXX: Can this ever occur? */
+               return;
+       memset(&prstatus, 0, sizeof(prstatus));
+       /* XXX: Xen does not have processes. For the crashing CPU on a dom0
+        * crash this could be pased down from dom0, but is this
+        * neccessary?
+        * prstatus.pr_pid = current->pid; */
+       ELF_CORE_COPY_REGS(prstatus.pr_reg, regs);
+       buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
+                               sizeof(prstatus));
+       final_note(buf);
+}
+
+static void crash_save_self(struct cpu_user_regs *regs)
+{
+       crash_save_this_cpu(regs, smp_processor_id());
+}
+
+#ifdef CONFIG_SMP
+static atomic_t waiting_for_crash_ipi;
+
+static int crash_nmi_callback(struct cpu_user_regs *regs, int cpu)
+{
+       struct cpu_user_regs fixed_regs;
+
+       /* Don't do anything if this handler is invoked on crashing cpu.
+        * Otherwise, system will completely hang. Crashing cpu can get
+        * an NMI if system was initially booted with nmi_watchdog parameter.
+        */
+       if (cpu == crashing_cpu)
+               return 1;
+       local_irq_disable();
+
+#ifdef CONFIG_X86_32
+       if (!user_mode(regs)) {
+               crash_fixup_ss_esp(&fixed_regs, regs);
+               regs = &fixed_regs;
+       }
+#endif
+       crash_save_this_cpu(regs, cpu);
+       disable_local_APIC();
+       atomic_dec(&waiting_for_crash_ipi);
+    hvm_disable();
+
+    for ( ; ; )
+        __asm__ __volatile__ ( "hlt" );
+
+       return 1;
+
+       /* Need to use this somewhere as Xen builds with -Werror */
+       crash_setup_regs(&fixed_regs, regs);
+}
+
+/*
+ * By using the NMI code instead of a vector we just sneak thru the
+ * word generator coming out with just what we want.  AND it does
+ * not matter if clustered_apic_mode is set or not.
+ */
+static void smp_send_nmi_allbutself(void)
+{
+       cpumask_t allbutself = cpu_online_map;
+       cpu_clear(smp_processor_id(), allbutself);
+       send_IPI_mask(allbutself, APIC_DM_NMI);
+}
+
+static void nmi_shootdown_cpus(void)
+{
+       unsigned long msecs;
+
+       atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
+       /* Would it be better to replace the trap vector here? */
+       set_nmi_callback(crash_nmi_callback);
+       /* Ensure the new callback function is set before sending
+        * out the NMI
+        */
+       wmb();
+
+       smp_send_nmi_allbutself();
+
+       msecs = 1000; /* Wait at most a second for the other cpus to stop */
+       while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
+               mdelay(1);
+               msecs--;
+       }
+
+       /* Leave the nmi callback set */
+       disable_local_APIC();
+}
+#else
+static void nmi_shootdown_cpus(void)
+{
+       /* There are no cpus to shootdown */
+}
+#endif
 
 void machine_crash_shutdown(struct cpu_user_regs *regs)
 {
-    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+       printk("machine_crash_shutdown: %d\n", smp_processor_id());
+       local_irq_disable();
+
+       crashing_cpu = smp_processor_id();
+       nmi_shootdown_cpus();
+
+#ifdef CONFIG_X86_IO_APIC
+    disable_IO_APIC();
+#endif
+    hvm_disable();
+
+       crash_save_self(regs);
 }
 
 /*
--- 0003/xen/arch/x86/machine_kexec.c
+++ work/xen/arch/x86/machine_kexec.c   2006-10-16 12:15:09.000000000 +0900
@@ -4,30 +4,84 @@
  * Created By: Horms
  *
  */
-
-#include <xen/lib.h>       /* for printk() used in stubs */
+  
+#include <xen/lib.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/flushtlb.h>
+#include <xen/smp.h>
+#include <xen/nmi.h>
 #include <xen/types.h>
+#include <xen/console.h>
+#include <xen/kexec.h>
 #include <public/kexec.h>
+#include <xen/domain_page.h>
+#include <asm/fixmap.h>
+#include <asm/hvm/hvm.h>
 
 int machine_kexec_load(int type, xen_kexec_image_t *image)
 {
-    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
-    return -1;
+    unsigned long prev_ma = 0;
+    int k;
+
+    /* setup fixmap to point to our pages and record the virtual address
+     * in every odd index in page_list[].
+     */
+
+    for (k = 0; k < KEXEC_XEN_NO_PAGES; k++) {
+        if ((k & 1) == 0) {               /* even pages: machine address */
+            prev_ma = image->page_list[k];
+        }
+        else {                            /* odd pages: va for previous ma */
+            set_fixmap(FIX_KEXEC_BASE_0 + (k >> 1), prev_ma);
+            image->page_list[k] = fix_to_virt(FIX_KEXEC_BASE_0 + (k >> 1));
+        }
+    }
+
+    return 0;
 }
 
 void machine_kexec_unload(int type, xen_kexec_image_t *image)
 {
-    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
 }
 
-void machine_kexec(xen_kexec_image_t *image)
+static void __machine_shutdown(void *data)
 {
-    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
-}
+    xen_kexec_image_t *image = (xen_kexec_image_t *)data;
+
+    watchdog_disable();
+    console_start_sync();
 
+    smp_send_stop();
+
+#ifdef CONFIG_X86_IO_APIC
+    disable_IO_APIC();
+#endif
+    hvm_disable();
+
+    machine_kexec(image);
+}
+  
 void machine_shutdown(xen_kexec_image_t *image)
 {
-    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+    int reboot_cpu_id;
+    cpumask_t reboot_cpu;
+
+    reboot_cpu_id = 0;
+
+    if (!cpu_isset(reboot_cpu_id, cpu_online_map))
+        reboot_cpu_id = smp_processor_id();
+    
+    if (reboot_cpu_id != smp_processor_id()) {
+        cpus_clear(reboot_cpu);
+        cpu_set(reboot_cpu_id, reboot_cpu);
+        on_selected_cpus(reboot_cpu, __machine_shutdown, image, 1, 0);
+        for (;;)
+                ; /* nothing */
+    }
+    else
+        __machine_shutdown(image);
+    BUG();
 }
 
 /*
--- 0001/xen/arch/x86/setup.c
+++ work/xen/arch/x86/setup.c   2006-10-16 12:20:51.000000000 +0900
@@ -26,6 +26,7 @@
 #include <asm/shadow.h>
 #include <asm/e820.h>
 #include <acm/acm_hooks.h>
+#include <xen/kexec.h>
 
 extern void dmi_scan_machine(void);
 extern void generic_apic_probe(void);
@@ -219,6 +220,20 @@ static void __init init_idle_domain(void
     setup_idle_pagetable();
 }
 
+void __init move_memory(unsigned long dst, 
+                          unsigned long src_start, unsigned long src_end)
+{
+#if defined(CONFIG_X86_32)
+    memmove((void *)dst,  /* use low mapping */
+            (void *)src_start,      /* use low mapping */
+            src_end - src_start);
+#elif defined(CONFIG_X86_64)
+    memmove(__va(dst),
+            __va(src_start),
+            src_end - src_start);
+#endif
+}
+
 void __init __start_xen(multiboot_info_t *mbi)
 {
     char __cmdline[] = "", *cmdline = __cmdline;
@@ -228,6 +243,7 @@ void __init __start_xen(multiboot_info_t
     unsigned long nr_pages, modules_length;
     paddr_t s, e;
     int i, e820_warn = 0, e820_raw_nr = 0, bytes = 0;
+    xen_kexec_reserve_t crash_area;
     struct ns16550_defaults ns16550 = {
         .data_bits = 8,
         .parity    = 'n',
@@ -359,15 +375,8 @@ void __init __start_xen(multiboot_info_t
         initial_images_start = xenheap_phys_end;
     initial_images_end = initial_images_start + modules_length;
 
-#if defined(CONFIG_X86_32)
-    memmove((void *)initial_images_start,  /* use low mapping */
-            (void *)mod[0].mod_start,      /* use low mapping */
-            mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
-#elif defined(CONFIG_X86_64)
-    memmove(__va(initial_images_start),
-            __va(mod[0].mod_start),
-            mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
-#endif
+    move_memory(initial_images_start, 
+                mod[0].mod_start, mod[mbi->mods_count-1].mod_end);
 
     /* Initialise boot-time allocator with all RAM situated after modules. */
     xenheap_phys_start = init_boot_allocator(__pa(&_end));
@@ -415,6 +424,52 @@ void __init __start_xen(multiboot_info_t
 #endif
     }
 
+    machine_kexec_reserved(&crash_area);
+    if (crash_area.size > 0) {
+        unsigned long kdump_start, kdump_size, k;
+
+        /* mark images pages as free for now */
+
+        init_boot_pages(initial_images_start, initial_images_end);
+
+        kdump_start = crash_area.start;
+        kdump_size = crash_area.size;
+
+        printk("Kdump: %luMB (%lukB) at 0x%lx\n", 
+               kdump_size >> 20,
+               kdump_size >> 10,
+               kdump_start);
+
+        if ((kdump_start & ~PAGE_MASK) || (kdump_size & ~PAGE_MASK))
+            panic("Kdump parameters not page aligned\n");
+
+        kdump_start >>= PAGE_SHIFT;
+        kdump_size >>= PAGE_SHIFT;
+
+        /* allocate pages for Kdump memory area */
+
+        k = alloc_boot_pages_at(kdump_size, kdump_start);
+
+        if (k != kdump_start)
+            panic("Unable to reserve Kdump memory\n");
+
+        /* allocate pages for relocated initial images */
+
+        k = ((initial_images_end - initial_images_start) & ~PAGE_MASK) ? 1 : 0;
+        k += (initial_images_end - initial_images_start) >> PAGE_SHIFT;
+
+        k = alloc_boot_pages(k, 1);
+
+        if (!k)
+            panic("Unable to allocate initial images memory\n");
+
+        move_memory(k << PAGE_SHIFT, initial_images_start, initial_images_end);
+
+        initial_images_end -= initial_images_start;
+        initial_images_start = k << PAGE_SHIFT;
+        initial_images_end += initial_images_start;
+    }        
+
     memguard_init();
     percpu_guard_areas();
 
--- 0001/xen/arch/x86/traps.c
+++ work/xen/arch/x86/traps.c   2006-10-16 12:15:09.000000000 +0900
@@ -105,6 +105,8 @@ unsigned long do_get_debugreg(int reg);
 static int debug_stack_lines = 20;
 integer_param("debug_stack_lines", debug_stack_lines);
 
+extern void crash_kexec(struct cpu_user_regs *regs);
+
 #ifdef CONFIG_X86_32
 #define stack_words_per_line 8
 #define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)&regs->esp)
@@ -1595,6 +1597,7 @@ static void unknown_nmi_error(unsigned c
         printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
         printk("Dazed and confused, but trying to continue\n");
         printk("Do you have a strange power saving mode enabled?\n");
+        crash_kexec(NULL);
     }
 }
 
--- 0001/xen/arch/x86/x86_32/Makefile
+++ work/xen/arch/x86/x86_32/Makefile   2006-10-16 12:15:09.000000000 +0900
@@ -3,5 +3,6 @@ obj-y += entry.o
 obj-y += mm.o
 obj-y += seg_fixup.o
 obj-y += traps.o
+obj-y += machine_kexec.o
 
 obj-$(supervisor_mode_kernel) += supervisor_mode_kernel.o
--- /dev/null
+++ work/xen/arch/x86/x86_32/machine_kexec.c    2006-10-16 12:15:11.000000000 
+0900
@@ -0,0 +1,26 @@
+/*
+ * arch/x86/x86_32/machine_kexec.c
+ * Handle transition of Linux booting another kernel
+ *
+ * Created By: Horms <horms@xxxxxxxxxxxx>
+ *
+ * Should be losely based on arch/i386/kernel/machine_kexec.c
+ */
+
+#include <xen/lib.h>       /* for printk() used in stub */
+#include <public/kexec.h>
+
+void machine_kexec(xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- 0001/xen/arch/x86/x86_64/Makefile
+++ work/xen/arch/x86/x86_64/Makefile   2006-10-16 12:15:09.000000000 +0900
@@ -1,3 +1,4 @@
 obj-y += entry.o
 obj-y += mm.o
 obj-y += traps.o
+obj-y += machine_kexec.o
--- /dev/null
+++ work/xen/arch/x86/x86_64/machine_kexec.c    2006-10-16 12:15:11.000000000 
+0900
@@ -0,0 +1,27 @@
+/******************************************************************************
+ * arch/x86/x86_64/machine_kexec.c
+ * Handle transition of Linux booting another kernel
+ *
+ * Created By: Horms <horms@xxxxxxxxxxxx>
+ *
+ * Should be losely based on arch/x86_64/kernel/machine_kexec.c
+ */
+
+#include <xen/lib.h>       /* for printk() used in stub */
+#include <xen/types.h>
+#include <public/kexec.h>
+
+void machine_kexec(xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+++ work/xen/include/asm-x86/elf.h      2006-10-16 12:15:10.000000000 +0900
@@ -0,0 +1,27 @@
+/******************************************************************************
+ * include/asm-x86/elf.h
+ * 
+ * Created By: Horms
+ *
+ */
+
+#ifndef __X86_ELF_H__
+#define __X86_ELF_H__
+
+#ifdef __x86_64__
+#include <asm/x86_64/elf.h>
+#else
+#include <asm/x86_32/elf.h>
+#endif
+
+#endif /* __X86_ELF_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- 0001/xen/include/asm-x86/fixmap.h
+++ work/xen/include/asm-x86/fixmap.h   2006-10-16 12:15:09.000000000 +0900
@@ -16,6 +16,7 @@
 #include <asm/apicdef.h>
 #include <asm/acpi.h>
 #include <asm/page.h>
+#include <public/kexec.h>
 
 /*
  * Here we define all the compile-time 'special' virtual
@@ -36,6 +37,8 @@ enum fixed_addresses {
     FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
     FIX_HPET_BASE,
     FIX_CYCLONE_TIMER,
+    FIX_KEXEC_BASE_0,
+    FIX_KEXEC_BASE_END = FIX_KEXEC_BASE_0 + (KEXEC_XEN_NO_PAGES >> 1)-1,
     __end_of_fixed_addresses
 };
 
--- 0001/xen/include/asm-x86/hypercall.h
+++ work/xen/include/asm-x86/hypercall.h        2006-10-16 12:15:09.000000000 
+0900
@@ -6,6 +6,7 @@
 #define __ASM_X86_HYPERCALL_H__
 
 #include <public/physdev.h>
+#include <xen/types.h>
 
 extern long
 do_event_channel_op_compat(
@@ -87,6 +88,10 @@ extern long
 arch_do_vcpu_op(
     int cmd, struct vcpu *v, XEN_GUEST_HANDLE(void) arg);
 
+extern int
+do_kexec(
+    unsigned long op, unsigned arg1, XEN_GUEST_HANDLE(void) uarg);
+
 #ifdef __x86_64__
 
 extern long
--- 0003/xen/include/asm-x86/kexec.h
+++ work/xen/include/asm-x86/kexec.h    2006-10-16 12:15:09.000000000 +0900
@@ -8,15 +8,16 @@
 #ifndef __X86_KEXEC_H__
 #define __X86_KEXEC_H__
 
-#include <xen/lib.h>       /* for printk() used in stub */
+#include <asm/processor.h>
 #include <xen/types.h>
+#include <xen/string.h>
 #include <public/xen.h>
 
-static void crash_setup_regs(struct cpu_user_regs *newregs,
-                            struct cpu_user_regs *oldregs)
-{
-    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
-}
+#ifdef __x86_64__
+#include <asm/x86_64/kexec.h>
+#else
+#include <asm/x86_32/kexec.h>
+#endif
 
 #endif /* __X86_KEXEC_H__ */
 
--- /dev/null
+++ work/xen/include/asm-x86/x86_32/elf.h       2006-10-16 12:15:10.000000000 
+0900
@@ -0,0 +1,28 @@
+/******************************************************************************
+ * include/asm-x86/x86_32/elf.h
+ * 
+ * Created By: Horms
+ *
+ * Should pull be based on include/asm-i386/elf.h:ELF_CORE_COPY_REGS
+ * from Linux 2.6.16
+ */
+
+#ifndef __X86_ELF_X86_32_H__
+#define __X86_ELF_X86_32_H__
+
+#include <xen/lib.h>       /* for printk() used in stub */
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs)                                \
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+
+#endif /* __X86_ELF_X86_32_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+++ work/xen/include/asm-x86/x86_32/kexec.h     2006-10-16 12:15:10.000000000 
+0900
@@ -0,0 +1,48 @@
+/******************************************************************************
+ * include/asm-x86/x86_32/kexec.h
+ * 
+ * Created By: Horms
+ *
+ * Should be based heavily on include/asm-i386/kexec.h from Linux 2.6.16
+ *
+ */
+
+#ifndef __X86_32_KEXEC_H__
+#define __X86_32_KEXEC_H__
+
+#include <xen/lib.h>       /* for printk() used in stub */
+#include <xen/types.h>
+#include <public/xen.h>
+
+static void crash_fixup_ss_esp(struct cpu_user_regs *newregs,
+                   struct cpu_user_regs *oldregs)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+    return;
+    crash_fixup_ss_esp(newregs, oldregs);
+}
+
+static void crash_setup_regs(struct cpu_user_regs *newregs,
+                            struct cpu_user_regs *oldregs)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
+static inline int user_mode(struct cpu_user_regs *regs)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+    return -1;
+}
+
+
+#endif /* __X86_32_KEXEC_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+++ work/xen/include/asm-x86/x86_64/elf.h       2006-10-16 12:15:10.000000000 
+0900
@@ -0,0 +1,28 @@
+/******************************************************************************
+ * include/asm-x86/x86_64/elf.h
+ * 
+ * Created By: Horms
+ *
+ * Should pull be based on include/asm-x86_64/elf.h:ELF_CORE_COPY_REGS
+ * from Linux 2.6.16
+ */
+
+#ifndef __X86_ELF_X86_64_H__
+#define __X86_ELF_X86_64_H__
+
+#include <xen/lib.h>       /* for printk() used in stub */
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs)                                \
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+
+#endif /* __X86_ELF_X86_64_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+++ work/xen/include/asm-x86/x86_64/kexec.h     2006-10-16 12:15:10.000000000 
+0900
@@ -0,0 +1,33 @@
+/******************************************************************************
+ * include/asm-x86/x86_64/kexec.h
+ * 
+ * Created By: Horms
+ *
+ * Should be based heavily on include/asm-x86_64/kexec.h from Linux 2.6.16
+ *
+ */
+
+#ifndef __X86_64_KEXEC_H__
+#define __X86_64_KEXEC_H__
+
+#include <xen/lib.h>       /* for printk() used in stub */
+#include <xen/types.h>
+#include <public/xen.h>
+
+static void crash_setup_regs(struct cpu_user_regs *newregs,
+                            struct cpu_user_regs *oldregs)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
+#endif /* __X86_64_KEXEC_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- 0003/xen/include/public/kexec.h
+++ work/xen/include/public/kexec.h     2006-10-16 12:15:09.000000000 +0900
@@ -11,6 +11,10 @@
 
 #include "xen.h"
 
+#if defined(__i386__) || defined(__x86_64__)
+#define KEXEC_XEN_NO_PAGES 17
+#endif
+
 /*
  * Prototype for this hypercall is:
  *  int kexec_op(int cmd, int type, void *extra_args)
@@ -43,6 +47,9 @@
  */
 #define KEXEC_CMD_kexec_load            1
 typedef struct xen_kexec_image {
+#if defined(__i386__) || defined(__x86_64__)
+    unsigned long page_list[KEXEC_XEN_NO_PAGES];
+#endif
     unsigned long indirection_page;
     unsigned long start_address;
 } xen_kexec_image_t;
--- 0003/xen/include/xen/elfcore.h
+++ work/xen/include/xen/elfcore.h      2006-10-16 12:15:09.000000000 +0900
@@ -16,6 +16,9 @@
 #include <public/xen.h>
 
 #define NT_PRSTATUS     1
+#define NT_XEN_DOM0_CR3 0x10000001 /* XXX: Hopefully this is unused,
+                                          feel free to change to a 
+                                          better/different value */
 
 typedef struct
 {

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel