xen/53a1990a-IOMMU-prevent-VT-d-device-IOTLB-operations-on-wrong-IOMMU.patch
Charles Arnold ba5dde9750 - bnc#882127 - Xen kernel panics on booting SLES12 Beta 8
53a199d7-x86-EFI-allow-FPU-XMM-use-in-runtime-service-functions.patch
- Upstream patches from Jan
  538c338f-x86-amd_ucode-flip-revision-numbers-in-printk.patch
  538ee637-ACPI-Prevent-acpi_table_entries-from-falling-into-a-infinite-loop.patch
  5390917a-VT-d-honor-APEI-firmware-first-mode-in-XSA-59-workaround-code.patch
  53909259-x86-domctl-two-functional-fixes-to-XEN_DOMCTL_-gs-etvcpuextstate.patch
  5390927f-x86-fix-reboot-shutdown-with-running-HVM-guests.patch
  5396d818-avoid-crash-on-HVM-domain-destroy-with-PCI-passthrough.patch
  5396e805-x86-HVM-refine-SMEP-test-in-HVM_CR4_GUEST_RESERVED_BITS.patch
  539ebe62-x86-EFI-improve-boot-time-diagnostics.patch
  539ec004-x86-mce-don-t-spam-the-console-with-CPUx-Temperature-z.patch
  53a040c6-page-alloc-scrub-pages-used-by-hypervisor-upon-freeing.patch (replaces xsa100.patch)
  53a1990a-IOMMU-prevent-VT-d-device-IOTLB-operations-on-wrong-IOMMU.patch

- Replace 'domUloader' with 'pygrub' when converting or importing
  Xen domains into libvirt with xen2libvirt.  domUloader is no
  longer provided in xen-tools.
  Modified: xen2libvirt.py

Thu Jun  13 15:50:19 MDT 2014 - cyliu@suse.com
- fate#310956: Support Direct Kernel Boot for FV guests
  patches would go to upstream:
  qemu side: qemu-support-xen-hvm-direct-kernel-boot.patch
  xen side: xen-pass-kernel-initrd-to-qemu.patch
- bnc#880751 - VUL-0: xen: Hypervisor heap contents leaked to
  guests
  xsa100.patch

OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=320
2014-07-01 03:36:17 +00:00

110 lines
4.3 KiB
Diff

# Commit 84c340ba4c3eb99278b6ba885616bb183b88ad67
# Date 2014-06-18 15:50:02 +0200
# Author Malcolm Crossley <malcolm.crossley@citrix.com>
# Committer Jan Beulich <jbeulich@suse.com>
IOMMU: prevent VT-d device IOTLB operations on wrong IOMMU
PCIe ATS allows for devices to contain IOTLBs, the VT-d code was iterating
around all ATS capable devices and issuing IOTLB operations for all IOMMUs,
even though each ATS device is only accessible via one particular IOMMU.
Issuing an IOMMU operation to a device not accessible via that IOMMU results
in an IOMMU timeout because the device does not reply. VT-d IOMMU timeouts
result in a Xen panic.
Therefore this bug prevents any Intel system with 2 or more ATS enabled IOMMUs,
each with an ATS device connected to them, from booting Xen.
The patch adds a IOMMU pointer to the ATS device struct so the VT-d code can
ensure it does not issue IOMMU ATS operations on the wrong IOMMU. A void
pointer has to be used because AMD and Intel IOMMU implementations do not have
a common IOMMU structure or indexing mechanism.
Signed-off-by: Malcolm Crossley <malcolm.crossley@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -163,7 +163,7 @@ static void amd_iommu_setup_domain_devic
!pci_ats_enabled(iommu->seg, bus, pdev->devfn) )
{
if ( devfn == pdev->devfn )
- enable_ats_device(iommu->seg, bus, devfn);
+ enable_ats_device(iommu->seg, bus, devfn, iommu);
amd_iommu_flush_iotlb(devfn, pdev, INV_IOMMU_ALL_PAGES_ADDRESS, 0);
}
--- a/xen/drivers/passthrough/ats.h
+++ b/xen/drivers/passthrough/ats.h
@@ -24,6 +24,7 @@ struct pci_ats_dev {
u8 bus;
u8 devfn;
u16 ats_queue_depth; /* ATS device invalidation queue depth */
+ const void *iommu; /* No common IOMMU struct so use void pointer */
};
#define ATS_REG_CAP 4
@@ -34,7 +35,7 @@ struct pci_ats_dev {
extern struct list_head ats_devices;
extern bool_t ats_enabled;
-int enable_ats_device(int seg, int bus, int devfn);
+int enable_ats_device(int seg, int bus, int devfn, const void *iommu);
void disable_ats_device(int seg, int bus, int devfn);
struct pci_ats_dev *get_ats_device(int seg, int bus, int devfn);
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -1442,7 +1442,7 @@ static int domain_context_mapping(
ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn,
pdev);
if ( !ret && devfn == pdev->devfn && ats_device(pdev, drhd) > 0 )
- enable_ats_device(seg, bus, devfn);
+ enable_ats_device(seg, bus, devfn, drhd->iommu);
break;
@@ -1930,7 +1930,7 @@ static int intel_iommu_enable_device(str
if ( ret <= 0 )
return ret;
- ret = enable_ats_device(pdev->seg, pdev->bus, pdev->devfn);
+ ret = enable_ats_device(pdev->seg, pdev->bus, pdev->devfn, drhd->iommu);
return ret >= 0 ? 0 : ret;
}
--- a/xen/drivers/passthrough/vtd/x86/ats.c
+++ b/xen/drivers/passthrough/vtd/x86/ats.c
@@ -120,6 +120,10 @@ int dev_invalidate_iotlb(struct iommu *i
{
sid = (pdev->bus << 8) | pdev->devfn;
+ /* Only invalidate devices that belong to this IOMMU */
+ if ( pdev->iommu != iommu )
+ continue;
+
switch ( type ) {
case DMA_TLB_DSI_FLUSH:
if ( !device_in_domain(iommu, pdev, did) )
--- a/xen/drivers/passthrough/x86/ats.c
+++ b/xen/drivers/passthrough/x86/ats.c
@@ -23,7 +23,7 @@ LIST_HEAD(ats_devices);
bool_t __read_mostly ats_enabled = 1;
boolean_param("ats", ats_enabled);
-int enable_ats_device(int seg, int bus, int devfn)
+int enable_ats_device(int seg, int bus, int devfn, const void *iommu)
{
struct pci_ats_dev *pdev = NULL;
u32 value;
@@ -66,6 +66,7 @@ int enable_ats_device(int seg, int bus,
pdev->seg = seg;
pdev->bus = bus;
pdev->devfn = devfn;
+ pdev->iommu = iommu;
value = pci_conf_read16(seg, bus, PCI_SLOT(devfn),
PCI_FUNC(devfn), pos + ATS_REG_CAP);
pdev->ats_queue_depth = value & ATS_QUEUE_DEPTH_MASK ?: