From: Greg Kroah-Hartman Date: Tue, 11 Feb 2025 10:32:13 +0000 (+0100) Subject: 6.13-stable patches X-Git-Tag: v6.6.78~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9b0fd240742cdaeb5c276da474190bdd5b8c964e;p=thirdparty%2Fkernel%2Fstable-queue.git 6.13-stable patches 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 --- 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 index 0000000000..33aeb3e74d --- /dev/null +++ b/queue-6.13/mips-ftrace-declare-ftrace_get_parent_ra_addr-as-static.patch @@ -0,0 +1,47 @@ +From ddd068d81445b17ac0bed084dfeb9e58b4df3ddd Mon Sep 17 00:00:00 2001 +From: WangYuli +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 + +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 +Acked-by: Masami Hiramatsu (Google) +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..4bda544734 --- /dev/null +++ b/queue-6.13/s390-fpu-add-fpc-exception-handler-remove-fixup-section-again.patch @@ -0,0 +1,115 @@ +From ae02615b7fcea9ce9a4ec40b3c5b5dafd322b179 Mon Sep 17 00:00:00 2001 +From: Heiko Carstens +Date: Fri, 10 Jan 2025 11:52:17 +0100 +Subject: s390/fpu: Add fpc exception handler / remove fixup section again + +From: Heiko Carstens + +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 +Signed-off-by: Heiko Carstens +Signed-off-by: Alexander Gordeev +Signed-off-by: Greg Kroah-Hartman +--- + 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"); + } diff --git a/queue-6.13/series b/queue-6.13/series index 86644f5105..10135730a5 100644 --- a/queue-6.13/series +++ b/queue-6.13/series @@ -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 index 0000000000..32f79abd3b --- /dev/null +++ b/queue-6.13/spi-atmel-qspi-memory-barriers-after-memory-mapped-i-o.patch @@ -0,0 +1,90 @@ +From be92ab2de0ee1a13291c3b47b2d7eb24d80c0a2c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bence=20Cs=C3=B3k=C3=A1s?= +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 + +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 +Link: https://patch.msgid.link/20241219091258.395187-1-csokas.bence@prolan.hu +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..819207d1bc --- /dev/null +++ b/queue-6.13/spi-atmel-quadspi-create-atmel_qspi_ops-to-support-newer-soc-families.patch @@ -0,0 +1,207 @@ +From c0a0203cf57963792d59b3e4317a1d07b73df42a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Cs=C3=B3k=C3=A1s=2C=20Bence?= +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 + +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 +Link: https://patch.msgid.link/20241128174316.3209354-2-csokas.bence@prolan.hu +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + 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");