aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/amd_iommu.c7
-rw-r--r--drivers/base/iommu.c7
-rw-r--r--drivers/pci/intel-iommu.c12
-rw-r--r--include/linux/iommu.h12
4 files changed, 38 insertions, 0 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 5113c080f0c4..65c9b58655ff 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -1924,6 +1924,12 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
1924 return paddr; 1924 return paddr;
1925} 1925}
1926 1926
1927static int amd_iommu_domain_has_cap(struct iommu_domain *domain,
1928 unsigned long cap)
1929{
1930 return 0;
1931}
1932
1927static struct iommu_ops amd_iommu_ops = { 1933static struct iommu_ops amd_iommu_ops = {
1928 .domain_init = amd_iommu_domain_init, 1934 .domain_init = amd_iommu_domain_init,
1929 .domain_destroy = amd_iommu_domain_destroy, 1935 .domain_destroy = amd_iommu_domain_destroy,
@@ -1932,5 +1938,6 @@ static struct iommu_ops amd_iommu_ops = {
1932 .map = amd_iommu_map_range, 1938 .map = amd_iommu_map_range,
1933 .unmap = amd_iommu_unmap_range, 1939 .unmap = amd_iommu_unmap_range,
1934 .iova_to_phys = amd_iommu_iova_to_phys, 1940 .iova_to_phys = amd_iommu_iova_to_phys,
1941 .domain_has_cap = amd_iommu_domain_has_cap,
1935}; 1942};
1936 1943
diff --git a/drivers/base/iommu.c b/drivers/base/iommu.c
index 5e039d4f877c..c314f144825f 100644
--- a/drivers/base/iommu.c
+++ b/drivers/base/iommu.c
@@ -98,3 +98,10 @@ phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
98 return iommu_ops->iova_to_phys(domain, iova); 98 return iommu_ops->iova_to_phys(domain, iova);
99} 99}
100EXPORT_SYMBOL_GPL(iommu_iova_to_phys); 100EXPORT_SYMBOL_GPL(iommu_iova_to_phys);
101
102int iommu_domain_has_cap(struct iommu_domain *domain,
103 unsigned long cap)
104{
105 return iommu_ops->domain_has_cap(domain, cap);
106}
107EXPORT_SYMBOL_GPL(iommu_domain_has_cap);
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index be999ff025af..3778ab149baf 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -3158,6 +3158,17 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
3158 return phys; 3158 return phys;
3159} 3159}
3160 3160
3161static int intel_iommu_domain_has_cap(struct iommu_domain *domain,
3162 unsigned long cap)
3163{
3164 struct dmar_domain *dmar_domain = domain->priv;
3165
3166 if (cap == IOMMU_CAP_CACHE_COHERENCY)
3167 return dmar_domain->iommu_snooping;
3168
3169 return 0;
3170}
3171
3161static struct iommu_ops intel_iommu_ops = { 3172static struct iommu_ops intel_iommu_ops = {
3162 .domain_init = intel_iommu_domain_init, 3173 .domain_init = intel_iommu_domain_init,
3163 .domain_destroy = intel_iommu_domain_destroy, 3174 .domain_destroy = intel_iommu_domain_destroy,
@@ -3166,6 +3177,7 @@ static struct iommu_ops intel_iommu_ops = {
3166 .map = intel_iommu_map_range, 3177 .map = intel_iommu_map_range,
3167 .unmap = intel_iommu_unmap_range, 3178 .unmap = intel_iommu_unmap_range,
3168 .iova_to_phys = intel_iommu_iova_to_phys, 3179 .iova_to_phys = intel_iommu_iova_to_phys,
3180 .domain_has_cap = intel_iommu_domain_has_cap,
3169}; 3181};
3170 3182
3171static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) 3183static void __devinit quirk_iommu_rwbf(struct pci_dev *dev)
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 8a7bfb1b6ca0..0cf3a4e43f23 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -28,6 +28,8 @@ struct iommu_domain {
28 void *priv; 28 void *priv;
29}; 29};
30 30
31#define IOMMU_CAP_CACHE_COHERENCY 0x1
32
31struct iommu_ops { 33struct iommu_ops {
32 int (*domain_init)(struct iommu_domain *domain); 34 int (*domain_init)(struct iommu_domain *domain);
33 void (*domain_destroy)(struct iommu_domain *domain); 35 void (*domain_destroy)(struct iommu_domain *domain);
@@ -39,6 +41,8 @@ struct iommu_ops {
39 size_t size); 41 size_t size);
40 phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, 42 phys_addr_t (*iova_to_phys)(struct iommu_domain *domain,
41 unsigned long iova); 43 unsigned long iova);
44 int (*domain_has_cap)(struct iommu_domain *domain,
45 unsigned long cap);
42}; 46};
43 47
44#ifdef CONFIG_IOMMU_API 48#ifdef CONFIG_IOMMU_API
@@ -57,6 +61,8 @@ extern void iommu_unmap_range(struct iommu_domain *domain, unsigned long iova,
57 size_t size); 61 size_t size);
58extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, 62extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
59 unsigned long iova); 63 unsigned long iova);
64extern int iommu_domain_has_cap(struct iommu_domain *domain,
65 unsigned long cap);
60 66
61#else /* CONFIG_IOMMU_API */ 67#else /* CONFIG_IOMMU_API */
62 68
@@ -107,6 +113,12 @@ static inline phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
107 return 0; 113 return 0;
108} 114}
109 115
116static inline int domain_has_cap(struct iommu_domain *domain,
117 unsigned long cap)
118{
119 return 0;
120}
121
110#endif /* CONFIG_IOMMU_API */ 122#endif /* CONFIG_IOMMU_API */
111 123
112#endif /* __LINUX_IOMMU_H */ 124#endif /* __LINUX_IOMMU_H */