[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.