From 58dc7c1a78d37b8b8f6c2e66857231214d558a6c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 24 Jan 2017 08:29:47 +0100 Subject: [PATCH] 4.9-stable patches added patches: swiotlb-add-swiotlb-noforce-debug-option.patch swiotlb-convert-swiotlb_force-from-int-to-enum.patch --- queue-4.9/series | 2 + ...tlb-add-swiotlb-noforce-debug-option.patch | 112 +++++++++++ ...nvert-swiotlb_force-from-int-to-enum.patch | 184 ++++++++++++++++++ 3 files changed, 298 insertions(+) create mode 100644 queue-4.9/swiotlb-add-swiotlb-noforce-debug-option.patch create mode 100644 queue-4.9/swiotlb-convert-swiotlb_force-from-int-to-enum.patch diff --git a/queue-4.9/series b/queue-4.9/series index b34af6b9c4f..7968dc4f523 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -104,6 +104,8 @@ xprtrdma-make-frwr-send-queue-entry-accounting-more-accurate.patch xprtrdma-squelch-max-send-max-recv-messages-at-connect-time.patch arm64-mm-avoid-name-clash-in-__page_to_voff.patch arm64-fix-swiotlb-fallback-allocation.patch +swiotlb-convert-swiotlb_force-from-int-to-enum.patch +swiotlb-add-swiotlb-noforce-debug-option.patch scsi-ses-fix-sas-device-detection-in-enclosure.patch scsi-mpt3sas-fix-hang-on-ata-passthrough-commands.patch pm-devfreq-exynos-bus-fix-the-wrong-return-value.patch diff --git a/queue-4.9/swiotlb-add-swiotlb-noforce-debug-option.patch b/queue-4.9/swiotlb-add-swiotlb-noforce-debug-option.patch new file mode 100644 index 00000000000..8bd2ff15adf --- /dev/null +++ b/queue-4.9/swiotlb-add-swiotlb-noforce-debug-option.patch @@ -0,0 +1,112 @@ +From fff5d99225107f5f13fe4a9805adc2a1c4b5fb00 Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven +Date: Fri, 16 Dec 2016 14:28:42 +0100 +Subject: swiotlb: Add swiotlb=noforce debug option + +From: Geert Uytterhoeven + +commit fff5d99225107f5f13fe4a9805adc2a1c4b5fb00 upstream. + +On architectures like arm64, swiotlb is tied intimately to the core +architecture DMA support. In addition, ZONE_DMA cannot be disabled. + +To aid debugging and catch devices not supporting DMA to memory outside +the 32-bit address space, add a kernel command line option +"swiotlb=noforce", which disables the use of bounce buffers. +If specified, trying to map memory that cannot be used with DMA will +fail, and a rate-limited warning will be printed. + +Note that io_tlb_nslabs is set to 1, which is the minimal supported +value. + +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Konrad Rzeszutek Wilk +Signed-off-by: Greg Kroah-Hartman + +--- + Documentation/kernel-parameters.txt | 3 ++- + include/linux/swiotlb.h | 1 + + include/trace/events/swiotlb.h | 3 ++- + lib/swiotlb.c | 18 ++++++++++++++++-- + 4 files changed, 21 insertions(+), 4 deletions(-) + +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -3998,10 +3998,11 @@ bytes respectively. Such letter suffixes + it if 0 is given (See Documentation/cgroup-v1/memory.txt) + + swiotlb= [ARM,IA-64,PPC,MIPS,X86] +- Format: { | force } ++ Format: { | force | noforce } + -- Number of I/O TLB slabs + force -- force using of bounce buffers even if they + wouldn't be automatically used by the kernel ++ noforce -- Never use bounce buffers (for debugging) + + switches= [HW,M68k] + +--- a/include/linux/swiotlb.h ++++ b/include/linux/swiotlb.h +@@ -12,6 +12,7 @@ struct scatterlist; + enum swiotlb_force { + SWIOTLB_NORMAL, /* Default - depending on HW DMA mask etc. */ + SWIOTLB_FORCE, /* swiotlb=force */ ++ SWIOTLB_NO_FORCE, /* swiotlb=noforce */ + }; + + extern enum swiotlb_force swiotlb_force; +--- a/include/trace/events/swiotlb.h ++++ b/include/trace/events/swiotlb.h +@@ -39,7 +39,8 @@ TRACE_EVENT(swiotlb_bounced, + __entry->size, + __print_symbolic(__entry->swiotlb_force, + { SWIOTLB_NORMAL, "NORMAL" }, +- { SWIOTLB_FORCE, "FORCE" })) ++ { SWIOTLB_FORCE, "FORCE" }, ++ { SWIOTLB_NO_FORCE, "NO_FORCE" })) + ); + + #endif /* _TRACE_SWIOTLB_H */ +--- a/lib/swiotlb.c ++++ b/lib/swiotlb.c +@@ -106,8 +106,12 @@ setup_io_tlb_npages(char *str) + } + if (*str == ',') + ++str; +- if (!strcmp(str, "force")) ++ if (!strcmp(str, "force")) { + swiotlb_force = SWIOTLB_FORCE; ++ } else if (!strcmp(str, "noforce")) { ++ swiotlb_force = SWIOTLB_NO_FORCE; ++ io_tlb_nslabs = 1; ++ } + + return 0; + } +@@ -541,8 +545,15 @@ static phys_addr_t + map_single(struct device *hwdev, phys_addr_t phys, size_t size, + enum dma_data_direction dir) + { +- dma_addr_t start_dma_addr = phys_to_dma(hwdev, io_tlb_start); ++ dma_addr_t start_dma_addr; ++ ++ if (swiotlb_force == SWIOTLB_NO_FORCE) { ++ dev_warn_ratelimited(hwdev, "Cannot do DMA to address %pa\n", ++ &phys); ++ return SWIOTLB_MAP_ERROR; ++ } + ++ start_dma_addr = phys_to_dma(hwdev, io_tlb_start); + return swiotlb_tbl_map_single(hwdev, start_dma_addr, phys, size, dir); + } + +@@ -707,6 +718,9 @@ static void + swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir, + int do_panic) + { ++ if (swiotlb_force == SWIOTLB_NO_FORCE) ++ return; ++ + /* + * Ran out of IOMMU space for this operation. This is very bad. + * Unfortunately the drivers cannot handle this operation properly. diff --git a/queue-4.9/swiotlb-convert-swiotlb_force-from-int-to-enum.patch b/queue-4.9/swiotlb-convert-swiotlb_force-from-int-to-enum.patch new file mode 100644 index 00000000000..3e32ae1ce65 --- /dev/null +++ b/queue-4.9/swiotlb-convert-swiotlb_force-from-int-to-enum.patch @@ -0,0 +1,184 @@ +From ae7871be189cb41184f1e05742b4a99e2c59774d Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven +Date: Fri, 16 Dec 2016 14:28:41 +0100 +Subject: swiotlb: Convert swiotlb_force from int to enum + +From: Geert Uytterhoeven + +commit ae7871be189cb41184f1e05742b4a99e2c59774d upstream. + +Convert the flag swiotlb_force from an int to an enum, to prepare for +the advent of more possible values. + +Suggested-by: Konrad Rzeszutek Wilk +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Konrad Rzeszutek Wilk +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/mm/dma-mapping.c | 3 ++- + arch/arm64/mm/init.c | 3 ++- + arch/x86/kernel/pci-swiotlb.c | 2 +- + arch/x86/xen/pci-swiotlb-xen.c | 2 +- + drivers/xen/swiotlb-xen.c | 4 ++-- + include/linux/swiotlb.h | 7 ++++++- + include/trace/events/swiotlb.h | 16 +++++++++------- + lib/swiotlb.c | 8 ++++---- + 8 files changed, 27 insertions(+), 18 deletions(-) + +--- a/arch/arm64/mm/dma-mapping.c ++++ b/arch/arm64/mm/dma-mapping.c +@@ -524,7 +524,8 @@ EXPORT_SYMBOL(dummy_dma_ops); + + static int __init arm64_dma_init(void) + { +- if (swiotlb_force || max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT)) ++ if (swiotlb_force == SWIOTLB_FORCE || ++ max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT)) + swiotlb = 1; + + return atomic_pool_init(); +--- a/arch/arm64/mm/init.c ++++ b/arch/arm64/mm/init.c +@@ -401,7 +401,8 @@ static void __init free_unused_memmap(vo + */ + void __init mem_init(void) + { +- if (swiotlb_force || max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT)) ++ if (swiotlb_force == SWIOTLB_FORCE || ++ max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT)) + swiotlb_init(1); + else + swiotlb_force = SWIOTLB_NO_FORCE; +--- a/arch/x86/kernel/pci-swiotlb.c ++++ b/arch/x86/kernel/pci-swiotlb.c +@@ -70,7 +70,7 @@ int __init pci_swiotlb_detect_override(v + { + int use_swiotlb = swiotlb | swiotlb_force; + +- if (swiotlb_force) ++ if (swiotlb_force == SWIOTLB_FORCE) + swiotlb = 1; + + return use_swiotlb; +--- a/arch/x86/xen/pci-swiotlb-xen.c ++++ b/arch/x86/xen/pci-swiotlb-xen.c +@@ -49,7 +49,7 @@ int __init pci_xen_swiotlb_detect(void) + * activate this IOMMU. If running as PV privileged, activate it + * irregardless. + */ +- if ((xen_initial_domain() || swiotlb || swiotlb_force)) ++ if (xen_initial_domain() || swiotlb || swiotlb_force == SWIOTLB_FORCE) + xen_swiotlb = 1; + + /* If we are running under Xen, we MUST disable the native SWIOTLB. +--- a/drivers/xen/swiotlb-xen.c ++++ b/drivers/xen/swiotlb-xen.c +@@ -392,7 +392,7 @@ dma_addr_t xen_swiotlb_map_page(struct d + if (dma_capable(dev, dev_addr, size) && + !range_straddles_page_boundary(phys, size) && + !xen_arch_need_swiotlb(dev, phys, dev_addr) && +- !swiotlb_force) { ++ (swiotlb_force != SWIOTLB_FORCE)) { + /* we are not interested in the dma_addr returned by + * xen_dma_map_page, only in the potential cache flushes executed + * by the function. */ +@@ -549,7 +549,7 @@ xen_swiotlb_map_sg_attrs(struct device * + phys_addr_t paddr = sg_phys(sg); + dma_addr_t dev_addr = xen_phys_to_bus(paddr); + +- if (swiotlb_force || ++ if (swiotlb_force == SWIOTLB_FORCE || + xen_arch_need_swiotlb(hwdev, paddr, dev_addr) || + !dma_capable(hwdev, dev_addr, sg->length) || + range_straddles_page_boundary(paddr, sg->length)) { +--- a/include/linux/swiotlb.h ++++ b/include/linux/swiotlb.h +@@ -9,7 +9,12 @@ struct device; + struct page; + struct scatterlist; + +-extern int swiotlb_force; ++enum swiotlb_force { ++ SWIOTLB_NORMAL, /* Default - depending on HW DMA mask etc. */ ++ SWIOTLB_FORCE, /* swiotlb=force */ ++}; ++ ++extern enum swiotlb_force swiotlb_force; + + /* + * Maximum allowable number of contiguous slabs to map, +--- a/include/trace/events/swiotlb.h ++++ b/include/trace/events/swiotlb.h +@@ -11,16 +11,16 @@ TRACE_EVENT(swiotlb_bounced, + TP_PROTO(struct device *dev, + dma_addr_t dev_addr, + size_t size, +- int swiotlb_force), ++ enum swiotlb_force swiotlb_force), + + TP_ARGS(dev, dev_addr, size, swiotlb_force), + + TP_STRUCT__entry( +- __string( dev_name, dev_name(dev) ) +- __field( u64, dma_mask ) +- __field( dma_addr_t, dev_addr ) +- __field( size_t, size ) +- __field( int, swiotlb_force ) ++ __string( dev_name, dev_name(dev) ) ++ __field( u64, dma_mask ) ++ __field( dma_addr_t, dev_addr ) ++ __field( size_t, size ) ++ __field( enum swiotlb_force, swiotlb_force ) + ), + + TP_fast_assign( +@@ -37,7 +37,9 @@ TRACE_EVENT(swiotlb_bounced, + __entry->dma_mask, + (unsigned long long)__entry->dev_addr, + __entry->size, +- __entry->swiotlb_force ? "swiotlb_force" : "" ) ++ __print_symbolic(__entry->swiotlb_force, ++ { SWIOTLB_NORMAL, "NORMAL" }, ++ { SWIOTLB_FORCE, "FORCE" })) + ); + + #endif /* _TRACE_SWIOTLB_H */ +--- a/lib/swiotlb.c ++++ b/lib/swiotlb.c +@@ -53,7 +53,7 @@ + */ + #define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT) + +-int swiotlb_force; ++enum swiotlb_force swiotlb_force; + + /* + * Used to do a quick range check in swiotlb_tbl_unmap_single and +@@ -107,7 +107,7 @@ setup_io_tlb_npages(char *str) + if (*str == ',') + ++str; + if (!strcmp(str, "force")) +- swiotlb_force = 1; ++ swiotlb_force = SWIOTLB_FORCE; + + return 0; + } +@@ -749,7 +749,7 @@ dma_addr_t swiotlb_map_page(struct devic + * we can safely return the device addr and not worry about bounce + * buffering it. + */ +- if (dma_capable(dev, dev_addr, size) && !swiotlb_force) ++ if (dma_capable(dev, dev_addr, size) && swiotlb_force != SWIOTLB_FORCE) + return dev_addr; + + trace_swiotlb_bounced(dev, dev_addr, size, swiotlb_force); +@@ -888,7 +888,7 @@ swiotlb_map_sg_attrs(struct device *hwde + phys_addr_t paddr = sg_phys(sg); + dma_addr_t dev_addr = phys_to_dma(hwdev, paddr); + +- if (swiotlb_force || ++ if (swiotlb_force == SWIOTLB_FORCE || + !dma_capable(hwdev, dev_addr, sg->length)) { + phys_addr_t map = map_single(hwdev, sg_phys(sg), + sg->length, dir); -- 2.47.3