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-devel

[Xen-devel] [PATCH 2/5] Cleanup IOMMU interrupt setup

Cleanup IOMMU interrupt setup
- Check for errors when allocating interrupt vectors
- Clean up if interrupt allocation failed
- Make sure that the allocated vector is not reused

Signed-off-by: Espen Skoglund <espen.skoglund@xxxxxxxxxxxxx>

diff -r 39a154721acb xen/drivers/passthrough/amd/iommu_init.c
--- a/xen/drivers/passthrough/amd/iommu_init.c  Thu Feb 05 14:29:02 2009 +0000
+++ b/xen/drivers/passthrough/amd/iommu_init.c  Thu Feb 05 18:42:00 2009 +0000
@@ -480,15 +480,9 @@ static int set_iommu_interrupt_handler(s
     int vector, ret;
 
     vector = assign_irq_vector(AUTO_ASSIGN);
-    vector_to_iommu[vector] = iommu;
-
-    /* make irq == vector */
-    irq_vector[vector] = vector;
-    vector_irq[vector] = vector;
-
-    if ( !vector )
+    if ( vector <= 0 )
     {
-        amd_iov_error("no vectors\n");
+        gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: no vectors\n");
         return 0;
     }
 
@@ -496,9 +490,15 @@ static int set_iommu_interrupt_handler(s
     ret = request_irq(vector, amd_iommu_page_fault, 0, "amd_iommu", iommu);
     if ( ret )
     {
+        irq_desc[vector].handler = &no_irq_type;
+        free_irq_vector(vector);
         amd_iov_error("can't request irq\n");
         return 0;
     }
+
+    /* Make sure that vector is never re-used. */
+    vector_irq[vector] = NEVER_ASSIGN;
+    vector_to_iommu[vector] = iommu;
     iommu->vector = vector;
     return vector;
 }
diff -r 39a154721acb xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c       Thu Feb 05 14:29:02 2009 +0000
+++ b/xen/drivers/passthrough/vtd/iommu.c       Thu Feb 05 18:42:00 2009 +0000
@@ -875,13 +875,7 @@ int iommu_set_interrupt(struct iommu *io
     int vector, ret;
 
     vector = assign_irq_vector(AUTO_ASSIGN);
-    vector_to_iommu[vector] = iommu;
-
-    /* VT-d fault is a MSI, make irq == vector */
-    irq_vector[vector] = vector;
-    vector_irq[vector] = vector;
-
-    if ( !vector )
+    if ( vector <= 0 )
     {
         gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: no vectors\n");
         return -EINVAL;
@@ -890,7 +884,17 @@ int iommu_set_interrupt(struct iommu *io
     irq_desc[vector].handler = &dma_msi_type;
     ret = request_irq(vector, iommu_page_fault, 0, "dmar", iommu);
     if ( ret )
+    {
+        irq_desc[vector].handler = &no_irq_type;
+        free_irq_vector(vector);
         gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: can't request irq\n");
+        return ret;
+    }
+
+    /* Make sure that vector is never re-used. */
+    vector_irq[vector] = NEVER_ASSIGN;
+    vector_to_iommu[vector] = iommu;
+
     return vector;
 }
 
@@ -1677,6 +1681,11 @@ static int init_vtd_hw(void)
         }
 
         vector = iommu_set_interrupt(iommu);
+        if ( vector < 0 )
+        {
+            gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: interrupt setup failed\n");
+            return vector;
+        }
         dma_msi_data_init(iommu, vector);
         dma_msi_addr_init(iommu, cpu_physical_id(first_cpu(cpu_online_map)));
         iommu->vector = vector;

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel