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, 16 Oct 2006 17:33:24 +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:36:25 -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 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-11760.

 linux-2.6-xen-sparse/drivers/xen/core/Makefile        |    1
 linux-2.6-xen-sparse/drivers/xen/core/reboot.c        |    4
 patches/linux-2.6.16.29/series                        |    1
 linux-2.6-xen-sparse/drivers/xen/core/crash.c         |   49 ++
 linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c |   76 +++
 patches/linux-2.6.16.29/kexec-generic.patch           |  283 ++++++++++++
 xen/arch/ia64/xen/crash.c                             |   26 +
 xen/arch/ia64/xen/machine_kexec.c                     |   41 +
 xen/arch/powerpc/crash.c                              |   26 +
 xen/arch/powerpc/machine_kexec.c                      |   41 +
 xen/arch/x86/crash.c                                  |   26 +
 xen/arch/x86/machine_kexec.c                          |   41 +
 xen/common/kexec.c                                    |  260 +++++++++++
 xen/include/asm-ia64/kexec.h                          |   32 +
 xen/include/asm-x86/kexec.h                           |   31 +
 xen/include/public/kexec.h                            |   84 +++
 xen/include/xen/elfcore.h                             |   73 +++
 xen/include/xen/kexec.h                               |   30 +
 xen/arch/ia64/xen/Makefile                            |    2
 xen/arch/powerpc/Makefile                             |    2
 xen/arch/x86/Makefile                                 |    2
 xen/common/Makefile                                   |    1
 xen/common/page_alloc.c                               |   33 -
 xen/drivers/char/console.c                            |    3
 xen/include/xen/hypercall.h                           |    6
 xen/include/xen/mm.h                                  |    1
 26 files changed, 1164 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-16 
