diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2009-06-26 13:50:28 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2009-06-29 07:37:42 -0400 |
commit | b213203e475212a69ad6fedfb73464087e317148 (patch) | |
tree | f5969a292e97f50f0bd0d4b7f775641464c3add2 /drivers/pci/intel-iommu.c | |
parent | bf92df30df909710c498d05620e2df1be1ef779b (diff) |
intel-iommu: Create new iommu_domain_identity_map() function
We'll want to do this to a _domain_ (the si_domain) rather than a PCI device.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/pci/intel-iommu.c')
-rw-r--r-- | drivers/pci/intel-iommu.c | 62 |
1 files changed, 36 insertions, 26 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 3cad7006ed8e..3a4f347e2f88 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -1849,25 +1849,12 @@ error: | |||
1849 | 1849 | ||
1850 | static int iommu_identity_mapping; | 1850 | static int iommu_identity_mapping; |
1851 | 1851 | ||
1852 | static int iommu_prepare_identity_map(struct pci_dev *pdev, | 1852 | static int iommu_domain_identity_map(struct dmar_domain *domain, |
1853 | unsigned long long start, | 1853 | unsigned long long start, |
1854 | unsigned long long end) | 1854 | unsigned long long end) |
1855 | { | 1855 | { |
1856 | struct dmar_domain *domain; | ||
1857 | unsigned long size; | 1856 | unsigned long size; |
1858 | unsigned long long base; | 1857 | unsigned long long base; |
1859 | int ret; | ||
1860 | |||
1861 | printk(KERN_INFO | ||
1862 | "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n", | ||
1863 | pci_name(pdev), start, end); | ||
1864 | if (iommu_identity_mapping) | ||
1865 | domain = si_domain; | ||
1866 | else | ||
1867 | /* page table init */ | ||
1868 | domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH); | ||
1869 | if (!domain) | ||
1870 | return -ENOMEM; | ||
1871 | 1858 | ||
1872 | /* The address might not be aligned */ | 1859 | /* The address might not be aligned */ |
1873 | base = start & PAGE_MASK; | 1860 | base = start & PAGE_MASK; |
@@ -1876,31 +1863,54 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev, | |||
1876 | if (!reserve_iova(&domain->iovad, IOVA_PFN(base), | 1863 | if (!reserve_iova(&domain->iovad, IOVA_PFN(base), |
1877 | IOVA_PFN(base + size) - 1)) { | 1864 | IOVA_PFN(base + size) - 1)) { |
1878 | printk(KERN_ERR "IOMMU: reserve iova failed\n"); | 1865 | printk(KERN_ERR "IOMMU: reserve iova failed\n"); |
1879 | ret = -ENOMEM; | 1866 | return -ENOMEM; |
1880 | goto error; | ||
1881 | } | 1867 | } |
1882 | 1868 | ||
1883 | pr_debug("Mapping reserved region %lx@%llx for %s\n", | 1869 | pr_debug("Mapping reserved region %lx@%llx for domain %d\n", |
1884 | size, base, pci_name(pdev)); | 1870 | size, base, domain->id); |
1885 | /* | 1871 | /* |
1886 | * RMRR range might have overlap with physical memory range, | 1872 | * RMRR range might have overlap with physical memory range, |
1887 | * clear it first | 1873 | * clear it first |
1888 | */ | 1874 | */ |
1889 | dma_pte_clear_range(domain, base, base + size); | 1875 | dma_pte_clear_range(domain, base, base + size); |
1890 | 1876 | ||
1891 | ret = domain_page_mapping(domain, base, base, size, | 1877 | return domain_page_mapping(domain, base, base, size, |
1892 | DMA_PTE_READ|DMA_PTE_WRITE); | 1878 | DMA_PTE_READ|DMA_PTE_WRITE); |
1879 | } | ||
1880 | |||
1881 | static int iommu_prepare_identity_map(struct pci_dev *pdev, | ||
1882 | unsigned long long start, | ||
1883 | unsigned long long end) | ||
1884 | { | ||
1885 | struct dmar_domain *domain; | ||
1886 | int ret; | ||
1887 | |||
1888 | printk(KERN_INFO | ||
1889 | "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n", | ||
1890 | pci_name(pdev), start, end); | ||
1891 | |||
1892 | if (iommu_identity_mapping) | ||
1893 | domain = si_domain; | ||
1894 | else | ||
1895 | /* page table init */ | ||
1896 | domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH); | ||
1897 | if (!domain) | ||
1898 | return -ENOMEM; | ||
1899 | |||
1900 | ret = iommu_domain_identity_map(domain, start, end); | ||
1893 | if (ret) | 1901 | if (ret) |
1894 | goto error; | 1902 | goto error; |
1895 | 1903 | ||
1896 | /* context entry init */ | 1904 | /* context entry init */ |
1897 | ret = domain_context_mapping(domain, pdev, CONTEXT_TT_MULTI_LEVEL); | 1905 | ret = domain_context_mapping(domain, pdev, CONTEXT_TT_MULTI_LEVEL); |
1898 | if (!ret) | 1906 | if (ret) |
1899 | return 0; | 1907 | goto error; |
1900 | error: | 1908 | |
1909 | return 0; | ||
1910 | |||
1911 | error: | ||
1901 | domain_exit(domain); | 1912 | domain_exit(domain); |
1902 | return ret; | 1913 | return ret; |
1903 | |||
1904 | } | 1914 | } |
1905 | 1915 | ||
1906 | static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, | 1916 | static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, |