diff options
author | Sheng Yang <sheng@linux.intel.com> | 2009-03-18 03:33:07 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2009-03-24 05:42:54 -0400 |
commit | 9cf0669746be19a4906a6c48920060bcf54c708b (patch) | |
tree | df324dd805268695b99e2237c6913d2f938b94b1 /drivers/pci | |
parent | dbb9fd8630e95b6155aff658a2b5f80e95ca2bc6 (diff) |
intel-iommu: VT-d page table to support snooping control bit
The user can request to enable snooping control through VT-d page table.
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/intel-iommu.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 3778ab149baf..a0ba568b831c 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -164,7 +164,8 @@ static inline void context_clear_entry(struct context_entry *context) | |||
164 | * 1: writable | 164 | * 1: writable |
165 | * 2-6: reserved | 165 | * 2-6: reserved |
166 | * 7: super page | 166 | * 7: super page |
167 | * 8-11: available | 167 | * 8-10: available |
168 | * 11: snoop behavior | ||
168 | * 12-63: Host physcial address | 169 | * 12-63: Host physcial address |
169 | */ | 170 | */ |
170 | struct dma_pte { | 171 | struct dma_pte { |
@@ -186,6 +187,11 @@ static inline void dma_set_pte_writable(struct dma_pte *pte) | |||
186 | pte->val |= DMA_PTE_WRITE; | 187 | pte->val |= DMA_PTE_WRITE; |
187 | } | 188 | } |
188 | 189 | ||
190 | static inline void dma_set_pte_snp(struct dma_pte *pte) | ||
191 | { | ||
192 | pte->val |= DMA_PTE_SNP; | ||
193 | } | ||
194 | |||
189 | static inline void dma_set_pte_prot(struct dma_pte *pte, unsigned long prot) | 195 | static inline void dma_set_pte_prot(struct dma_pte *pte, unsigned long prot) |
190 | { | 196 | { |
191 | pte->val = (pte->val & ~3) | (prot & 3); | 197 | pte->val = (pte->val & ~3) | (prot & 3); |
@@ -1685,6 +1691,8 @@ domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova, | |||
1685 | BUG_ON(dma_pte_addr(pte)); | 1691 | BUG_ON(dma_pte_addr(pte)); |
1686 | dma_set_pte_addr(pte, start_pfn << VTD_PAGE_SHIFT); | 1692 | dma_set_pte_addr(pte, start_pfn << VTD_PAGE_SHIFT); |
1687 | dma_set_pte_prot(pte, prot); | 1693 | dma_set_pte_prot(pte, prot); |
1694 | if (prot & DMA_PTE_SNP) | ||
1695 | dma_set_pte_snp(pte); | ||
1688 | domain_flush_cache(domain, pte, sizeof(*pte)); | 1696 | domain_flush_cache(domain, pte, sizeof(*pte)); |
1689 | start_pfn++; | 1697 | start_pfn++; |
1690 | index++; | 1698 | index++; |
@@ -3105,6 +3113,8 @@ static int intel_iommu_map_range(struct iommu_domain *domain, | |||
3105 | prot |= DMA_PTE_READ; | 3113 | prot |= DMA_PTE_READ; |
3106 | if (iommu_prot & IOMMU_WRITE) | 3114 | if (iommu_prot & IOMMU_WRITE) |
3107 | prot |= DMA_PTE_WRITE; | 3115 | prot |= DMA_PTE_WRITE; |
3116 | if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping) | ||
3117 | prot |= DMA_PTE_SNP; | ||
3108 | 3118 | ||
3109 | max_addr = (iova & VTD_PAGE_MASK) + VTD_PAGE_ALIGN(size); | 3119 | max_addr = (iova & VTD_PAGE_MASK) + VTD_PAGE_ALIGN(size); |
3110 | if (dmar_domain->max_addr < max_addr) { | 3120 | if (dmar_domain->max_addr < max_addr) { |