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] vtd: Only enable some VT-d features if al

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] vtd: Only enable some VT-d features if all VT-d engines support them.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 18 Mar 2009 07:25:15 -0700
Delivery-date: Wed, 18 Mar 2009 07:26:12 -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 1237376792 0
# Node ID 6d65dc14d21b5b598de925d1b1e0aa8305092273
# Parent  33270c9a3d2f56006a166b42ae0d717bc6b1644f
vtd: Only enable some VT-d features if all VT-d engines support them.

By default, we enable snoop control, queued invalidation and interrupt
remapping if all VT-d engines support them, and for DMA passthrough we
don't enable it by default.

A user can use 'iommu=passthrough' to enable DMA passthrough (only
for Dom0). A user can use 'iommu=no-snoop,no-qinval,no-intremap' to
disable the 3 features.

Signed-off-by: Dexuan Cui <dexuan.cui@xxxxxxxxx>=
---
 xen/drivers/passthrough/iommu.c     |   18 ++++--
 xen/drivers/passthrough/vtd/dmar.c  |    2 
 xen/drivers/passthrough/vtd/iommu.c |   95 +++++++++++++++++++++---------------
 xen/include/xen/iommu.h             |    2 
 4 files changed, 74 insertions(+), 43 deletions(-)

diff -r 33270c9a3d2f -r 6d65dc14d21b xen/drivers/passthrough/iommu.c
--- a/xen/drivers/passthrough/iommu.c   Wed Mar 18 11:37:59 2009 +0000
+++ b/xen/drivers/passthrough/iommu.c   Wed Mar 18 11:46:32 2009 +0000
@@ -32,9 +32,11 @@ int amd_iov_detect(void);
  *   pv                         Enable IOMMU for PV domains
  *   no-pv                      Disable IOMMU for PV domains (default)
  *   force|required             Don't boot unless IOMMU is enabled
- *   passthrough                Bypass VT-d translation for Dom0
- *   snoop                      Utilize the snoop control for IOMMU (default)
- *   no-snoop                   Dont utilize the snoop control for IOMMU
+ *   passthrough                Enable VT-d DMA passthrough (no DMA
+ *                              translation for Dom0)
+ *   no-snoop                   Disable VT-d Snoop Control
+ *   no-qinval                  Disable VT-d Queued Invalidation
+ *   no-intremap                Disable VT-d Interrupt Remapping
  */
 custom_param("iommu", parse_iommu_param);
 int iommu_enabled = 0;
@@ -42,12 +44,16 @@ int force_iommu = 0;
 int force_iommu = 0;
 int iommu_passthrough = 0;
 int iommu_snoop = 0;
