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-devel

[Xen-devel] [PATCH 5 of 5] amd iommu: enable ats devices

To: <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 5 of 5] amd iommu: enable ats devices
From: Wei Wang <wei.wang2@xxxxxxx>
Date: Thu, 3 Nov 2011 11:13:05 +0100
Cc: JBeulich@xxxxxxxxxx
Delivery-date: Thu, 03 Nov 2011 03:18:53 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1320315180@xxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <patchbomb.1320315180@xxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.9.3
# HG changeset patch
# User Wei Wang <wei.wang2@xxxxxxx>
# Date 1320314731 -3600
# Node ID 7316595e8f47fcf5a106d897f99105a14d7e646c
# Parent  c9dcbe6d80a355f1e50ff910d618660a78b40653
amd iommu: enable ats devices

Signed-off-by: Wei Wang <wei.wang2@xxxxxxx>

diff -r c9dcbe6d80a3 -r 7316595e8f47 xen/drivers/passthrough/amd/iommu_map.c
--- a/xen/drivers/passthrough/amd/iommu_map.c   Thu Nov 03 11:04:54 2011 +0100
+++ b/xen/drivers/passthrough/amd/iommu_map.c   Thu Nov 03 11:05:31 2011 +0100
@@ -370,6 +370,17 @@ void amd_iommu_set_root_page_table(
     dte[0] = entry;
 }
 
+void iommu_dte_set_iotlb(u32 *dte, u8 i)
+{
+    u32 entry;
+
+    entry = dte[3];
+    set_field_in_reg_u32(!!i, entry,
+                         IOMMU_DEV_TABLE_IOTLB_SUPPORT_MASK,
+                         IOMMU_DEV_TABLE_IOTLB_SUPPORT_SHIFT, &entry);
+    dte[3] = entry;
+}
+
 void __init amd_iommu_set_intremap_table(
     u32 *dte, u64 intremap_ptr, u8 int_valid)
 {
diff -r c9dcbe6d80a3 -r 7316595e8f47 xen/drivers/passthrough/amd/pci_amd_iommu.c
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c       Thu Nov 03 11:04:54 
2011 +0100
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c       Thu Nov 03 11:05:31 
2011 +0100
@@ -25,6 +25,7 @@
 #include <asm/hvm/iommu.h>
 #include <asm/amd-iommu.h>
 #include <asm/hvm/svm/amd-iommu-proto.h>
+#include "../ats.h"
 
 struct amd_iommu *find_iommu_for_device(int seg, int bdf)
 {
@@ -86,6 +87,9 @@ static void amd_iommu_setup_domain_devic
     void *dte;
     unsigned long flags;
     int req_id, valid = 1;
+    int dte_i = 0;
+    u8 bus = PCI_BUS(bdf);
+    u8 devfn = PCI_DEVFN2(bdf);
 
     struct hvm_iommu *hd = domain_hvm_iommu(domain);
 
@@ -94,6 +98,9 @@ static void amd_iommu_setup_domain_devic
     if ( iommu_passthrough && (domain->domain_id == 0) )
         valid = 0;
 
+    if ( ats_enabled )
+        dte_i = 1;
+
     /* get device-table entry */
     req_id = get_dma_requestor_id(iommu->seg, bdf);
     dte = iommu->dev_table.buffer + (req_id * IOMMU_DEV_TABLE_ENTRY_SIZE);
@@ -107,6 +114,10 @@ static void amd_iommu_setup_domain_devic
             (u32 *)dte, page_to_maddr(hd->root_table), hd->domain_id,
             hd->paging_mode, valid);
 
+        if ( pci_ats_device(iommu->seg, bus, devfn) &&
+             iommu->iotlb_support )
+            iommu_dte_set_iotlb((u32 *)dte, dte_i);
+
         invalidate_dev_table_entry(iommu, req_id);
         flush_command_buffer(iommu);
 
@@ -118,11 +129,27 @@ static void amd_iommu_setup_domain_devic
     }
 
     spin_unlock_irqrestore(&iommu->lock, flags);
