vtd: Add a command line param to enable/disable pass-through feature
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 10 Sep 2008 09:53:09 +0000 (10:53 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 10 Sep 2008 09:53:09 +0000 (10:53 +0100)
Taking security into accout, it's not suitable to bypass VT-d
translation for Dom0 by default when the pass-through field in
extended capability register is set. This feature is for people/usages
who are not overly worried about security/isolation, but want better
performance.

This patch adds a command line param that controls if it's enabled or
disabled.

Signed-off-by: Weidong Han <weidong.han@intel.com>
xen/drivers/passthrough/iommu.c
xen/drivers/passthrough/vtd/iommu.c
xen/include/xen/iommu.h

index 9cc39919d6148a4442b791ee91498d7041aa1e4e..a1c60ace353b94d17addb9b2a2aacd0d9136b2ee 100644 (file)
@@ -33,11 +33,13 @@ 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
  */
 custom_param("iommu", parse_iommu_param);
 int iommu_enabled = 0;
 int iommu_pv_enabled = 0;
 int force_iommu = 0;
+int iommu_passthrough = 0;
 
 static void __init parse_iommu_param(char *s)
 {
@@ -58,6 +60,8 @@ static void __init parse_iommu_param(char *s)
             iommu_pv_enabled = 0;
         else if ( !strcmp(s, "force") || !strcmp(s, "required") )
             force_iommu = 1;
+        else if ( !strcmp(s, "passthrough") )
+            iommu_passthrough = 1;
 
         s = ss + 1;
     } while ( ss );
index 5af9b4771a437cf20e0d1235f9fcd73040f56901..1a3757a2f4c77910c696e877f9e1964884944c79 100644 (file)
@@ -1090,7 +1090,8 @@ static int domain_context_mapping_one(
     }
 
     spin_lock_irqsave(&iommu->lock, flags);
-    if ( ecap_pass_thru(iommu->ecap) && (domain->domain_id == 0) )
+    if ( iommu_passthrough &&
+         ecap_pass_thru(iommu->ecap) && (domain->domain_id == 0) )
     {
         context_set_translation_type(*context, CONTEXT_TT_PASS_THRU);
         agaw = level_to_agaw(iommu->nr_pt_levels);
@@ -1463,7 +1464,8 @@ int intel_iommu_map_page(
     iommu = drhd->iommu;
 
     /* do nothing if dom0 and iommu supports pass thru */
-    if ( ecap_pass_thru(iommu->ecap) && (d->domain_id == 0) )
+    if ( iommu_passthrough &&
+         ecap_pass_thru(iommu->ecap) && (d->domain_id == 0) )
         return 0;
 
     pg_maddr = addr_to_dma_page_maddr(d, (paddr_t)gfn << PAGE_SHIFT_4K, 1);
@@ -1502,7 +1504,8 @@ int intel_iommu_unmap_page(struct domain *d, unsigned long gfn)
     iommu = drhd->iommu;
 
     /* do nothing if dom0 and iommu supports pass thru */
-    if ( ecap_pass_thru(iommu->ecap) && (d->domain_id == 0) )
+    if ( iommu_passthrough &&
+         ecap_pass_thru(iommu->ecap) && (d->domain_id == 0) )
         return 0;
 
     dma_pte_clear_one(d, (paddr_t)gfn << PAGE_SHIFT_4K);
index 2523fc6b66210d8a949b99e7dcdf5d7a44168a99..e9bd9532aab68e22943fcdcf0bf80ee7b24818bc 100644 (file)
@@ -31,6 +31,7 @@ extern int vtd_enabled;
 extern int iommu_enabled;
 extern int iommu_pv_enabled;
 extern int force_iommu;
+extern int iommu_passthrough;
 
 #define domain_hvm_iommu(d)     (&d->arch.hvm_domain.hvm_iommu)