aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/intel-iommu.c
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2009-06-26 14:10:36 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-06-29 07:37:44 -0400
commitc7ab48d2acaf959e4d59c3f55d12fdb7ca9afd7c (patch)
tree5474dadf86c95ddf3b347000f5c114f154e7a0ab /drivers/pci/intel-iommu.c
parentb213203e475212a69ad6fedfb73464087e317148 (diff)
intel-iommu: Clean up identity mapping code, remove CONFIG_DMAR_GFX_WA
There's no need for the GFX workaround now we have 'iommu=pt' for the cases where people really care about performance. There's no need to have a special case for just one type of device. This also speeds up the iommu=pt path and reduces memory usage by setting up the si_domain _once_ and then using it for all devices, rather than giving each device its own private page tables. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/pci/intel-iommu.c')
-rw-r--r--drivers/pci/intel-iommu.c107
1 files changed, 32 insertions, 75 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 3a4f347e2f88..fc121967cb5b 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -1889,11 +1889,7 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev,
1889 "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n", 1889 "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
1890 pci_name(pdev), start, end); 1890 pci_name(pdev), start, end);
1891 1891
1892 if (iommu_identity_mapping) 1892 domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
1893 domain = si_domain;
1894 else
1895 /* page table init */
1896 domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
1897 if (!domain) 1893 if (!domain)
1898 return -ENOMEM; 1894 return -ENOMEM;
1899 1895
@@ -1922,64 +1918,6 @@ static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
1922 rmrr->end_address + 1); 1918 rmrr->end_address + 1);
1923} 1919}
1924 1920
1925struct iommu_prepare_data {
1926 struct pci_dev *pdev;
1927 int ret;
1928};
1929
1930static int __init iommu_prepare_work_fn(unsigned long start_pfn,
1931 unsigned long end_pfn, void *datax)
1932{
1933 struct iommu_prepare_data *data;
1934
1935 data = (struct iommu_prepare_data *)datax;
1936
1937 data->ret = iommu_prepare_identity_map(data->pdev,
1938 start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
1939 return data->ret;
1940
1941}
1942
1943static int __init iommu_prepare_with_active_regions(struct pci_dev *pdev)
1944{
1945 int nid;
1946 struct iommu_prepare_data data;
1947
1948 data.pdev = pdev;
1949 data.ret = 0;
1950
1951 for_each_online_node(nid) {
1952 work_with_active_regions(nid, iommu_prepare_work_fn, &data);
1953 if (data.ret)
1954 return data.ret;
1955 }
1956 return data.ret;
1957}
1958
1959#ifdef CONFIG_DMAR_GFX_WA
1960static void __init iommu_prepare_gfx_mapping(void)
1961{
1962 struct pci_dev *pdev = NULL;
1963 int ret;
1964
1965 for_each_pci_dev(pdev) {
1966 if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO ||
1967 !IS_GFX_DEVICE(pdev))
1968 continue;
1969 printk(KERN_INFO "IOMMU: gfx device %s 1-1 mapping\n",
1970 pci_name(pdev));
1971 ret = iommu_prepare_with_active_regions(pdev);
1972 if (ret)
1973 printk(KERN_ERR "IOMMU: mapping reserved region failed\n");
1974 }
1975}
1976#else /* !CONFIG_DMAR_GFX_WA */
1977static inline void iommu_prepare_gfx_mapping(void)
1978{
1979 return;
1980}
1981#endif
1982
1983#ifdef CONFIG_DMAR_FLOPPY_WA 1921#ifdef CONFIG_DMAR_FLOPPY_WA
1984static inline void iommu_prepare_isa(void) 1922static inline void iommu_prepare_isa(void)
1985{ 1923{
@@ -1990,12 +1928,12 @@ static inline void iommu_prepare_isa(void)
1990 if (!pdev) 1928 if (!pdev)
1991 return; 1929 return;
1992 1930
1993 printk(KERN_INFO "IOMMU: Prepare 0-16M unity mapping for LPC\n"); 1931 printk(KERN_INFO "IOMMU: Prepare 0-16MiB unity mapping for LPC\n");
1994 ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024); 1932 ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024);
1995 1933
1996 if (ret) 1934 if (ret)
1997 printk(KERN_ERR "IOMMU: Failed to create 0-64M identity map, " 1935 printk(KERN_ERR "IOMMU: Failed to create 0-16MiB identity map; "
1998 "floppy might not work\n"); 1936 "floppy might not work\n");
1999 1937
2000} 1938}
2001#else 1939#else
@@ -2023,16 +1961,30 @@ static int __init init_context_pass_through(void)
2023} 1961}
2024 1962
2025static int md_domain_init(struct dmar_domain *domain, int guest_width); 1963static int md_domain_init(struct dmar_domain *domain, int guest_width);
1964
1965static int __init si_domain_work_fn(unsigned long start_pfn,
1966 unsigned long end_pfn, void *datax)
1967{
1968 int *ret = datax;
1969
1970 *ret = iommu_domain_identity_map(si_domain,
1971 (uint64_t)start_pfn << PAGE_SHIFT,
1972 (uint64_t)end_pfn << PAGE_SHIFT);
1973 return *ret;
1974
1975}
1976
2026static int si_domain_init(void) 1977static int si_domain_init(void)
2027{ 1978{
2028 struct dmar_drhd_unit *drhd; 1979 struct dmar_drhd_unit *drhd;
2029 struct intel_iommu *iommu; 1980 struct intel_iommu *iommu;
2030 int ret = 0; 1981 int nid, ret = 0;
2031 1982
2032 si_domain = alloc_domain(); 1983 si_domain = alloc_domain();
2033 if (!si_domain) 1984 if (!si_domain)
2034 return -EFAULT; 1985 return -EFAULT;
2035 1986
1987 pr_debug("Identity mapping domain is domain %d\n", si_domain->id);
2036 1988
2037 for_each_active_iommu(iommu, drhd) { 1989 for_each_active_iommu(iommu, drhd) {
2038 ret = iommu_attach_domain(si_domain, iommu); 1990 ret = iommu_attach_domain(si_domain, iommu);
@@ -2049,6 +2001,12 @@ static int si_domain_init(void)
2049 2001
2050 si_domain->flags = DOMAIN_FLAG_STATIC_IDENTITY; 2002 si_domain->flags = DOMAIN_FLAG_STATIC_IDENTITY;
2051 2003
2004 for_each_online_node(nid) {
2005 work_with_active_regions(nid, si_domain_work_fn, &ret);
2006 if (ret)
2007 return ret;
2008 }
2009
2052 return 0; 2010 return 0;
2053} 2011}
2054 2012
@@ -2102,13 +2060,14 @@ static int iommu_prepare_static_identity_mapping(void)
2102 if (ret) 2060 if (ret)
2103 return -EFAULT; 2061 return -EFAULT;
2104 2062
2105 printk(KERN_INFO "IOMMU: Setting identity map:\n");
2106 for_each_pci_dev(pdev) { 2063 for_each_pci_dev(pdev) {
2107 ret = iommu_prepare_with_active_regions(pdev); 2064 printk(KERN_INFO "IOMMU: identity mapping for device %s\n",
2108 if (ret) { 2065 pci_name(pdev));
2109 printk(KERN_INFO "1:1 mapping to one domain failed.\n"); 2066
2110 return -EFAULT; 2067 ret = domain_context_mapping(si_domain, pdev,
2111 } 2068 CONTEXT_TT_MULTI_LEVEL);
2069 if (ret)
2070 return ret;
2112 ret = domain_add_dev_info(si_domain, pdev); 2071 ret = domain_add_dev_info(si_domain, pdev);
2113 if (ret) 2072 if (ret)
2114 return ret; 2073 return ret;
@@ -2299,8 +2258,6 @@ int __init init_dmars(void)
2299 } 2258 }
2300 } 2259 }
2301 2260
2302 iommu_prepare_gfx_mapping();
2303
2304 iommu_prepare_isa(); 2261 iommu_prepare_isa();
2305 } 2262 }
2306 2263