]> xenbits.xensource.com Git - xen.git/commitdiff
vtd: fix iommu vector leak
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 31 Mar 2009 10:41:13 +0000 (11:41 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 31 Mar 2009 10:41:13 +0000 (11:41 +0100)
When we do Dom0 S3 for many times, iommu_set_interrupt() would fail
during S3 resume because it can't obtain vector. We should not request
new vector for every Dom0 S3 resume. We should re-use the same vector.

Signed-off-by: Dexuan Cui <dexuan.cui@intel.com>
xen/drivers/passthrough/vtd/iommu.c
xen/include/xen/iommu.h

index 6e4d4a1afad6be64f4070f0284bbbea8641ee5d0..e2b026ca7e80a30007b75f6d529ddcad18dc1d5b 100644 (file)
@@ -911,6 +911,8 @@ static int iommu_alloc(struct acpi_drhd_unit *drhd)
         return -ENOMEM;
     memset(iommu, 0, sizeof(struct iommu));
 
+    iommu->vector = -1; /* No vector assigned yet. */
+
     iommu->intel = alloc_intel_iommu();
     if ( iommu->intel == NULL )
     {
@@ -1666,15 +1668,18 @@ static int init_vtd_hw(void)
             return -EIO;
         }
 
-        vector = iommu_set_interrupt(iommu);
-        if ( vector < 0 )
+        if ( iommu->vector < 0 )
         {
-            gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: interrupt setup failed\n");
-            return vector;
+            vector = iommu_set_interrupt(iommu);
+            if ( vector < 0 )
+            {
+                gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: interrupt setup failed\n");
+                return vector;
+            }
+            iommu->vector = vector;
         }
-        dma_msi_data_init(iommu, vector);
+        dma_msi_data_init(iommu, iommu->vector);
         dma_msi_addr_init(iommu, cpu_physical_id(first_cpu(cpu_online_map)));
-        iommu->vector = vector;
         clear_fault_bits(iommu);
         dmar_writel(iommu->reg, DMAR_FECTL_REG, 0);
 
index 37fa3c7aa8a552304144fb42f1e65b660d66b580..b47049267dd6535a1aa659d85724eb24f2f47982 100644 (file)
@@ -55,7 +55,7 @@ struct iommu {
     spinlock_t lock; /* protect context, domain ids */
     spinlock_t register_lock; /* protect iommu register handling */
     u64 root_maddr; /* root entry machine address */
-    unsigned int vector;
+    int vector;
     struct intel_iommu *intel;
 };