aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/kexec.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-07-29 10:31:21 +0100
committerKeir Fraser <keir.fraser@citrix.com>2010-07-29 10:31:21 +0100
commit877ca1b20fecf14b364efe9ea0886f0be110a43f (patch)
tree3283c322156af9a2184772018e3de65fbac83460 /xen/common/kexec.c
parentb99b79d46b8b7c8b3d26600445e86db9db23c744 (diff)
downloadxen-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.c39
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 */