diff options
Diffstat (limited to 'drivers/pci/intel-iommu.c')
-rw-r--r-- | drivers/pci/intel-iommu.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 22ad8851b3e0..d2ffa7a6d723 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -57,6 +57,9 @@ | |||
57 | #define DMA_32BIT_PFN IOVA_PFN(DMA_32BIT_MASK) | 57 | #define DMA_32BIT_PFN IOVA_PFN(DMA_32BIT_MASK) |
58 | #define DMA_64BIT_PFN IOVA_PFN(DMA_64BIT_MASK) | 58 | #define DMA_64BIT_PFN IOVA_PFN(DMA_64BIT_MASK) |
59 | 59 | ||
60 | /* global iommu list, set NULL for ignored DMAR units */ | ||
61 | static struct intel_iommu **g_iommus; | ||
62 | |||
60 | /* | 63 | /* |
61 | * 0: Present | 64 | * 0: Present |
62 | * 1-11: Reserved | 65 | * 1-11: Reserved |
@@ -1153,6 +1156,17 @@ void free_dmar_iommu(struct intel_iommu *iommu) | |||
1153 | kfree(iommu->domains); | 1156 | kfree(iommu->domains); |
1154 | kfree(iommu->domain_ids); | 1157 | kfree(iommu->domain_ids); |
1155 | 1158 | ||
1159 | g_iommus[iommu->seq_id] = NULL; | ||
1160 | |||
1161 | /* if all iommus are freed, free g_iommus */ | ||
1162 | for (i = 0; i < g_num_of_iommus; i++) { | ||
1163 | if (g_iommus[i]) | ||
1164 | break; | ||
1165 | } | ||
1166 | |||
1167 | if (i == g_num_of_iommus) | ||
1168 | kfree(g_iommus); | ||
1169 | |||
1156 | /* free context mapping */ | 1170 | /* free context mapping */ |
1157 | free_context_table(iommu); | 1171 | free_context_table(iommu); |
1158 | } | 1172 | } |
@@ -1794,9 +1808,18 @@ static int __init init_dmars(void) | |||
1794 | */ | 1808 | */ |
1795 | } | 1809 | } |
1796 | 1810 | ||
1811 | g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *), | ||
1812 | GFP_KERNEL); | ||
1813 | if (!g_iommus) { | ||
1814 | printk(KERN_ERR "Allocating global iommu array failed\n"); | ||
1815 | ret = -ENOMEM; | ||
1816 | goto error; | ||
1817 | } | ||
1818 | |||
1797 | deferred_flush = kzalloc(g_num_of_iommus * | 1819 | deferred_flush = kzalloc(g_num_of_iommus * |
1798 | sizeof(struct deferred_flush_tables), GFP_KERNEL); | 1820 | sizeof(struct deferred_flush_tables), GFP_KERNEL); |
1799 | if (!deferred_flush) { | 1821 | if (!deferred_flush) { |
1822 | kfree(g_iommus); | ||
1800 | ret = -ENOMEM; | 1823 | ret = -ENOMEM; |
1801 | goto error; | 1824 | goto error; |
1802 | } | 1825 | } |
@@ -1806,6 +1829,7 @@ static int __init init_dmars(void) | |||
1806 | continue; | 1829 | continue; |
1807 | 1830 | ||
1808 | iommu = drhd->iommu; | 1831 | iommu = drhd->iommu; |
1832 | g_iommus[iommu->seq_id] = iommu; | ||
1809 | 1833 | ||
1810 | ret = iommu_init_domains(iommu); | 1834 | ret = iommu_init_domains(iommu); |
1811 | if (ret) | 1835 | if (ret) |
@@ -1918,6 +1942,7 @@ error: | |||
1918 | iommu = drhd->iommu; | 1942 | iommu = drhd->iommu; |
1919 | free_iommu(iommu); | 1943 | free_iommu(iommu); |
1920 | } | 1944 | } |
1945 | kfree(g_iommus); | ||
1921 | return ret; | 1946 | return ret; |
1922 | } | 1947 | } |
1923 | 1948 | ||