aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/intel-iommu.c
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2009-12-08 04:58:33 -0500
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-12-08 04:59:24 -0500
commitec208491936d6adb8a70c3dd4a517cdfe54e823d (patch)
treec7291450e8e559c5fbf3360df30999432204af3c /drivers/pci/intel-iommu.c
parentaa697079ee66315c4b9747a5eb3e48487fb1b8be (diff)
parent7b626acb8f983eb83b396ab96cc24b18d635d487 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Merge the BIOS workarounds from 2.6.32, and the swiotlb fallback on failure.
Diffstat (limited to 'drivers/pci/intel-iommu.c')
-rw-r--r--drivers/pci/intel-iommu.c45
1 files changed, 42 insertions, 3 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index c83113646223..cb5cae3e0205 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -2776,7 +2776,15 @@ static void *intel_alloc_coherent(struct device *hwdev, size_t size,
2776 2776
2777 size = PAGE_ALIGN(size); 2777 size = PAGE_ALIGN(size);
2778 order = get_order(size); 2778 order = get_order(size);
2779 flags &= ~(GFP_DMA | GFP_DMA32); 2779
2780 if (!iommu_no_mapping(hwdev))
2781 flags &= ~(GFP_DMA | GFP_DMA32);
2782 else if (hwdev->coherent_dma_mask < dma_get_required_mask(hwdev)) {
2783 if (hwdev->coherent_dma_mask < DMA_BIT_MASK(32))
2784 flags |= GFP_DMA;
2785 else
2786 flags |= GFP_DMA32;
2787 }
2780 2788
2781 vaddr = (void *)__get_free_pages(flags, order); 2789 vaddr = (void *)__get_free_pages(flags, order);
2782 if (!vaddr) 2790 if (!vaddr)
@@ -3216,6 +3224,33 @@ static int __init init_iommu_sysfs(void)
3216} 3224}
3217#endif /* CONFIG_PM */ 3225#endif /* CONFIG_PM */
3218 3226
3227/*
3228 * Here we only respond to action of unbound device from driver.
3229 *
3230 * Added device is not attached to its DMAR domain here yet. That will happen
3231 * when mapping the device to iova.
3232 */
3233static int device_notifier(struct notifier_block *nb,
3234 unsigned long action, void *data)
3235{
3236 struct device *dev = data;
3237 struct pci_dev *pdev = to_pci_dev(dev);
3238 struct dmar_domain *domain;
3239
3240 domain = find_domain(pdev);
3241 if (!domain)
3242 return 0;
3243
3244 if (action == BUS_NOTIFY_UNBOUND_DRIVER && !iommu_pass_through)
3245 domain_remove_one_dev_info(domain, pdev);
3246
3247 return 0;
3248}
3249
3250static struct notifier_block device_nb = {
3251 .notifier_call = device_notifier,
3252};
3253
3219int __init intel_iommu_init(void) 3254int __init intel_iommu_init(void)
3220{ 3255{
3221 int ret = 0; 3256 int ret = 0;
@@ -3240,7 +3275,7 @@ int __init intel_iommu_init(void)
3240 * Check the need for DMA-remapping initialization now. 3275 * Check the need for DMA-remapping initialization now.
3241 * Above initialization will also be used by Interrupt-remapping. 3276 * Above initialization will also be used by Interrupt-remapping.
3242 */ 3277 */
3243 if (no_iommu || swiotlb || dmar_disabled) 3278 if (no_iommu || dmar_disabled)
3244 return -ENODEV; 3279 return -ENODEV;
3245 3280
3246 iommu_init_mempool(); 3281 iommu_init_mempool();
@@ -3261,13 +3296,17 @@ int __init intel_iommu_init(void)
3261 "PCI-DMA: Intel(R) Virtualization Technology for Directed I/O\n"); 3296 "PCI-DMA: Intel(R) Virtualization Technology for Directed I/O\n");
3262 3297
3263 init_timer(&unmap_timer); 3298 init_timer(&unmap_timer);
3264 force_iommu = 1; 3299#ifdef CONFIG_SWIOTLB
3300 swiotlb = 0;
3301#endif
3265 dma_ops = &intel_dma_ops; 3302 dma_ops = &intel_dma_ops;
3266 3303
3267 init_iommu_sysfs(); 3304 init_iommu_sysfs();
3268 3305
3269 register_iommu(&intel_iommu_ops); 3306 register_iommu(&intel_iommu_ops);
3270 3307
3308 bus_register_notifier(&pci_bus_type, &device_nb);
3309
3271 return 0; 3310 return 0;
3272} 3311}
3273 3312