From 5200007510a6ebae89a2e375d730ad366703c699d9322134f083f68aabb095ee Mon Sep 17 00:00:00 2001 From: Charles Arnold Date: Mon, 23 Apr 2012 16:48:44 +0000 Subject: [PATCH] - Upstream patches from Jan 25098-x86-emul-lock-UD.patch 25101-x86-hpet-disable.patch ioemu-9877-MSI-X-device-cleanup.patch OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=181 --- 25098-x86-emul-lock-UD.patch | 73 +++++++++++++++ 25101-x86-hpet-disable.patch | 125 ++++++++++++++++++++++++++ ioemu-9877-MSI-X-device-cleanup.patch | 73 +++++++++++++++ xen.changes | 8 ++ xen.spec | 11 ++- 5 files changed, 287 insertions(+), 3 deletions(-) create mode 100644 25098-x86-emul-lock-UD.patch create mode 100644 25101-x86-hpet-disable.patch create mode 100644 ioemu-9877-MSI-X-device-cleanup.patch diff --git a/25098-x86-emul-lock-UD.patch b/25098-x86-emul-lock-UD.patch new file mode 100644 index 0000000..c9e1c1c --- /dev/null +++ b/25098-x86-emul-lock-UD.patch @@ -0,0 +1,73 @@ +# HG changeset patch +# User Andrew Cooper +# Date 1332535516 0 +# Node ID 2e45b26bc412099a2b8f009bcf111e4b6c23847b +# Parent 2ca43b65718fbe2d3f9ea36132e139ef774d9a11 +x86_emulate: raise #UD rather than #GP on invalid use of LOCK prefix + +From: Andrew Cooper +Signed-off-by: Keir Fraser +Committed-by: Keir Fraser + +# HG changeset patch +# User Keir Fraser +# Date 1332535908 0 +# Node ID 4bd752a4cdf323c41c50f8cd6286f566d67adeae +# Parent 2e45b26bc412099a2b8f009bcf111e4b6c23847b +x86_emulate: Do not push an error code onto a #UD exception stack + +Signed-off-by: Keir Fraser + +--- a/xen/arch/x86/x86_emulate/x86_emulate.c ++++ b/xen/arch/x86/x86_emulate/x86_emulate.c +@@ -1353,7 +1353,7 @@ x86_emulate( + } + + /* Lock prefix is allowed only on RMW instructions. */ +- generate_exception_if((d & Mov) && lock_prefix, EXC_GP, 0); ++ generate_exception_if((d & Mov) && lock_prefix, EXC_UD, -1); + + /* ModRM and SIB bytes. */ + if ( d & ModRM ) +@@ -1572,12 +1572,12 @@ x86_emulate( + lock_prefix && + ((b < 0x20) || (b > 0x23)) && /* MOV CRn/DRn */ + (b != 0xc7), /* CMPXCHG{8,16}B */ +- EXC_GP, 0); ++ EXC_UD, -1); + dst.type = OP_NONE; + break; + + case DstReg: +- generate_exception_if(lock_prefix, EXC_GP, 0); ++ generate_exception_if(lock_prefix, EXC_UD, -1); + dst.type = OP_REG; + if ( d & ByteOp ) + { +@@ -1633,7 +1633,7 @@ x86_emulate( + dst = ea; + if ( dst.type == OP_REG ) + { +- generate_exception_if(lock_prefix, EXC_GP, 0); ++ generate_exception_if(lock_prefix, EXC_UD, -1); + switch ( dst.bytes ) + { + case 1: dst.val = *(uint8_t *)dst.reg; break; +@@ -3645,14 +3645,14 @@ x86_emulate( + struct segment_register cs = { 0 }, ss = { 0 }; + int rc; + +- generate_exception_if(in_realmode(ctxt, ops), EXC_UD, 0); +- generate_exception_if(!in_protmode(ctxt, ops), EXC_UD, 0); ++ generate_exception_if(in_realmode(ctxt, ops), EXC_UD, -1); ++ generate_exception_if(!in_protmode(ctxt, ops), EXC_UD, -1); + + /* Inject #UD if syscall/sysret are disabled. */ + fail_if(ops->read_msr == NULL); + if ( (rc = ops->read_msr(MSR_EFER, &msr_content, ctxt)) != 0 ) + goto done; +- generate_exception_if((msr_content & EFER_SCE) == 0, EXC_UD, 0); ++ generate_exception_if((msr_content & EFER_SCE) == 0, EXC_UD, -1); + + if ( (rc = ops->read_msr(MSR_STAR, &msr_content, ctxt)) != 0 ) + goto done; diff --git a/25101-x86-hpet-disable.patch b/25101-x86-hpet-disable.patch new file mode 100644 index 0000000..304a01b --- /dev/null +++ b/25101-x86-hpet-disable.patch @@ -0,0 +1,125 @@ +References: bnc#748896 + +# HG changeset patch +# User Jan Beulich +# Date 1332854423 -7200 +# Node ID f06ff3dfde08ee563970cffba502742249ff5820 +# Parent ed48258053aea953afd28b746b53af7b8b30531b +x86/hpet: disable before reboot or kexec + +Linux up to now is not smart enough to properly clear the HPET when it +boots, which is particularly a problem when a kdump attempt from +running under Xen is being made. Linux itself added code to work around +this to its shutdown paths quite some time ago, so let's do something +similar in Xen: Save the configuration register settings during boot, +and restore them during shutdown. This should cover the majority of +cases where the secondary kernel might not come up because timer +interrupts don't work. + +Signed-off-by: Jan Beulich +Acked-by: Keir Fraser + +--- a/xen/arch/x86/crash.c ++++ b/xen/arch/x86/crash.c +@@ -94,6 +94,7 @@ static void nmi_shootdown_cpus(void) + x2apic_enabled = (current_local_apic_mode() == APIC_MODE_X2APIC); + + disable_IO_APIC(); ++ hpet_disable(); + } + + void machine_crash_shutdown(void) +--- a/xen/arch/x86/hpet.c ++++ b/xen/arch/x86/hpet.c +@@ -721,12 +721,14 @@ int hpet_legacy_irq_tick(void) + return 1; + } + ++static u32 *hpet_boot_cfg; ++ + u64 hpet_setup(void) + { + static u64 hpet_rate; + static u32 system_reset_latch; + u32 hpet_id, hpet_period, cfg; +- int i; ++ unsigned int i, last; + + if ( system_reset_latch == system_reset_counter ) + return hpet_rate; +@@ -752,13 +754,20 @@ u64 hpet_setup(void) + return 0; + } + ++ last = (hpet_id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT; ++ hpet_boot_cfg = xmalloc_array(u32, 2 + last); ++ + cfg = hpet_read32(HPET_CFG); ++ if ( hpet_boot_cfg ) ++ *hpet_boot_cfg = cfg; + cfg &= ~(HPET_CFG_ENABLE | HPET_CFG_LEGACY); + hpet_write32(cfg, HPET_CFG); + +- for ( i = 0; i <= ((hpet_id >> 8) & 31); i++ ) ++ for ( i = 0; i <= last; ++i ) + { + cfg = hpet_read32(HPET_Tn_CFG(i)); ++ if ( hpet_boot_cfg ) ++ hpet_boot_cfg[i + 1] = cfg; + cfg &= ~HPET_TN_ENABLE; + hpet_write32(cfg, HPET_Tn_CFG(i)); + } +@@ -772,3 +781,21 @@ u64 hpet_setup(void) + + return hpet_rate; + } ++ ++void hpet_disable(void) ++{ ++ unsigned int i; ++ u32 id; ++ ++ if ( !hpet_boot_cfg ) ++ return; ++ ++ hpet_write32(*hpet_boot_cfg & ~HPET_CFG_ENABLE, HPET_CFG); ++ ++ id = hpet_read32(HPET_ID); ++ for ( i = 0; i <= ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT); ++i ) ++ hpet_write32(hpet_boot_cfg[i + 1], HPET_Tn_CFG(i)); ++ ++ if ( *hpet_boot_cfg & HPET_CFG_ENABLE ) ++ hpet_write32(*hpet_boot_cfg, HPET_CFG); ++} +--- a/xen/arch/x86/smp.c ++++ b/xen/arch/x86/smp.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -373,6 +374,7 @@ void smp_send_stop(void) + local_irq_disable(); + __stop_this_cpu(); + disable_IO_APIC(); ++ hpet_disable(); + local_irq_enable(); + } + +--- a/xen/include/asm-x86/hpet.h ++++ b/xen/include/asm-x86/hpet.h +@@ -68,6 +68,11 @@ extern unsigned long hpet_address; + u64 hpet_setup(void); + + /* ++ * Disable HPET hardware: restore it to boot time state. ++ */ ++void hpet_disable(void); ++ ++/* + * Callback from legacy timer (PIT channel 0) IRQ handler. + * Returns 1 if tick originated from HPET; else 0. + */ diff --git a/ioemu-9877-MSI-X-device-cleanup.patch b/ioemu-9877-MSI-X-device-cleanup.patch new file mode 100644 index 0000000..4a68756 --- /dev/null +++ b/ioemu-9877-MSI-X-device-cleanup.patch @@ -0,0 +1,73 @@ +# HG changeset patch +# User Jan Beulich +# Date 1333384536 -3600 +# Node ID c39da254d7b9a029080e970508a6aebac4e01220 +# Parent 40274e03bcbf22d9456f8526d488bc47b1917246 +qemu-traditional/passthrough: adjust MSI-X device cleanup (bug 1809) + +To address http://bugzilla.xen.org/bugzilla/show_bug.cgi?id=1809, +pt_unregister_regions() also needs to use the newly introduced +_pt_iomem_helper() instead of calling xc_domain_memory_mapping() +directly, to take into consideration the hole created for the MSI-X +table. + +For this to work, two calls in unregister_real_device() need to be +swapped, since otherwise we'd have + +unregister_real_device() + -> pt_config_delete() + -> pt_msix_delete() (frees [and fails to clear] ->msix) + -> pt_unregister_regions() + -> _pt_iomem_helper() (with the patch below) + -> has_msix_mapping() (uses ->msix) + +And to be certain to prevent (catch) further/future use-after-free +instances, let's also clear dev->msix in pt_msix_delete(). + +Signed-off-by: Jan Beulich +Tested-by: Yongjie Ren +Acked-by: Stefano Stabellini + +committer: Ian Jackson + +--- a/tools/ioemu-qemu-xen/hw/pass-through.c ++++ b/tools/ioemu-qemu-xen/hw/pass-through.c +@@ -1988,11 +1988,9 @@ static void pt_unregister_regions(struct + if ( type == PCI_ADDRESS_SPACE_MEM || + type == PCI_ADDRESS_SPACE_MEM_PREFETCH ) + { +- ret = xc_domain_memory_mapping(xc_handle, domid, +- assigned_device->bases[i].e_physbase >> XC_PAGE_SHIFT, +- assigned_device->bases[i].access.maddr >> XC_PAGE_SHIFT, +- (e_size+XC_PAGE_SIZE-1) >> XC_PAGE_SHIFT, +- DPCI_REMOVE_MAPPING); ++ ret = _pt_iomem_helper(assigned_device, i, ++ assigned_device->bases[i].e_physbase, ++ e_size, DPCI_REMOVE_MAPPING); + if ( ret != 0 ) + { + PT_LOG("Error: remove old mem mapping failed!\n"); +@@ -4425,12 +4423,12 @@ static int unregister_real_device(int de + } + } + +- /* delete all emulated config registers */ +- pt_config_delete(assigned_device); +- + /* unregister real device's MMIO/PIO BARs */ + pt_unregister_regions(assigned_device); + ++ /* delete all emulated config registers */ ++ pt_config_delete(assigned_device); ++ + pt_iomul_free(assigned_device); + + /* mark this devfn as free */ +--- a/tools/ioemu-qemu-xen/hw/pt-msi.c ++++ b/tools/ioemu-qemu-xen/hw/pt-msi.c +@@ -621,4 +621,5 @@ void pt_msix_delete(struct pt_dev *dev) + + + free(dev->msix); ++ dev->msix = NULL; + } diff --git a/xen.changes b/xen.changes index 95d3f11..e45763d 100644 --- a/xen.changes +++ b/xen.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue Apr 3 08:33:36 MDT 2012 - carnold@novell.com + +- Upstream patches from Jan + 25098-x86-emul-lock-UD.patch + 25101-x86-hpet-disable.patch + ioemu-9877-MSI-X-device-cleanup.patch + ------------------------------------------------------------------- Mon Apr 2 13:07:20 CEST 2012 - ohering@suse.de diff --git a/xen.spec b/xen.spec index e457549..52ffc39 100644 --- a/xen.spec +++ b/xen.spec @@ -15,7 +15,6 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # - Name: xen ExclusiveArch: %ix86 x86_64 %define xvers 4.1 @@ -100,7 +99,7 @@ BuildRequires: kernel-syms BuildRequires: module-init-tools BuildRequires: xorg-x11 %endif -Version: 4.1.2_15 +Version: 4.1.2_17 Release: 0 PreReq: %insserv_prereq %fillup_prereq Summary: Xen Virtualization: Hypervisor (aka VMM aka Microkernel) @@ -366,11 +365,14 @@ Patch24950: 24950-gnttab-copy-mapped.patch Patch24970: 24970-x86-cpuidle-deny-port-access.patch Patch24996: 24996-x86-cpuidle-array-overrun.patch Patch25041: 25041-tapdisk2-create-init-name.patch +Patch25098: 25098-x86-emul-lock-UD.patch +Patch25101: 25101-x86-hpet-disable.patch # Upstream qemu patches Patch100: ioemu-9868-MSI-X.patch Patch101: ioemu-9869-MSI-X-init.patch Patch102: ioemu-9873-MSI-X-fix-unregister_iomem.patch -Patch103: cve-2012-0029-qemu-xen-unstable.patch +Patch103: ioemu-9877-MSI-X-device-cleanup.patch +Patch104: cve-2012-0029-qemu-xen-unstable.patch # Our patches Patch300: xen-config.diff Patch301: xend-config.diff @@ -1087,11 +1089,14 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools %patch24970 -p1 %patch24996 -p1 %patch25041 -p1 +%patch25098 -p1 +%patch25101 -p1 # Qemu %patch100 -p1 %patch101 -p1 %patch102 -p1 %patch103 -p1 +%patch104 -p1 # Our patches %patch300 -p1 %patch301 -p1