]> xenbits.xensource.com Git - xen.git/commitdiff
iommu: Consolidate iommu enablement logic. Now there is only one
authorKeir Fraser <keir.fraser@citrix.com>
Mon, 21 Apr 2008 09:33:40 +0000 (10:33 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Mon, 21 Apr 2008 09:33:40 +0000 (10:33 +0100)
command-line parameter for disabling IOV/VTD: "iommu"/"no-iommu".

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/hvm/svm/intr.c
xen/arch/x86/hvm/vmx/intr.c
xen/drivers/passthrough/amd/pci_amd_iommu.c
xen/drivers/passthrough/iommu.c
xen/drivers/passthrough/vtd/dmar.c
xen/drivers/passthrough/vtd/iommu.c
xen/drivers/passthrough/vtd/utils.c
xen/include/asm-x86/amd-iommu.h
xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
xen/include/xen/iommu.h

index 17a9c3bc7b13b99abe561631c69e78ca0bc076d1..4b3dcd33add3593872c759ec0b8d7f0dcd38613c 100644 (file)
@@ -102,7 +102,7 @@ static void svm_dirq_assist(struct vcpu *v)
     struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
     struct dev_intx_gsi_link *digl;
 
-    if ( !amd_iommu_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
+    if ( !iommu_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
         return;
 
     for ( irq = find_first_bit(hvm_irq_dpci->dirq_mask, NR_IRQS);
index a212310d75b6478e391fedb92de5baee30a19108..dc47430a63ae54bc37cd1e325fdc9f2d12a00056 100644 (file)
@@ -111,7 +111,7 @@ static void vmx_dirq_assist(struct vcpu *v)
     struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
     struct dev_intx_gsi_link *digl;
 
-    if ( !vtd_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
+    if ( !iommu_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
         return;
 
     for ( irq = find_first_bit(hvm_irq_dpci->dirq_mask, NR_IRQS);
index 08d46e37e7f1e84a096fd6f4957a6228da4cae55..ab2b86e20d056fab5580320b68cc47af48977822 100644 (file)
@@ -30,16 +30,10 @@ struct list_head amd_iommu_head;
 long amd_iommu_poll_comp_wait = COMPLETION_WAIT_DEFAULT_POLLING_COUNT;
 static long amd_iommu_cmd_buffer_entries = IOMMU_CMD_BUFFER_DEFAULT_ENTRIES;
 static long amd_iommu_event_log_entries = IOMMU_EVENT_LOG_DEFAULT_ENTRIES;
-int nr_amd_iommus = 0;
+int nr_amd_iommus;
 
-unsigned short ivrs_bdf_entries = 0;
-struct ivrs_mappings *ivrs_mappings = NULL;
-
-/* will set if amd-iommu HW is found */
-int amd_iommu_enabled = 0;
-
-static int enable_amd_iommu = 0;
-boolean_param("enable_amd_iov", enable_amd_iommu);
+unsigned short ivrs_bdf_entries;
+struct ivrs_mappings *ivrs_mappings;
 
 static void deallocate_domain_page_tables(struct hvm_iommu *hd)
 {
@@ -78,24 +72,6 @@ static void __init deallocate_iommu_resources(struct amd_iommu *iommu)
     deallocate_iommu_table_struct(&iommu->event_log);
 }
 
-static void __init detect_cleanup(void)
-{
-    struct amd_iommu *iommu, *next;
-
-    list_for_each_entry_safe ( iommu, next, &amd_iommu_head, list )
-    {
-        list_del(&iommu->list);
-        deallocate_iommu_resources(iommu);
-        xfree(iommu);
-    }
-
-    if ( ivrs_mappings )
-    {
-        xfree(ivrs_mappings);
-        ivrs_mappings = NULL;
-    }
-}
-
 static int __init allocate_iommu_table_struct(struct table_struct *table,
                                               const char *name)
 {
@@ -246,8 +222,6 @@ static int __init amd_iommu_init(void)
         nr_amd_iommus++;
     }
 
-    amd_iommu_enabled = 1;
-
     return 0;
 
  error_out:
@@ -277,7 +251,7 @@ struct amd_iommu *find_iommu_for_device(int bus, int devfn)
     return NULL;
 }
 
-void amd_iommu_setup_domain_device(
+static void amd_iommu_setup_domain_device(
     struct domain *domain, struct amd_iommu *iommu, int bdf)
 {
     void *dte;
@@ -316,7 +290,7 @@ void amd_iommu_setup_domain_device(
     }
 }
 
-void __init amd_iommu_setup_dom0_devices(void)
+static void __init amd_iommu_setup_dom0_devices(void)
 {
     struct hvm_iommu *hd = domain_hvm_iommu(dom0);
     struct amd_iommu *iommu;
@@ -358,13 +332,7 @@ int amd_iov_detect(void)
 {
     unsigned long i;
     int last_bus;
-    struct amd_iommu *iommu;
-
-    if ( !enable_amd_iommu )
-    {
-        printk("AMD_IOV: Disabled.\n");
-        return 0;
-    }
+    struct amd_iommu *iommu, *next;
 
     INIT_LIST_HEAD(&amd_iommu_head);
 
@@ -377,29 +345,26 @@ int amd_iov_detect(void)
     if ( !iommu_found() )
     {
         printk("AMD_IOV: IOMMU not found!\n");
-        return 0;
+        goto error_out;
     }
-    else
+
+    /* allocate 'ivrs mappings' table */
+    /* note: the table has entries to accomodate all IOMMUs */
+    last_bus = 0;
+    for_each_amd_iommu ( iommu )
+        if ( iommu->last_downstream_bus > last_bus )
+            last_bus = iommu->last_downstream_bus;
+
+    ivrs_bdf_entries = (last_bus + 1) *
+        IOMMU_DEV_TABLE_ENTRIES_PER_BUS;
+    ivrs_mappings = xmalloc_array( struct ivrs_mappings, ivrs_bdf_entries);
+    if ( ivrs_mappings == NULL )
     {
-        /* allocate 'ivrs mappings' table */
-        /* note: the table has entries to accomodate all IOMMUs */
-        last_bus = 0;
-        for_each_amd_iommu ( iommu )
-            if ( iommu->last_downstream_bus > last_bus )
-                last_bus = iommu->last_downstream_bus;
-
-        ivrs_bdf_entries = (last_bus + 1) *
-            IOMMU_DEV_TABLE_ENTRIES_PER_BUS;
-        ivrs_mappings = xmalloc_array( struct ivrs_mappings, ivrs_bdf_entries);
-
-        if ( !ivrs_mappings )
-        {
-            amd_iov_error("Error allocating IVRS DevMappings table\n");
-            goto error_out;
-        }
-        memset(ivrs_mappings, 0,
-               ivrs_bdf_entries * sizeof(struct ivrs_mappings));
+        amd_iov_error("Error allocating IVRS DevMappings table\n");
+        goto error_out;
     }
+    memset(ivrs_mappings, 0,
+           ivrs_bdf_entries * sizeof(struct ivrs_mappings));
 
     if ( amd_iommu_init() != 0 )
     {
@@ -418,9 +383,20 @@ int amd_iov_detect(void)
     return 0;
 
  error_out:
-    detect_cleanup();
-    return -ENODEV;
+    list_for_each_entry_safe ( iommu, next, &amd_iommu_head, list )
+    {
+        list_del(&iommu->list);
+        deallocate_iommu_resources(iommu);
+        xfree(iommu);
+    }
+
+    if ( ivrs_mappings )
+    {
+        xfree(ivrs_mappings);
+        ivrs_mappings = NULL;
+    }
 
+    return -ENODEV;
 }
 
 static int allocate_domain_resources(struct hvm_iommu *hd)
@@ -464,7 +440,7 @@ static int get_paging_mode(unsigned long entries)
     return level;
 }
 
-int amd_iommu_domain_init(struct domain *domain)
+static int amd_iommu_domain_init(struct domain *domain)
 {
     struct hvm_iommu *hd = domain_hvm_iommu(domain);
 
@@ -561,7 +537,7 @@ static int reassign_device( struct domain *source, struct domain *target,
     return 0;
 }
 
-int amd_iommu_assign_device(struct domain *d, u8 bus, u8 devfn)
+static int amd_iommu_assign_device(struct domain *d, u8 bus, u8 devfn)
 {
     int bdf = (bus << 8) | devfn;
     int req_id = ivrs_mappings[bdf].dte_requestor_id;
@@ -647,16 +623,13 @@ static void deallocate_iommu_page_tables(struct domain *d)
     hd ->root_table = NULL;
 }
 
-void amd_iommu_domain_destroy(struct domain *d)
+static void amd_iommu_domain_destroy(struct domain *d)
 {
-    if ( !amd_iommu_enabled )
-        return;
-
     deallocate_iommu_page_tables(d);
     release_domain_devices(d);
 }
 
-void amd_iommu_return_device(
+static void amd_iommu_return_device(
     struct domain *s, struct domain *t, u8 bus, u8 devfn)
 {
     pdev_flr(bus, devfn);
index 51a6e20b4456dc35d9fc3dfa667181c312b8a5a6..9fbd41a584542efe4e6277818f79801d3490200d 100644 (file)
@@ -21,6 +21,9 @@ extern struct iommu_ops amd_iommu_ops;
 int intel_vtd_setup(void);
 int amd_iov_detect(void);
 
+int iommu_enabled = 1;
+boolean_param("iommu", iommu_enabled);
+
 int iommu_domain_init(struct domain *domain)
 {
     struct hvm_iommu *hd = domain_hvm_iommu(domain);
@@ -139,13 +142,24 @@ void deassign_device(struct domain *d, u8 bus, u8 devfn)
 
 int iommu_setup(void)
 {
+    int rc = -ENODEV;
+
+    if ( !iommu_enabled )
+        goto out;
+
     switch ( boot_cpu_data.x86_vendor )
     {
     case X86_VENDOR_INTEL:
-        return intel_vtd_setup();
+        rc = intel_vtd_setup();
+        break;
     case X86_VENDOR_AMD:
-        return amd_iov_detect();
+        rc = amd_iov_detect();
+        break;
     }
 
-    return 0;
+    iommu_enabled = (rc == 0);
+
+ out:
+    printk("I/O virtualisation %sabled\n", iommu_enabled ? "en" : "dis");
+    return rc;
 }
index 9498914044ec7d4c6b90820fa94d630ea4316056..6ba260b37e3453c01d5f54b803650d9bc96fae44 100644 (file)
@@ -30,8 +30,7 @@
 #include "dmar.h"
 #include "../pci_regs.h"
 
-int vtd_enabled;
-boolean_param("vtd", vtd_enabled);
+int vtd_enabled = 1;
 
 #undef PREFIX
 #define PREFIX VTDPREFIX "ACPI DMAR:"
@@ -604,22 +603,24 @@ int acpi_dmar_init(void)
 {
     int rc;
 
-    if ( !vtd_enabled )
-        return -ENODEV;
+    rc = -ENODEV;
+    if ( !iommu_enabled )
+        goto fail;
 
     if ( (rc = vtd_hw_check()) != 0 )
-        return rc;
+        goto fail;
 
     acpi_table_parse(ACPI_DMAR, acpi_parse_dmar);
 
+    rc = -ENODEV;
     if ( list_empty(&acpi_drhd_units) )
-    {
-        dprintk(XENLOG_ERR VTDPREFIX, "No DMAR devices found\n");
-        vtd_enabled = 0;
-        return -ENODEV;
-    }
+        goto fail;
 
     printk("Intel VT-d has been enabled\n");
 
     return 0;
+
+ fail:
+    vtd_enabled = 0;
+    return -ENODEV;
 }
index d7498e4d351687581ea546bac267e7405a9044a7..9396959dc1b969ba5bf31fb637652793aec8c9b1 100644 (file)
@@ -1111,7 +1111,7 @@ static void free_iommu(struct iommu *iommu)
         agaw = 64;                              \
     agaw; })
 
-int intel_iommu_domain_init(struct domain *domain)
+static int intel_iommu_domain_init(struct domain *domain)
 {
     struct hvm_iommu *hd = domain_hvm_iommu(domain);
     struct iommu *iommu = NULL;
@@ -1120,9 +1120,6 @@ int intel_iommu_domain_init(struct domain *domain)
     unsigned long sagaw;
     struct acpi_drhd_unit *drhd;
 
-    if ( !vtd_enabled || list_empty(&acpi_drhd_units) )
-        return 0;
-
     for_each_drhd_unit ( drhd )
         iommu = drhd->iommu ? : iommu_alloc(drhd);
 
@@ -1911,7 +1908,7 @@ int intel_vtd_setup(void)
     unsigned long i;
 
     if ( !vtd_enabled )
-        return 0;
+        return -ENODEV;
 
     spin_lock_init(&domid_bitmap_lock);
     INIT_LIST_HEAD(&hd->pdev_list);
@@ -1946,13 +1943,13 @@ int intel_vtd_setup(void)
     return 0;
 
  error:
-    printk("iommu_setup() failed\n");
     for_each_drhd_unit ( drhd )
     {
         iommu = drhd->iommu;
         free_iommu(iommu);
     }
-    return -EIO;
+    vtd_enabled = 0;
+    return -ENOMEM;
 }
 
 /*
index 3c33a2c300f78bd822bb5e6291d4d89fa40d6c64..47c6b7b83cdf9bd9d1f42826a1f116b786d0d0f9 100644 (file)
@@ -60,10 +60,10 @@ int vtd_hw_check(void)
             dprintk(XENLOG_WARNING VTDPREFIX,
                     "***  vendor = %x device = %x revision = %x\n",
                     vendor, device, revision);
-            vtd_enabled = 0;
             return -ENODEV;
         }
     }
+
     return 0;
 }
 
index f896088f8de712f1be44c31dac624af446b30d13..8acfb55189aac39bbcc5f035e01d6a8497675591 100644 (file)
@@ -28,7 +28,6 @@
 
 #define iommu_found()           (!list_empty(&amd_iommu_head))
 
-extern int amd_iommu_enabled;
 extern struct list_head amd_iommu_head;
 
 extern int __init amd_iov_detect(void);
index 646ab7047e50c1d628ca0ab26667b15810f0093e..0886776cea7a171b2321d8b22d0f1d4f33330d6f 100644 (file)
@@ -84,11 +84,6 @@ void invalidate_dev_table_entry(struct amd_iommu *iommu,
 int send_iommu_command(struct amd_iommu *iommu, u32 cmd[]);
 void flush_command_buffer(struct amd_iommu *iommu);
 
-/* iommu domain funtions */
-int amd_iommu_domain_init(struct domain *domain);
-void amd_iommu_setup_domain_device(struct domain *domain,
-    struct amd_iommu *iommu, int bdf);
-
 /* find iommu for bdf */
 struct amd_iommu *find_iommu_for_device(int bus, int devfn);
 
index bde167694e28cdec470160e7a423d1742523efaf..7ad55190fa803ba4d8ec36758146de1ec15520ad 100644 (file)
@@ -27,9 +27,8 @@
 #include <public/domctl.h>
 
 extern int vtd_enabled;
-extern int amd_iommu_enabled;
+extern int iommu_enabled;
 
-#define iommu_enabled ( amd_iommu_enabled || vtd_enabled )
 #define domain_hvm_iommu(d)     (&d->arch.hvm_domain.hvm_iommu)
 #define domain_vmx_iommu(d)     (&d->arch.hvm_domain.hvm_iommu.vmx_iommu)