+
+    ASSERT(spin_is_locked(&pcidevs_lock));
+
+    if ( pci_ats_device(iommu->seg, bus, devfn) &&
+         !pci_ats_enabled(iommu->seg, bus, devfn) )
+    {
+        struct pci_dev *pdev;
+
+        enable_ats_device(iommu->seg, bus, devfn);
+
+        ASSERT(spin_is_locked(&pcidevs_lock));
+        pdev = pci_get_pdev(iommu->seg, bus, devfn);
+
+        ASSERT( pdev != NULL );
+        amd_iommu_flush_iotlb(pdev, INV_IOMMU_ALL_PAGES_ADDRESS, 0);
+    }
 }
 
 static void __init amd_iommu_setup_dom0_device(struct pci_dev *pdev)
 {
-    int bdf = (pdev->bus << 8) | pdev->devfn;
+    int bdf = PCI_BDF2(pdev->bus, pdev->devfn);
     struct amd_iommu *iommu = find_iommu_for_device(pdev->seg, bdf);
 
     if ( likely(iommu != NULL) )
@@ -261,12 +288,14 @@ static void __init amd_iommu_dom0_init(s
     setup_dom0_pci_devices(d, amd_iommu_setup_dom0_device);
 }
 
-static void amd_iommu_disable_domain_device(
-    struct domain *domain, struct amd_iommu *iommu, int bdf)
+void amd_iommu_disable_domain_device(struct domain *domain, 
+                                     struct amd_iommu *iommu, int bdf)
 {
     void *dte;
     unsigned long flags;
     int req_id;
+    u8 bus = PCI_BUS(bdf);
+    u8 devfn = PCI_DEVFN2(bdf);
 
     BUG_ON ( iommu->dev_table.buffer == NULL );
     req_id = get_dma_requestor_id(iommu->seg, bdf);
@@ -276,6 +305,11 @@ static void amd_iommu_disable_domain_dev
     if ( is_translation_valid((u32 *)dte) )
     {
         disable_translation((u32 *)dte);
+
+        if ( pci_ats_device(iommu->seg, bus, devfn) &&
+             iommu->iotlb_support )
+            iommu_dte_set_iotlb((u32 *)dte, 0);
+
         invalidate_dev_table_entry(iommu, req_id);
         flush_command_buffer(iommu);
         AMD_IOMMU_DEBUG("Disable: device id = 0x%04x, "
@@ -284,6 +318,12 @@ static void amd_iommu_disable_domain_dev
                         domain_hvm_iommu(domain)->paging_mode);
     }
     spin_unlock_irqrestore(&iommu->lock, flags);
+
+    ASSERT(spin_is_locked(&pcidevs_lock));
+
+    if ( pci_ats_device(iommu->seg, bus, devfn) && 
+         pci_ats_enabled(iommu->seg, bus, devfn) )
+       disable_ats_device(iommu->seg, bus, devfn); 
 }
 
 static int reassign_device( struct domain *source, struct domain *target,
@@ -299,7 +339,7 @@ static int reassign_device( struct domai
     if ( !pdev )
         return -ENODEV;
 
-    bdf = (bus << 8) | devfn;
+    bdf = PCI_BDF2(bus, devfn);
     iommu = find_iommu_for_device(seg, bdf);
     if ( !iommu )
     {
@@ -421,7 +461,7 @@ static int amd_iommu_add_device(struct p
     if ( !pdev->domain )
         return -EINVAL;
 
-    bdf = (pdev->bus << 8) | pdev->devfn;
+    bdf = PCI_BDF2(pdev->bus, pdev->devfn);
     iommu = find_iommu_for_device(pdev->seg, bdf);
     if ( !iommu )
     {
@@ -443,7 +483,7 @@ static int amd_iommu_remove_device(struc
     if ( !pdev->domain )
         return -EINVAL;
 
-    bdf = (pdev->bus << 8) | pdev->devfn;
+    bdf = PCI_BDF2(pdev->bus, pdev->devfn);
     iommu = find_iommu_for_device(pdev->seg, bdf);
     if ( !iommu )
     {
diff -r c9dcbe6d80a3 -r 7316595e8f47 
xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h     Thu Nov 03 11:04:54 
2011 +0100
+++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h     Thu Nov 03 11:05:31 
2011 +0100
@@ -75,6 +75,7 @@ void amd_iommu_set_intremap_table(
     u32 *dte, u64 intremap_ptr, u8 int_valid);
 void amd_iommu_set_root_page_table(
     u32 *dte, u64 root_ptr, u16 domain_id, u8 paging_mode, u8 valid);
+void iommu_dte_set_iotlb(u32 *dte, u8 i);
 void invalidate_dev_table_entry(struct amd_iommu *iommu, u16 devic_id);
 
 /* send cmd to iommu */


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