]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
intel-iommu: VT-d page table to support snooping control bit
authorSheng Yang <sheng@linux.intel.com>
Wed, 18 Mar 2009 07:33:07 +0000 (15:33 +0800)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Tue, 24 Mar 2009 09:42:54 +0000 (09:42 +0000)
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>
drivers/pci/intel-iommu.c
include/linux/dma_remapping.h
include/linux/iommu.h

index 3778ab149baf3394fd9fa73356fedf3b17c4f123..a0ba568b831c318d2216c29b744211bc54e56cfd 100644 (file)
@@ -164,7 +164,8 @@ static inline void context_clear_entry(struct context_entry *context)
  * 1: writable
  * 2-6: reserved
  * 7: super page
- * 8-11: available
+ * 8-10: available
+ * 11: snoop behavior
  * 12-63: Host physcial address
  */
 struct dma_pte {
@@ -186,6 +187,11 @@ static inline void dma_set_pte_writable(struct dma_pte *pte)
        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)
 {
        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));
                dma_set_pte_addr(pte, start_pfn << VTD_PAGE_SHIFT);
                dma_set_pte_prot(pte, prot);
+               if (prot & DMA_PTE_SNP)
+                       dma_set_pte_snp(pte);
                domain_flush_cache(domain, pte, sizeof(*pte));
                start_pfn++;
                index++;
@@ -3105,6 +3113,8 @@ static int intel_iommu_map_range(struct iommu_domain *domain,
                prot |= DMA_PTE_READ;
        if (iommu_prot & IOMMU_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);
        if (dmar_domain->max_addr < max_addr) {
index af1dab41674bfdf3ceacbf49c6aca7ec24cd606d..1a455f1f86d763da366f178852e7adb652bc86ce 100644 (file)
@@ -11,6 +11,7 @@
 
 #define DMA_PTE_READ (1)
 #define DMA_PTE_WRITE (2)
+#define DMA_PTE_SNP (1 << 11)
 
 struct intel_iommu;
 struct dmar_domain;
index 0cf3a4e43f238e85117365dfa7a7f7c7f5b26ae0..3af4ffd591b978c4f7f815a5952131a0b673aa13 100644 (file)
@@ -21,6 +21,7 @@
 
 #define IOMMU_READ     (1)
 #define IOMMU_WRITE    (2)
+#define IOMMU_CACHE    (4) /* DMA cache coherency */
 
 struct device;