]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.13-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 11 Feb 2025 10:32:13 +0000 (11:32 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 11 Feb 2025 10:32:13 +0000 (11:32 +0100)
added patches:
mips-ftrace-declare-ftrace_get_parent_ra_addr-as-static.patch
s390-fpu-add-fpc-exception-handler-remove-fixup-section-again.patch
spi-atmel-qspi-memory-barriers-after-memory-mapped-i-o.patch
spi-atmel-quadspi-create-atmel_qspi_ops-to-support-newer-soc-families.patch

queue-6.13/mips-ftrace-declare-ftrace_get_parent_ra_addr-as-static.patch [new file with mode: 0644]
queue-6.13/s390-fpu-add-fpc-exception-handler-remove-fixup-section-again.patch [new file with mode: 0644]
queue-6.13/series
queue-6.13/spi-atmel-qspi-memory-barriers-after-memory-mapped-i-o.patch [new file with mode: 0644]
queue-6.13/spi-atmel-quadspi-create-atmel_qspi_ops-to-support-newer-soc-families.patch [new file with mode: 0644]

diff --git a/queue-6.13/mips-ftrace-declare-ftrace_get_parent_ra_addr-as-static.patch b/queue-6.13/mips-ftrace-declare-ftrace_get_parent_ra_addr-as-static.patch
new file mode 100644 (file)
index 0000000..33aeb3e
--- /dev/null
@@ -0,0 +1,47 @@
+From ddd068d81445b17ac0bed084dfeb9e58b4df3ddd Mon Sep 17 00:00:00 2001
+From: WangYuli <wangyuli@uniontech.com>
+Date: Sat, 4 Jan 2025 22:47:08 +0800
+Subject: MIPS: ftrace: Declare ftrace_get_parent_ra_addr() as static
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: WangYuli <wangyuli@uniontech.com>
+
+commit ddd068d81445b17ac0bed084dfeb9e58b4df3ddd upstream.
+
+Declare ftrace_get_parent_ra_addr() as static to suppress clang
+compiler warning that 'no previous prototype'. This function is
+not intended to be called from other parts.
+
+Fix follow error with clang-19:
+
+arch/mips/kernel/ftrace.c:251:15: error: no previous prototype for function 'ftrace_get_parent_ra_addr' [-Werror,-Wmissing-prototypes]
+  251 | unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long
+      |               ^
+arch/mips/kernel/ftrace.c:251:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
+  251 | unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long
+      | ^
+      | static
+1 error generated.
+
+Signed-off-by: WangYuli <wangyuli@uniontech.com>
+Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/mips/kernel/ftrace.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/mips/kernel/ftrace.c
++++ b/arch/mips/kernel/ftrace.c
+@@ -248,7 +248,7 @@ int ftrace_disable_ftrace_graph_caller(v
+ #define S_R_SP        (0xafb0 << 16)  /* s{d,w} R, offset(sp) */
+ #define OFFSET_MASK   0xffff  /* stack offset range: 0 ~ PT_SIZE */
+-unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long
++static unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long
+               old_parent_ra, unsigned long parent_ra_addr, unsigned long fp)
+ {
+       unsigned long sp, ip, tmp;
diff --git a/queue-6.13/s390-fpu-add-fpc-exception-handler-remove-fixup-section-again.patch b/queue-6.13/s390-fpu-add-fpc-exception-handler-remove-fixup-section-again.patch
new file mode 100644 (file)
index 0000000..4bda544
--- /dev/null
@@ -0,0 +1,115 @@
+From ae02615b7fcea9ce9a4ec40b3c5b5dafd322b179 Mon Sep 17 00:00:00 2001
+From: Heiko Carstens <hca@linux.ibm.com>
+Date: Fri, 10 Jan 2025 11:52:17 +0100
+Subject: s390/fpu: Add fpc exception handler / remove fixup section again
+
+From: Heiko Carstens <hca@linux.ibm.com>
+
+commit ae02615b7fcea9ce9a4ec40b3c5b5dafd322b179 upstream.
+
+The fixup section was added again by mistake when test_fp_ctl() was
+removed. The reason for the removal of the fixup section is described in
+commit 484a8ed8b7d1 ("s390/extable: add dedicated uaccess handler").
+Remove it again for the same reason.
+
+Add an exception handler which handles exceptions when the floating point
+control register is attempted to be set to invalid values. The exception
+handler sets the floating point control register to zero and continues
+execution at the specified address.
+
+The new sfpc inline assembly is open-coded to make back porting a bit
+easier.
+
+Fixes: 702644249d3e ("s390/fpu: get rid of test_fp_ctl()")
+Cc: stable@vger.kernel.org
+Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/include/asm/asm-extable.h |    4 ++++
+ arch/s390/include/asm/fpu-insn.h    |   17 +++++------------
+ arch/s390/kernel/vmlinux.lds.S      |    1 -
+ arch/s390/mm/extable.c              |    9 +++++++++
+ 4 files changed, 18 insertions(+), 13 deletions(-)
+
+--- a/arch/s390/include/asm/asm-extable.h
++++ b/arch/s390/include/asm/asm-extable.h
+@@ -14,6 +14,7 @@
+ #define EX_TYPE_UA_LOAD_REG   5
+ #define EX_TYPE_UA_LOAD_REGPAIR       6
+ #define EX_TYPE_ZEROPAD               7
++#define EX_TYPE_FPC           8
+ #define EX_DATA_REG_ERR_SHIFT 0
+ #define EX_DATA_REG_ERR               GENMASK(3, 0)
+@@ -84,4 +85,7 @@
+ #define EX_TABLE_ZEROPAD(_fault, _target, _regdata, _regaddr)         \
+       __EX_TABLE(__ex_table, _fault, _target, EX_TYPE_ZEROPAD, _regdata, _regaddr, 0)
++#define EX_TABLE_FPC(_fault, _target)                                 \
++      __EX_TABLE(__ex_table, _fault, _target, EX_TYPE_FPC, __stringify(%%r0), __stringify(%%r0), 0)
++
+ #endif /* __ASM_EXTABLE_H */
+--- a/arch/s390/include/asm/fpu-insn.h
++++ b/arch/s390/include/asm/fpu-insn.h
+@@ -100,19 +100,12 @@ static __always_inline void fpu_lfpc(uns
+  */
+ static inline void fpu_lfpc_safe(unsigned int *fpc)
+ {
+-      u32 tmp;
+-
+       instrument_read(fpc, sizeof(*fpc));
+-      asm volatile("\n"
+-              "0:     lfpc    %[fpc]\n"
+-              "1:     nopr    %%r7\n"
+-              ".pushsection .fixup, \"ax\"\n"
+-              "2:     lghi    %[tmp],0\n"
+-              "       sfpc    %[tmp]\n"
+-              "       jg      1b\n"
+-              ".popsection\n"
+-              EX_TABLE(1b, 2b)
+-              : [tmp] "=d" (tmp)
++      asm_inline volatile(
++              "       lfpc    %[fpc]\n"
++              "0:     nopr    %%r7\n"
++              EX_TABLE_FPC(0b, 0b)
++              :
+               : [fpc] "Q" (*fpc)
+               : "memory");
+ }
+--- a/arch/s390/kernel/vmlinux.lds.S
++++ b/arch/s390/kernel/vmlinux.lds.S
+@@ -52,7 +52,6 @@ SECTIONS
+               SOFTIRQENTRY_TEXT
+               FTRACE_HOTPATCH_TRAMPOLINES_TEXT
+               *(.text.*_indirect_*)
+-              *(.fixup)
+               *(.gnu.warning)
+               . = ALIGN(PAGE_SIZE);
+               _etext = .;             /* End of text section */
+--- a/arch/s390/mm/extable.c
++++ b/arch/s390/mm/extable.c
+@@ -77,6 +77,13 @@ static bool ex_handler_zeropad(const str
+       return true;
+ }
++static bool ex_handler_fpc(const struct exception_table_entry *ex, struct pt_regs *regs)
++{
++      asm volatile("sfpc      %[val]\n" : : [val] "d" (0));
++      regs->psw.addr = extable_fixup(ex);
++      return true;
++}
++
+ bool fixup_exception(struct pt_regs *regs)
+ {
+       const struct exception_table_entry *ex;
+@@ -99,6 +106,8 @@ bool fixup_exception(struct pt_regs *reg
+               return ex_handler_ua_load_reg(ex, true, regs);
+       case EX_TYPE_ZEROPAD:
+               return ex_handler_zeropad(ex, regs);
++      case EX_TYPE_FPC:
++              return ex_handler_fpc(ex, regs);
+       }
+       panic("invalid exception table entry");
+ }
index 86644f5105abcaca66f829271ba56f75a9e06d2c..10135730a51b23697d1fbbcdc3e86e8ed6d804f0 100644 (file)
@@ -430,3 +430,7 @@ rdma-mlx5-fix-a-race-for-an-odp-mr-which-leads-to-cqe-with-error.patch
 rtc-zynqmp-fix-optional-clock-name-property.patch
 statmount-let-unset-strings-be-empty.patch
 timers-migration-fix-off-by-one-root-mis-connection.patch
+s390-fpu-add-fpc-exception-handler-remove-fixup-section-again.patch
+mips-ftrace-declare-ftrace_get_parent_ra_addr-as-static.patch
+spi-atmel-quadspi-create-atmel_qspi_ops-to-support-newer-soc-families.patch
+spi-atmel-qspi-memory-barriers-after-memory-mapped-i-o.patch
diff --git a/queue-6.13/spi-atmel-qspi-memory-barriers-after-memory-mapped-i-o.patch b/queue-6.13/spi-atmel-qspi-memory-barriers-after-memory-mapped-i-o.patch
new file mode 100644 (file)
index 0000000..32f79ab
--- /dev/null
@@ -0,0 +1,90 @@
+From be92ab2de0ee1a13291c3b47b2d7eb24d80c0a2c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bence=20Cs=C3=B3k=C3=A1s?= <csokas.bence@prolan.hu>
+Date: Thu, 19 Dec 2024 10:12:58 +0100
+Subject: spi: atmel-qspi: Memory barriers after memory-mapped I/O
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Bence Csókás <csokas.bence@prolan.hu>
+
+commit be92ab2de0ee1a13291c3b47b2d7eb24d80c0a2c upstream.
+
+The QSPI peripheral control and status registers are
+accessible via the SoC's APB bus, whereas MMIO transactions'
+data travels on the AHB bus.
+
+Microchip documentation and even sample code from Atmel
+emphasises the need for a memory barrier before the first
+MMIO transaction to the AHB-connected QSPI, and before the
+last write to its registers via APB. This is achieved by
+the following lines in `atmel_qspi_transfer()`:
+
+       /* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */
+       (void)atmel_qspi_read(aq, QSPI_IFR);
+
+However, the current documentation makes no mention to
+synchronization requirements in the other direction, i.e.
+after the last data written via AHB, and before the first
+register access on APB.
+
+In our case, we were facing an issue where the QSPI peripheral
+would cease to send any new CSR (nCS Rise) interrupts,
+leading to a timeout in `atmel_qspi_wait_for_completion()`
+and ultimately this panic in higher levels:
+
+       ubi0 error: ubi_io_write: error -110 while writing 63108 bytes
+ to PEB 491:128, written 63104 bytes
+
+After months of extensive research of the codebase, fiddling
+around the debugger with kgdb, and back-and-forth with
+Microchip, we came to the conclusion that the issue is
+probably that the peripheral is still busy receiving on AHB
+when the LASTXFER bit is written to its Control Register
+on APB, therefore this write gets lost, and the peripheral
+still thinks there is more data to come in the MMIO transfer.
+This was first formulated when we noticed that doubling the
+write() of QSPI_CR_LASTXFER seemed to solve the problem.
+
+Ultimately, the solution is to introduce memory barriers
+after the AHB-mapped MMIO transfers, to ensure ordering.
+
+Fixes: d5433def3153 ("mtd: spi-nor: atmel-quadspi: Add spi-mem support to atmel-quadspi")
+Cc: Hari.PrasathGE@microchip.com
+Cc: Mahesh.Abotula@microchip.com
+Cc: Marco.Cardellini@microchip.com
+Cc: stable@vger.kernel.org # c0a0203cf579: ("spi: atmel-quadspi: Create `atmel_qspi_ops`"...)
+Cc: stable@vger.kernel.org # 6.x.y
+Signed-off-by: Bence Csókás <csokas.bence@prolan.hu>
+Link: https://patch.msgid.link/20241219091258.395187-1-csokas.bence@prolan.hu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/atmel-quadspi.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/spi/atmel-quadspi.c
++++ b/drivers/spi/atmel-quadspi.c
+@@ -454,13 +454,20 @@ static int atmel_qspi_transfer(struct sp
+       (void)atmel_qspi_read(aq, QSPI_IFR);
+       /* Send/Receive data */
+-      if (op->data.dir == SPI_MEM_DATA_IN)
++      if (op->data.dir == SPI_MEM_DATA_IN) {
+               memcpy_fromio(op->data.buf.in, aq->mem + offset,
+                             op->data.nbytes);
+-      else
++
++              /* Synchronize AHB and APB accesses again */
++              rmb();
++      } else {
+               memcpy_toio(aq->mem + offset, op->data.buf.out,
+                           op->data.nbytes);
++              /* Synchronize AHB and APB accesses again */
++              wmb();
++      }
++
+       /* Release the chip-select */
+       atmel_qspi_write(QSPI_CR_LASTXFER, aq, QSPI_CR);
diff --git a/queue-6.13/spi-atmel-quadspi-create-atmel_qspi_ops-to-support-newer-soc-families.patch b/queue-6.13/spi-atmel-quadspi-create-atmel_qspi_ops-to-support-newer-soc-families.patch
new file mode 100644 (file)
index 0000000..819207d
--- /dev/null
@@ -0,0 +1,207 @@
+From c0a0203cf57963792d59b3e4317a1d07b73df42a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Cs=C3=B3k=C3=A1s=2C=20Bence?= <csokas.bence@prolan.hu>
+Date: Thu, 28 Nov 2024 18:43:14 +0100
+Subject: spi: atmel-quadspi: Create `atmel_qspi_ops` to support newer SoC families
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Csókás, Bence <csokas.bence@prolan.hu>
+
+commit c0a0203cf57963792d59b3e4317a1d07b73df42a upstream.
+
+Refactor the code to introduce an ops struct, to prepare for merging
+support for later SoCs, such as SAMA7G5. This code was based on the
+vendor's kernel (linux4microchip). Cc'ing original contributors.
+
+Signed-off-by: Csókás, Bence <csokas.bence@prolan.hu>
+Link: https://patch.msgid.link/20241128174316.3209354-2-csokas.bence@prolan.hu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/atmel-quadspi.c |  111 ++++++++++++++++++++++++++++++--------------
+ 1 file changed, 77 insertions(+), 34 deletions(-)
+
+--- a/drivers/spi/atmel-quadspi.c
++++ b/drivers/spi/atmel-quadspi.c
+@@ -138,11 +138,15 @@
+ #define QSPI_WPSR_WPVSRC_MASK           GENMASK(15, 8)
+ #define QSPI_WPSR_WPVSRC(src)           (((src) << 8) & QSPI_WPSR_WPVSRC)
++#define ATMEL_QSPI_TIMEOUT            1000    /* ms */
++
+ struct atmel_qspi_caps {
+       bool has_qspick;
+       bool has_ricr;
+ };
++struct atmel_qspi_ops;
++
+ struct atmel_qspi {
+       void __iomem            *regs;
+       void __iomem            *mem;
+@@ -150,13 +154,22 @@ struct atmel_qspi {
+       struct clk              *qspick;
+       struct platform_device  *pdev;
+       const struct atmel_qspi_caps *caps;
++      const struct atmel_qspi_ops *ops;
+       resource_size_t         mmap_size;
+       u32                     pending;
++      u32                     irq_mask;
+       u32                     mr;
+       u32                     scr;
+       struct completion       cmd_completion;
+ };
++struct atmel_qspi_ops {
++      int (*set_cfg)(struct atmel_qspi *aq, const struct spi_mem_op *op,
++                     u32 *offset);
++      int (*transfer)(struct spi_mem *mem, const struct spi_mem_op *op,
++                      u32 offset);
++};
++
+ struct atmel_qspi_mode {
+       u8 cmd_buswidth;
+       u8 addr_buswidth;
+@@ -404,10 +417,60 @@ static int atmel_qspi_set_cfg(struct atm
+       return 0;
+ }
++static int atmel_qspi_wait_for_completion(struct atmel_qspi *aq, u32 irq_mask)
++{
++      int err = 0;
++      u32 sr;
++
++      /* Poll INSTRuction End status */
++      sr = atmel_qspi_read(aq, QSPI_SR);
++      if ((sr & irq_mask) == irq_mask)
++              return 0;
++
++      /* Wait for INSTRuction End interrupt */
++      reinit_completion(&aq->cmd_completion);
++      aq->pending = sr & irq_mask;
++      aq->irq_mask = irq_mask;
++      atmel_qspi_write(irq_mask, aq, QSPI_IER);
++      if (!wait_for_completion_timeout(&aq->cmd_completion,
++                                       msecs_to_jiffies(ATMEL_QSPI_TIMEOUT)))
++              err = -ETIMEDOUT;
++      atmel_qspi_write(irq_mask, aq, QSPI_IDR);
++
++      return err;
++}
++
++static int atmel_qspi_transfer(struct spi_mem *mem,
++                             const struct spi_mem_op *op, u32 offset)
++{
++      struct atmel_qspi *aq = spi_controller_get_devdata(mem->spi->controller);
++
++      /* Skip to the final steps if there is no data */
++      if (!op->data.nbytes)
++              return atmel_qspi_wait_for_completion(aq,
++                                                    QSPI_SR_CMD_COMPLETED);
++
++      /* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */
++      (void)atmel_qspi_read(aq, QSPI_IFR);
++
++      /* Send/Receive data */
++      if (op->data.dir == SPI_MEM_DATA_IN)
++              memcpy_fromio(op->data.buf.in, aq->mem + offset,
++                            op->data.nbytes);
++      else
++              memcpy_toio(aq->mem + offset, op->data.buf.out,
++                          op->data.nbytes);
++
++      /* Release the chip-select */
++      atmel_qspi_write(QSPI_CR_LASTXFER, aq, QSPI_CR);
++
++      return atmel_qspi_wait_for_completion(aq, QSPI_SR_CMD_COMPLETED);
++}
++
+ static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+ {
+       struct atmel_qspi *aq = spi_controller_get_devdata(mem->spi->controller);
+-      u32 sr, offset;
++      u32 offset;
+       int err;
+       /*
+@@ -416,46 +479,20 @@ static int atmel_qspi_exec_op(struct spi
+        * when the flash memories overrun the controller's memory space.
+        */
+       if (op->addr.val + op->data.nbytes > aq->mmap_size)
+-              return -ENOTSUPP;
++              return -EOPNOTSUPP;
++
++      if (op->addr.nbytes > 4)
++              return -EOPNOTSUPP;
+       err = pm_runtime_resume_and_get(&aq->pdev->dev);
+       if (err < 0)
+               return err;
+-      err = atmel_qspi_set_cfg(aq, op, &offset);
++      err = aq->ops->set_cfg(aq, op, &offset);
+       if (err)
+               goto pm_runtime_put;
+-      /* Skip to the final steps if there is no data */
+-      if (op->data.nbytes) {
+-              /* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */
+-              (void)atmel_qspi_read(aq, QSPI_IFR);
+-
+-              /* Send/Receive data */
+-              if (op->data.dir == SPI_MEM_DATA_IN)
+-                      memcpy_fromio(op->data.buf.in, aq->mem + offset,
+-                                    op->data.nbytes);
+-              else
+-                      memcpy_toio(aq->mem + offset, op->data.buf.out,
+-                                  op->data.nbytes);
+-
+-              /* Release the chip-select */
+-              atmel_qspi_write(QSPI_CR_LASTXFER, aq, QSPI_CR);
+-      }
+-
+-      /* Poll INSTRuction End status */
+-      sr = atmel_qspi_read(aq, QSPI_SR);
+-      if ((sr & QSPI_SR_CMD_COMPLETED) == QSPI_SR_CMD_COMPLETED)
+-              goto pm_runtime_put;
+-
+-      /* Wait for INSTRuction End interrupt */
+-      reinit_completion(&aq->cmd_completion);
+-      aq->pending = sr & QSPI_SR_CMD_COMPLETED;
+-      atmel_qspi_write(QSPI_SR_CMD_COMPLETED, aq, QSPI_IER);
+-      if (!wait_for_completion_timeout(&aq->cmd_completion,
+-                                       msecs_to_jiffies(1000)))
+-              err = -ETIMEDOUT;
+-      atmel_qspi_write(QSPI_SR_CMD_COMPLETED, aq, QSPI_IDR);
++      err = aq->ops->transfer(mem, op, offset);
+ pm_runtime_put:
+       pm_runtime_mark_last_busy(&aq->pdev->dev);
+@@ -599,12 +636,17 @@ static irqreturn_t atmel_qspi_interrupt(
+               return IRQ_NONE;
+       aq->pending |= pending;
+-      if ((aq->pending & QSPI_SR_CMD_COMPLETED) == QSPI_SR_CMD_COMPLETED)
++      if ((aq->pending & aq->irq_mask) == aq->irq_mask)
+               complete(&aq->cmd_completion);
+       return IRQ_HANDLED;
+ }
++static const struct atmel_qspi_ops atmel_qspi_ops = {
++      .set_cfg = atmel_qspi_set_cfg,
++      .transfer = atmel_qspi_transfer,
++};
++
+ static int atmel_qspi_probe(struct platform_device *pdev)
+ {
+       struct spi_controller *ctrl;
+@@ -629,6 +671,7 @@ static int atmel_qspi_probe(struct platf
+       init_completion(&aq->cmd_completion);
+       aq->pdev = pdev;
++      aq->ops = &atmel_qspi_ops;
+       /* Map the registers */
+       aq->regs = devm_platform_ioremap_resource_byname(pdev, "qspi_base");