vtd: Add 'force_iommu' option
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 6 Aug 2008 08:37:53 +0000 (09:37 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 6 Aug 2008 08:37:53 +0000 (09:37 +0100)
For security reasons, add 'force_iommu' option to ensure that it
should not be possible under any conditions to boot Xen w/o VT-d being
enabled. This would only be specified by users that really want the
added security.

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

index 0a3fc48da9dae3cf280833f5ae3c5320452e51a3..a522b80221282d3c4249950340477a9060bf49bf 100644 (file)
@@ -30,6 +30,9 @@ boolean_param("iommu", iommu_enabled);
 int iommu_pv_enabled = 0;
 boolean_param("iommu_pv", iommu_pv_enabled);
 
+int force_iommu = 0;
+boolean_param("force_iommu", force_iommu);
+
 int iommu_domain_init(struct domain *domain)
 {
     struct hvm_iommu *hd = domain_hvm_iommu(domain);
@@ -215,6 +218,9 @@ static int iommu_setup(void)
     iommu_enabled = (rc == 0);
 
  out:
+    if ( force_iommu && !iommu_enabled )
+        panic("IOMMU setup failed, crash Xen for security purpose!\n");
+
     if ( !iommu_enabled )
         iommu_pv_enabled = 0;
     printk("I/O virtualisation %sabled\n", iommu_enabled ? "en" : "dis");
index 5be3246e71e2a712dd4d8acff75c639b73d4c776..43107b3ae345a8af6a0554facf6d24d43de814d3 100644 (file)
@@ -427,6 +427,9 @@ static int __init acpi_parse_dmar(struct acpi_table_header *table)
     if ( !dmar->width )
     {
         dprintk(XENLOG_WARNING VTDPREFIX, "Zero: Invalid DMAR width\n");
+        if ( force_iommu )
+            panic("acpi_parse_dmar: Invalid DMAR width,"
+                  " crash Xen for security purpose!\n");
         return -EINVAL;
     }
 
@@ -468,8 +471,15 @@ static int __init acpi_parse_dmar(struct acpi_table_header *table)
 
     if ( ret )
     {
-        printk(XENLOG_WARNING "Failed to parse ACPI DMAR.  Disabling VT-d.\n");
-        disable_all_dmar_units();
+        if ( force_iommu )
+            panic("acpi_parse_dmar: Failed to parse ACPI DMAR,"
+                  " crash Xen for security purpose!\n");
+        else
+        {
+            printk(XENLOG_WARNING
+                   "Failed to parse ACPI DMAR.  Disabling VT-d.\n");
+            disable_all_dmar_units();
+        }
     }
 
     return ret;
@@ -480,10 +490,15 @@ int acpi_dmar_init(void)
     int rc;
 
     rc = -ENODEV;
+    if ( force_iommu )
+        iommu_enabled = 1;
+
     if ( !iommu_enabled )
         goto fail;
 
-    acpi_table_parse(ACPI_SIG_DMAR, acpi_parse_dmar);
+    rc = acpi_table_parse(ACPI_SIG_DMAR, acpi_parse_dmar);
+    if ( rc )
+        goto fail;
 
     rc = -ENODEV;
     if ( list_empty(&acpi_drhd_units) )
@@ -494,6 +509,10 @@ int acpi_dmar_init(void)
     return 0;
 
  fail:
+    if ( force_iommu )
+        panic("acpi_dmar_init: acpi_dmar_init failed,"
+              " crash Xen for security purpose!\n");
+
     vtd_enabled = 0;
     return -ENODEV;
 }
index 20ba06062c97ca8619a2b32042c9ace1d7b2e52e..71204d56dee956e78ea32ffcf6bbf58b5f6f34dd 100644 (file)
@@ -30,6 +30,7 @@
 extern int vtd_enabled;
 extern int iommu_enabled;
 extern int iommu_pv_enabled;
+extern int force_iommu;
 
 #define domain_hvm_iommu(d)     (&d->arch.hvm_domain.hvm_iommu)
 #define domain_vmx_iommu(d)     (&d->arch.hvm_domain.hvm_iommu.vmx_iommu)