diff options
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/amd_iommu.c | 35 | ||||
-rw-r--r-- | arch/x86/kernel/amd_iommu_init.c | 18 |
2 files changed, 11 insertions, 42 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index b75fcd9b6a0f..32fb09102a13 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -1309,8 +1309,6 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain) | |||
1309 | { | 1309 | { |
1310 | u64 pte_root = virt_to_phys(domain->pt_root); | 1310 | u64 pte_root = virt_to_phys(domain->pt_root); |
1311 | 1311 | ||
1312 | BUG_ON(amd_iommu_pd_table[devid] != NULL); | ||
1313 | |||
1314 | pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK) | 1312 | pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK) |
1315 | << DEV_ENTRY_MODE_SHIFT; | 1313 | << DEV_ENTRY_MODE_SHIFT; |
1316 | pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV; | 1314 | pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV; |
@@ -1318,20 +1316,10 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain) | |||
1318 | amd_iommu_dev_table[devid].data[2] = domain->id; | 1316 | amd_iommu_dev_table[devid].data[2] = domain->id; |
1319 | amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root); | 1317 | amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root); |
1320 | amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root); | 1318 | amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root); |
1321 | |||
1322 | amd_iommu_pd_table[devid] = domain; | ||
1323 | |||
1324 | } | 1319 | } |
1325 | 1320 | ||
1326 | static void clear_dte_entry(u16 devid) | 1321 | static void clear_dte_entry(u16 devid) |
1327 | { | 1322 | { |
1328 | struct protection_domain *domain = amd_iommu_pd_table[devid]; | ||
1329 | |||
1330 | BUG_ON(domain == NULL); | ||
1331 | |||
1332 | /* remove domain from the lookup table */ | ||
1333 | amd_iommu_pd_table[devid] = NULL; | ||
1334 | |||
1335 | /* remove entry from the device table seen by the hardware */ | 1323 | /* remove entry from the device table seen by the hardware */ |
1336 | amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV; | 1324 | amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV; |
1337 | amd_iommu_dev_table[devid].data[1] = 0; | 1325 | amd_iommu_dev_table[devid].data[1] = 0; |
@@ -1641,15 +1629,11 @@ static struct protection_domain *get_domain(struct device *dev) | |||
1641 | 1629 | ||
1642 | static void update_device_table(struct protection_domain *domain) | 1630 | static void update_device_table(struct protection_domain *domain) |
1643 | { | 1631 | { |
1644 | unsigned long flags; | 1632 | struct iommu_dev_data *dev_data; |
1645 | int i; | ||
1646 | 1633 | ||
1647 | for (i = 0; i <= amd_iommu_last_bdf; ++i) { | 1634 | list_for_each_entry(dev_data, &domain->dev_list, list) { |
1648 | if (amd_iommu_pd_table[i] != domain) | 1635 | u16 devid = get_device_id(dev_data->dev); |
1649 | continue; | 1636 | set_dte_entry(devid, domain); |
1650 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); | ||
1651 | set_dte_entry(i, domain); | ||
1652 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | ||
1653 | } | 1637 | } |
1654 | } | 1638 | } |
1655 | 1639 | ||
@@ -2259,14 +2243,17 @@ free_domains: | |||
2259 | 2243 | ||
2260 | static void cleanup_domain(struct protection_domain *domain) | 2244 | static void cleanup_domain(struct protection_domain *domain) |
2261 | { | 2245 | { |
2246 | struct iommu_dev_data *dev_data, *next; | ||
2262 | unsigned long flags; | 2247 | unsigned long flags; |
2263 | u16 devid; | ||
2264 | 2248 | ||
2265 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); | 2249 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); |
2266 | 2250 | ||
2267 | for (devid = 0; devid <= amd_iommu_last_bdf; ++devid) | 2251 | list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) { |
2268 | if (amd_iommu_pd_table[devid] == domain) | 2252 | struct device *dev = dev_data->dev; |
2269 | clear_dte_entry(devid); | 2253 | |
2254 | do_detach(dev); | ||
2255 | atomic_set(&dev_data->bind, 0); | ||
2256 | } | ||
2270 | 2257 | ||
2271 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | 2258 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); |
2272 | } | 2259 | } |
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index fe1686f6f91b..7ffc39965233 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
@@ -165,12 +165,6 @@ u16 *amd_iommu_alias_table; | |||
165 | struct amd_iommu **amd_iommu_rlookup_table; | 165 | struct amd_iommu **amd_iommu_rlookup_table; |
166 | 166 | ||
167 | /* | 167 | /* |
168 | * The pd table (protection domain table) is used to find the protection domain | ||
169 | * data structure a device belongs to. Indexed with the PCI device id too. | ||
170 | */ | ||
171 | struct protection_domain **amd_iommu_pd_table; | ||
172 | |||
173 | /* | ||
174 | * AMD IOMMU allows up to 2^16 differend protection domains. This is a bitmap | 168 | * AMD IOMMU allows up to 2^16 differend protection domains. This is a bitmap |
175 | * to know which ones are already in use. | 169 | * to know which ones are already in use. |
176 | */ | 170 | */ |
@@ -1238,15 +1232,6 @@ static int __init amd_iommu_init(void) | |||
1238 | if (amd_iommu_rlookup_table == NULL) | 1232 | if (amd_iommu_rlookup_table == NULL) |
1239 | goto free; | 1233 | goto free; |
1240 | 1234 | ||
1241 | /* | ||
1242 | * Protection Domain table - maps devices to protection domains | ||
1243 | * This table has the same size as the rlookup_table | ||
1244 | */ | ||
1245 | amd_iommu_pd_table = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, | ||
1246 | get_order(rlookup_table_size)); | ||
1247 | if (amd_iommu_pd_table == NULL) | ||
1248 | goto free; | ||
1249 | |||
1250 | amd_iommu_pd_alloc_bitmap = (void *)__get_free_pages( | 1235 | amd_iommu_pd_alloc_bitmap = (void *)__get_free_pages( |
1251 | GFP_KERNEL | __GFP_ZERO, | 1236 | GFP_KERNEL | __GFP_ZERO, |
1252 | get_order(MAX_DOMAIN_ID/8)); | 1237 | get_order(MAX_DOMAIN_ID/8)); |
@@ -1314,9 +1299,6 @@ free: | |||
1314 | free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, | 1299 | free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, |
1315 | get_order(MAX_DOMAIN_ID/8)); | 1300 | get_order(MAX_DOMAIN_ID/8)); |
1316 | 1301 | ||
1317 | free_pages((unsigned long)amd_iommu_pd_table, | ||
1318 | get_order(rlookup_table_size)); | ||
1319 | |||
1320 | free_pages((unsigned long)amd_iommu_rlookup_table, | 1302 | free_pages((unsigned long)amd_iommu_rlookup_table, |
1321 | get_order(rlookup_table_size)); | 1303 | get_order(rlookup_table_size)); |
1322 | 1304 | ||