diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2010-08-02 17:18:37 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2010-08-02 17:18:37 +0100 |
commit | 0772f7b860224c19b1a59d471e9e88256e9ec92b (patch) | |
tree | e71cc0cef388ddee15e398e1de67aaecc108380e | |
parent | ffc1e7f1549a5715018579ef3c02b0c1a8da363f (diff) | |
download | xen-0772f7b860224c19b1a59d471e9e88256e9ec92b.tar.gz xen-0772f7b860224c19b1a59d471e9e88256e9ec92b.tar.bz2 xen-0772f7b860224c19b1a59d471e9e88256e9ec92b.zip |
kexec: Clean up shutdown logic. Reinstate ACPI DMAR during kexec.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen-unstable changeset: 21886:578ed14c3c67
xen-unstable date: Thu Jul 29 10:31:21 2010 +0100
-rw-r--r-- | xen/arch/x86/crash.c | 24 | ||||
-rw-r--r-- | xen/arch/x86/machine_kexec.c | 35 | ||||
-rw-r--r-- | xen/arch/x86/smp.c | 2 | ||||
-rw-r--r-- | xen/arch/x86/tboot.c | 5 | ||||
-rw-r--r-- | xen/common/kexec.c | 39 | ||||
-rw-r--r-- | xen/drivers/acpi/tables.c | 4 | ||||
-rw-r--r-- | xen/drivers/passthrough/vtd/dmar.c | 3 | ||||
-rw-r--r-- | xen/include/asm-x86/smp.h | 3 |
8 files changed, 60 insertions, 55 deletions
diff --git a/xen/arch/x86/crash.c b/xen/arch/x86/crash.c index 1c90b6eca2..a76f9aca20 100644 --- a/xen/arch/x86/crash.c +++ b/xen/arch/x86/crash.c @@ -25,7 +25,6 @@ #include <public/xen.h> #include <asm/shared.h> #include <asm/hvm/support.h> -#include <asm/hpet.h> static atomic_t waiting_for_crash_ipi; static unsigned int crashing_cpu; @@ -41,9 +40,10 @@ static int crash_nmi_callback(struct cpu_user_regs *regs, int cpu) local_irq_disable(); kexec_crash_save_cpu(); - disable_local_APIC(); + + __stop_this_cpu(); + atomic_dec(&waiting_for_crash_ipi); - hvm_cpu_down(); for ( ; ; ) halt(); @@ -55,7 +55,10 @@ static void nmi_shootdown_cpus(void) { unsigned long msecs; + local_irq_disable(); + crashing_cpu = smp_processor_id(); + local_irq_count(crashing_cpu) = 0; atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); /* Would it be better to replace the trap vector here? */ @@ -72,25 +75,18 @@ static void nmi_shootdown_cpus(void) msecs--; } - /* Leave the nmi callback set */ - disable_local_APIC(); + __stop_this_cpu(); + disable_IO_APIC(); + + local_irq_enable(); } void machine_crash_shutdown(void) { crash_xen_info_t *info; - local_irq_disable(); - nmi_shootdown_cpus(); - if ( hpet_broadcast_is_available() ) - hpet_disable_legacy_broadcast(); - - disable_IO_APIC(); - - hvm_cpu_down(); - info = kexec_crash_save_info(); info->xen_phys_start = xen_phys_start; info->dom0_pfn_to_mfn_frame_list_list = diff --git a/xen/arch/x86/machine_kexec.c b/xen/arch/x86/machine_kexec.c index f44aba2b5b..d3f146854f 100644 --- a/xen/arch/x86/machine_kexec.c +++ b/xen/arch/x86/machine_kexec.c @@ -18,6 +18,7 @@ #include <xen/domain_page.h> #include <asm/fixmap.h> #include <asm/hvm/hvm.h> +#include <asm/hpet.h> typedef void (*relocate_new_kernel_t)( unsigned long indirection_page, @@ -76,38 +77,11 @@ void machine_kexec_unload(int type, int slot, xen_kexec_image_t *image) { } -static void __machine_reboot_kexec(void *data) +void machine_reboot_kexec(xen_kexec_image_t *image) { - xen_kexec_image_t *image = (xen_kexec_image_t *)data; - - watchdog_disable(); - console_start_sync(); - + BUG_ON(smp_processor_id() != 0); smp_send_stop(); - machine_kexec(image); -} - -void machine_reboot_kexec(xen_kexec_image_t *image) -{ - int reboot_cpu_id; - - 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() ) - { - on_selected_cpus(cpumask_of(reboot_cpu_id), __machine_reboot_kexec, - image, 0); - for (;;) - ; /* nothing */ - } - else - { - __machine_reboot_kexec(image); - } BUG(); } @@ -118,6 +92,9 @@ void machine_kexec(xen_kexec_image_t *image) .limit = LAST_RESERVED_GDT_BYTE }; + if ( hpet_broadcast_is_available() ) + hpet_disable_legacy_broadcast(); + /* * compat_machine_kexec() returns to idle pagetables, which requires us * to be running on a static GDT mapping (idle pagetables have no GDT diff --git a/xen/arch/x86/smp.c b/xen/arch/x86/smp.c index 2a01923900..a0f7d8e947 100644 --- a/xen/arch/x86/smp.c +++ b/xen/arch/x86/smp.c @@ -326,7 +326,7 @@ int on_selected_cpus( return 0; } -static void __stop_this_cpu(void) +void __stop_this_cpu(void) { ASSERT(!local_irq_is_enabled()); diff --git a/xen/arch/x86/tboot.c b/xen/arch/x86/tboot.c index f5930401a2..4e86146f7d 100644 --- a/xen/arch/x86/tboot.c +++ b/xen/arch/x86/tboot.c @@ -482,7 +482,10 @@ int __init tboot_parse_dmar_table(acpi_table_handler dmar_handler) dmar_table = NULL; acpi_get_table(ACPI_SIG_DMAR, 0, &dmar_table); if ( dmar_table != NULL ) - ((struct acpi_table_dmar *)dmar_table)->header.signature[0] = '\0'; + { + dmar_table->signature[0] = 'X'; + dmar_table->checksum -= 'X'-'D'; + } return rc; } diff --git a/xen/common/kexec.c b/xen/common/kexec.c index c8cf1ac33d..da50880030 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> @@ -107,6 +109,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; @@ -115,17 +133,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); @@ -446,7 +472,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; @@ -464,8 +490,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 */ diff --git a/xen/drivers/acpi/tables.c b/xen/drivers/acpi/tables.c index 252bf98873..a25d9b2be1 100644 --- a/xen/drivers/acpi/tables.c +++ b/xen/drivers/acpi/tables.c @@ -41,7 +41,7 @@ mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" }; static const char *__initdata mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" }; -static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata; +static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES]; static int acpi_apic_instance __initdata; @@ -239,7 +239,7 @@ acpi_table_parse_madt(enum acpi_madt_type id, * Scan the ACPI System Descriptor Table (STD) for a table matching @id, * run @handler on it. Return 0 if table found, return on if not. */ -int __init acpi_table_parse(char *id, acpi_table_handler handler) +int acpi_table_parse(char *id, acpi_table_handler handler) { struct acpi_table_header *table = NULL; diff --git a/xen/drivers/passthrough/vtd/dmar.c b/xen/drivers/passthrough/vtd/dmar.c index 55c911cfe0..f4078ff44b 100644 --- a/xen/drivers/passthrough/vtd/dmar.c +++ b/xen/drivers/passthrough/vtd/dmar.c @@ -738,7 +738,8 @@ static int __init acpi_parse_dmar(struct acpi_table_header *table) out: /* Zap ACPI DMAR signature to prevent dom0 using vt-d HW. */ - dmar->header.signature[0] = '\0'; + dmar->header.signature[0] = 'X'; + dmar->header.checksum -= 'X'-'D'; return ret; } diff --git a/xen/include/asm-x86/smp.h b/xen/include/asm-x86/smp.h index 6f5200dbed..a3c440daeb 100644 --- a/xen/include/asm-x86/smp.h +++ b/xen/include/asm-x86/smp.h @@ -102,6 +102,9 @@ static __inline int logical_smp_processor_id(void) extern int __cpu_disable(void); extern void __cpu_die(unsigned int cpu); + +void __stop_this_cpu(void); + #endif /* !__ASSEMBLY__ */ #else /* CONFIG_SMP */ |