]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 24 Jan 2017 07:29:47 +0000 (08:29 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 24 Jan 2017 07:29:47 +0000 (08:29 +0100)
added patches:
swiotlb-add-swiotlb-noforce-debug-option.patch
swiotlb-convert-swiotlb_force-from-int-to-enum.patch

queue-4.9/series
queue-4.9/swiotlb-add-swiotlb-noforce-debug-option.patch [new file with mode: 0644]
queue-4.9/swiotlb-convert-swiotlb_force-from-int-to-enum.patch [new file with mode: 0644]

index b34af6b9c4fb22b24becd6b205a90aad91e3fec9..7968dc4f5231ca10b7e452d2654b32e7dae0b70a 100644 (file)
@@ -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 (file)
index 0000000..8bd2ff1
--- /dev/null
@@ -0,0 +1,112 @@
+From fff5d99225107f5f13fe4a9805adc2a1c4b5fb00 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Fri, 16 Dec 2016 14:28:42 +0100
+Subject: swiotlb: Add swiotlb=noforce debug option
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+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 <geert+renesas@glider.be>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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: { <int> | force }
++                      Format: { <int> | force | noforce }
+                       <int> -- 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 (file)
index 0000000..3e32ae1
--- /dev/null
@@ -0,0 +1,184 @@
+From ae7871be189cb41184f1e05742b4a99e2c59774d Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Fri, 16 Dec 2016 14:28:41 +0100
+Subject: swiotlb: Convert swiotlb_force from int to enum
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+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 <konrad.wilk@oracle.com>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);