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>
This commit is contained in:
Sheng Yang 2009-03-18 15:33:07 +08:00 committed by David Woodhouse
parent dbb9fd8630
commit 9cf0669746
3 changed files with 13 additions and 1 deletions

View file

@ -164,7 +164,8 @@ static inline void context_clear_entry(struct context_entry *context)
* 1: writable * 1: writable
* 2-6: reserved * 2-6: reserved
* 7: super page * 7: super page
* 8-11: available * 8-10: available
* 11: snoop behavior
* 12-63: Host physcial address * 12-63: Host physcial address
*/ */
struct dma_pte { struct dma_pte {
@ -186,6 +187,11 @@ static inline void dma_set_pte_writable(struct dma_pte *pte)
pte->val |= DMA_PTE_WRITE; pte->val |= DMA_PTE_WRITE;
} }
static inline void dma_set_pte_snp(struct dma_pte *pte)
{
pte->val |= DMA_PTE_SNP;
}
static inline void dma_set_pte_prot(struct dma_pte *pte, unsigned long prot) static inline void dma_set_pte_prot(struct dma_pte *pte, unsigned long prot)
{ {
pte->val = (pte->val & ~3) | (prot & 3); pte->val = (pte->val & ~3) | (prot & 3);
@ -1685,6 +1691,8 @@ domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova,
BUG_ON(dma_pte_addr(pte)); BUG_ON(dma_pte_addr(pte));
dma_set_pte_addr(pte, start_pfn << VTD_PAGE_SHIFT); dma_set_pte_addr(pte, start_pfn << VTD_PAGE_SHIFT);
dma_set_pte_prot(pte, prot); dma_set_pte_prot(pte, prot);
if (prot & DMA_PTE_SNP)
dma_set_pte_snp(pte);
domain_flush_cache(domain, pte, sizeof(*pte)); domain_flush_cache(domain, pte, sizeof(*pte));
start_pfn++; start_pfn++;
index++; index++;
@ -3105,6 +3113,8 @@ static int intel_iommu_map_range(struct iommu_domain *domain,
prot |= DMA_PTE_READ; prot |= DMA_PTE_READ;
if (iommu_prot & IOMMU_WRITE) if (iommu_prot & IOMMU_WRITE)
prot |= DMA_PTE_WRITE; prot |= DMA_PTE_WRITE;
if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
prot |= DMA_PTE_SNP;
max_addr = (iova & VTD_PAGE_MASK) + VTD_PAGE_ALIGN(size); max_addr = (iova & VTD_PAGE_MASK) + VTD_PAGE_ALIGN(size);
if (dmar_domain->max_addr < max_addr) { if (dmar_domain->max_addr < max_addr) {

View file

@ -11,6 +11,7 @@
#define DMA_PTE_READ (1) #define DMA_PTE_READ (1)
#define DMA_PTE_WRITE (2) #define DMA_PTE_WRITE (2)
#define DMA_PTE_SNP (1 << 11)
struct intel_iommu; struct intel_iommu;
struct dmar_domain; struct dmar_domain;

View file

@ -21,6 +21,7 @@
#define IOMMU_READ (1) #define IOMMU_READ (1)
#define IOMMU_WRITE (2) #define IOMMU_WRITE (2)
#define IOMMU_CACHE (4) /* DMA cache coherency */
struct device; struct device;