aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2009-11-24 11:19:23 -0500
committerJoerg Roedel <joerg.roedel@amd.com>2009-11-27 08:20:29 -0500
commit98fc5a693bbdda498a556654c70d1e31a186c988 (patch)
tree6e53b9a3fd846fab4ff514d724f0ba6825f816af /arch
parent71c70984e5afc20d304fbb523f1c8bb42c4ceb36 (diff)
x86/amd-iommu: Use get_device_id and check_device where appropriate
The logic of these two functions is reimplemented (at least in parts) in places in the code. This patch removes these code duplications and uses the functions instead. As a side effect it moves check_device() to the helper function code section. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/amd_iommu.c110
1 files changed, 49 insertions, 61 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 405f8dad7c77..d10195b685a7 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -111,6 +111,33 @@ static struct dma_ops_domain *find_protection_domain(u16 devid)
111 return ret; 111 return ret;
112} 112}
113 113
114/*
115 * This function checks if the driver got a valid device from the caller to
116 * avoid dereferencing invalid pointers.
117 */
118static bool check_device(struct device *dev)
119{
120 u16 devid;
121
122 if (!dev || !dev->dma_mask)
123 return false;
124
125 /* No device or no PCI device */
126 if (!dev || dev->bus != &pci_bus_type)
127 return false;
128
129 devid = get_device_id(dev);
130
131 /* Out of our scope? */
132 if (devid > amd_iommu_last_bdf)
133 return false;
134
135 if (amd_iommu_rlookup_table[devid] == NULL)
136 return false;
137
138 return true;
139}
140
114#ifdef CONFIG_AMD_IOMMU_STATS 141#ifdef CONFIG_AMD_IOMMU_STATS
115 142
116/* 143/*
@@ -1386,22 +1413,17 @@ static int device_change_notifier(struct notifier_block *nb,
1386 unsigned long action, void *data) 1413 unsigned long action, void *data)
1387{ 1414{
1388 struct device *dev = data; 1415 struct device *dev = data;
1389 struct pci_dev *pdev = to_pci_dev(dev); 1416 u16 devid;
1390 u16 devid = calc_devid(pdev->bus->number, pdev->devfn);
1391 struct protection_domain *domain; 1417 struct protection_domain *domain;
1392 struct dma_ops_domain *dma_domain; 1418 struct dma_ops_domain *dma_domain;
1393 struct amd_iommu *iommu; 1419 struct amd_iommu *iommu;
1394 unsigned long flags; 1420 unsigned long flags;
1395 1421
1396 if (devid > amd_iommu_last_bdf) 1422 if (!check_device(dev))
1397 goto out; 1423 return 0;
1398
1399 devid = amd_iommu_alias_table[devid];
1400
1401 iommu = amd_iommu_rlookup_table[devid];
1402 if (iommu == NULL)
1403 goto out;
1404 1424
1425 devid = get_device_id(dev);
1426 iommu = amd_iommu_rlookup_table[devid];
1405 domain = domain_for_device(dev); 1427 domain = domain_for_device(dev);
1406 1428
1407 if (domain && !dma_ops_domain(domain)) 1429 if (domain && !dma_ops_domain(domain))
@@ -1453,36 +1475,6 @@ static struct notifier_block device_nb = {
1453 *****************************************************************************/ 1475 *****************************************************************************/
1454 1476
1455/* 1477/*
1456 * This function checks if the driver got a valid device from the caller to
1457 * avoid dereferencing invalid pointers.
1458 */
1459static bool check_device(struct device *dev)
1460{
1461 u16 bdf;
1462 struct pci_dev *pcidev;
1463
1464 if (!dev || !dev->dma_mask)
1465 return false;
1466
1467 /* No device or no PCI device */
1468 if (!dev || dev->bus != &pci_bus_type)
1469 return false;
1470
1471 pcidev = to_pci_dev(dev);
1472
1473 bdf = calc_devid(pcidev->bus->number, pcidev->devfn);
1474
1475 /* Out of our scope? */
1476 if (bdf > amd_iommu_last_bdf)
1477 return false;
1478
1479 if (amd_iommu_rlookup_table[bdf] == NULL)
1480 return false;
1481
1482 return true;
1483}
1484
1485/*
1486 * In the dma_ops path we only have the struct device. This function 1478 * In the dma_ops path we only have the struct device. This function
1487 * finds the corresponding IOMMU, the protection domain and the 1479 * finds the corresponding IOMMU, the protection domain and the
1488 * requestor id for a given device. 1480 * requestor id for a given device.
@@ -2094,15 +2086,20 @@ static void prealloc_protection_domains(void)
2094 struct pci_dev *dev = NULL; 2086 struct pci_dev *dev = NULL;
2095 struct dma_ops_domain *dma_dom; 2087 struct dma_ops_domain *dma_dom;
2096 struct amd_iommu *iommu; 2088 struct amd_iommu *iommu;
2097 u16 devid, __devid; 2089 u16 devid;
2098 2090
2099 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { 2091 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
2100 __devid = devid = calc_devid(dev->bus->number, dev->devfn); 2092
2101 if (devid > amd_iommu_last_bdf) 2093 /* Do we handle this device? */
2094 if (!check_device(&dev->dev))
2102 continue; 2095 continue;
2103 devid = amd_iommu_alias_table[devid]; 2096
2097 /* Is there already any domain for it? */
2104 if (domain_for_device(&dev->dev)) 2098 if (domain_for_device(&dev->dev))
2105 continue; 2099 continue;
2100
2101 devid = get_device_id(&dev->dev);
2102
2106 iommu = amd_iommu_rlookup_table[devid]; 2103 iommu = amd_iommu_rlookup_table[devid];
2107 if (!iommu) 2104 if (!iommu)
2108 continue; 2105 continue;
@@ -2294,17 +2291,14 @@ static void amd_iommu_detach_device(struct iommu_domain *dom,
2294 struct device *dev) 2291 struct device *dev)
2295{ 2292{
2296 struct amd_iommu *iommu; 2293 struct amd_iommu *iommu;
2297 struct pci_dev *pdev;
2298 u16 devid; 2294 u16 devid;
2299 2295
2300 if (dev->bus != &pci_bus_type) 2296 if (!check_device(dev))
2301 return; 2297 return;
2302 2298
2303 pdev = to_pci_dev(dev); 2299 devid = get_device_id(dev);
2304
2305 devid = calc_devid(pdev->bus->number, pdev->devfn);
2306 2300
2307 if (devid > 0) 2301 if (amd_iommu_pd_table[devid] != NULL)
2308 detach_device(dev); 2302 detach_device(dev);
2309 2303
2310 iommu = amd_iommu_rlookup_table[devid]; 2304 iommu = amd_iommu_rlookup_table[devid];
@@ -2321,20 +2315,13 @@ static int amd_iommu_attach_device(struct iommu_domain *dom,
2321 struct protection_domain *domain = dom->priv; 2315 struct protection_domain *domain = dom->priv;
2322 struct protection_domain *old_domain; 2316 struct protection_domain *old_domain;
2323 struct amd_iommu *iommu; 2317 struct amd_iommu *iommu;
2324 struct pci_dev *pdev;
2325 int ret; 2318 int ret;
2326 u16 devid; 2319 u16 devid;
2327 2320
2328 if (dev->bus != &pci_bus_type) 2321 if (!check_device(dev))
2329 return -EINVAL; 2322 return -EINVAL;
2330 2323
2331 pdev = to_pci_dev(dev); 2324 devid = get_device_id(dev);
2332
2333 devid = calc_devid(pdev->bus->number, pdev->devfn);
2334
2335 if (devid >= amd_iommu_last_bdf ||
2336 devid != amd_iommu_alias_table[devid])
2337 return -EINVAL;
2338 2325
2339 iommu = amd_iommu_rlookup_table[devid]; 2326 iommu = amd_iommu_rlookup_table[devid];
2340 if (!iommu) 2327 if (!iommu)
@@ -2458,10 +2445,11 @@ int __init amd_iommu_init_passthrough(void)
2458 2445
2459 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { 2446 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
2460 2447
2461 devid = calc_devid(dev->bus->number, dev->devfn); 2448 if (!check_device(&dev->dev))
2462 if (devid > amd_iommu_last_bdf)
2463 continue; 2449 continue;
2464 2450
2451 devid = get_device_id(&dev->dev);
2452
2465 iommu = amd_iommu_rlookup_table[devid]; 2453 iommu = amd_iommu_rlookup_table[devid];
2466 if (!iommu) 2454 if (!iommu)
2467 continue; 2455 continue;