ba5dde9750
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
110 lines
4.3 KiB
Diff
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 ?:
|