aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--patches/linux-2.6.16.33/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch62
-rw-r--r--patches/linux-2.6.16.33/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch93
-rw-r--r--patches/linux-2.6.16.33/series2
-rw-r--r--xen/arch/x86/crash.c115
-rw-r--r--xen/arch/x86/machine_kexec.c83
-rw-r--r--xen/arch/x86/setup.c73
-rw-r--r--xen/arch/x86/traps.c2
-rw-r--r--xen/include/asm-x86/elf.h18
-rw-r--r--xen/include/asm-x86/fixmap.h4
-rw-r--r--xen/include/asm-x86/hypercall.h5
-rw-r--r--xen/include/asm-x86/kexec.h14
-rw-r--r--xen/include/asm-x86/x86_32/elf.h26
-rw-r--r--xen/include/asm-x86/x86_32/kexec.h24
-rw-r--r--xen/include/asm-x86/x86_64/elf.h26
-rw-r--r--xen/include/asm-x86/x86_64/kexec.h24
-rw-r--r--xen/include/public/kexec.h7
-rw-r--r--xen/include/xen/elfcore.h3
17 files changed, 538 insertions, 43 deletions
diff --git a/patches/linux-2.6.16.33/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch b/patches/linux-2.6.16.33/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch
new file mode 100644
index 0000000000..3e7c024b38
--- /dev/null
+++ b/patches/linux-2.6.16.33/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch
@@ -0,0 +1,62 @@
+From: Eric W. Biederman <ebiederm@xmission.com>
+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@xmission.com>
+Cc: Andi Kleen <ak@muc.de>
+Acked-by: Horms <horms@verge.net.au>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Linus Torvalds <torvalds@osdl.org>
+---
+
+--- 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.
diff --git a/patches/linux-2.6.16.33/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch b/patches/linux-2.6.16.33/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch
new file mode 100644
index 0000000000..9d0b701ffb
--- /dev/null
+++ b/patches/linux-2.6.16.33/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch
@@ -0,0 +1,93 @@
+From: Tobias Klauser <tklauser@nuerscht.ch>
+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@nuerscht.ch>
+Signed-off-by: Adrian Bunk <bunk@stusta.de>
+---
+
+--- 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)
+ {
diff --git a/patches/linux-2.6.16.33/series b/patches/linux-2.6.16.33/series
index 8d3ec1a0df..025a7be77d 100644
--- a/patches/linux-2.6.16.33/series
+++ b/patches/linux-2.6.16.33/series
@@ -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
diff --git a/xen/arch/x86/crash.c b/xen/arch/x86/crash.c
index f1729786ea..73ed160021 100644
--- a/xen/arch/x86/crash.c
+++ b/xen/arch/x86/crash.c
@@ -1,10 +1,119 @@
-#include <xen/lib.h> /* for printk() used in stub */
+/******************************************************************************
+ * crash.c
+ *
+ * Based heavily on arch/i386/kernel/crash.c from Linux 2.6.16
+ *
+ * Xen port written by:
+ * - Simon 'Horms' Horman <horms@verge.net.au>
+ * - Magnus Damm <magnus@valinux.co.jp>
+ */
+
+#include <asm/atomic.h>
+#include <asm/elf.h>
+#include <asm/percpu.h>
+#include <asm/kexec.h>
#include <xen/types.h>
-#include <public/kexec.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 <xen/sched.h>
+#include <public/xen.h>
+#include <asm/hvm/hvm.h>
+
+#ifdef CONFIG_SMP
+static atomic_t waiting_for_crash_ipi;
+
+static int crash_nmi_callback(struct cpu_user_regs *regs, int cpu)
+{
+ /* 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();
+
+ machine_crash_save_cpu();
+ disable_local_APIC();
+ atomic_dec(&waiting_for_crash_ipi);
+ hvm_disable();
+
+ for ( ; ; )
+ __asm__ __volatile__ ( "hlt" );
+
+ return 1;
+}
+
+/*
+ * 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();
+}
+#endif
+
+static void crash_save_xen_notes(void)
+{
+ crash_xen_info_t *info;
+
+ info = machine_crash_save_info();
+
+ info->dom0_pfn_to_mfn_frame_list_list = \
+ dom0->shared_info->arch.pfn_to_mfn_frame_list_list;
+}
void machine_crash_shutdown(void)
{
- printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+ printk("machine_crash_shutdown: %d\n", smp_processor_id());
+ local_irq_disable();
+
+#ifdef CONFIG_SMP
+ nmi_shootdown_cpus();
+#endif
+
+#ifdef CONFIG_X86_IO_APIC
+ disable_IO_APIC();
+#endif
+ hvm_disable();
+
+ crash_save_xen_notes();
}
/*
diff --git a/xen/arch/x86/machine_kexec.c b/xen/arch/x86/machine_kexec.c
index 639f845ac1..f60296271d 100644
--- a/xen/arch/x86/machine_kexec.c
+++ b/xen/arch/x86/machine_kexec.c
@@ -1,26 +1,89 @@
-#include <xen/lib.h> /* for printk() used in stubs */
+/******************************************************************************
+ * machine_kexec.c
+ *
+ * Xen port written by:
+ * - Simon 'Horms' Horman <horms@verge.net.au>
+ * - Magnus Damm <magnus@valinux.co.jp>
+ */
+
+#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 <public/kexec.h>
+#include <xen/console.h>
+#include <xen/kexec.h>
+#include <asm/kexec.h>
+#include <xen/domain_page.h>
+#include <asm/fixmap.h>
+#include <asm/hvm/hvm.h>
int machine_kexec_load(int type, int slot, xen_kexec_image_t *image)
{
- printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
- return -1;
+ unsigned long prev_ma = 0;
+ int fix_base = FIX_KEXEC_BASE_0 + (slot * (KEXEC_XEN_NO_PAGES >> 1));
+ 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_base + (k >> 1), prev_ma);
+ image->page_list[k] = fix_to_virt(fix_base + (k >> 1));
+ }
+ }
+
+ return 0;
}
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)
+
+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();
}
/*
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index e144b6ca47..181ca84f5f 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -27,6 +27,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);
@@ -273,6 +274,20 @@ static void srat_detect_node(int cpu)
printk(KERN_INFO "CPU %d APIC %d -> Node %d\n", cpu, apicid, node);
}
+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;
@@ -284,6 +299,7 @@ void __init __start_xen(multiboot_info_t *mbi)
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',
@@ -415,15 +431,8 @@ void __init __start_xen(multiboot_info_t *mbi)
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));
@@ -471,6 +480,52 @@ void __init __start_xen(multiboot_info_t *mbi)
#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();
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 87f3f79491..3e6ab2856d 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -45,6 +45,7 @@
#include <xen/iocap.h>
#include <xen/nmi.h>
#include <xen/version.h>
+#include <xen/kexec.h>
#include <asm/shadow.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -1633,6 +1634,7 @@ static void unknown_nmi_error(unsigned char reason)
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");
+ machine_crash_kexec();
}
}
diff --git a/xen/include/asm-x86/elf.h b/xen/include/asm-x86/elf.h
index bfd7913d10..9747d46e61 100644
--- a/xen/include/asm-x86/elf.h
+++ b/xen/include/asm-x86/elf.h
@@ -1,21 +1,15 @@
#ifndef __X86_ELF_H__
#define __X86_ELF_H__
-#include <xen/lib.h> /* for printk() used in stub */
-
-typedef struct {
- unsigned long dummy;
-} ELF_Gregset;
-
typedef struct {
- unsigned long dummy;
+ unsigned long cr0, cr2, cr3, cr4;
} crash_xen_core_t;
-extern inline void elf_core_save_regs(ELF_Gregset *core_regs,
- crash_xen_core_t *xen_core_regs)
-{
- printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
-}
+#ifdef __x86_64__
+#include <asm/x86_64/elf.h>
+#else
+#include <asm/x86_32/elf.h>
+#endif
#endif /* __X86_ELF_H__ */
diff --git a/xen/include/asm-x86/fixmap.h b/xen/include/asm-x86/fixmap.h
index dbf1b70c55..8444e21262 100644
--- a/xen/include/asm-x86/fixmap.h
+++ b/xen/include/asm-x86/fixmap.h
@@ -16,6 +16,7 @@
#include <asm/apicdef.h>
#include <asm/acpi.h>
#include <asm/page.h>
+#include <xen/kexec.h>
/*
* Here we define all the compile-time 'special' virtual
@@ -36,6 +37,9 @@ 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) * KEXEC_IMAGE_NR) - 1,
__end_of_fixed_addresses
};
diff --git a/xen/include/asm-x86/hypercall.h b/xen/include/asm-x86/hypercall.h
index 69d7ba793d..860fb2ce77 100644
--- a/xen/include/asm-x86/hypercall.h
+++ b/xen/include/asm-x86/hypercall.h
@@ -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
diff --git a/xen/include/asm-x86/kexec.h b/xen/include/asm-x86/kexec.h
index ba47dbf6dc..d137337da0 100644
--- a/xen/include/asm-x86/kexec.h
+++ b/xen/include/asm-x86/kexec.h
@@ -1,15 +1,11 @@
#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 inline void machine_kexec(xen_kexec_image_t *image)
-{
- 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__ */
diff --git a/xen/include/asm-x86/x86_32/elf.h b/xen/include/asm-x86/x86_32/elf.h
new file mode 100644
index 0000000000..982906cace
--- /dev/null
+++ b/xen/include/asm-x86/x86_32/elf.h
@@ -0,0 +1,26 @@
+#ifndef __X86_32_ELF_H__
+#define __X86_32_ELF_H__
+
+#include <xen/lib.h> /* for printk() used in stub */
+
+typedef struct {
+ unsigned long dummy;
+} ELF_Gregset;
+
+extern inline void elf_core_save_regs(ELF_Gregset *core_regs,
+ crash_xen_core_t *xen_core_regs)
+{
+ printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
+#endif /* __X86_32_ELF_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/asm-x86/x86_32/kexec.h b/xen/include/asm-x86/x86_32/kexec.h
new file mode 100644
index 0000000000..97bbab8bb2
--- /dev/null
+++ b/xen/include/asm-x86/x86_32/kexec.h
@@ -0,0 +1,24 @@
+#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>
+#include <xen/kexec.h>
+
+static inline void machine_kexec(xen_kexec_image_t *image)
+{
+ printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
+#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:
+ */
diff --git a/xen/include/asm-x86/x86_64/elf.h b/xen/include/asm-x86/x86_64/elf.h
new file mode 100644
index 0000000000..8068c3ab5d
--- /dev/null
+++ b/xen/include/asm-x86/x86_64/elf.h
@@ -0,0 +1,26 @@
+#ifndef __X86_64_ELF_H__
+#define __X86_64_ELF_H__
+
+#include <xen/lib.h> /* for printk() used in stub */
+
+typedef struct {
+ unsigned long dummy;
+} ELF_Gregset;
+
+extern inline void elf_core_save_regs(ELF_Gregset *core_regs,
+ crash_xen_core_t *xen_core_regs)
+{
+ printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
+#endif /* __X86_64_ELF_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/asm-x86/x86_64/kexec.h b/xen/include/asm-x86/x86_64/kexec.h
new file mode 100644
index 0000000000..3433ba7846
--- /dev/null
+++ b/xen/include/asm-x86/x86_64/kexec.h
@@ -0,0 +1,24 @@
+#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>
+#include <xen/kexec.h>
+
+static inline void machine_kexec(xen_kexec_image_t *image)
+{
+ 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:
+ */
diff --git a/xen/include/public/kexec.h b/xen/include/public/kexec.h
index c51f24ccdd..556aaecb3d 100644
--- a/xen/include/public/kexec.h
+++ b/xen/include/public/kexec.h
@@ -40,6 +40,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, void *args)
@@ -72,6 +76,9 @@
*/
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;
diff --git a/xen/include/xen/elfcore.h b/xen/include/xen/elfcore.h
index 158621ef64..d578d0dd0b 100644
--- a/xen/include/xen/elfcore.h
+++ b/xen/include/xen/elfcore.h
@@ -108,6 +108,9 @@ typedef struct {
unsigned long xen_compile_date;
unsigned long xen_compile_time;
unsigned long tainted;
+#ifdef CONFIG_X86
+ unsigned long dom0_pfn_to_mfn_frame_list_list;
+#endif
} crash_xen_info_t;
TYPEDEF_NOTE(crash_note_xen_info_t, XEN_STR_LEN, crash_xen_info_t);