+int iommu_qinval = 0;
+int iommu_intremap = 0;
 
 static void __init parse_iommu_param(char *s)
 {
     char *ss;
     iommu_enabled = 1;
     iommu_snoop = 1;
+    iommu_qinval = 1;
+    iommu_intremap = 1;
 
     do {
         ss = strchr(s, ',');
@@ -65,10 +71,12 @@ static void __init parse_iommu_param(cha
             force_iommu = 1;
         else if ( !strcmp(s, "passthrough") )
             iommu_passthrough = 1;
-        else if ( !strcmp(s, "snoop") )
-            iommu_snoop = 1;
         else if ( !strcmp(s, "no-snoop") )
             iommu_snoop = 0;
+        else if ( !strcmp(s, "no-qinval") )
+            iommu_qinval = 0;
+        else if ( !strcmp(s, "no-intremap") )
+            iommu_intremap = 0;
 
         s = ss + 1;
     } while ( ss );
diff -r 33270c9a3d2f -r 6d65dc14d21b xen/drivers/passthrough/vtd/dmar.c
--- a/xen/drivers/passthrough/vtd/dmar.c        Wed Mar 18 11:37:59 2009 +0000
+++ b/xen/drivers/passthrough/vtd/dmar.c        Wed Mar 18 11:46:32 2009 +0000
@@ -548,7 +548,7 @@ int acpi_dmar_init(void)
     if ( list_empty(&acpi_drhd_units) )
         goto fail;
 
-    printk("Intel VT-d has been enabled\n");
+    printk("Intel VT-d DMAR tables have been parsed.\n");
 
     return 0;
 
diff -r 33270c9a3d2f -r 6d65dc14d21b xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c       Wed Mar 18 11:37:59 2009 +0000
+++ b/xen/drivers/passthrough/vtd/iommu.c       Wed Mar 18 11:46:32 2009 +0000
@@ -1041,8 +1041,7 @@ static int domain_context_mapping_one(
         return res;
     }
 
-    if ( iommu_passthrough &&
-         ecap_pass_thru(iommu->ecap) && (domain->domain_id == 0) )
+    if ( iommu_passthrough && (domain->domain_id == 0) )
     {
         context_set_translation_type(*context, CONTEXT_TT_PASS_THRU);
         agaw = level_to_agaw(iommu->nr_pt_levels);
@@ -1449,8 +1448,7 @@ int intel_iommu_map_page(
     iommu = drhd->iommu;
 
     /* do nothing if dom0 and iommu supports pass thru */
-    if ( iommu_passthrough &&
-         ecap_pass_thru(iommu->ecap) && (d->domain_id == 0) )
+    if ( iommu_passthrough && (d->domain_id == 0) )
         return 0;
 
     spin_lock(&hd->mapping_lock);
@@ -1504,8 +1502,7 @@ int intel_iommu_unmap_page(struct domain
     iommu = drhd->iommu;
 
     /* do nothing if dom0 and iommu supports pass thru */
-    if ( iommu_passthrough &&
-         ecap_pass_thru(iommu->ecap) && (d->domain_id == 0) )
+    if ( iommu_passthrough && (d->domain_id == 0) )
         return 0;
 
     dma_pte_clear_one(d, (paddr_t)gfn << PAGE_SHIFT_4K);
@@ -1682,20 +1679,32 @@ static int init_vtd_hw(void)
         flush->iotlb = flush_iotlb_reg;
     }
 
-    for_each_drhd_unit ( drhd )
-    {
-        iommu = drhd->iommu;
-        if ( qinval_setup(iommu) != 0 )
-            dprintk(XENLOG_INFO VTDPREFIX,
-                    "Queued Invalidation hardware not found\n");
-    }
-
-    for_each_drhd_unit ( drhd )
-    {
-        iommu = drhd->iommu;
-        if ( intremap_setup(iommu) != 0 )
-            dprintk(XENLOG_INFO VTDPREFIX,
-                    "Interrupt Remapping hardware not found\n");
+    if ( iommu_qinval )
+    {
+        for_each_drhd_unit ( drhd )
+        {
+            iommu = drhd->iommu;
+            if ( qinval_setup(iommu) != 0 )
+            {
+                dprintk(XENLOG_INFO VTDPREFIX,
+                        "Failed to enable Queued Invalidation!\n");
+                break;
+            }
+        }
+    }
+
+    if ( iommu_intremap )
+    {
+        for_each_drhd_unit ( drhd )
+        {
+            iommu = drhd->iommu;
+            if ( intremap_setup(iommu) != 0 )
+            {
+                dprintk(XENLOG_INFO VTDPREFIX,
+                        "Failed to enable Interrupt Remapping!\n");
+                break;
+            }
+        }
     }
 
     return 0;
@@ -1744,9 +1753,35 @@ int intel_vtd_setup(void)
     spin_lock_init(&domid_bitmap_lock);
     clflush_size = get_cache_line_size();
 
+    /* We enable the following features only if they are supported by all VT-d
+     * engines: Snoop Control, DMA passthrough, Queued Invalidation and
+     * Interrupt Remapping.
+     */
     for_each_drhd_unit ( drhd )
+    {
         if ( iommu_alloc(drhd) != 0 )
             goto error;
+
+        iommu = drhd->iommu;
+
+        if ( iommu_snoop && !ecap_snp_ctl(iommu->ecap) )
+            iommu_snoop = 0;
+
+        if ( iommu_passthrough && !ecap_pass_thru(iommu->ecap) )
+            iommu_passthrough = 0;
+
+        if ( iommu_qinval && !ecap_queued_inval(iommu->ecap) )
+            iommu_qinval = 0;
+
+        if ( iommu_intremap && !ecap_intr_remap(iommu->ecap) )
+            iommu_intremap = 0;
+    }
+#define P(p,s) printk("Intel VT-d %s %ssupported.\n", s, (p)? "" : "not ")
+    P(iommu_snoop, "Snoop Control");
+    P(iommu_passthrough, "DMA Passthrough");
+    P(iommu_qinval, "Queued Invalidation");
+    P(iommu_intremap, "Interrupt Remapping");
+#undef P
 
     /* Allocate IO page directory page for the domain. */
     drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
@@ -1764,23 +1799,6 @@ int intel_vtd_setup(void)
     if ( init_vtd_hw() )
         goto error;
 
-    /* Giving that all devices within guest use same io page table,
-     * enable snoop control only if all VT-d engines support it.
-     */
-
-    if ( iommu_snoop )
-    {
-        for_each_drhd_unit ( drhd )
-        {
-            iommu = drhd->iommu;
-            if ( !ecap_snp_ctl(iommu->ecap) ) {
-                iommu_snoop = 0;
-                break;
-            }
-        }
-    }
-    
-    printk("Intel VT-d snoop control %sabled\n", iommu_snoop ? "en" : "dis");
     register_keyhandler('V', dump_iommu_info, "dump iommu info");
 
     return 0;
@@ -1790,6 +1808,9 @@ int intel_vtd_setup(void)
         iommu_free(drhd);
     vtd_enabled = 0;
     iommu_snoop = 0;
+    iommu_passthrough = 0;
+    iommu_qinval = 0;
+    iommu_intremap = 0;
     return -ENOMEM;
 }
 
diff -r 33270c9a3d2f -r 6d65dc14d21b xen/include/xen/iommu.h
--- a/xen/include/xen/iommu.h   Wed Mar 18 11:37:59 2009 +0000
+++ b/xen/include/xen/iommu.h   Wed Mar 18 11:46:32 2009 +0000
@@ -32,6 +32,8 @@ extern int force_iommu;
 extern int force_iommu;
 extern int iommu_passthrough;
 extern int iommu_snoop;
+extern int iommu_qinval;
+extern int iommu_intremap;
 
 #define domain_hvm_iommu(d)     (&d->arch.hvm_domain.hvm_iommu)
 

_______________________________________________
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] vtd: Only enable some VT-d features if all VT-d engines support them., Xen patchbot-unstable <=