xen/qemu-MSI-X-latch-writes.patch
Charles Arnold 97a0425e04 - Update to Xen Version 4.5.1 FCS (fate#315675)
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
2015-06-30 14:23:29 +00:00

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,