[PATCH 02/04] Kexec / Kdump: Code shared between x86_32 and x86_64
This patch contains Kexec / Kdump code shared between x86_32 and x86_64.
Signed-Off-By: Magnus Damm <magnus@xxxxxxxxxxxxx>
---
Applies on top of xen-unstable-12281.
patches/linux-2.6.16.29/git-2a...f7.patch | 62 ++++
patches/linux-2.6.16.29/git-2e...11.patch | 93 +++++++
patches/linux-2.6.16.29/series | 2
xen/arch/x86/crash.c | 130 +++++++++-
xen/arch/x86/machine_kexec.c | 83 +++++-
xen/arch/x86/setup.c | 73 ++++-
xen/arch/x86/traps.c | 2
xen/include/asm-x86/elf.h | 15 -
xen/include/asm-x86/fixmap.h | 4
xen/include/asm-x86/hypercall.h | 5
xen/include/asm-x86/kexec.h | 14 -
xen/include/asm-x86/x86_32/elf.h | 25 +
xen/include/asm-x86/x86_32/kexec.h | 24 +
xen/include/asm-x86/x86_64/elf.h | 25 +
xen/include/asm-x86/x86_64/kexec.h | 24 +
xen/include/public/kexec.h | 7
xen/include/xen/elfcore.h | 3
17 files changed, 550 insertions(+), 41 deletions(-)
--- /dev/null
+++
work/patches/linux-2.6.16.29/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch
@@ -0,0 +1,62 @@
+From: Eric W. Biederman <ebiederm@xxxxxxxxxxxx>
+Date: Sun, 30 Jul 2006 10:03:20 +0000 (-0700)
+Subject: [PATCH] machine_kexec.c: Fix the description of segment handling
+X-Git-Tag: v2.6.18-rc4
+X-Git-Url:
http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=2a8a3d5b65e86ec1dfef7d268c64a909eab94af7
+
+[PATCH] machine_kexec.c: Fix the description of segment handling
+
+One of my original comments in machine_kexec was unclear
+and this should fix it.
+
+Signed-off-by: Eric W. Biederman <ebiederm@xxxxxxxxxxxx>
+Cc: Andi Kleen <ak@xxxxxx>
+Acked-by: Horms <horms@xxxxxxxxxxxx>
+Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
+Signed-off-by: Linus Torvalds <torvalds@xxxxxxxx>
+---
+
+--- a/arch/i386/kernel/machine_kexec.c
++++ b/arch/i386/kernel/machine_kexec.c
+@@ -189,14 +189,11 @@ NORET_TYPE void machine_kexec(struct kim
+ memcpy((void *)reboot_code_buffer, relocate_new_kernel,
+ relocate_new_kernel_size);
+
+- /* The segment registers are funny things, they are
+- * automatically loaded from a table, in memory wherever you
+- * set them to a specific selector, but this table is never
+- * accessed again you set the segment to a different selector.
+- *
+- * The more common model is are caches where the behide
+- * the scenes work is done, but is also dropped at arbitrary
+- * times.
++ /* The segment registers are funny things, they have both a
++ * visible and an invisible part. Whenever the visible part is
++ * set to a specific selector, the invisible part is loaded
++ * with from a table in memory. At no other time is the
++ * descriptor table in memory accessed.
+ *
+ * I take advantage of this here by force loading the
+ * segments, before I zap the gdt with an invalid value.
+--- a/arch/x86_64/kernel/machine_kexec.c
++++ b/arch/x86_64/kernel/machine_kexec.c
+@@ -207,14 +207,11 @@ NORET_TYPE void machine_kexec(struct kim
+ __flush_tlb();
+
+
+- /* The segment registers are funny things, they are
+- * automatically loaded from a table, in memory wherever you
+- * set them to a specific selector, but this table is never
+- * accessed again unless you set the segment to a different selector.
+- *
+- * The more common model are caches where the behide
+- * the scenes work is done, but is also dropped at arbitrary
+- * times.
++ /* The segment registers are funny things, they have both a
++ * visible and an invisible part. Whenever the visible part is
++ * set to a specific selector, the invisible part is loaded
++ * with from a table in memory. At no other time is the
++ * descriptor table in memory accessed.
+ *
+ * I take advantage of this here by force loading the
+ * segments, before I zap the gdt with an invalid value.
--- /dev/null
+++
work/patches/linux-2.6.16.29/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch
@@ -0,0 +1,93 @@
+From: Tobias Klauser <tklauser@xxxxxxxxxxx>
+Date: Mon, 26 Jun 2006 16:57:34 +0000 (+0200)
+Subject: Storage class should be first
+X-Git-Tag: v2.6.18-rc1
+X-Git-Url:
http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=2efe55a9cec8418f0e0cde3dc3787a42fddc4411
+
+Storage class should be first
+
+Storage class should be before const
+
+Signed-off-by: Tobias Klauser <tklauser@xxxxxxxxxxx>
+Signed-off-by: Adrian Bunk <bunk@xxxxxxxxx>
+---
+
+--- a/arch/i386/kernel/machine_kexec.c
++++ b/arch/i386/kernel/machine_kexec.c
+@@ -133,9 +133,9 @@ typedef asmlinkage NORET_TYPE void (*rel
+ unsigned long start_address,
+ unsigned int has_pae) ATTRIB_NORET;
+
+-const extern unsigned char relocate_new_kernel[];
++extern const unsigned char relocate_new_kernel[];
+ extern void relocate_new_kernel_end(void);
+-const extern unsigned int relocate_new_kernel_size;
++extern const unsigned int relocate_new_kernel_size;
+
+ /*
+ * A architecture hook called to validate the
+--- a/arch/powerpc/kernel/machine_kexec_32.c
++++ b/arch/powerpc/kernel/machine_kexec_32.c
+@@ -30,8 +30,8 @@ typedef NORET_TYPE void (*relocate_new_k
+ */
+ void default_machine_kexec(struct kimage *image)
+ {
+- const extern unsigned char relocate_new_kernel[];
+- const extern unsigned int relocate_new_kernel_size;
++ extern const unsigned char relocate_new_kernel[];
++ extern const unsigned int relocate_new_kernel_size;
+ unsigned long page_list;
+ unsigned long reboot_code_buffer, reboot_code_buffer_phys;
+ relocate_new_kernel_t rnk;
+--- a/arch/ppc/kernel/machine_kexec.c
++++ b/arch/ppc/kernel/machine_kexec.c
+@@ -25,8 +25,8 @@ typedef NORET_TYPE void (*relocate_new_k
+ unsigned long reboot_code_buffer,
+ unsigned long start_address) ATTRIB_NORET;
+
+-const extern unsigned char relocate_new_kernel[];
+-const extern unsigned int relocate_new_kernel_size;
++extern const unsigned char relocate_new_kernel[];
++extern const unsigned int relocate_new_kernel_size;
+
+ void machine_shutdown(void)
+ {
+--- a/arch/s390/kernel/machine_kexec.c
++++ b/arch/s390/kernel/machine_kexec.c
+@@ -27,8 +27,8 @@ static void kexec_halt_all_cpus(void *);
+
+ typedef void (*relocate_kernel_t) (kimage_entry_t *, unsigned long);
+
+-const extern unsigned char relocate_kernel[];
+-const extern unsigned long long relocate_kernel_len;
++extern const unsigned char relocate_kernel[];
++extern const unsigned long long relocate_kernel_len;
+
+ int
+ machine_kexec_prepare(struct kimage *image)
+--- a/arch/sh/kernel/machine_kexec.c
++++ b/arch/sh/kernel/machine_kexec.c
+@@ -25,8 +25,8 @@ typedef NORET_TYPE void (*relocate_new_k
+ unsigned long start_address,
+ unsigned long vbr_reg) ATTRIB_NORET;
+
+-const extern unsigned char relocate_new_kernel[];
+-const extern unsigned int relocate_new_kernel_size;
++extern const unsigned char relocate_new_kernel[];
++extern const unsigned int relocate_new_kernel_size;
+ extern void *gdb_vbr_vector;
+
+ /*
+--- a/arch/x86_64/kernel/machine_kexec.c
++++ b/arch/x86_64/kernel/machine_kexec.c
+@@ -149,8 +149,8 @@ typedef NORET_TYPE void (*relocate_new_k
+ unsigned long start_address,
+ unsigned long pgtable) ATTRIB_NORET;
+
+-const extern unsigned char relocate_new_kernel[];
+-const extern unsigned long relocate_new_kernel_size;
++extern const unsigned char relocate_new_kernel[];
++extern const unsigned long relocate_new_kernel_size;
+
+ int machine_kexec_prepare(struct kimage *image)
+ {
--- 0003/patches/linux-2.6.16.29/series
+++ work/patches/linux-2.6.16.29/series
@@ -1,4 +1,6 @@
kexec-generic.patch
+git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch
+git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch
blktap-aio-16_03_06.patch
device_bind.patch
fix-hz-suspend.patch
--- 0003/xen/arch/x86/crash.c
+++ work/xen/arch/x86/crash.c
@@ -1,10 +1,134 @@
-#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@xxxxxxxxxxxx>
+ * - Magnus Damm <magnus@xxxxxxxxxxxxx>
+ */
+
+#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 <xen/version.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)
+{
+ int cpu = smp_processor_id();
+ crash_note_t *cntp = &per_cpu(crash_notes, cpu);
+
+ /* this code assumes that the first note has been written already */
+
+ cntp->xen.note.note.note.namesz = XEN_STR_LEN;
+ cntp->xen.note.note.note.descsz = sizeof(xen_crash_xen_regs_t);
+ cntp->xen.note.note.note.type = 0x10000001; /* NT_XEN_DOM0_CR3 */
+ memcpy(cntp->xen.note.note.name, XEN_STR, XEN_STR_LEN);
+
+ cntp->xen.desc.desc.xen_major_version = xen_major_version();
+ cntp->xen.desc.desc.xen_minor_version = xen_minor_version();
+ cntp->xen.desc.desc.xen_extra_version = __pa(xen_extra_version());
+ cntp->xen.desc.desc.xen_changeset = __pa(xen_changeset());
+ cntp->xen.desc.desc.xen_compiler = __pa(xen_compiler());
+ cntp->xen.desc.desc.xen_compile_date = __pa(xen_compile_date());
+ cntp->xen.desc.desc.xen_compile_time = __pa(xen_compile_time());
+
+ cntp->xen.desc.desc.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();
}
/*
--- 0003/xen/arch/x86/machine_kexec.c
+++ work/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@xxxxxxxxxxxx>
+ * - Magnus Damm <magnus@xxxxxxxxxxxxx>
+ */
+
+#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();
}
/*
--- 0001/xen/arch/x86/setup.c
+++ work/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
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
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
#endif
}
+ machine_kexec_reserved(&crash_area);
+ if (crash_area.size > 0) {
+ unsigned long kdump_start, kdump_size, k;
+
+ /* mark images pages as free for now */
+
+ init_boot_pages(initial_images_start, initial_images_end);
+
+ kdump_start = crash_area.start;
+ kdump_size = crash_area.size;
+
+ printk("Kdump: %luMB (%lukB) at 0x%lx\n",
+ kdump_size >> 20,
+ kdump_size >> 10,
+ kdump_start);
+
+ if ((kdump_start & ~PAGE_MASK) || (kdump_size & ~PAGE_MASK))
+ panic("Kdump parameters not page aligned\n");
+
+ kdump_start >>= PAGE_SHIFT;
+ kdump_size >>= PAGE_SHIFT;
+
+ /* allocate pages for Kdump memory area */
+
+ k = alloc_boot_pages_at(kdump_size, kdump_start);
+
+ if (k != kdump_start)
+ panic("Unable to reserve Kdump memory\n");
+
+ /* allocate pages for relocated initial images */
+
+ k = ((initial_images_end - initial_images_start) & ~PAGE_MASK) ? 1 : 0;
+ k += (initial_images_end - initial_images_start) >> PAGE_SHIFT;
+
+ k = alloc_boot_pages(k, 1);
+
+ if (!k)
+ panic("Unable to allocate initial images memory\n");
+
+ move_memory(k << PAGE_SHIFT, initial_images_start, initial_images_end);
+
+ initial_images_end -= initial_images_start;
+ initial_images_start = k << PAGE_SHIFT;
+ initial_images_end += initial_images_start;
+ }
+
memguard_init();
percpu_guard_areas();
--- 0001/xen/arch/x86/traps.c
+++ work/xen/arch/x86/traps.c
@@ -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>
@@ -1579,6 +1580,7 @@ static void unknown_nmi_error(unsigned c
printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
printk("Dazed and confused, but trying to continue\n");
printk("Do you have a strange power saving mode enabled?\n");
+ machine_crash_kexec();
}
}
--- 0003/xen/include/asm-x86/elf.h
+++ work/xen/include/asm-x86/elf.h
@@ -1,16 +1,11 @@
#ifndef __X86_ELF_H__
#define __X86_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 *dst)
-{
- 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__ */
--- 0001/xen/include/asm-x86/fixmap.h
+++ work/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
};
--- 0001/xen/include/asm-x86/hypercall.h
+++ work/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
--- 0003/xen/include/asm-x86/kexec.h
+++ work/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__ */
--- /dev/null
+++ work/xen/include/asm-x86/x86_32/elf.h
@@ -0,0 +1,25 @@
+#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 *dst)
+{
+ 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:
+ */
--- /dev/null
+++ work/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:
+ */
--- /dev/null
+++ work/xen/include/asm-x86/x86_64/elf.h
@@ -0,0 +1,25 @@
+#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 *dst)
+{
+ 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:
+ */
--- /dev/null
+++ work/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:
+ */
--- 0003/xen/include/public/kexec.h
+++ work/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;
--- 0003/xen/include/xen/elfcore.h
+++ work/xen/include/xen/elfcore.h
@@ -102,6 +102,9 @@ typedef struct {
unsigned long xen_compiler;
unsigned long xen_compile_date;
unsigned long xen_compile_time;
+#ifdef CONFIG_X86
+ unsigned long dom0_pfn_to_mfn_frame_list_list;
+#endif
} xen_crash_xen_regs_t;
TYPEDEF_NOTE(crash_note_xen_t, XEN_STR_LEN, xen_crash_xen_regs_t);
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|