aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2014-03-09 18:48:15 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2014-03-24 10:07:54 -0400
commit0b9d9753155b9ed72e864592f9bf482a688c3c11 (patch)
treee46a9d1a8fa919ada2570492104b59254063c45e
parent146922ec798de6484897a43fc6180e49c425f183 (diff)
iommu/vt-d: Handle RMRRs for non-PCI devices
Should hopefully never happen (RMRRs are an abomination) but while we're busy eliminating all the PCI assumptions, we might as well do it. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
-rw-r--r--drivers/iommu/intel-iommu.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 1c5f656ff19d..7b2b9f321c74 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2311,14 +2311,14 @@ static int iommu_domain_identity_map(struct dmar_domain *domain,
2311 DMA_PTE_READ|DMA_PTE_WRITE); 2311 DMA_PTE_READ|DMA_PTE_WRITE);
2312} 2312}
2313 2313
2314static int iommu_prepare_identity_map(struct pci_dev *pdev, 2314static int iommu_prepare_identity_map(struct device *dev,
2315 unsigned long long start, 2315 unsigned long long start,
2316 unsigned long long end) 2316 unsigned long long end)
2317{ 2317{
2318 struct dmar_domain *domain; 2318 struct dmar_domain *domain;
2319 int ret; 2319 int ret;
2320 2320
2321 domain = get_domain_for_dev(&pdev->dev, DEFAULT_DOMAIN_ADDRESS_WIDTH); 2321 domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
2322 if (!domain) 2322 if (!domain)
2323 return -ENOMEM; 2323 return -ENOMEM;
2324 2324
@@ -2328,13 +2328,13 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev,
2328 up to start with in si_domain */ 2328 up to start with in si_domain */
2329 if (domain == si_domain && hw_pass_through) { 2329 if (domain == si_domain && hw_pass_through) {
2330 printk("Ignoring identity map for HW passthrough device %s [0x%Lx - 0x%Lx]\n", 2330 printk("Ignoring identity map for HW passthrough device %s [0x%Lx - 0x%Lx]\n",
2331 pci_name(pdev), start, end); 2331 dev_name(dev), start, end);
2332 return 0; 2332 return 0;
2333 } 2333 }
2334 2334
2335 printk(KERN_INFO 2335 printk(KERN_INFO
2336 "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n", 2336 "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
2337 pci_name(pdev), start, end); 2337 dev_name(dev), start, end);
2338 2338
2339 if (end < start) { 2339 if (end < start) {
2340 WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n" 2340 WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
@@ -2362,7 +2362,7 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev,
2362 goto error; 2362 goto error;
2363 2363
2364 /* context entry init */ 2364 /* context entry init */
2365 ret = domain_context_mapping(domain, &pdev->dev, CONTEXT_TT_MULTI_LEVEL); 2365 ret = domain_context_mapping(domain, dev, CONTEXT_TT_MULTI_LEVEL);
2366 if (ret) 2366 if (ret)
2367 goto error; 2367 goto error;
2368 2368
@@ -2374,12 +2374,12 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev,
2374} 2374}
2375 2375
2376static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, 2376static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
2377 struct pci_dev *pdev) 2377 struct device *dev)
2378{ 2378{
2379 if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) 2379 if (dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
2380 return 0; 2380 return 0;
2381 return iommu_prepare_identity_map(pdev, rmrr->base_address, 2381 return iommu_prepare_identity_map(dev, rmrr->base_address,
2382 rmrr->end_address); 2382 rmrr->end_address);
2383} 2383}
2384 2384
2385#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA 2385#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
@@ -2393,7 +2393,7 @@ static inline void iommu_prepare_isa(void)
2393 return; 2393 return;
2394 2394
2395 printk(KERN_INFO "IOMMU: Prepare 0-16MiB unity mapping for LPC\n"); 2395 printk(KERN_INFO "IOMMU: Prepare 0-16MiB unity mapping for LPC\n");
2396 ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024 - 1); 2396 ret = iommu_prepare_identity_map(&pdev->dev, 0, 16*1024*1024 - 1);
2397 2397
2398 if (ret) 2398 if (ret)
2399 printk(KERN_ERR "IOMMU: Failed to create 0-16MiB identity map; " 2399 printk(KERN_ERR "IOMMU: Failed to create 0-16MiB identity map; "
@@ -2495,7 +2495,7 @@ static int domain_add_dev_info(struct dmar_domain *domain,
2495 return 0; 2495 return 0;
2496} 2496}
2497 2497
2498static bool device_has_rmrr(struct pci_dev *dev) 2498static bool device_has_rmrr(struct device *dev)
2499{ 2499{
2500 struct dmar_rmrr_unit *rmrr; 2500 struct dmar_rmrr_unit *rmrr;
2501 struct device *tmp; 2501 struct device *tmp;
@@ -2509,7 +2509,7 @@ static bool device_has_rmrr(struct pci_dev *dev)
2509 */ 2509 */
2510 for_each_active_dev_scope(rmrr->devices, 2510 for_each_active_dev_scope(rmrr->devices,
2511 rmrr->devices_cnt, i, tmp) 2511 rmrr->devices_cnt, i, tmp)
2512 if (tmp == &dev->dev) { 2512 if (tmp == dev) {
2513 rcu_read_unlock(); 2513 rcu_read_unlock();
2514 return true; 2514 return true;
2515 } 2515 }
@@ -2529,7 +2529,7 @@ static int iommu_should_identity_map(struct pci_dev *pdev, int startup)
2529 * from this process due to their usage of RMRRs that are known 2529 * from this process due to their usage of RMRRs that are known
2530 * to not be needed after BIOS hand-off to OS. 2530 * to not be needed after BIOS hand-off to OS.
2531 */ 2531 */
2532 if (device_has_rmrr(pdev) && 2532 if (device_has_rmrr(&pdev->dev) &&
2533 (pdev->class >> 8) != PCI_CLASS_SERIAL_USB) 2533 (pdev->class >> 8) != PCI_CLASS_SERIAL_USB)
2534 return 0; 2534 return 0;
2535 2535
@@ -2766,9 +2766,7 @@ static int __init init_dmars(void)
2766 /* some BIOS lists non-exist devices in DMAR table. */ 2766 /* some BIOS lists non-exist devices in DMAR table. */
2767 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt, 2767 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
2768 i, dev) { 2768 i, dev) {
2769 if (!dev_is_pci(dev)) 2769 ret = iommu_prepare_rmrr_dev(rmrr, dev);
2770 continue;
2771 ret = iommu_prepare_rmrr_dev(rmrr, to_pci_dev(dev));
2772 if (ret) 2770 if (ret)
2773 printk(KERN_ERR 2771 printk(KERN_ERR
2774 "IOMMU: mapping reserved region failed\n"); 2772 "IOMMU: mapping reserved region failed\n");