diff options
author | Ian Campbell <ian.campbell@xensource.com> | 2006-11-30 12:38:51 +0000 |
---|---|---|
committer | Ian Campbell <ian.campbell@xensource.com> | 2006-11-30 12:38:51 +0000 |
commit | 6dd60f6880df6d369385bdac2e41a5b6211423d9 (patch) | |
tree | 6d5b586741d303a0a4003648b1a8ed20d559173b /xen/arch/x86/machine_kexec.c | |
parent | a173b7d011523df95259a206a5ff5d6ceeea336b (diff) | |
download | xen-6dd60f6880df6d369385bdac2e41a5b6211423d9.tar.gz xen-6dd60f6880df6d369385bdac2e41a5b6211423d9.tar.bz2 xen-6dd60f6880df6d369385bdac2e41a5b6211423d9.zip |
[XEN] 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@valinux.co.jp>
Signed-Off-By: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'xen/arch/x86/machine_kexec.c')
-rw-r--r-- | xen/arch/x86/machine_kexec.c | 83 |
1 files changed, 73 insertions, 10 deletions
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(); } /* |