guest 21971-pod-accounting.patch - bnc#584204 - xm usb-list broken usb-list.patch - bnc#625520 - TP-L3: NMI cannot be triggered for xen kernel 21926-x86-pv-NMI-inject.patch - bnc#613529 - TP-L3: kdump kernel hangs when crash was initiated from xen kernel 21886-kexec-shutdown.patch - Upstream Intel patches to improve X2APIC handling. 21716-iommu-alloc.patch 21717-ir-qi.patch 21718-x2apic-logic.patch 21933-vtd-ioapic-write.patch 21953-msi-enable.patch OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=71
289 lines
7.3 KiB
Diff
289 lines
7.3 KiB
Diff
# HG changeset patch
|
|
# User Keir Fraser <keir.fraser@citrix.com>
|
|
# Date 1280395881 -3600
|
|
# Node ID 578ed14c3c673d734318bcefa4597a7d7d9aee37
|
|
# Parent 2007fd03f53d9a3e8774a6df06beef7c74801b07
|
|
kexec: Clean up shutdown logic. Reinstate ACPI DMAR during kexec.
|
|
References: bnc#613529
|
|
|
|
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
|
|
|
|
--- 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
|
|
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 =
|
|
--- 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
|
|
{
|
|
}
|
|
|
|
-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 *im
|
|
.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
|
|
--- 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());
|
|
|
|
--- a/xen/arch/x86/tboot.c
|
|
+++ b/xen/arch/x86/tboot.c
|
|
@@ -491,7 +491,10 @@ int __init tboot_parse_dmar_table(acpi_t
|
|
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;
|
|
}
|
|
--- 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(
|
|
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(v
|
|
{
|
|
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(v
|
|
{
|
|
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 */
|
|
--- a/xen/drivers/acpi/tables.c
|
|
+++ b/xen/drivers/acpi/tables.c
|
|
@@ -41,7 +41,7 @@ mps_inti_flags_polarity[] = { "dfl", "hi
|
|
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_typ
|
|
* 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;
|
|
|
|
--- 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
|
|
|
|
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;
|
|
}
|
|
|
|
--- a/xen/include/asm-x86/smp.h
|
|
+++ b/xen/include/asm-x86/smp.h
|
|
@@ -102,6 +102,9 @@ static __inline int logical_smp_processo
|
|
|
|
extern int __cpu_disable(void);
|
|
extern void __cpu_die(unsigned int cpu);
|
|
+
|
|
+void __stop_this_cpu(void);
|
|
+
|
|
#endif /* !__ASSEMBLY__ */
|
|
|
|
#else /* CONFIG_SMP */
|