12:04:03.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-16 
12:04:04.000000000 +0900
@@ -0,0 +1,49 @@
+/*
+ * drivers/xen/core/crash.c
+ * Architecture independent functions for kexec based crash dumps in xen.
+ *
+ * Created by: Horms <horms@xxxxxxxxxxxx>
+ *
+ */
+
+#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)
+{
+       struct cpu_user_regs xen_regs;
+       printk("machine_crash_shutdown: %d\n", smp_processor_id());
+       local_irq_disable();
+#ifdef CONFIG_X86_IO_APIC
+       disable_IO_APIC();
+#endif
+       crash_translate_regs(regs, &xen_regs);
+       HYPERVISOR_kexec(KEXEC_CMD_kexec, KEXEC_TYPE_CRASH, &xen_regs);
+}
+
+/*
+ * 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-16 
12:04:04.000000000 +0900
@@ -0,0 +1,76 @@
+/*
+ * drivers/xen/core/machine_kexec.c 
+ * handle transition of Linux booting another kernel
+ *
+ * Created By: Horms <horms@xxxxxxxxxxxx>
+ *
+ * Losely based on arch/i386/kernel/machine_kexec.c
+ */
+
+#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)
+{
+       memset(xki, 0, sizeof(*xki));
+
+       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_image_t xki;
+
+       setup_load_arg(&xki, image);
+       return HYPERVISOR_kexec(KEXEC_CMD_kexec_load, image->type, &xki);
+}
+
+/*
+ * 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)
+{
+       HYPERVISOR_kexec(KEXEC_CMD_kexec_unload, image->type, NULL);
+}
+
+/*
+ * 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)
+{
+       HYPERVISOR_kexec(KEXEC_CMD_kexec, image->type, NULL);
+       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-16 
12:04:03.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-16 
12:04:04.000000000 +0900
@@ -0,0 +1,283 @@
+ drivers/base/cpu.c    |   20 +++++++++++++++++
+ include/linux/kexec.h |    5 ++++
+ kernel/kexec.c        |   57 ++++++++++++++++++++++++++++++++++++++-----------
+ kernel/sys.c          |    4 +++
+ 4 files changed, 74 insertions(+), 12 deletions(-)
+
+--- x/drivers/base/cpu.c
++++ x/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,18 @@ static inline void register_cpu_control(
+ #ifdef CONFIG_KEXEC
+ #include <linux/kexec.h>
+ 
++#ifdef CONFIG_XEN
++static unsigned long get_crash_notes(int cpu)
++{
++      unsigned long crash_note;
++
++      if (HYPERVISOR_kexec(KEXEC_CMD_kexec_crash_note, cpu, &crash_note) < 0)
++              return 0UL;
++      return crash_note;
++}
++#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 +117,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;
+ }
+--- x/include/linux/kexec.h
++++ x/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,
+--- x/kernel/kexec.c
++++ x/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
+--- x/kernel/sys.c
++++ x/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-16 12:04:03.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-16 12:04:03.000000000 +0900
@@ -25,5 +25,7 @@ obj-y += xensetup.o
 obj-y += xentime.o
 obj-y += flushd.o
 obj-y += privop_stat.o
+obj-y += machine_kexec.o
+obj-y += crash.o
 
 obj-$(crash_debug) += gdbstub.o
--- /dev/null
+++ work/xen/arch/ia64/xen/crash.c      2006-10-16 12:04:04.000000000 +0900
@@ -0,0 +1,26 @@
+/**********************************************************************
+ * arch/ia64/xen/crash.c
+ *
+ * Created By: Horms
+ * 
+ */
+
+#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-16 12:04:04.000000000 
+0900
@@ -0,0 +1,41 @@
+/**********************************************************************
+ * arch/ia64/xen/machine_kexec.c
+ *
+ * Created By: Horms
+ * 
+ */
+
+#include <xen/lib.h>       /* for printk() used in stubs */
+#include <xen/types.h>
+#include <public/kexec.h>
+
+int machine_kexec_load(int type, xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+    return -1;
+}
+
+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)
+{
+    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-16 12:04:03.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-16 12:04:04.000000000 +0900
@@ -0,0 +1,26 @@
+/**********************************************************************
+ * arch/powerpc/crash.c
+ *
+ * Created By: Horms
+ * 
+ */
+
+#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-16 12:04:04.000000000 
+0900
@@ -0,0 +1,41 @@
+/**********************************************************************
+ * arch/powerpc/machine_kexec.c
+ *
+ * Created By: Horms
+ * 
+ */
+
+#include <xen/lib.h>       /* for printk() used in stubs */
+#include <xen/types.h>
+#include <public/kexec.h>
+
+int machine_kexec_load(int type, xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+    return -1;
+}
+
+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)
+{
+    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-16 12:04:03.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-16 12:04:04.000000000 +0900
@@ -0,0 +1,26 @@
+/******************************************************************************
+ * arch/x86/crash.c
+ * 
+ * Created By: Horms
+ *
+ * Should be based heavily on arch/i386/kernel/crash.c from Linux 2.6.16
+ */
+
+#include <xen/lib.h>       /* for printk() used in stub */
+#include <xen/types.h>
+#include <public/xen.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-16 12:04:04.000000000 +0900
@@ -0,0 +1,41 @@
+/******************************************************************************
+ * arch/x86/machine_kexec.c
+ * 
+ * Created By: Horms
+ *
+ */
+
+#include <xen/lib.h>       /* for printk() used in stubs */
+#include <xen/types.h>
+#include <public/kexec.h>
+
+int machine_kexec_load(int type, xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+    return -1;
+}
+
+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)
+{
+    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-16 12:04:03.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-16 12:23:11.000000000 +0900
@@ -0,0 +1,260 @@
+/******************************************************************************
+ * common/kexec.c - Achitecture independent kexec code for Xen
+ *
+ * Created By: Horms <horms@xxxxxxxxxxxx>
+ *
+ * Based in part on Linux 2.6.16's kernel/kexec.c
+ */
+
+#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>
+
+static char opt_crashkernel[32] = "";
+string_param("crashkernel", opt_crashkernel);
+
+DEFINE_PER_CPU (note_buf_t, crash_notes);
+
+static xen_kexec_image_t kexec_image;
+static int kexec_image_set = 0;
+static xen_kexec_image_t kexec_crash_image;
+static int kexec_crash_image_set = 0;
+static int kexec_crash_lock = 0;
+
+/* Must call with kexec_crash_lock held */
+void __crash_kexec(struct cpu_user_regs *regs)
+{
+    struct cpu_user_regs fixed_regs;
+
+    if (!kexec_crash_image_set)
+           return;
+    crash_setup_regs(&fixed_regs, regs);
+    machine_crash_shutdown(&fixed_regs);
+    machine_kexec(&kexec_crash_image); /* Does not return */
+}
+
+void crash_kexec(struct cpu_user_regs *regs)
+{
+    int locked;
+
+    locked = xchg(&kexec_crash_lock, 1);
+    if (locked)
+        return;
+    __crash_kexec(regs);
+
+    /* The if() here is bogus, but gcc will throws a warning that the
+     * computed value is unused and xen compiles with -Werror.
+     * This seems like a viable work around.
+     * This did not seem to happen with slightly older gcc.
+     * Observed with: 
+     * gcc version 4.1.2 20060604 (prerelease) (Debian * 4.1.1-2) */
+    if (xchg(&kexec_crash_lock, 0)) ;
+
+    return;
+}
+
+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 get_crash_note(int vcpuid, XEN_GUEST_HANDLE(void) uarg)
+{
+    struct domain *domain = current->domain;
+    unsigned long crash_note;
+    struct vcpu *vcpu;
+    int locked;
+
+    if (vcpuid < 0 || vcpuid > MAX_VIRT_CPUS)
+       return -EINVAL;
+
+    if ( ! (vcpu = domain->vcpu[vcpuid]) )
+       return -EINVAL;
+
+    locked = xchg(&kexec_crash_lock, 1);
+    if (locked)
+    {
+       printk("do_kexec_op: (CMD_kexec_crash_note): dump is locked\n");
+       return -EFAULT;
+    }
+    crash_note = __pa((unsigned long)per_cpu(crash_notes, vcpu->processor));
+
+    /* The if() here is bogus, but gcc will throws a warning that the
+     * computed value is unused and xen compiles with -Werror.
+     * This seems like a viable work around.
+     * This did not seem to happen with slightly older gcc.
+     * Observed with: 
+     * gcc version 4.1.2 20060604 (prerelease) (Debian * 4.1.1-2) */
+    if (xchg(&kexec_crash_lock, 0)) ;
+
+    if ( unlikely(copy_to_guest(uarg, &crash_note, 1) != 0) )
+    {
+        printk("do_kexec_op: (CMD_kexec_crash_note): copy_to_guest failed\n");
+        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 get_reserve(XEN_GUEST_HANDLE(void) uarg)
+{
+    xen_kexec_reserve_t reservation;
+    
+    machine_kexec_reserved(&reservation);
+    if ( unlikely(copy_to_guest(uarg, &reservation, 1) != 0) )
+    {
+        printk("do_kexec_op (CMD_kexec_reserve): copy_to_guest failed\n");
+        return -EFAULT;
+    }
+    
+    return 0;
+}
+
+static int __do_kexec(unsigned long type, XEN_GUEST_HANDLE(void) uarg,
+                     xen_kexec_image_t *image)
+{
+    cpu_user_regs_t regs;
+
+    if (type == KEXEC_TYPE_DEFAULT)
+        machine_shutdown(image); /* Does not return */
+    else
+    {
+        if ( unlikely(copy_from_guest(&regs, uarg, 1) != 0) )
+        {
+            printk("do_kexec_op (CMD_kexec): copy_from_guest failed\n");
+            return -EFAULT;
+        }
+        __crash_kexec(&regs); /* Does not return */
+    }
+
+    return -EINVAL;
+}
+
+long do_kexec_op(unsigned long op, int arg1, XEN_GUEST_HANDLE(void) uarg)
+{
+    xen_kexec_image_t *image;
+    int locked;
+    int *image_set;
+    int status = -EINVAL;
+
+    if ( !IS_PRIV(current->domain) )  
+        return -EPERM;
+
+    switch (op)
+    {
+    case KEXEC_CMD_kexec_crash_note:
+        return get_crash_note(arg1, uarg);
+    case KEXEC_CMD_kexec_reserve:
+       return get_reserve(uarg);
+    }
+
+    /* For all other ops, arg1 is the type of kexec, that is
+     * KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH */
+    if (arg1 == KEXEC_TYPE_CRASH)
+    {
+        image = &kexec_crash_image;
+        image_set = &kexec_crash_image_set;
+        locked = xchg(&kexec_crash_lock, 1);
+        if (locked)
+        {
+           printk("do_kexec_op: dump is locked\n");
+           return -EFAULT;
+        }
+    }
+    else
+    {
+        image = &kexec_image;
+        image_set = &kexec_image_set;
+    }
+
+    switch(op) {
+    case KEXEC_CMD_kexec:
+        BUG_ON(!*image_set);
+       status = __do_kexec(arg1, uarg, image);
+        break;
+    case KEXEC_CMD_kexec_load:
+        BUG_ON(*image_set);
+        if ( unlikely(copy_from_guest(image, uarg, 1) != 0) )
+        {
+            printk("do_kexec_op (CMD_kexec_load): copy_from_guest failed\n");
+            status = -EFAULT;
+           break;
+        }
+        *image_set = 1;
+        status = machine_kexec_load(arg1, image);
+        break;
+    case KEXEC_CMD_kexec_unload:
+        BUG_ON(!*image_set);
+        *image_set = 0;
+        machine_kexec_unload(arg1, image);
+        status = 0;
+        break;
+    }
+
+    if (arg1 == KEXEC_TYPE_CRASH)
+        /* The if() here is bogus, but gcc will throws a warning that the
+         * computed value is unused and xen compiles with -Werror.
+         * This seems like a viable work around.
+         * This did not seem to happen with slightly older gcc.
+         * Observed with: 
+         * gcc version 4.1.2 20060604 (prerelease) (Debian * 4.1.1-2) */
+        if (xchg(&kexec_crash_lock, 0)) ;
+
+    return status;
+}
+
+/*
+ * 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-16 12:04:03.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-16 12:04:03.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/kexec.h   2006-10-16 12:04:04.000000000 +0900
@@ -0,0 +1,32 @@
+/******************************************************************************
+ * include/asm-ia64/kexec.h
+ * 
+ * Created By: Horms
+ *
+ */
+
+#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>
+
+static void crash_setup_regs(struct cpu_user_regs *newregs,
+                            struct cpu_user_regs *oldregs)
+{
+    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-x86/kexec.h    2006-10-16 12:04:04.000000000 +0900
@@ -0,0 +1,31 @@
+/******************************************************************************
+ * include/asm-x86/kexec.h
+ * 
+ * Created By: Horms
+ *
+ */
+
+#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>
+
+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_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-16 12:04:04.000000000 +0900
@@ -0,0 +1,84 @@
+/******************************************************************************
+ * kexec.h - Public portion
+ *
+ * Created By: Horms <horms@xxxxxxxxxxxx>
+ *
+ * Types based on those in ./vcpu.h on request from Keir Frasier
+ */
+
+#ifndef _XEN_PUBLIC_KEXEC_H
+#define _XEN_PUBLIC_KEXEC_H
+
+#include "xen.h"
+
+/*
+ * Prototype for this hypercall is:
+ *  int kexec_op(int cmd, int type, void *extra_args)
+ * @cmd        == KEXEC_CMD_... 
+ *                KEXEC operation to perform
+ * @arg1       == Operation-specific unsigned long argument
+ *                This could be in extra_args, but by putting it here
+ *                copy_from_user can be avoided, inparticular in
+ *                KEXEC_CMD_kexec during a crash dump, which is a failry
+ *                critical section of code.If this turns out not to be
+ *                important then it can be collapsed into extra_args.
+ * @extra_args == Operation-specific extra arguments (NULL if none).
+ */
+
+#define KEXEC_TYPE_DEFAULT 0
+#define KEXEC_TYPE_CRASH   1
+
+/*
+ * Perform kexec having previously loaded a kexec or kdump kernel
+ * as appropriate.
+ * @arg1      == KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH
+ * @extra_arg == pointer to cpu_user_regs_t structure.
+ */
+#define KEXEC_CMD_kexec                 0
+
+/*
+ * Load kernel image in preparation for kexec or kdump.
+ * @arg1      == KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH
+ * @extra_arg == pointer to xen_kexec_image_t structure.
+ */
+#define KEXEC_CMD_kexec_load            1
+typedef struct xen_kexec_image {
+    unsigned long indirection_page;
+    unsigned long start_address;
+} xen_kexec_image_t;
+
+/*
+ * Clean up image loaded by KEXEC_CMD_kexec_load
+ * @arg1      == KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH
+ */
+#define KEXEC_CMD_kexec_unload          2
+
+/*
+ * Find the base pointer and size of the area that xen has 
+ * reserved for use by the crash kernel.
+ * @extra_arg == pointer to xen_kexec_reserve_t structure.
+ */
+#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
+ * @extra_arg == pointer to unsigned long.
+ */
+#define KEXEC_CMD_kexec_crash_note      4
+
+#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-16 12:04:04.000000000 +0900
@@ -0,0 +1,73 @@
+/******************************************************************************
+ * include/xen/elfcore.h
+ * 
+ * Created By: Horms
+ *
+ * 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 <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;
+#define ELF_NGREG (sizeof (struct cpu_user_regs) / sizeof(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-16 12:04:03.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-16 12:21:58.000000000 +0900
@@ -0,0 +1,30 @@
+/******************************************************************************
+ * include/xen/kexec.h - Internal archtecture independant portion
+ *
+ * Created By: Horms <horms@xxxxxxxxxxxx>
+ *
+ */
+
+#include <public/kexec.h>
+
+#define MAX_NOTE_BYTES 1024
+
+typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
+DECLARE_PER_CPU (note_buf_t, crash_notes);
+
+int machine_kexec_load(int type, xen_kexec_image_t *image);
+void machine_kexec_unload(int type, xen_kexec_image_t *image);
+void machine_kexec_reserved(xen_kexec_reserve_t *reservation);
+void machine_kexec(xen_kexec_image_t *image);
+void machine_shutdown(xen_kexec_image_t *image);
+void machine_crash_shutdown(cpu_user_regs_t *regs);
+
+/*
+ * 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-16 12:04:03.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