aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2009-05-10 14:58:49 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-05-10 14:58:49 -0400
commit1f0ef2aa18802a8ce7eb5a5164aaaf4d59073801 (patch)
tree953fd29f1853b0773e9dcd72ab1ecb3231c6b457
parent4c25a2c1b90bf785fc2e2f0f0c74a80b3e070d39 (diff)
intel-iommu: Clean up handling of "caching mode" vs. IOTLB flushing.
As we just did for context cache flushing, clean up the logic around whether we need to flush the iotlb or just the write-buffer, depending on caching mode. Fix the same bug in qi_flush_iotlb() that qi_flush_context() had -- it isn't supposed to be returning an error; it's supposed to be returning a flag which triggers a write-buffer flush. Remove some superfluous conditional write-buffer flushes which could never have happened because they weren't for non-present-to-present mapping changes anyway. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
-rw-r--r--drivers/pci/dmar.c14
-rw-r--r--drivers/pci/intel-iommu.c78
-rw-r--r--include/linux/intel-iommu.h9
3 files changed, 37 insertions, 64 deletions
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 10a071ba3232..df6af0d4ec03 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -735,22 +735,14 @@ void qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm,
735 qi_submit_sync(&desc, iommu); 735 qi_submit_sync(&desc, iommu);
736} 736}
737 737
738int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, 738void qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
739 unsigned int size_order, u64 type, 739 unsigned int size_order, u64 type)
740 int non_present_entry_flush)
741{ 740{
742 u8 dw = 0, dr = 0; 741 u8 dw = 0, dr = 0;
743 742
744 struct qi_desc desc; 743 struct qi_desc desc;
745 int ih = 0; 744 int ih = 0;
746 745
747 if (non_present_entry_flush) {
748 if (!cap_caching_mode(iommu->cap))
749 return 1;
750 else
751 did = 0;
752 }
753
754 if (cap_write_drain(iommu->cap)) 746 if (cap_write_drain(iommu->cap))
755 dw = 1; 747 dw = 1;
756 748
@@ -762,7 +754,7 @@ int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
762 desc.high = QI_IOTLB_ADDR(addr) | QI_IOTLB_IH(ih) 754 desc.high = QI_IOTLB_ADDR(addr) | QI_IOTLB_IH(ih)
763 | QI_IOTLB_AM(size_order); 755 | QI_IOTLB_AM(size_order);
764 756
765 return qi_submit_sync(&desc, iommu); 757 qi_submit_sync(&desc, iommu);
766} 758}
767 759
768/* 760/*
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 9f5d9151edc9..f47d04aced87 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -891,27 +891,13 @@ static void __iommu_flush_context(struct intel_iommu *iommu,
891} 891}
892 892
893/* return value determine if we need a write buffer flush */ 893/* return value determine if we need a write buffer flush */
894static int __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did, 894static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
895 u64 addr, unsigned int size_order, u64 type, 895 u64 addr, unsigned int size_order, u64 type)
896 int non_present_entry_flush)
897{ 896{
898 int tlb_offset = ecap_iotlb_offset(iommu->ecap); 897 int tlb_offset = ecap_iotlb_offset(iommu->ecap);
899 u64 val = 0, val_iva = 0; 898 u64 val = 0, val_iva = 0;
900 unsigned long flag; 899 unsigned long flag;
901 900
902 /*
903 * In the non-present entry flush case, if hardware doesn't cache
904 * non-present entry we do nothing and if hardware cache non-present
905 * entry, we flush entries of domain 0 (the domain id is used to cache
906 * any non-present entries)
907 */
908 if (non_present_entry_flush) {
909 if (!cap_caching_mode(iommu->cap))
910 return 1;
911 else
912 did = 0;
913 }
914
915 switch (type) { 901 switch (type) {
916 case DMA_TLB_GLOBAL_FLUSH: 902 case DMA_TLB_GLOBAL_FLUSH:
917 /* global flush doesn't need set IVA_REG */ 903 /* global flush doesn't need set IVA_REG */
@@ -959,12 +945,10 @@ static int __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
959 pr_debug("IOMMU: tlb flush request %Lx, actual %Lx\n", 945 pr_debug("IOMMU: tlb flush request %Lx, actual %Lx\n",
960 (unsigned long long)DMA_TLB_IIRG(type), 946 (unsigned long long)DMA_TLB_IIRG(type),
961 (unsigned long long)DMA_TLB_IAIG(val)); 947 (unsigned long long)DMA_TLB_IAIG(val));
962 /* flush iotlb entry will implicitly flush write buffer */
963 return 0;
964} 948}
965 949
966static int iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did, 950static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did,
967 u64 addr, unsigned int pages, int non_present_entry_flush) 951 u64 addr, unsigned int pages)
968{ 952{
969 unsigned int mask; 953 unsigned int mask;
970 954
@@ -974,8 +958,7 @@ static int iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did,
974 /* Fallback to domain selective flush if no PSI support */ 958 /* Fallback to domain selective flush if no PSI support */
975 if (!cap_pgsel_inv(iommu->cap)) 959 if (!cap_pgsel_inv(iommu->cap))
976 return iommu->flush.flush_iotlb(iommu, did, 0, 0, 960 return iommu->flush.flush_iotlb(iommu, did, 0, 0,
977 DMA_TLB_DSI_FLUSH, 961 DMA_TLB_DSI_FLUSH);
978 non_present_entry_flush);
979 962
980 /* 963 /*
981 * PSI requires page size to be 2 ^ x, and the base address is naturally 964 * PSI requires page size to be 2 ^ x, and the base address is naturally
@@ -985,11 +968,10 @@ static int iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did,
985 /* Fallback to domain selective flush if size is too big */ 968 /* Fallback to domain selective flush if size is too big */
986 if (mask > cap_max_amask_val(iommu->cap)) 969 if (mask > cap_max_amask_val(iommu->cap))
987 return iommu->flush.flush_iotlb(iommu, did, 0, 0, 970 return iommu->flush.flush_iotlb(iommu, did, 0, 0,
988 DMA_TLB_DSI_FLUSH, non_present_entry_flush); 971 DMA_TLB_DSI_FLUSH);
989 972
990 return iommu->flush.flush_iotlb(iommu, did, addr, mask, 973 return iommu->flush.flush_iotlb(iommu, did, addr, mask,
991 DMA_TLB_PSI_FLUSH, 974 DMA_TLB_PSI_FLUSH);
992 non_present_entry_flush);
993} 975}
994 976
995static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu) 977static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
@@ -1423,7 +1405,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment,
1423 (((u16)bus) << 8) | devfn, 1405 (((u16)bus) << 8) | devfn,
1424 DMA_CCMD_MASK_NOBIT, 1406 DMA_CCMD_MASK_NOBIT,
1425 DMA_CCMD_DEVICE_INVL); 1407 DMA_CCMD_DEVICE_INVL);
1426 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_DSI_FLUSH, 0); 1408 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_DSI_FLUSH);
1427 } else { 1409 } else {
1428 iommu_flush_write_buffer(iommu); 1410 iommu_flush_write_buffer(iommu);
1429 } 1411 }
@@ -1558,8 +1540,7 @@ static void iommu_detach_dev(struct intel_iommu *iommu, u8 bus, u8 devfn)
1558 clear_context_table(iommu, bus, devfn); 1540 clear_context_table(iommu, bus, devfn);
1559 iommu->flush.flush_context(iommu, 0, 0, 0, 1541 iommu->flush.flush_context(iommu, 0, 0, 0,
1560 DMA_CCMD_GLOBAL_INVL); 1542 DMA_CCMD_GLOBAL_INVL);
1561 iommu->flush.flush_iotlb(iommu, 0, 0, 0, 1543 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
1562 DMA_TLB_GLOBAL_FLUSH, 0);
1563} 1544}
1564 1545
1565static void domain_remove_dev_info(struct dmar_domain *domain) 1546static void domain_remove_dev_info(struct dmar_domain *domain)
@@ -2096,8 +2077,7 @@ static int __init init_dmars(void)
2096 iommu_set_root_entry(iommu); 2077 iommu_set_root_entry(iommu);
2097 2078
2098 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL); 2079 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
2099 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH, 2080 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
2100 0);
2101 iommu_disable_protect_mem_regions(iommu); 2081 iommu_disable_protect_mem_regions(iommu);
2102 2082
2103 ret = iommu_enable_translation(iommu); 2083 ret = iommu_enable_translation(iommu);
@@ -2244,10 +2224,11 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr,
2244 if (ret) 2224 if (ret)
2245 goto error; 2225 goto error;
2246 2226
2247 /* it's a non-present to present mapping */ 2227 /* it's a non-present to present mapping. Only flush if caching mode */
2248 ret = iommu_flush_iotlb_psi(iommu, domain->id, 2228 if (cap_caching_mode(iommu->cap))
2249 start_paddr, size >> VTD_PAGE_SHIFT, 1); 2229 iommu_flush_iotlb_psi(iommu, 0, start_paddr,
2250 if (ret) 2230 size >> VTD_PAGE_SHIFT);
2231 else
2251 iommu_flush_write_buffer(iommu); 2232 iommu_flush_write_buffer(iommu);
2252 2233
2253 return start_paddr + ((u64)paddr & (~PAGE_MASK)); 2234 return start_paddr + ((u64)paddr & (~PAGE_MASK));
@@ -2283,7 +2264,7 @@ static void flush_unmaps(void)
2283 2264
2284 if (deferred_flush[i].next) { 2265 if (deferred_flush[i].next) {
2285 iommu->flush.flush_iotlb(iommu, 0, 0, 0, 2266 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
2286 DMA_TLB_GLOBAL_FLUSH, 0); 2267 DMA_TLB_GLOBAL_FLUSH);
2287 for (j = 0; j < deferred_flush[i].next; j++) { 2268 for (j = 0; j < deferred_flush[i].next; j++) {
2288 __free_iova(&deferred_flush[i].domain[j]->iovad, 2269 __free_iova(&deferred_flush[i].domain[j]->iovad,
2289 deferred_flush[i].iova[j]); 2270 deferred_flush[i].iova[j]);
@@ -2362,9 +2343,8 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
2362 /* free page tables */ 2343 /* free page tables */
2363 dma_pte_free_pagetable(domain, start_addr, start_addr + size); 2344 dma_pte_free_pagetable(domain, start_addr, start_addr + size);
2364 if (intel_iommu_strict) { 2345 if (intel_iommu_strict) {
2365 if (iommu_flush_iotlb_psi(iommu, 2346 iommu_flush_iotlb_psi(iommu, domain->id, start_addr,
2366 domain->id, start_addr, size >> VTD_PAGE_SHIFT, 0)) 2347 size >> VTD_PAGE_SHIFT);
2367 iommu_flush_write_buffer(iommu);
2368 /* free iova */ 2348 /* free iova */
2369 __free_iova(&domain->iovad, iova); 2349 __free_iova(&domain->iovad, iova);
2370 } else { 2350 } else {
@@ -2455,9 +2435,8 @@ static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
2455 /* free page tables */ 2435 /* free page tables */
2456 dma_pte_free_pagetable(domain, start_addr, start_addr + size); 2436 dma_pte_free_pagetable(domain, start_addr, start_addr + size);
2457 2437
2458 if (iommu_flush_iotlb_psi(iommu, domain->id, start_addr, 2438 iommu_flush_iotlb_psi(iommu, domain->id, start_addr,
2459 size >> VTD_PAGE_SHIFT, 0)) 2439 size >> VTD_PAGE_SHIFT);
2460 iommu_flush_write_buffer(iommu);
2461 2440
2462 /* free iova */ 2441 /* free iova */
2463 __free_iova(&domain->iovad, iova); 2442 __free_iova(&domain->iovad, iova);
@@ -2549,10 +2528,13 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne
2549 offset += size; 2528 offset += size;
2550 } 2529 }
2551 2530
2552 /* it's a non-present to present mapping */ 2531 /* it's a non-present to present mapping. Only flush if caching mode */
2553 if (iommu_flush_iotlb_psi(iommu, domain->id, 2532 if (cap_caching_mode(iommu->cap))
2554 start_addr, offset >> VTD_PAGE_SHIFT, 1)) 2533 iommu_flush_iotlb_psi(iommu, 0, start_addr,
2534 offset >> VTD_PAGE_SHIFT);
2535 else
2555 iommu_flush_write_buffer(iommu); 2536 iommu_flush_write_buffer(iommu);
2537
2556 return nelems; 2538 return nelems;
2557} 2539}
2558 2540
@@ -2711,9 +2693,9 @@ static int init_iommu_hw(void)
2711 iommu_set_root_entry(iommu); 2693 iommu_set_root_entry(iommu);
2712 2694
2713 iommu->flush.flush_context(iommu, 0, 0, 0, 2695 iommu->flush.flush_context(iommu, 0, 0, 0,
2714 DMA_CCMD_GLOBAL_INVL); 2696 DMA_CCMD_GLOBAL_INVL);
2715 iommu->flush.flush_iotlb(iommu, 0, 0, 0, 2697 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
2716 DMA_TLB_GLOBAL_FLUSH, 0); 2698 DMA_TLB_GLOBAL_FLUSH);
2717 iommu_disable_protect_mem_regions(iommu); 2699 iommu_disable_protect_mem_regions(iommu);
2718 iommu_enable_translation(iommu); 2700 iommu_enable_translation(iommu);
2719 } 2701 }
@@ -2728,9 +2710,9 @@ static void iommu_flush_all(void)
2728 2710
2729 for_each_active_iommu(iommu, drhd) { 2711 for_each_active_iommu(iommu, drhd) {
2730 iommu->flush.flush_context(iommu, 0, 0, 0, 2712 iommu->flush.flush_context(iommu, 0, 0, 0,
2731 DMA_CCMD_GLOBAL_INVL); 2713 DMA_CCMD_GLOBAL_INVL);
2732 iommu->flush.flush_iotlb(iommu, 0, 0, 0, 2714 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
2733 DMA_TLB_GLOBAL_FLUSH, 0); 2715 DMA_TLB_GLOBAL_FLUSH);
2734 } 2716 }
2735} 2717}
2736 2718
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index f2b94dafbf38..29e05a034c09 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -283,8 +283,8 @@ struct ir_table {
283struct iommu_flush { 283struct iommu_flush {
284 void (*flush_context)(struct intel_iommu *iommu, u16 did, u16 sid, 284 void (*flush_context)(struct intel_iommu *iommu, u16 did, u16 sid,
285 u8 fm, u64 type); 285 u8 fm, u64 type);
286 int (*flush_iotlb)(struct intel_iommu *iommu, u16 did, u64 addr, 286 void (*flush_iotlb)(struct intel_iommu *iommu, u16 did, u64 addr,
287 unsigned int size_order, u64 type, int non_present_entry_flush); 287 unsigned int size_order, u64 type);
288}; 288};
289 289
290enum { 290enum {
@@ -341,9 +341,8 @@ extern void qi_global_iec(struct intel_iommu *iommu);
341 341
342extern void qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, 342extern void qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid,
343 u8 fm, u64 type); 343 u8 fm, u64 type);
344extern int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, 344extern void qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
345 unsigned int size_order, u64 type, 345 unsigned int size_order, u64 type);
346 int non_present_entry_flush);
347 346
348extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu); 347extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu);
349 348