Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge git://git.infradead.org/iommu-2.6

* git://git.infradead.org/iommu-2.6:
intel-iommu: Don't use identity mapping for PCI devices behind bridges
intel-iommu: Use iommu_should_identity_map() at startup time too.
intel-iommu: No mapping for non-PCI devices
intel-iommu: Restore DMAR_BROKEN_GFX_WA option for broken graphics drivers
intel-iommu: Add iommu_should_identity_map() function
intel-iommu: Fix reattaching of devices to identity mapping domain
intel-iommu: Don't set identity mapping for bypassed graphics devices
intel-iommu: Fix dma vs. mm page confusion with aligned_nrpages()

+95 -23
+12
arch/x86/Kconfig
··· 1913 1913 recommended you say N here while the DMAR code remains 1914 1914 experimental. 1915 1915 1916 + config DMAR_BROKEN_GFX_WA 1917 + def_bool n 1918 + prompt "Workaround broken graphics drivers (going away soon)" 1919 + depends on DMAR 1920 + ---help--- 1921 + Current Graphics drivers tend to use physical address 1922 + for DMA and avoid using DMA APIs. Setting this config 1923 + option permits the IOMMU driver to set a unity map for 1924 + all the OS-visible memory. Hence the driver can continue 1925 + to use physical addresses for DMA, at least until this 1926 + option is removed in the 2.6.32 kernel. 1927 + 1916 1928 config DMAR_FLOPPY_WA 1917 1929 def_bool y 1918 1930 depends on DMAR
+83 -23
drivers/pci/intel-iommu.c
··· 2117 2117 return 0; 2118 2118 } 2119 2119 2120 + static int iommu_should_identity_map(struct pci_dev *pdev, int startup) 2121 + { 2122 + if (iommu_identity_mapping == 2) 2123 + return IS_GFX_DEVICE(pdev); 2124 + 2125 + /* 2126 + * We want to start off with all devices in the 1:1 domain, and 2127 + * take them out later if we find they can't access all of memory. 2128 + * 2129 + * However, we can't do this for PCI devices behind bridges, 2130 + * because all PCI devices behind the same bridge will end up 2131 + * with the same source-id on their transactions. 2132 + * 2133 + * Practically speaking, we can't change things around for these 2134 + * devices at run-time, because we can't be sure there'll be no 2135 + * DMA transactions in flight for any of their siblings. 2136 + * 2137 + * So PCI devices (unless they're on the root bus) as well as 2138 + * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of 2139 + * the 1:1 domain, just in _case_ one of their siblings turns out 2140 + * not to be able to map all of memory. 2141 + */ 2142 + if (!pdev->is_pcie) { 2143 + if (!pci_is_root_bus(pdev->bus)) 2144 + return 0; 2145 + if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI) 2146 + return 0; 2147 + } else if (pdev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) 2148 + return 0; 2149 + 2150 + /* 2151 + * At boot time, we don't yet know if devices will be 64-bit capable. 2152 + * Assume that they will -- if they turn out not to be, then we can 2153 + * take them out of the 1:1 domain later. 2154 + */ 2155 + if (!startup) 2156 + return pdev->dma_mask > DMA_BIT_MASK(32); 2157 + 2158 + return 1; 2159 + } 2160 + 2120 2161 static int iommu_prepare_static_identity_mapping(void) 2121 2162 { 2122 2163 struct pci_dev *pdev = NULL; ··· 2168 2127 return -EFAULT; 2169 2128 2170 2129 for_each_pci_dev(pdev) { 2171 - printk(KERN_INFO "IOMMU: identity mapping for device %s\n", 2172 - pci_name(pdev)); 2130 + if (iommu_should_identity_map(pdev, 1)) { 2131 + printk(KERN_INFO "IOMMU: identity mapping for device %s\n", 2132 + pci_name(pdev)); 2173 2133 2174 - ret = domain_context_mapping(si_domain, pdev, 2175 - CONTEXT_TT_MULTI_LEVEL); 2176 - if (ret) 2177 - return ret; 2178 - ret = domain_add_dev_info(si_domain, pdev); 2179 - if (ret) 2180 - return ret; 2134 + ret = domain_context_mapping(si_domain, pdev, 2135 + CONTEXT_TT_MULTI_LEVEL); 2136 + if (ret) 2137 + return ret; 2138 + ret = domain_add_dev_info(si_domain, pdev); 2139 + if (ret) 2140 + return ret; 2141 + } 2181 2142 } 2182 2143 2183 2144 return 0; ··· 2334 2291 * identity mapping if iommu_identity_mapping is set. 2335 2292 */ 2336 2293 if (!iommu_pass_through) { 2294 + #ifdef CONFIG_DMAR_BROKEN_GFX_WA 2295 + if (!iommu_identity_mapping) 2296 + iommu_identity_mapping = 2; 2297 + #endif 2337 2298 if (iommu_identity_mapping) 2338 2299 iommu_prepare_static_identity_mapping(); 2339 2300 /* ··· 2415 2368 return ret; 2416 2369 } 2417 2370 2371 + /* Returns a number of VTD pages, but aligned to MM page size */ 2418 2372 static inline unsigned long aligned_nrpages(unsigned long host_addr, 2419 2373 size_t size) 2420 2374 { 2421 2375 host_addr &= ~PAGE_MASK; 2422 - host_addr += size + PAGE_SIZE - 1; 2423 - 2424 - return host_addr >> VTD_PAGE_SHIFT; 2376 + return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT; 2425 2377 } 2426 2378 2379 + /* This takes a number of _MM_ pages, not VTD pages */ 2427 2380 static struct iova *intel_alloc_iova(struct device *dev, 2428 2381 struct dmar_domain *domain, 2429 2382 unsigned long nrpages, uint64_t dma_mask) ··· 2490 2443 } 2491 2444 2492 2445 /* Check if the pdev needs to go through non-identity map and unmap process.*/ 2493 - static int iommu_no_mapping(struct pci_dev *pdev) 2446 + static int iommu_no_mapping(struct device *dev) 2494 2447 { 2448 + struct pci_dev *pdev; 2495 2449 int found; 2496 2450 2451 + if (unlikely(dev->bus != &pci_bus_type)) 2452 + return 1; 2453 + 2454 + pdev = to_pci_dev(dev); 2455 + if (iommu_dummy(pdev)) 2456 + return 1; 2457 + 2497 2458 if (!iommu_identity_mapping) 2498 - return iommu_dummy(pdev); 2459 + return 0; 2499 2460 2500 2461 found = identity_mapping(pdev); 2501 2462 if (found) { 2502 - if (pdev->dma_mask > DMA_BIT_MASK(32)) 2463 + if (iommu_should_identity_map(pdev, 0)) 2503 2464 return 1; 2504 2465 else { 2505 2466 /* ··· 2524 2469 * In case of a detached 64 bit DMA device from vm, the device 2525 2470 * is put into si_domain for identity mapping. 2526 2471 */ 2527 - if (pdev->dma_mask > DMA_BIT_MASK(32)) { 2472 + if (iommu_should_identity_map(pdev, 0)) { 2528 2473 int ret; 2529 2474 ret = domain_add_dev_info(si_domain, pdev); 2475 + if (ret) 2476 + return 0; 2477 + ret = domain_context_mapping(si_domain, pdev, CONTEXT_TT_MULTI_LEVEL); 2530 2478 if (!ret) { 2531 2479 printk(KERN_INFO "64bit %s uses identity mapping\n", 2532 2480 pci_name(pdev)); ··· 2538 2480 } 2539 2481 } 2540 2482 2541 - return iommu_dummy(pdev); 2483 + return 0; 2542 2484 } 2543 2485 2544 2486 static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, ··· 2554 2496 2555 2497 BUG_ON(dir == DMA_NONE); 2556 2498 2557 - if (iommu_no_mapping(pdev)) 2499 + if (iommu_no_mapping(hwdev)) 2558 2500 return paddr; 2559 2501 2560 2502 domain = get_valid_domain_for_dev(pdev); ··· 2564 2506 iommu = domain_get_iommu(domain); 2565 2507 size = aligned_nrpages(paddr, size); 2566 2508 2567 - iova = intel_alloc_iova(hwdev, domain, size, pdev->dma_mask); 2509 + iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size), 2510 + pdev->dma_mask); 2568 2511 if (!iova) 2569 2512 goto error; 2570 2513 ··· 2694 2635 struct iova *iova; 2695 2636 struct intel_iommu *iommu; 2696 2637 2697 - if (iommu_no_mapping(pdev)) 2638 + if (iommu_no_mapping(dev)) 2698 2639 return; 2699 2640 2700 2641 domain = find_domain(pdev); ··· 2785 2726 struct iova *iova; 2786 2727 struct intel_iommu *iommu; 2787 2728 2788 - if (iommu_no_mapping(pdev)) 2729 + if (iommu_no_mapping(hwdev)) 2789 2730 return; 2790 2731 2791 2732 domain = find_domain(pdev); ··· 2844 2785 struct intel_iommu *iommu; 2845 2786 2846 2787 BUG_ON(dir == DMA_NONE); 2847 - if (iommu_no_mapping(pdev)) 2788 + if (iommu_no_mapping(hwdev)) 2848 2789 return intel_nontranslate_map_sg(hwdev, sglist, nelems, dir); 2849 2790 2850 2791 domain = get_valid_domain_for_dev(pdev); ··· 2856 2797 for_each_sg(sglist, sg, nelems, i) 2857 2798 size += aligned_nrpages(sg->offset, sg->length); 2858 2799 2859 - iova = intel_alloc_iova(hwdev, domain, size, pdev->dma_mask); 2800 + iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size), 2801 + pdev->dma_mask); 2860 2802 if (!iova) { 2861 2803 sglist->dma_length = 0; 2862 2804 return 0;