xen-4.5.1-testing-src.tar.bz2 - Dropped patches now contained in tarball 556c2cf2-x86-don-t-crash-mapping-a-page-using-EFI-rt-page-tables.patch 556d9718-efi-fix-allocation-problems-if-ExitBootServices-fails.patch 556eabf7-x86-apic-Disable-the-LAPIC-later-in-smp_send_stop.patch 556eac15-x86-crash-don-t-use-set_fixmap-in-the-crash-path.patch 55780aaa-efi-avoid-calling-boot-services-after-ExitBootServices.patch 55780aff-x86-EFI-fix-EFI_MEMORY_WP-handling.patch 55780b43-EFI-early-add-mapbs-to-map-EfiBootServices-Code-Data.patch 55780b97-EFI-support-default-attributes-to-map-Runtime-service-areas.patch - Replace 5124efbe-add-qxl-support.patch with the variant that finally made it upstream, 554cc211-libxl-add-qxl.patch - bsc#931627 - VUL-0: CVE-2015-4105: XSA-130: xen: Guest triggerable qemu MSI-X pass-through error messages qemu-MSI-X-latch-writes.patch - bsc#907514 - Bus fatal error & sles12 sudden reboot has been observed - bsc#910258 - SLES12 Xen host crashes with FATAL NMI after shutdown of guest with VT-d NIC - bsc#918984 - Bus fatal error & sles11-SP4 sudden reboot has been observed - bsc#923967 - Partner-L3: Bus fatal error & sles11-SP3 sudden reboot has been observed x86-MSI-X-teardown.patch x86-MSI-X-enable.patch x86-MSI-X-guest-mask.patch x86-MSI-X-maskall.patch qemu-MSI-X-enable-maskall.patch OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=364
142 lines
4.8 KiB
Diff
142 lines
4.8 KiB
Diff
References: bsc#931627
|
|
|
|
xen/MSI-X: latch MSI-X table writes
|
|
|
|
The remaining log message in pci_msix_write() is wrong, as there guest
|
|
behavior may only appear to be wrong: For one, the old logic didn't
|
|
take the mask-all bit into account. And then this shouldn't depend on
|
|
host device state (i.e. the host may have masked the entry without the
|
|
guest having done so). Plus these writes shouldn't be dropped even when
|
|
an entry gets unmasked. Instead, if they can't be made take effect
|
|
right away, they should take effect on the next unmasking or enabling
|
|
operation - the specification explicitly describes such caching
|
|
behavior.
|
|
|
|
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
|
|
|
--- trunk.orig/tools/qemu-xen-dir-remote/hw/xen/xen_pt.h 2015-06-10 00:00:00.000000000 +0200
|
|
+++ trunk/tools/qemu-xen-dir-remote/hw/xen/xen_pt.h 2015-04-14 08:58:43.000000000 +0200
|
|
@@ -175,9 +175,8 @@ typedef struct XenPTMSIXEntry {
|
|
int pirq;
|
|
uint64_t addr;
|
|
uint32_t data;
|
|
- uint32_t vector_ctrl;
|
|
+ uint32_t latch[4];
|
|
bool updated; /* indicate whether MSI ADDR or DATA is updated */
|
|
- bool warned; /* avoid issuing (bogus) warning more than once */
|
|
} XenPTMSIXEntry;
|
|
typedef struct XenPTMSIX {
|
|
uint32_t ctrl_offset;
|
|
--- trunk.orig/tools/qemu-xen-dir-remote/hw/xen/xen_pt_msi.c 2015-06-10 00:00:00.000000000 +0200
|
|
+++ trunk/tools/qemu-xen-dir-remote/hw/xen/xen_pt_msi.c 2015-05-07 12:46:09.000000000 +0200
|
|
@@ -25,6 +25,7 @@
|
|
#define XEN_PT_GFLAGSSHIFT_DELIV_MODE 12
|
|
#define XEN_PT_GFLAGSSHIFT_TRG_MODE 15
|
|
|
|
+#define latch(fld) latch[PCI_MSIX_ENTRY_##fld / sizeof(uint32_t)]
|
|
|
|
/*
|
|
* Helpers
|
|
@@ -322,6 +323,13 @@ static int xen_pt_msix_update_one(XenPCI
|
|
|
|
pirq = entry->pirq;
|
|
|
|
+ if (pirq == XEN_PT_UNASSIGNED_PIRQ || s->msix->maskall ||
|
|
+ (entry->latch(VECTOR_CTRL) & PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
|
|
+ entry->addr = entry->latch(LOWER_ADDR) |
|
|
+ ((uint64_t)entry->latch(UPPER_ADDR) << 32);
|
|
+ entry->data = entry->latch(DATA);
|
|
+ }
|
|
+
|
|
rc = msi_msix_setup(s, entry->addr, entry->data, &pirq, true, entry_nr,
|
|
entry->pirq == XEN_PT_UNASSIGNED_PIRQ);
|
|
if (rc) {
|
|
@@ -396,35 +404,15 @@ int xen_pt_msix_update_remap(XenPCIPasst
|
|
|
|
static uint32_t get_entry_value(XenPTMSIXEntry *e, int offset)
|
|
{
|
|
- switch (offset) {
|
|
- case PCI_MSIX_ENTRY_LOWER_ADDR:
|
|
- return e->addr & UINT32_MAX;
|
|
- case PCI_MSIX_ENTRY_UPPER_ADDR:
|
|
- return e->addr >> 32;
|
|
- case PCI_MSIX_ENTRY_DATA:
|
|
- return e->data;
|
|
- case PCI_MSIX_ENTRY_VECTOR_CTRL:
|
|
- return e->vector_ctrl;
|
|
- default:
|
|
- return 0;
|
|
- }
|
|
+ return !(offset % sizeof(*e->latch))
|
|
+ ? e->latch[offset / sizeof(*e->latch)] : 0;
|
|
}
|
|
|
|
static void set_entry_value(XenPTMSIXEntry *e, int offset, uint32_t val)
|
|
{
|
|
- switch (offset) {
|
|
- case PCI_MSIX_ENTRY_LOWER_ADDR:
|
|
- e->addr = (e->addr & ((uint64_t)UINT32_MAX << 32)) | val;
|
|
- break;
|
|
- case PCI_MSIX_ENTRY_UPPER_ADDR:
|
|
- e->addr = (uint64_t)val << 32 | (e->addr & UINT32_MAX);
|
|
- break;
|
|
- case PCI_MSIX_ENTRY_DATA:
|
|
- e->data = val;
|
|
- break;
|
|
- case PCI_MSIX_ENTRY_VECTOR_CTRL:
|
|
- e->vector_ctrl = val;
|
|
- break;
|
|
+ if (!(offset % sizeof(*e->latch)))
|
|
+ {
|
|
+ e->latch[offset / sizeof(*e->latch)] = val;
|
|
}
|
|
}
|
|
|
|
@@ -444,39 +432,28 @@ static void pci_msix_write(void *opaque,
|
|
offset = addr % PCI_MSIX_ENTRY_SIZE;
|
|
|
|
if (offset != PCI_MSIX_ENTRY_VECTOR_CTRL) {
|
|
- const volatile uint32_t *vec_ctrl;
|
|
-
|
|
if (get_entry_value(entry, offset) == val
|
|
&& entry->pirq != XEN_PT_UNASSIGNED_PIRQ) {
|
|
return;
|
|
}
|
|
|
|
+ entry->updated = true;
|
|
+ } else if (msix->enabled && entry->updated &&
|
|
+ !(val & PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
|
|
+ const volatile uint32_t *vec_ctrl;
|
|
+
|
|
/*
|
|
* If Xen intercepts the mask bit access, entry->vec_ctrl may not be
|
|
* up-to-date. Read from hardware directly.
|
|
*/
|
|
vec_ctrl = s->msix->phys_iomem_base + entry_nr * PCI_MSIX_ENTRY_SIZE
|
|
+ PCI_MSIX_ENTRY_VECTOR_CTRL;
|
|
+ set_entry_value(entry, offset, *vec_ctrl);
|
|
|
|
- if (msix->enabled && !(*vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
|
|
- if (!entry->warned) {
|
|
- entry->warned = true;
|
|
- XEN_PT_ERR(&s->dev, "Can't update msix entry %d since MSI-X is"
|
|
- " already enabled.\n", entry_nr);
|
|
- }
|
|
- return;
|
|
- }
|
|
-
|
|
- entry->updated = true;
|
|
+ xen_pt_msix_update_one(s, entry_nr);
|
|
}
|
|
|
|
set_entry_value(entry, offset, val);
|
|
-
|
|
- if (offset == PCI_MSIX_ENTRY_VECTOR_CTRL) {
|
|
- if (msix->enabled && !(val & PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
|
|
- xen_pt_msix_update_one(s, entry_nr);
|
|
- }
|
|
- }
|
|
}
|
|
|
|
static uint64_t pci_msix_read(void *opaque, hwaddr addr,
|