|
@@ -1399,6 +1399,16 @@ static void init_device_table_dma(void)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void __init uninit_device_table_dma(void)
|
|
|
+{
|
|
|
+ u32 devid;
|
|
|
+
|
|
|
+ for (devid = 0; devid <= amd_iommu_last_bdf; ++devid) {
|
|
|
+ amd_iommu_dev_table[devid].data[0] = 0ULL;
|
|
|
+ amd_iommu_dev_table[devid].data[1] = 0ULL;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void init_device_table(void)
|
|
|
{
|
|
|
u32 devid;
|
|
@@ -1567,11 +1577,6 @@ static void __init free_on_init_error(void)
|
|
|
|
|
|
}
|
|
|
|
|
|
- amd_iommu_uninit_devices();
|
|
|
-
|
|
|
- free_pages((unsigned long)amd_iommu_pd_alloc_bitmap,
|
|
|
- get_order(MAX_DOMAIN_ID/8));
|
|
|
-
|
|
|
free_pages((unsigned long)amd_iommu_rlookup_table,
|
|
|
get_order(rlookup_table_size));
|
|
|
|
|
@@ -1583,8 +1588,6 @@ static void __init free_on_init_error(void)
|
|
|
|
|
|
free_iommu_all();
|
|
|
|
|
|
- free_unity_maps();
|
|
|
-
|
|
|
#ifdef CONFIG_GART_IOMMU
|
|
|
/*
|
|
|
* We failed to initialize the AMD IOMMU - try fallback to GART
|
|
@@ -1612,6 +1615,16 @@ static bool __init check_ioapic_information(void)
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+static void __init free_dma_resources(void)
|
|
|
+{
|
|
|
+ amd_iommu_uninit_devices();
|
|
|
+
|
|
|
+ free_pages((unsigned long)amd_iommu_pd_alloc_bitmap,
|
|
|
+ get_order(MAX_DOMAIN_ID/8));
|
|
|
+
|
|
|
+ free_unity_maps();
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* This is the hardware init function for AMD IOMMU in the system.
|
|
|
* This function is called either from amd_iommu_init or from the interrupt
|
|
@@ -1952,8 +1965,17 @@ static int __init amd_iommu_init(void)
|
|
|
|
|
|
ret = iommu_go_to_state(IOMMU_INITIALIZED);
|
|
|
if (ret) {
|
|
|
- disable_iommus();
|
|
|
- free_on_init_error();
|
|
|
+ free_dma_resources();
|
|
|
+ if (!irq_remapping_enabled) {
|
|
|
+ disable_iommus();
|
|
|
+ free_on_init_error();
|
|
|
+ } else {
|
|
|
+ struct amd_iommu *iommu;
|
|
|
+
|
|
|
+ uninit_device_table_dma();
|
|
|
+ for_each_iommu(iommu)
|
|
|
+ iommu_flush_all_caches(iommu);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return ret;
|