diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2009-11-26 05:13:32 -0500 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2009-11-27 08:20:34 -0500 |
commit | 7c392cbe984d904f7c89a6a75b2ac245254e8da5 (patch) | |
tree | 48b5d1f73cd3814de15d32a0e82a963dd4237f9c /arch/x86/kernel/amd_iommu.c | |
parent | 241000556f751dacd332df6ab2e903a23746e51e (diff) |
x86/amd-iommu: Keep devices per domain in a list
This patch introduces a list to each protection domain which
keeps all devices associated with the domain. This can be
used later to optimize certain functions and to completly
remove the amd_iommu_pd_table.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'arch/x86/kernel/amd_iommu.c')
-rw-r--r-- | arch/x86/kernel/amd_iommu.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index f5db7d5e444e..530d6080940f 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -1286,6 +1286,7 @@ static struct dma_ops_domain *dma_ops_domain_alloc(void) | |||
1286 | dma_dom->domain.id = domain_id_alloc(); | 1286 | dma_dom->domain.id = domain_id_alloc(); |
1287 | if (dma_dom->domain.id == 0) | 1287 | if (dma_dom->domain.id == 0) |
1288 | goto free_dma_dom; | 1288 | goto free_dma_dom; |
1289 | INIT_LIST_HEAD(&dma_dom->domain.dev_list); | ||
1289 | dma_dom->domain.mode = PAGE_MODE_2_LEVEL; | 1290 | dma_dom->domain.mode = PAGE_MODE_2_LEVEL; |
1290 | dma_dom->domain.pt_root = (void *)get_zeroed_page(GFP_KERNEL); | 1291 | dma_dom->domain.pt_root = (void *)get_zeroed_page(GFP_KERNEL); |
1291 | dma_dom->domain.flags = PD_DMA_OPS_MASK; | 1292 | dma_dom->domain.flags = PD_DMA_OPS_MASK; |
@@ -1408,6 +1409,7 @@ static int __attach_device(struct device *dev, | |||
1408 | if (alias != devid) { | 1409 | if (alias != devid) { |
1409 | if (alias_data->domain == NULL) { | 1410 | if (alias_data->domain == NULL) { |
1410 | alias_data->domain = domain; | 1411 | alias_data->domain = domain; |
1412 | list_add(&alias_data->list, &domain->dev_list); | ||
1411 | set_dte_entry(alias, domain); | 1413 | set_dte_entry(alias, domain); |
1412 | } | 1414 | } |
1413 | 1415 | ||
@@ -1416,6 +1418,7 @@ static int __attach_device(struct device *dev, | |||
1416 | 1418 | ||
1417 | if (dev_data->domain == NULL) { | 1419 | if (dev_data->domain == NULL) { |
1418 | dev_data->domain = domain; | 1420 | dev_data->domain = domain; |
1421 | list_add(&dev_data->list, &domain->dev_list); | ||
1419 | set_dte_entry(devid, domain); | 1422 | set_dte_entry(devid, domain); |
1420 | } | 1423 | } |
1421 | 1424 | ||
@@ -1460,6 +1463,7 @@ static void __detach_device(struct device *dev) | |||
1460 | struct amd_iommu *iommu = amd_iommu_rlookup_table[devid]; | 1463 | struct amd_iommu *iommu = amd_iommu_rlookup_table[devid]; |
1461 | struct iommu_dev_data *dev_data = get_dev_data(dev); | 1464 | struct iommu_dev_data *dev_data = get_dev_data(dev); |
1462 | struct iommu_dev_data *alias_data; | 1465 | struct iommu_dev_data *alias_data; |
1466 | unsigned long flags; | ||
1463 | 1467 | ||
1464 | BUG_ON(!iommu); | 1468 | BUG_ON(!iommu); |
1465 | 1469 | ||
@@ -1469,13 +1473,19 @@ static void __detach_device(struct device *dev) | |||
1469 | if (devid != alias) { | 1473 | if (devid != alias) { |
1470 | alias_data = get_dev_data(dev_data->alias); | 1474 | alias_data = get_dev_data(dev_data->alias); |
1471 | if (atomic_dec_and_test(&alias_data->bind)) { | 1475 | if (atomic_dec_and_test(&alias_data->bind)) { |
1476 | spin_lock_irqsave(&alias_data->domain->lock, flags); | ||
1472 | clear_dte_entry(alias); | 1477 | clear_dte_entry(alias); |
1478 | list_del(&alias_data->list); | ||
1479 | spin_unlock_irqrestore(&alias_data->domain->lock, flags); | ||
1473 | alias_data->domain = NULL; | 1480 | alias_data->domain = NULL; |
1474 | } | 1481 | } |
1475 | } | 1482 | } |
1476 | 1483 | ||
1477 | if (atomic_dec_and_test(&dev_data->bind)) { | 1484 | if (atomic_dec_and_test(&dev_data->bind)) { |
1485 | spin_lock_irqsave(&dev_data->domain->lock, flags); | ||
1478 | clear_dte_entry(devid); | 1486 | clear_dte_entry(devid); |
1487 | list_del(&dev_data->list); | ||
1488 | spin_unlock_irqrestore(&dev_data->domain->lock, flags); | ||
1479 | dev_data->domain = NULL; | 1489 | dev_data->domain = NULL; |
1480 | } | 1490 | } |
1481 | 1491 | ||
@@ -2294,6 +2304,7 @@ static struct protection_domain *protection_domain_alloc(void) | |||
2294 | domain->id = domain_id_alloc(); | 2304 | domain->id = domain_id_alloc(); |
2295 | if (!domain->id) | 2305 | if (!domain->id) |
2296 | goto out_err; | 2306 | goto out_err; |
2307 | INIT_LIST_HEAD(&domain->dev_list); | ||
2297 | 2308 | ||
2298 | add_domain_to_list(domain); | 2309 | add_domain_to_list(domain); |
2299 | 2310 | ||