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
|