diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2010-07-29 10:31:21 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2010-07-29 10:31:21 +0100 |
commit | 877ca1b20fecf14b364efe9ea0886f0be110a43f (patch) | |
tree | 3283c322156af9a2184772018e3de65fbac83460 /xen/common/kexec.c | |
parent | b99b79d46b8b7c8b3d26600445e86db9db23c744 (diff) | |
download | xen-877ca1b20fecf14b364efe9ea0886f0be110a43f.tar.gz xen-877ca1b20fecf14b364efe9ea0886f0be110a43f.tar.bz2 xen-877ca1b20fecf14b364efe9ea0886f0be110a43f.zip |
kexec: Clean up shutdown logic. Reinstate ACPI DMAR during kexec.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'xen/common/kexec.c')
-rw-r--r-- | xen/common/kexec.c | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/xen/common/kexec.c b/xen/common/kexec.c index 263faebcf5..f6ce3b16a2 100644 --- a/xen/common/kexec.c +++ b/xen/common/kexec.c @@ -6,7 +6,9 @@ * - Magnus Damm <magnus@valinux.co.jp> */ +#include <xen/init.h> #include <xen/lib.h> +#include <xen/acpi.h> #include <xen/ctype.h> #include <xen/errno.h> #include <xen/guest_access.h> @@ -201,6 +203,22 @@ crash_xen_info_t *kexec_crash_save_info(void) return out; } +static int acpi_dmar_reinstate(struct acpi_table_header *table) +{ + table->signature[0] = 'D'; + table->checksum += 'X'-'D'; + return 0; +} + +static void kexec_common_shutdown(void) +{ + watchdog_disable(); + console_start_sync(); + spin_debug_disable(); + one_cpu_only(); + acpi_table_parse(ACPI_SIG_DMAR, acpi_dmar_reinstate); +} + void kexec_crash(void) { int pos; @@ -209,17 +227,25 @@ void kexec_crash(void) if ( !test_bit(KEXEC_IMAGE_CRASH_BASE + pos, &kexec_flags) ) return; - console_start_sync(); - - one_cpu_only(); + kexec_common_shutdown(); kexec_crash_save_cpu(); machine_crash_shutdown(); - machine_kexec(&kexec_image[KEXEC_IMAGE_CRASH_BASE + pos]); BUG(); } +static long kexec_reboot(void *_image) +{ + xen_kexec_image_t *image = _image; + + kexec_common_shutdown(); + machine_reboot_kexec(image); + + BUG(); + return 0; +} + static void do_crashdump_trigger(unsigned char key) { printk("'%c' pressed -> triggering crashdump\n", key); @@ -540,7 +566,7 @@ static int kexec_exec(XEN_GUEST_HANDLE(void) uarg) { xen_kexec_exec_t exec; xen_kexec_image_t *image; - int base, bit, pos; + int base, bit, pos, ret = -EINVAL; if ( unlikely(copy_from_guest(&exec, uarg, 1)) ) return -EFAULT; @@ -558,8 +584,7 @@ static int kexec_exec(XEN_GUEST_HANDLE(void) uarg) { case KEXEC_TYPE_DEFAULT: image = &kexec_image[base + pos]; - one_cpu_only(); - machine_reboot_kexec(image); /* Does not return */ + ret = continue_hypercall_on_cpu(0, kexec_reboot, image); break; case KEXEC_TYPE_CRASH: kexec_crash(); /* Does not return */ |