WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] VT-d: Fix ATS enabling for device assignm

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] VT-d: Fix ATS enabling for device assignment
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 19 May 2010 05:16:16 -0700
Delivery-date: Wed, 19 May 2010 05:22:26 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1274253726 -3600
# Node ID f67ae6f9d4107f091d062fc1501a96f873671d10
# Parent  eb4ecc037b7a53647f0ac89c7067d11ea622ab00
VT-d: Fix ATS enabling for device assignment

Currently, Xen only enables ATS in Xen booting. When an ATS capable
device is assigned to guest, ATS is actually not enabled because FLR
before assignment causes it to be disabled. Thus ATS cannot be used in
guest. This patch enables ATS in domain_context_mapping. This ensures
ATS is enabled in assignment because FLR is earlier than
domain_context_mapping call. Therefore ATS can be used in guest. This
patch also implements disable_ats_device to disable ATS when the
device is deassigned from a domain.

Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx>
---
 xen/drivers/passthrough/vtd/ia64/ats.c |    5 +++
 xen/drivers/passthrough/vtd/iommu.c    |    8 ++++-
 xen/drivers/passthrough/vtd/x86/ats.c  |   46 +++++++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+), 2 deletions(-)

diff -r eb4ecc037b7a -r f67ae6f9d410 xen/drivers/passthrough/vtd/ia64/ats.c
--- a/xen/drivers/passthrough/vtd/ia64/ats.c    Wed May 19 08:20:46 2010 +0100
+++ b/xen/drivers/passthrough/vtd/ia64/ats.c    Wed May 19 08:22:06 2010 +0100
@@ -47,6 +47,11 @@ int enable_ats_device(int seg, int bus, 
     return 0;
 }
 
+int disable_ats_device(int seg, int bus, int devfn)
+{
+    return 0;
+}
+
 int dev_invalidate_iotlb(struct iommu *iommu, u16 did,
     u64 addr, unsigned int size_order, u64 type)
 {
diff -r eb4ecc037b7a -r f67ae6f9d410 xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c       Wed May 19 08:20:46 2010 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c       Wed May 19 08:22:06 2010 +0100
@@ -1325,6 +1325,9 @@ static int domain_context_mapping(struct
             dprintk(VTDPREFIX, "d%d:PCIe: map bdf = %x:%x.%x\n",
                     domain->domain_id, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
         ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn);
+        if ( !ret && ats_device(0, bus, devfn) )
+            enable_ats_device(0, bus, devfn);
+
         break;
 
     case DEV_TYPE_PCI:
@@ -1454,6 +1457,9 @@ static int domain_context_unmap(struct d
             dprintk(VTDPREFIX, "d%d:PCIe: unmap bdf = %x:%x.%x\n",
                     domain->domain_id, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
         ret = domain_context_unmap_one(domain, iommu, bus, devfn);
+        if ( !ret && ats_device(0, bus, devfn) )
+            disable_ats_device(0, bus, devfn);
+
         break;
 
     case DEV_TYPE_PCI:
@@ -1772,8 +1778,6 @@ static void setup_dom0_devices(struct do
             list_add(&pdev->domain_list, &d->arch.pdev_list);
             domain_context_mapping(d, pdev->bus, pdev->devfn);
             pci_enable_acs(pdev);
-            if ( ats_device(0, pdev->bus, pdev->devfn) )
-                enable_ats_device(0, pdev->bus, pdev->devfn);
         }
     }
     spin_unlock(&pcidevs_lock);
diff -r eb4ecc037b7a -r f67ae6f9d410 xen/drivers/passthrough/vtd/x86/ats.c
--- a/xen/drivers/passthrough/vtd/x86/ats.c     Wed May 19 08:20:46 2010 +0100
+++ b/xen/drivers/passthrough/vtd/x86/ats.c     Wed May 19 08:22:06 2010 +0100
@@ -92,6 +92,9 @@ int ats_device(int seg, int bus, int dev
 
     pdev = pci_get_pdev(bus, devfn);
     drhd = acpi_find_matched_drhd_unit(pdev);
+    if ( !drhd )
+        return 0;
+
     if ( !ecap_queued_inval(drhd->iommu->ecap) ||
          !ecap_dev_iotlb(drhd->iommu->ecap) )
         return 0;
@@ -144,6 +147,9 @@ int enable_ats_device(int seg, int bus, 
 
     value = pci_conf_read16(bus, PCI_SLOT(devfn),
                             PCI_FUNC(devfn), pos + ATS_REG_CTL);
+    if ( value & ATS_ENABLE )
+        return 0;
+
     value |= ATS_ENABLE;
     pci_conf_write16(bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
                      pos + ATS_REG_CTL, value);
@@ -153,9 +159,49 @@ int enable_ats_device(int seg, int bus, 
     pdev->devfn = devfn;
     pdev->ats_queue_depth = queue_depth;
     list_add(&(pdev->list), &ats_devices);
+    if ( iommu_verbose )
+        dprintk(XENLOG_INFO VTDPREFIX, "%x:%x.%x: ATS is enabled\n",
+                bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
 
     return pos;
 }
+
+int disable_ats_device(int seg, int bus, int devfn)
+{
+    struct list_head *pdev_list, *tmp;
+    struct pci_ats_dev *pdev;
+    u32 value;
+    int pos;
+
+    pos = pci_find_ext_capability(seg, bus, devfn, PCI_EXT_CAP_ID_ATS);
+    if ( !pos )
+        return 0;
+
+    /* BUGBUG: add back seg when multi-seg platform support is enabled */
+    value = pci_conf_read16(bus, PCI_SLOT(devfn),
+                            PCI_FUNC(devfn), pos + ATS_REG_CTL);
+    value &= ~ATS_ENABLE;
+    pci_conf_write16(bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+                     pos + ATS_REG_CTL, value);
+
+    list_for_each_safe( pdev_list, tmp, &ats_devices )
+    {
+        pdev = list_entry(pdev_list, struct pci_ats_dev, list);
+        if ( pdev->bus == bus && pdev->devfn == devfn )
+        {
+            list_del(&pdev->list);
+            xfree(pdev);
+            break;
+        }
+    }
+
+    if ( iommu_verbose )
+        dprintk(XENLOG_INFO VTDPREFIX, "%x:%x.%x: ATS is disabled\n",
+                bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+
+    return 0;
+}
+
 
 static int device_in_domain(struct iommu *iommu, struct pci_ats_dev *pdev, u16 
did)
 {

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] VT-d: Fix ATS enabling for device assignment, Xen patchbot-unstable <=