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 01/04] Kexec / Kdump: Generic code

To: Keir Fraser <Keir.Fraser@xxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 01/04] Kexec / Kdump: Generic code
From: Magnus Damm <magnus@xxxxxxxxxxxxx>
Date: Mon, 23 Oct 2006 18:05:23 +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: Tue, 24 Oct 2006 08:09:13 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <20061023090515.26706.69407.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: <20061023090515.26706.69407.sendpatchset@localhost>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
[PATCH 01/04] Kexec / Kdump: Generic code

This patch implements the generic portion of the Kexec / Kdump port to Xen.

Signed-Off-By: Magnus Damm <magnus@xxxxxxxxxxxxx>
---

 Applies on top of xen-unstable-11856.

 linux-2.6-xen-sparse/drivers/xen/core/Makefile        |    1
 linux-2.6-xen-sparse/drivers/xen/core/crash.c         |   44 ++
 linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c |   80 ++++
 linux-2.6-xen-sparse/drivers/xen/core/reboot.c        |    4
 patches/linux-2.6.16.29/kexec-generic.patch           |  281 ++++++++++++++++
 patches/linux-2.6.16.29/series                        |    1
 xen/arch/ia64/xen/Makefile                            |    2
 xen/arch/ia64/xen/crash.c                             |   19 +
 xen/arch/ia64/xen/machine_kexec.c                     |   34 ++
 xen/arch/powerpc/Makefile                             |    2
 xen/arch/powerpc/crash.c                              |   19 +
 xen/arch/powerpc/machine_kexec.c                      |   34 ++
 xen/arch/x86/Makefile                                 |    2
 xen/arch/x86/crash.c                                  |   19 +
 xen/arch/x86/machine_kexec.c                          |   34 ++
 xen/common/Makefile                                   |    1
 xen/common/kexec.c                                    |  288 +++++++++++++++++
 xen/common/page_alloc.c                               |   33 +
 xen/drivers/char/console.c                            |    3
 xen/include/asm-ia64/elf.h                            |   23 +
 xen/include/asm-ia64/kexec.h                          |   31 +
 xen/include/asm-powerpc/elf.h                         |   23 +
 xen/include/asm-powerpc/kexec.h                       |   31 +
 xen/include/asm-x86/elf.h                             |   23 +
 xen/include/asm-x86/kexec.h                           |   30 +
 xen/include/public/kexec.h                            |   88 +++++
 xen/include/xen/elfcore.h                             |   71 ++++
 xen/include/xen/hypercall.h                           |    6
 xen/include/xen/kexec.h                               |   37 ++
 xen/include/xen/mm.h                                  |    1
 30 files changed, 1254 insertions(+), 11 deletions(-)

--- 0001/linux-2.6-xen-sparse/drivers/xen/core/Makefile
+++ work/linux-2.6-xen-sparse/drivers/xen/core/Makefile 2006-10-23 
11:36:13.000000000 +0900
@@ -11,3 +11,4 @@ obj-$(CONFIG_XEN_SYSFS)               += xen_sysfs.o
 obj-$(CONFIG_XEN_SKBUFF)       += skbuff.o
 obj-$(CONFIG_XEN_REBOOT)       += reboot.o
 obj-$(CONFIG_XEN_SMPBOOT)      += smpboot.o
+obj-$(CONFIG_KEXEC)            += machine_kexec.o crash.o
--- /dev/null
+++ work/linux-2.6-xen-sparse/drivers/xen/core/crash.c  2006-10-23 
11:36:14.000000000 +0900
@@ -0,0 +1,44 @@
+#include <asm/ptrace.h>
+#include <linux/types.h>
+#include <asm/kexec-xen.h>
+#include <asm/hypervisor.h>
+#include <asm/system.h>
+#include <linux/preempt.h>
+#include <linux/smp.h>
+#include <asm/hw_irq.h>
+#include <xen/interface/kexec.h>
+
+/* 
+ * This passes the registers's down to the hypervisor and has it kexec()
+ * This is a bit different to the linux implementation which
+ * has this call save registers and stop CPUs and then goes into
+ * machine_kexec() later. But for Xen it makes more sense to
+ * have the kexec hypercall do everything, and this call
+ * has the registers parameter that is needed.
+ * to the hypervisor to allow the hypervisor to kdump itself
+ * on an internal panic 
+ */
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+       xen_kexec_exec_t xke;
+
+       printk("machine_crash_shutdown: %d\n", smp_processor_id());
+
+       local_irq_disable();
+       memset(&xke, 0, sizeof(xke));
+       xke.type = KEXEC_TYPE_CRASH;
+       crash_translate_regs(regs, &xke.regs);
+
+       HYPERVISOR_kexec_op(KEXEC_CMD_kexec, &xke);
+       panic("KEXEC_CMD_kexec hypercall should not return\n");
+}
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
--- /dev/null
+++ work/linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c  2006-10-23 
11:36:14.000000000 +0900
@@ -0,0 +1,80 @@
+/*
+ * drivers/xen/core/machine_kexec.c 
+ * handle transition of Linux booting another kernel
+ */
+
+#include <linux/kexec.h>
+#include <xen/interface/kexec.h>
+#include <linux/mm.h>
+#include <asm/hypercall.h>
+#include <asm/kexec-xen.h>
+
+extern void machine_kexec_setup_load_arg(xen_kexec_image_t *xki, 
+                                        struct kimage *image);
+
+static void setup_load_arg(xen_kexec_image_t *xki, struct kimage *image)
+{
+       machine_kexec_setup_load_arg(xki, image);
+
+       xki->indirection_page = image->head;
+       xki->start_address = image->start;
+}
+
+/*
+ * Load the image into xen so xen can kdump itself
+ * This might have been done in prepare, but prepare
+ * is currently called too early. It might make sense
+ * to move prepare, but for now, just add an extra hook.
+ */
+int xen_machine_kexec_load(struct kimage *image)
+{
+       xen_kexec_load_t xkl;
+
+       memset(&xkl, 0, sizeof(xkl));
+       xkl.type = image->type;
+       setup_load_arg(&xkl.image, image);
+       return HYPERVISOR_kexec_op(KEXEC_CMD_kexec_load, &xkl);
+}
+
+/*
+ * Unload the image that was stored by machine_kexec_load()
+ * This might have been done in machine_kexec_cleanup() but it
+ * is called too late, and its possible xen could try and kdump
+ * using resources that have been freed.
+ */
+void xen_machine_kexec_unload(struct kimage *image)
+{
+       xen_kexec_load_t xkl;
+
+       memset(&xkl, 0, sizeof(xkl));
+       xkl.type = image->type;
+       HYPERVISOR_kexec_op(KEXEC_CMD_kexec_unload, &xkl);
+}
+
+/*
+ * Do not allocate memory (or fail in any way) in machine_kexec().
+ * We are past the point of no return, committed to rebooting now.
+ *
+ * This has the hypervisor move to the prefered reboot CPU, 
+ * stop all CPUs and kexec. That is it combines machine_shutdown()
+ * and machine_kexec() in Linux kexec terms.
+ */
+NORET_TYPE void xen_machine_kexec(struct kimage *image)
+{
+       xen_kexec_exec_t xke;
+
+       memset(&xke, 0, sizeof(xke));
+       xke.type = image->type;
+       HYPERVISOR_kexec_op(KEXEC_CMD_kexec, &xke);
+       panic("KEXEC_CMD_kexec hypercall should not return\n");
+}
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
--- 0001/linux-2.6-xen-sparse/drivers/xen/core/reboot.c
+++ work/linux-2.6-xen-sparse/drivers/xen/core/reboot.c 2006-10-23 
11:36:13.000000000 +0900
@@ -65,6 +65,10 @@ void machine_power_off(void)
        HYPERVISOR_shutdown(SHUTDOWN_poweroff);
 }
 
