intel-iommu: Restore DMAR_BROKEN_GFX_WA option for broken graphics drivers
authorDavid Woodhouse <David.Woodhouse@intel.com>
Sat, 4 Jul 2009 09:59:46 +0000 (10:59 +0100)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Sat, 4 Jul 2009 09:59:46 +0000 (10:59 +0100)
We need to give people a little more time to fix the broken drivers.
Re-introduce this, but tied in properly with the 'iommu=pt' support this
time. Change the config option name and make it default to 'no' too.

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
arch/x86/Kconfig
drivers/pci/intel-iommu.c

index c07f722059094567ef61ceedda182a6de01bdfae..738bdc6b0f8b8dcd938eddefa79beb4ed77e16f2 100644 (file)
@@ -1913,6 +1913,18 @@ config DMAR_DEFAULT_ON
          recommended you say N here while the DMAR code remains
          experimental.
 
+config DMAR_BROKEN_GFX_WA
+       def_bool n
+       prompt "Workaround broken graphics drivers (going away soon)"
+       depends on DMAR
+       ---help---
+         Current Graphics drivers tend to use physical address
+         for DMA and avoid using DMA APIs. Setting this config
+         option permits the IOMMU driver to set a unity map for
+         all the OS-visible memory. Hence the driver can continue
+         to use physical addresses for DMA, at least until this
+         option is removed in the 2.6.32 kernel.
+
 config DMAR_FLOPPY_WA
        def_bool y
        depends on DMAR
index ae5ccdf8b19f1b9985d760f92ef7967193a6b2d6..5ee8305257eafb447fe7b6c539acaa6cbeb192ba 100644 (file)
@@ -2127,16 +2127,18 @@ static int iommu_prepare_static_identity_mapping(void)
                return -EFAULT;
 
        for_each_pci_dev(pdev) {
-               printk(KERN_INFO "IOMMU: identity mapping for device %s\n",
-                      pci_name(pdev));
+               if (iommu_identity_mapping == 1 || IS_GFX_DEVICE(pdev)) {
+                       printk(KERN_INFO "IOMMU: identity mapping for device %s\n",
+                              pci_name(pdev));
 
-               ret = domain_context_mapping(si_domain, pdev,
-                                            CONTEXT_TT_MULTI_LEVEL);
-               if (ret)
-                       return ret;
-               ret = domain_add_dev_info(si_domain, pdev);
-               if (ret)
-                       return ret;
+                       ret = domain_context_mapping(si_domain, pdev,
+                                                    CONTEXT_TT_MULTI_LEVEL);
+                       if (ret)
+                               return ret;
+                       ret = domain_add_dev_info(si_domain, pdev);
+                       if (ret)
+                               return ret;
+               }
        }
 
        return 0;
@@ -2291,6 +2293,10 @@ int __init init_dmars(void)
         * identity mapping if iommu_identity_mapping is set.
         */
        if (!iommu_pass_through) {
+#ifdef CONFIG_DMAR_BROKEN_GFX_WA
+               if (!iommu_identity_mapping)
+                       iommu_identity_mapping = 2;
+#endif
                if (iommu_identity_mapping)
                        iommu_prepare_static_identity_mapping();
                /*
@@ -2444,7 +2450,10 @@ static int iommu_dummy(struct pci_dev *pdev)
 
 static int iommu_should_identity_map(struct pci_dev *pdev)
 {
-       return pdev->dma_mask > DMA_BIT_MASK(32);
+       if (iommu_identity_mapping == 2)
+               return IS_GFX_DEVICE(pdev);
+       else
+               return pdev->dma_mask > DMA_BIT_MASK(32);
 }
 
 /* Check if the pdev needs to go through non-identity map and unmap process.*/