diff options
-rw-r--r-- | drivers/pci/dmar.c | 14 | ||||
-rw-r--r-- | drivers/pci/intel-iommu.c | 78 | ||||
-rw-r--r-- | include/linux/intel-iommu.h | 9 |
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 | ||
738 | int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, | 738 | void 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 */ |
894 | static int __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did, | 894 | static 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 | ||
966 | static int iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did, | 950 | static 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 | ||
995 | static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu) | 977 | static 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 | ||
1565 | static void domain_remove_dev_info(struct dmar_domain *domain) | 1546 | static 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 { | |||
283 | struct iommu_flush { | 283 | struct 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 | ||
290 | enum { | 290 | enum { |
@@ -341,9 +341,8 @@ extern void qi_global_iec(struct intel_iommu *iommu); | |||
341 | 341 | ||
342 | extern void qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, | 342 | extern void qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, |
343 | u8 fm, u64 type); | 343 | u8 fm, u64 type); |
344 | extern int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, | 344 | extern 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 | ||
348 | extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu); | 347 | extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu); |
349 | 348 | ||