+#ifdef CONFIG_KEXEC
+void machine_shutdown(void) { }
+#endif
+
 int reboot_thru_bios = 0;      /* for dmi_scan.c */
 EXPORT_SYMBOL(machine_restart);
 EXPORT_SYMBOL(machine_halt);
--- /dev/null
+++ work/patches/linux-2.6.16.29/kexec-generic.patch    2006-10-23 
11:36:14.000000000 +0900
@@ -0,0 +1,281 @@
+--- 0002/drivers/base/cpu.c
++++ work/drivers/base/cpu.c
+@@ -11,6 +11,10 @@
+ 
+ #include "base.h"
+ 
++#ifdef CONFIG_XEN
++#include <xen/interface/kexec.h>
++#endif
++
+ struct sysdev_class cpu_sysdev_class = {
+       set_kset_name("cpu"),
+ };
+@@ -86,6 +90,22 @@ static inline void register_cpu_control(
+ #ifdef CONFIG_KEXEC
+ #include <linux/kexec.h>
+ 
++#ifdef CONFIG_XEN
++static unsigned long get_crash_notes(int cpu)
++{
++      xen_kexec_note_t note;
++
++      memset(&note, 0, sizeof(note));
++      note.vcpu = cpu;
++
++      if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_crash_note, &note) < 0)
++              return 0UL;
++
++      return note.address;
++}
++#endif
++
++/* XXX: This only finds dom0's CPU's */
+ static ssize_t show_crash_notes(struct sys_device *dev, char *buf)
+ {
+       struct cpu *cpu = container_of(dev, struct cpu, sysdev);
+@@ -101,7 +121,11 @@ static ssize_t show_crash_notes(struct s
+        * boot up and this data does not change there after. Hence this
+        * operation should be safe. No locking required.
+        */
++#ifndef CONFIG_XEN
+       addr = __pa(per_cpu_ptr(crash_notes, cpunum));
++#else
++      addr = (unsigned long long)get_crash_notes(cpunum);
++#endif
+       rc = sprintf(buf, "%Lx\n", addr);
+       return rc;
+ }
+--- 0001/include/linux/kexec.h
++++ work/include/linux/kexec.h
+@@ -91,6 +91,11 @@ struct kimage {
+ extern NORET_TYPE void machine_kexec(struct kimage *image) ATTRIB_NORET;
+ extern int machine_kexec_prepare(struct kimage *image);
+ extern void machine_kexec_cleanup(struct kimage *image);
++#ifdef CONFIG_XEN
++extern int xen_machine_kexec_load(struct kimage *image);
++extern void xen_machine_kexec_unload(struct kimage *image);
++extern NORET_TYPE void xen_machine_kexec(struct kimage *image) ATTRIB_NORET;
++#endif
+ extern asmlinkage long sys_kexec_load(unsigned long entry,
+                                       unsigned long nr_segments,
+                                       struct kexec_segment __user *segments,
+--- 0001/kernel/kexec.c
++++ work/kernel/kexec.c
+@@ -26,6 +26,9 @@
+ #include <asm/io.h>
+ #include <asm/system.h>
+ #include <asm/semaphore.h>
++#ifdef CONFIG_XEN
++#include <asm/kexec-xen.h>
++#endif
+ 
+ /* Per cpu memory for storing cpu states in case of system crash. */
+ note_buf_t* crash_notes;
+@@ -403,7 +406,7 @@ static struct page *kimage_alloc_normal_
+               pages = kimage_alloc_pages(GFP_KERNEL, order);
+               if (!pages)
+                       break;
+-              pfn   = page_to_pfn(pages);
++              pfn   = kexec_page_to_pfn(pages);
+               epfn  = pfn + count;
+               addr  = pfn << PAGE_SHIFT;
+               eaddr = epfn << PAGE_SHIFT;
+@@ -437,6 +440,7 @@ static struct page *kimage_alloc_normal_
+       return pages;
+ }
+ 
++#ifndef CONFIG_XEN
+ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
+                                                     unsigned int order)
+ {
+@@ -490,7 +494,7 @@ static struct page *kimage_alloc_crash_c
+               }
+               /* If I don't overlap any segments I have found my hole! */
+               if (i == image->nr_segments) {
+-                      pages = pfn_to_page(hole_start >> PAGE_SHIFT);
++                      pages = kexec_pfn_to_page(hole_start >> PAGE_SHIFT);
+                       break;
+               }
+       }
+@@ -517,6 +521,13 @@ struct page *kimage_alloc_control_pages(
+ 
+       return pages;
+ }
++#else /* !CONFIG_XEN */
++struct page *kimage_alloc_control_pages(struct kimage *image,
++                                       unsigned int order)
++{
++      return kimage_alloc_normal_control_pages(image, order);
++}
++#endif
+ 
+ static int kimage_add_entry(struct kimage *image, kimage_entry_t entry)
+ {
+@@ -532,7 +543,7 @@ static int kimage_add_entry(struct kimag
+                       return -ENOMEM;
+ 
+               ind_page = page_address(page);
+-              *image->entry = virt_to_phys(ind_page) | IND_INDIRECTION;
++              *image->entry = kexec_virt_to_phys(ind_page) | IND_INDIRECTION;
+               image->entry = ind_page;
+               image->last_entry = ind_page +
+                                     ((PAGE_SIZE/sizeof(kimage_entry_t)) - 1);
+@@ -593,13 +604,13 @@ static int kimage_terminate(struct kimag
+ #define for_each_kimage_entry(image, ptr, entry) \
+       for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE); \
+               ptr = (entry & IND_INDIRECTION)? \
+-                      phys_to_virt((entry & PAGE_MASK)): ptr +1)
++                      kexec_phys_to_virt((entry & PAGE_MASK)): ptr +1)
+ 
+ static void kimage_free_entry(kimage_entry_t entry)
+ {
+       struct page *page;
+ 
+-      page = pfn_to_page(entry >> PAGE_SHIFT);
++      page = kexec_pfn_to_page(entry >> PAGE_SHIFT);
+       kimage_free_pages(page);
+ }
+ 
+@@ -611,6 +622,10 @@ static void kimage_free(struct kimage *i
+       if (!image)
+               return;
+ 
++#ifdef CONFIG_XEN
++      xen_machine_kexec_unload(image);
++#endif
++
+       kimage_free_extra_pages(image);
+       for_each_kimage_entry(image, ptr, entry) {
+               if (entry & IND_INDIRECTION) {
+@@ -686,7 +701,7 @@ static struct page *kimage_alloc_page(st
+        * have a match.
+        */
+       list_for_each_entry(page, &image->dest_pages, lru) {
+-              addr = page_to_pfn(page) << PAGE_SHIFT;
++              addr = kexec_page_to_pfn(page) << PAGE_SHIFT;
+               if (addr == destination) {
+                       list_del(&page->lru);
+                       return page;
+@@ -701,12 +716,12 @@ static struct page *kimage_alloc_page(st
+               if (!page)
+                       return NULL;
+               /* If the page cannot be used file it away */
+-              if (page_to_pfn(page) >
++              if (kexec_page_to_pfn(page) >
+                               (KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) {
+                       list_add(&page->lru, &image->unuseable_pages);
+                       continue;
+               }
+-              addr = page_to_pfn(page) << PAGE_SHIFT;
++              addr = kexec_page_to_pfn(page) << PAGE_SHIFT;
+ 
+               /* If it is the destination page we want use it */
+               if (addr == destination)
+@@ -729,7 +744,7 @@ static struct page *kimage_alloc_page(st
+                       struct page *old_page;
+ 
+                       old_addr = *old & PAGE_MASK;
+-                      old_page = pfn_to_page(old_addr >> PAGE_SHIFT);
++                      old_page = kexec_pfn_to_page(old_addr >> PAGE_SHIFT);
+                       copy_highpage(page, old_page);
+                       *old = addr | (*old & ~PAGE_MASK);
+ 
+@@ -779,7 +794,7 @@ static int kimage_load_normal_segment(st
+                       result  = -ENOMEM;
+                       goto out;
+               }
+-              result = kimage_add_page(image, page_to_pfn(page)
++              result = kimage_add_page(image, kexec_page_to_pfn(page)
+                                                               << PAGE_SHIFT);
+               if (result < 0)
+                       goto out;
+@@ -811,6 +826,7 @@ out:
+       return result;
+ }
+ 
++#ifndef CONFIG_XEN
+ static int kimage_load_crash_segment(struct kimage *image,
+                                       struct kexec_segment *segment)
+ {
+@@ -833,7 +849,7 @@ static int kimage_load_crash_segment(str
+               char *ptr;
+               size_t uchunk, mchunk;
+ 
+-              page = pfn_to_page(maddr >> PAGE_SHIFT);
++              page = kexec_pfn_to_page(maddr >> PAGE_SHIFT);
+               if (page == 0) {
+                       result  = -ENOMEM;
+                       goto out;
+@@ -881,6 +897,13 @@ static int kimage_load_segment(struct ki
+ 
+       return result;
+ }
++#else /* CONFIG_XEN */
++static int kimage_load_segment(struct kimage *image,
++                              struct kexec_segment *segment)
++{
++      return kimage_load_normal_segment(image, segment);
++}
++#endif
+ 
+ /*
+  * Exec Kernel system call: for obvious reasons only root may call it.
+@@ -991,6 +1014,11 @@ asmlinkage long sys_kexec_load(unsigned 
+               if (result)
+                       goto out;
+       }
++#ifdef CONFIG_XEN
++      result = xen_machine_kexec_load(image);
++      if (result)
++              goto out;
++#endif
+       /* Install the new kernel, and  Uninstall the old */
+       image = xchg(dest_image, image);
+ 
+@@ -1045,7 +1073,6 @@ void crash_kexec(struct pt_regs *regs)
+       struct kimage *image;
+       int locked;
+ 
+-
+       /* Take the kexec_lock here to prevent sys_kexec_load
+        * running on one cpu from replacing the crash kernel
+        * we are using after a panic on a different cpu.
+@@ -1061,12 +1088,17 @@ void crash_kexec(struct pt_regs *regs)
+                       struct pt_regs fixed_regs;
+                       crash_setup_regs(&fixed_regs, regs);
+                       machine_crash_shutdown(&fixed_regs);
++#ifdef CONFIG_XEN
++                      xen_machine_kexec(image);
++#else
+                       machine_kexec(image);
++#endif
+               }
+               xchg(&kexec_lock, 0);
+       }
+ }
+ 
++#ifndef CONFIG_XEN
+ static int __init crash_notes_memory_init(void)
+ {
+       /* Allocate memory for saving cpu registers. */
+@@ -1079,3 +1111,4 @@ static int __init crash_notes_memory_ini
+       return 0;
+ }
+ module_init(crash_notes_memory_init)
++#endif
+--- 0002/kernel/sys.c
++++ work/kernel/sys.c
+@@ -435,8 +435,12 @@ void kernel_kexec(void)
+       kernel_restart_prepare(NULL);
+       printk(KERN_EMERG "Starting new kernel\n");
+       machine_shutdown();
++#ifdef CONFIG_XEN
++      xen_machine_kexec(image);
++#else
+       machine_kexec(image);
+ #endif
++#endif
+ }
+ EXPORT_SYMBOL_GPL(kernel_kexec);
+ 
--- 0001/patches/linux-2.6.16.29/series
+++ work/patches/linux-2.6.16.29/series 2006-10-23 11:36:13.000000000 +0900
@@ -1,3 +1,4 @@
+kexec-generic.patch
 blktap-aio-16_03_06.patch
 device_bind.patch
 fix-hz-suspend.patch
--- 0001/xen/arch/ia64/xen/Makefile
+++ work/xen/arch/ia64/xen/Makefile     2006-10-23 11:36:13.000000000 +0900
@@ -1,3 +1,5 @@
+obj-y += machine_kexec.o
+obj-y += crash.o
 obj-y += acpi.o
 obj-y += dom0_ops.o
 obj-y += domain.o
--- /dev/null
+++ work/xen/arch/ia64/xen/crash.c      2006-10-23 11:36:14.000000000 +0900
@@ -0,0 +1,19 @@
+#include <xen/lib.h>       /* for printk() used in stub */
+#include <xen/types.h>
+#include <public/kexec.h>
+
+void machine_crash_shutdown(struct cpu_user_regs *regs)
+{
+    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/arch/ia64/xen/machine_kexec.c      2006-10-23 11:36:14.000000000 
+0900
@@ -0,0 +1,34 @@
+#include <xen/lib.h>       /* for printk() used in stubs */
+#include <xen/types.h>
+#include <public/kexec.h>
+
+int machine_kexec_load(int type, int slot, xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+    return -1;
+}
+
+void machine_kexec_unload(int type, int slot, xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
+void machine_kexec(xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
+void machine_shutdown(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/powerpc/Makefile
+++ work/xen/arch/powerpc/Makefile      2006-10-23 11:36:13.000000000 +0900
@@ -40,6 +40,8 @@ obj-y += smp-tbsync.o
 obj-y += sysctl.o
 obj-y += time.o
 obj-y += usercopy.o
+obj-y += machine_kexec.o
+obj-y += crash.o
 
 obj-$(debug) += 0opt.o
 obj-$(crash_debug) += gdbstub.o
--- /dev/null
+++ work/xen/arch/powerpc/crash.c       2006-10-23 11:36:14.000000000 +0900
@@ -0,0 +1,19 @@
+#include <xen/lib.h>       /* for printk() used in stub */
+#include <xen/types.h>
+#include <public/kexec.h>
+
+void machine_crash_shutdown(struct cpu_user_regs *regs)
+{
+    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/arch/powerpc/machine_kexec.c       2006-10-23 11:36:14.000000000 
+0900
@@ -0,0 +1,34 @@
+#include <xen/lib.h>       /* for printk() used in stubs */
+#include <xen/types.h>
+#include <public/kexec.h>
+
+int machine_kexec_load(int type, int slot, xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+    return -1;
+}
+
+void machine_kexec_unload(int type, int slot, xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
+void machine_kexec(xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
+void machine_shutdown(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/Makefile
+++ work/xen/arch/x86/Makefile  2006-10-23 11:36:13.000000000 +0900
@@ -41,6 +41,8 @@ obj-y += trampoline.o
 obj-y += traps.o
 obj-y += usercopy.o
 obj-y += x86_emulate.o
+obj-y += machine_kexec.o
+obj-y += crash.o
 
 obj-$(crash_debug) += gdbstub.o
 
--- /dev/null
+++ work/xen/arch/x86/crash.c   2006-10-23 11:36:14.000000000 +0900
@@ -0,0 +1,19 @@
+#include <xen/lib.h>       /* for printk() used in stub */
+#include <xen/types.h>
+#include <public/kexec.h>
+
+void machine_crash_shutdown(struct cpu_user_regs *regs)
+{
+    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/arch/x86/machine_kexec.c   2006-10-23 11:36:14.000000000 +0900
@@ -0,0 +1,34 @@
+#include <xen/lib.h>       /* for printk() used in stubs */
+#include <xen/types.h>
+#include <public/kexec.h>
+
+int machine_kexec_load(int type, int slot, xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+    return -1;
+}
+
+void machine_kexec_unload(int type, int slot, xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
+void machine_kexec(xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
+void machine_shutdown(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/common/Makefile
+++ work/xen/common/Makefile    2006-10-23 11:36:13.000000000 +0900
@@ -7,6 +7,7 @@ obj-y += event_channel.o
 obj-y += grant_table.o
 obj-y += kernel.o
 obj-y += keyhandler.o
+obj-y += kexec.o
 obj-y += lib.o
 obj-y += memory.o
 obj-y += multicall.o
--- /dev/null
+++ work/xen/common/kexec.c     2006-10-23 11:36:14.000000000 +0900
@@ -0,0 +1,288 @@
+/******************************************************************************
+ * kexec.c - Achitecture independent kexec code for Xen
+ * 
+ * Xen port written by:
+ * - Simon 'Horms' Horman <horms@xxxxxxxxxxxx>
+ * - Magnus Damm <magnus@xxxxxxxxxxxxx>
+ */
+
+#include <asm/kexec.h>
+#include <xen/lib.h>
+#include <xen/ctype.h>
+#include <xen/errno.h>
+#include <xen/guest_access.h>
+#include <xen/sched.h>
+#include <xen/types.h>
+#include <xen/kexec.h>
+#include <xen/keyhandler.h>
+#include <public/kexec.h>
+#include <asm/atomic.h>
+#include <xen/spinlock.h>
+
+static char opt_crashkernel[32] = "";
+string_param("crashkernel", opt_crashkernel);
+
+DEFINE_PER_CPU (note_buf_t, crash_notes);
+
+xen_kexec_image_t kexec_image[KEXEC_IMAGE_NR];
+
+#define KEXEC_FLAG_DEFAULT_POS   (KEXEC_IMAGE_NR + 0)
+#define KEXEC_FLAG_CRASH_POS     (KEXEC_IMAGE_NR + 1)
+#define KEXEC_FLAG_IN_PROGRESS   (KEXEC_IMAGE_NR + 2)
+
+unsigned long kexec_flags = 0; /* the lowest bits are for KEXEC_IMAGE... */
+
+spinlock_t kexec_lock = SPIN_LOCK_UNLOCKED;
+
+static void one_cpu_only(void)
+{
+   /* Only allow the first cpu to continue - force other cpus to spin */
+    if (test_and_set_bit(KEXEC_FLAG_IN_PROGRESS, &kexec_flags))
+    {
+        while (1);
+    }
+}
+
+void crash_kexec(struct cpu_user_regs *regs)
+{
+    int pos;
+    xen_kexec_image_t *image;
+    struct cpu_user_regs fixed_regs;
+
+    one_cpu_only();
+ 
+    crash_setup_regs(&fixed_regs, regs);
+    machine_crash_shutdown(&fixed_regs);
+
+    pos = (test_bit(KEXEC_FLAG_CRASH_POS, &kexec_flags) != 0);
+
+    if (test_bit(KEXEC_IMAGE_CRASH_BASE + pos, &kexec_flags))
+    {
+        image = &kexec_image[KEXEC_IMAGE_CRASH_BASE + pos];
+        machine_kexec(image); /* Does not return */
+    }
+
+    while (1); /* No image available - just spin */
+}
+
+static void do_crashdump_trigger(unsigned char key)
+{
+       printk("triggering crashdump\n");
+       crash_kexec(NULL);
+}
+
+static __init int register_crashdump_trigger(void)
+{
+       register_keyhandler('c', do_crashdump_trigger, "trigger a crashdump");
+       return 0;
+}
+__initcall(register_crashdump_trigger);
+
+static int kexec_get_crash_note(XEN_GUEST_HANDLE(void) uarg)
+{
+    xen_kexec_note_t note;
+    struct domain *domain = current->domain;
+    struct vcpu *vcpu;
+
+    if (unlikely(copy_from_guest(&note, uarg, 1)))
+        return -EFAULT;
+
+    if (note.vcpu < 0 || note.vcpu >= MAX_VIRT_CPUS)
+        return -EINVAL;
+
+    if (!(vcpu = domain->vcpu[note.vcpu]))
+        return -EINVAL;
+
+    note.address = __pa((unsigned long)per_cpu(crash_notes, vcpu->processor));
+
+    if (unlikely(copy_to_guest(uarg, &note, 1)))
+        return -EFAULT;
+    
+    return 0;
+}
+
+void machine_kexec_reserved(xen_kexec_reserve_t *reservation)
+{
+    unsigned long val[2];
+    char *str = opt_crashkernel;
+    int k = 0; 
+
+    memset(reservation, 0, sizeof(*reservation));
+
+    while (k < ARRAY_SIZE(val)) {
+        if (*str == '\0') {
+            break;
+        }
+        val[k] = simple_strtoul(str, &str, 0);
+        switch (toupper(*str)) {
+        case 'G': val[k] <<= 10;
+        case 'M': val[k] <<= 10;
+        case 'K': val[k] <<= 10;
+            str++;
+        }
+        if (*str == '@') {
+            str++;
+        }
+        k++;
+    }
+
+    if (k == ARRAY_SIZE(val)) {
+        reservation->size = val[0];
+        reservation->start = val[1];
+    }
+}
+
+static int kexec_get_reserve(XEN_GUEST_HANDLE(void) uarg)
+{
+    xen_kexec_reserve_t reservation;
+    
+    machine_kexec_reserved(&reservation);
+
+    if (unlikely(copy_to_guest(uarg, &reservation, 1)))
+        return -EFAULT;
+    
+    return 0;
+}
+
+static int kexec_load_get_bits(int type, int *base, int *bit)
+{
+    switch (type)
+    {
+    case KEXEC_TYPE_DEFAULT:
+        *base = KEXEC_IMAGE_DEFAULT_BASE;
+        *bit = KEXEC_FLAG_DEFAULT_POS;
+        break;
+    case KEXEC_TYPE_CRASH:
+        *base = KEXEC_IMAGE_CRASH_BASE;
+        *bit = KEXEC_FLAG_CRASH_POS;
+        break;
+    default:
+        return -1;
+    }
+    return 0;
+}
+
+static int kexec_load_unload(unsigned long op, XEN_GUEST_HANDLE(void) uarg)
+{
+    xen_kexec_load_t load;
+    xen_kexec_image_t *image;
+    int base, bit, pos;
+    int ret = 0;
+
+    if (unlikely(copy_from_guest(&load, uarg, 1)))
+        return -EFAULT;
+
+    if (kexec_load_get_bits(load.type, &base, &bit))
+        return -EINVAL;
+
+    pos = (test_bit(bit, &kexec_flags) != 0);
+
+    /* Load the user data into an unused image */
+    if (op == KEXEC_CMD_kexec_load)
+    {
+        image = &kexec_image[base + !pos];
+
+        BUG_ON(test_bit((base + !pos), &kexec_flags)); /* must be free */
+
+        memcpy(image, &load.image, sizeof(*image));
+            
+        if (!(ret = machine_kexec_load(load.type, base + !pos, image)))
+        {
+            /* Set image present bit */
+            set_bit((base + !pos), &kexec_flags);
+
+            /* Make new image the active one */
+            change_bit(bit, &kexec_flags);
+        }
+    }
+
+    /* Unload the old image if present and load successful */
+    if (ret == 0 && !test_bit(KEXEC_FLAG_IN_PROGRESS, &kexec_flags))
+    {
+        if (test_and_clear_bit((base + pos), &kexec_flags))
+        {
+            image = &kexec_image[base + pos];
+            machine_kexec_unload(load.type, base + pos, image);
+        }
+    }
+
+    return ret;
+}
+
+static int kexec_exec(XEN_GUEST_HANDLE(void) uarg)
+{
+    xen_kexec_exec_t exec;
+    xen_kexec_image_t *image;
+    int base, bit, pos;
+
+    if (unlikely(copy_from_guest(&exec, uarg, 1)))
+        return -EFAULT;
+
+    if (kexec_load_get_bits(exec.type, &base, &bit))
+        return -EINVAL;
+
+    pos = (test_bit(bit, &kexec_flags) != 0);
+
+    /* Only allow kexec/kdump into loaded images */
+    if (!test_bit(base + pos, &kexec_flags))
+        return -ENOENT;
+
+    switch (exec.type)
+    {
+    case KEXEC_TYPE_DEFAULT:
+        image = &kexec_image[base + pos];
+        one_cpu_only();
+        machine_shutdown(image); /* Does not return */
+        break;
+    case KEXEC_TYPE_CRASH:
+        crash_kexec(&exec.regs); /* Does not return */
+        break;
+    }
+
+    return -EINVAL; /* never reached */
+}
+
+long do_kexec_op(unsigned long op, XEN_GUEST_HANDLE(void) uarg)
+{
+    unsigned long flags;
+    int ret = -EINVAL;
+
+    if ( !IS_PRIV(current->domain) )  
+        return -EPERM;
+
+    switch (op)
+    {
+    case KEXEC_CMD_kexec_crash_note:
+        spin_lock_irqsave(&kexec_lock, flags);
+        ret = kexec_get_crash_note(uarg);
+        spin_unlock_irqrestore(&kexec_lock, flags);
+        break;
+    case KEXEC_CMD_kexec_reserve:
+        ret = kexec_get_reserve(uarg);
+        break;
+    case KEXEC_CMD_kexec_load:
+    case KEXEC_CMD_kexec_unload:
+        spin_lock_irqsave(&kexec_lock, flags);
+        if (!test_bit(KEXEC_FLAG_IN_PROGRESS, &kexec_flags))
+        {
+            ret = kexec_load_unload(op, uarg);
+        }
+        spin_unlock_irqrestore(&kexec_lock, flags);
+        break;
+    case KEXEC_CMD_kexec:
+        ret = kexec_exec(uarg);
+        break;
+    }
+
+    return ret;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- 0001/xen/common/page_alloc.c
+++ work/xen/common/page_alloc.c        2006-10-23 11:36:13.000000000 +0900
@@ -213,24 +213,35 @@ void init_boot_pages(paddr_t ps, paddr_t
     }
 }
 
+unsigned long alloc_boot_pages_at(unsigned long nr_pfns, unsigned long pfn_at)
+{
+    unsigned long i;
+
+    for ( i = 0; i < nr_pfns; i++ )
+        if ( allocated_in_map(pfn_at + i) )
+             break;
+
+    if ( i == nr_pfns )
+    {
+        map_alloc(pfn_at, nr_pfns);
+        return pfn_at;
+    }
+
+    return 0;
+}
+
 unsigned long alloc_boot_pages(unsigned long nr_pfns, unsigned long pfn_align)
 {
-    unsigned long pg, i;
+    unsigned long pg, i = 0;
 
     for ( pg = 0; (pg + nr_pfns) < max_page; pg += pfn_align )
     {
-        for ( i = 0; i < nr_pfns; i++ )
-            if ( allocated_in_map(pg + i) )
-                 break;
-
-        if ( i == nr_pfns )
-        {
-            map_alloc(pg, nr_pfns);
-            return pg;
-        }
+        i = alloc_boot_pages_at(nr_pfns, pg);
+        if (i != 0)
+            break;
     }
 
-    return 0;
+    return i;
 }
 
 
--- 0001/xen/drivers/char/console.c
+++ work/xen/drivers/char/console.c     2006-10-23 11:36:13.000000000 +0900
@@ -613,6 +613,7 @@ void panic(const char *fmt, ...)
     char buf[128];
     unsigned long flags;
     static DEFINE_SPINLOCK(lock);
+    extern void crash_kexec(struct cpu_user_regs *regs);
     
     debugtrace_dump();
 
@@ -635,6 +636,8 @@ void panic(const char *fmt, ...)
 
     debugger_trap_immediate();
 
+    crash_kexec(NULL);
+
     if ( opt_noreboot )
     {
         machine_halt();
--- /dev/null
+++ work/xen/include/asm-ia64/elf.h     2006-10-23 11:36:14.000000000 +0900
@@ -0,0 +1,23 @@
+#ifndef __IA64_ELF_H__
+#define __IA64_ELF_H__
+
+#include <xen/lib.h>       /* for printk() used in stub */
+
+#define ELF_NGREG 1       /* XXX: Define to be at least as large as
+                             however many register slots are needed when
+                             crash notes are written during crash dump */
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs)                                \
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+
+#endif /* __IA64_ELF_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-ia64/kexec.h   2006-10-23 11:36:14.000000000 +0900
@@ -0,0 +1,31 @@
+#ifndef __IA64_KEXEC_H__
+#define __IA64_KEXEC_H__
+
+#include <xen/lib.h>       /* for printk() used in stub */
+#include <xen/types.h>
+#include <public/xen.h>
+#include <xen/kexec.h>
+
+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 void machine_kexec(xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
+#endif /* __IA64_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-powerpc/elf.h  2006-10-23 11:36:14.000000000 +0900
@@ -0,0 +1,23 @@
+#ifndef _ASM_ELF_H__
+#define _ASM_ELF_H__
+
+#include <xen/lib.h>       /* for printk() used in stub */
+
+#define ELF_NGREG 1       /* XXX: Define to be at least as large as
+                             however many register slots are needed when
+                             crash notes are written during crash dump */
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs)                                \
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+
+#endif /* _ASM_ELF_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-powerpc/kexec.h        2006-10-23 11:36:14.000000000 
+0900
@@ -0,0 +1,31 @@
+#ifndef _ASM_KEXEC_H__
+#define _ASM_KEXEC_H__
+
+#include <xen/lib.h>       /* for printk() used in stub */
+#include <xen/types.h>
+#include <public/xen.h>
+#include <xen/kexec.h>
+
+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 void machine_kexec(xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
+#endif /* _ASM_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/elf.h      2006-10-23 11:36:14.000000000 +0900
@@ -0,0 +1,23 @@
+#ifndef __X86_ELF_H__
+#define __X86_ELF_H__
+
+#include <xen/lib.h>       /* for printk() used in stub */
+
+#define ELF_NGREG 1       /* XXX: Define to be at least as large as
+                             however many register slots are needed when
+                             crash notes are written during crash dump */
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs)                                \
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+
+#endif /* __X86_ELF_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/kexec.h    2006-10-23 11:36:14.000000000 +0900
@@ -0,0 +1,30 @@
+#ifndef __X86_KEXEC_H__
+#define __X86_KEXEC_H__
+
+#include <xen/lib.h>       /* for printk() used in stub */
+#include <xen/types.h>
+#include <public/xen.h>
+#include <xen/kexec.h>
+
+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 void machine_kexec(xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
+#endif /* __X86_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/public/kexec.h     2006-10-23 11:36:14.000000000 +0900
@@ -0,0 +1,88 @@
+/******************************************************************************
+ * kexec.h - Public portion
+ * 
+ * Xen port written by:
+ * - Simon 'Horms' Horman <horms@xxxxxxxxxxxx>
+ * - Magnus Damm <magnus@xxxxxxxxxxxxx>
+ */
+
+#ifndef _XEN_PUBLIC_KEXEC_H
+#define _XEN_PUBLIC_KEXEC_H
+
+#include "xen.h"
+
+/*
+ * Prototype for this hypercall is:
+ *  int kexec_op(int cmd, void *args)
+ * @cmd  == KEXEC_CMD_... 
+ *          KEXEC operation to perform
+ * @args == Operation-specific extra arguments (NULL if none).
+ */
+
+#define KEXEC_TYPE_DEFAULT 0
+#define KEXEC_TYPE_CRASH   1
+
+typedef struct xen_kexec_image {
+    unsigned long indirection_page;
+    unsigned long start_address;
+} xen_kexec_image_t;
+
+/*
+ * Perform kexec having previously loaded a kexec or kdump kernel
+ * as appropriate.
+ * type == KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH [in]
+ * regs == pointer to cpu_user_regs_t structure (ignored for default) [in]
+ */
+#define KEXEC_CMD_kexec                 0
+typedef struct xen_kexec_exec {
+    int type;
+    cpu_user_regs_t regs;
+} xen_kexec_exec_t;
+
+/*
+ * Load/Unload kernel image for kexec or kdump.
+ * type  == KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH [in]
+ * image == relocation information for kexec (ignored for unload) [in]
+ */
+#define KEXEC_CMD_kexec_load            1
+#define KEXEC_CMD_kexec_unload          2
+typedef struct xen_kexec_load {
+    int type;
+    xen_kexec_image_t image;
+} xen_kexec_load_t;
+
+/*
+ * Find the base pointer and size of the area that xen has 
+ * reserved for use by the crash kernel.
+ * size  == number of bytes reserved in window [out]
+ * start == machine address of the first byte in the window [out]
+ */
+#define KEXEC_CMD_kexec_reserve         3
+typedef struct xen_kexec_reserve {
+    unsigned long size;
+    unsigned long start;
+} xen_kexec_reserve_t;
+
+/*
+ * Find the base pointer of the area that xen has 
+ * reserved for use by a crash note for a given VCPU
+ * vcpu    == VCPU number to look up [in]
+ * address == VCPU crash note machine address [out]
+ */
+#define KEXEC_CMD_kexec_crash_note      4
+typedef struct xen_kexec_note {
+    int vcpu;
+    unsigned long address;
+} xen_kexec_note_t;
+
+#endif /* _XEN_PUBLIC_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/xen/elfcore.h      2006-10-23 11:36:14.000000000 +0900
@@ -0,0 +1,71 @@
+/******************************************************************************
+ * elfcore.h
+ *
+ * Based heavily on include/linux/elfcore.h from Linux 2.6.16
+ * Naming scheeme based on include/xen/elf.h (not include/linux/elfcore.h)
+ *
+ */
+
+#ifndef __ELFCOREC_H__
+#define __ELFCOREC_H__
+
+#include <xen/types.h>
+#include <xen/elf.h>
+#include <asm/elf.h>
+#include <public/xen.h>
+
+#define NT_PRSTATUS     1
+
+typedef struct
+{
+    int signo;                       /* signal number */
+    int code;                        /* extra code */
+    int errno;                       /* errno */
+} ELF_Signifo;
+
+/* These seem to be the same length on all architectures on Linux */
+typedef int ELF_Pid;
+typedef struct {
+       long tv_sec;
+       long tv_usec;
+} ELF_Timeval;
+typedef unsigned long ELF_Greg;
+typedef ELF_Greg ELF_Gregset[ELF_NGREG];
+
+/*
+ * Definitions to generate Intel SVR4-like core files.
+ * These mostly have the same names as the SVR4 types with "elf_"
+ * tacked on the front to prevent clashes with linux definitions,
+ * and the typedef forms have been avoided.  This is mostly like
+ * the SVR4 structure, but more Linuxy, with things that Linux does
+ * not support and which gdb doesn't really use excluded.
+ */
+typedef struct
+{
+    ELF_Signifo pr_info;         /* Info associated with signal */
+    short pr_cursig;             /* Current signal */
+    unsigned long pr_sigpend;    /* Set of pending signals */
+    unsigned long pr_sighold;    /* Set of held signals */
+    ELF_Pid pr_pid;
+    ELF_Pid pr_ppid;
+    ELF_Pid pr_pgrp;
+    ELF_Pid pr_sid;
+    ELF_Timeval pr_utime;        /* User time */
+    ELF_Timeval pr_stime;        /* System time */
+    ELF_Timeval pr_cutime;       /* Cumulative user time */
+    ELF_Timeval pr_cstime;       /* Cumulative system time */
+    ELF_Gregset pr_reg;          /* GP registers */
+    int pr_fpvalid;              /* True if math co-processor being used.  */
+} ELF_Prstatus;
+
+#endif /* __ELFCOREC_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- 0001/xen/include/xen/hypercall.h
+++ work/xen/include/xen/hypercall.h    2006-10-23 11:36:13.000000000 +0900
@@ -102,4 +102,10 @@ do_hvm_op(
     unsigned long op,
     XEN_GUEST_HANDLE(void) arg);
 
+extern long
+do_kexec_op(
+    unsigned long op,
+    int arg1,
+    XEN_GUEST_HANDLE(void) arg);
+
 #endif /* __XEN_HYPERCALL_H__ */
--- /dev/null
+++ work/xen/include/xen/kexec.h        2006-10-23 11:36:14.000000000 +0900
@@ -0,0 +1,37 @@
+#ifndef __XEN_KEXEC_H__
+#define __XEN_KEXEC_H__
+
+#include <public/kexec.h>
+#include <asm/percpu.h>
+
+#define MAX_NOTE_BYTES 1024
+
+typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
+DECLARE_PER_CPU (note_buf_t, crash_notes);
+
+/* We have space for 4 images to support atomic update
+ * of images. This is important for CRASH images since
+ * a panic can happen at any time...
+ */
+
+#define KEXEC_IMAGE_DEFAULT_BASE 0
+#define KEXEC_IMAGE_CRASH_BASE   2
+#define KEXEC_IMAGE_NR           4
+
+int machine_kexec_load(int type, int slot, xen_kexec_image_t *image);
+void machine_kexec_unload(int type, int slot, xen_kexec_image_t *image);
+void machine_kexec_reserved(xen_kexec_reserve_t *reservation);
+void machine_shutdown(xen_kexec_image_t *image);
+void machine_crash_shutdown(cpu_user_regs_t *regs);
+
+#endif /* __XEN_KEXEC_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- 0001/xen/include/xen/mm.h
+++ work/xen/include/xen/mm.h   2006-10-23 11:36:13.000000000 +0900
@@ -40,6 +40,7 @@ struct page_info;
 paddr_t init_boot_allocator(paddr_t bitmap_start);
 void init_boot_pages(paddr_t ps, paddr_t pe);
 unsigned long alloc_boot_pages(unsigned long nr_pfns, unsigned long pfn_align);
+unsigned long alloc_boot_pages_at(unsigned long nr_pfns, unsigned long pfn_at);
 void end_boot_allocator(void);
 
 /* Generic allocator. These functions are *not* interrupt-safe. */

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