From: Sasha Levin Date: Sun, 26 Oct 2025 14:23:50 +0000 (-0400) Subject: Fixes for all trees X-Git-Tag: v5.4.301~34^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=18b0eece60bd029d619c7eb452a7e5ac46ec3122;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for all trees Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/risc-v-correctly-print-supported-extensions.patch b/queue-5.10/risc-v-correctly-print-supported-extensions.patch new file mode 100644 index 0000000000..88b28e02e7 --- /dev/null +++ b/queue-5.10/risc-v-correctly-print-supported-extensions.patch @@ -0,0 +1,70 @@ +From 93ed5cf563a402e786e8eeedc6f4ad5a7c4ef7af Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Mar 2022 13:38:40 -0700 +Subject: RISC-V: Correctly print supported extensions + +From: Tsukasa OI + +[ Upstream commit 58004f266918912771ee71f46bfb92bf64ab9108 ] + +This commit replaces BITS_PER_LONG with number of alphabet letters. + +Current ISA pretty-printing code expects extension 'a' (bit 0) through +'z' (bit 25). Although bit 26 and higher is not currently used (thus never +cause an issue in practice), it will be an annoying problem if we start to +use those in the future. + +This commit disables printing high bits for now. + +Reviewed-by: Anup Patel +Tested-by: Heiko Stuebner +Signed-off-by: Tsukasa OI +Signed-off-by: Atish Patra +Signed-off-by: Palmer Dabbelt +Stable-dep-of: d2721bb165b3 ("RISC-V: Don't print details of CPUs disabled in DT") +Signed-off-by: Sasha Levin +--- + arch/riscv/kernel/cpufeature.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c +index ac202f44a6702..ece126dad3547 100644 +--- a/arch/riscv/kernel/cpufeature.c ++++ b/arch/riscv/kernel/cpufeature.c +@@ -13,6 +13,8 @@ + #include + #include + ++#define NUM_ALPHA_EXTS ('z' - 'a' + 1) ++ + unsigned long elf_hwcap __read_mostly; + + /* Host ISA bitmap */ +@@ -63,7 +65,7 @@ void riscv_fill_hwcap(void) + { + struct device_node *node; + const char *isa; +- char print_str[BITS_PER_LONG + 1]; ++ char print_str[NUM_ALPHA_EXTS + 1]; + size_t i, j, isa_len; + static unsigned long isa2hwcap[256] = {0}; + +@@ -133,13 +135,13 @@ void riscv_fill_hwcap(void) + } + + memset(print_str, 0, sizeof(print_str)); +- for (i = 0, j = 0; i < BITS_PER_LONG; i++) ++ for (i = 0, j = 0; i < NUM_ALPHA_EXTS; i++) + if (riscv_isa[0] & BIT_MASK(i)) + print_str[j++] = (char)('a' + i); + pr_info("riscv: ISA extensions %s\n", print_str); + + memset(print_str, 0, sizeof(print_str)); +- for (i = 0, j = 0; i < BITS_PER_LONG; i++) ++ for (i = 0, j = 0; i < NUM_ALPHA_EXTS; i++) + if (elf_hwcap & BIT_MASK(i)) + print_str[j++] = (char)('a' + i); + pr_info("riscv: ELF capabilities %s\n", print_str); +-- +2.51.0 + diff --git a/queue-5.10/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch b/queue-5.10/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch new file mode 100644 index 0000000000..9e5abfeb43 --- /dev/null +++ b/queue-5.10/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch @@ -0,0 +1,46 @@ +From b18c59a5af52f5e6fec761e22d9f630db10a7786 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 22:00:09 +0530 +Subject: RISC-V: Don't print details of CPUs disabled in DT + +From: Anup Patel + +[ Upstream commit d2721bb165b3ee00dd23525885381af07fec852a ] + +Early boot stages may disable CPU DT nodes for unavailable +CPUs based on SKU, pinstraps, eFuse, etc. Currently, the +riscv_early_of_processor_hartid() prints details of a CPU +if it is disabled in DT which has no value and gives a +false impression to the users that there some issue with +the CPU. + +Fixes: e3d794d555cd ("riscv: treat cpu devicetree nodes without status as enabled") +Signed-off-by: Anup Patel +Reviewed-by: Andrew Jones +Reviewed-by: Conor Dooley +Link: https://lore.kernel.org/r/20251014163009.182381-1-apatel@ventanamicro.com +Signed-off-by: Paul Walmsley +Signed-off-by: Sasha Levin +--- + arch/riscv/kernel/cpu.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c +index 11d6d6cc61d51..39013aedbe0ab 100644 +--- a/arch/riscv/kernel/cpu.c ++++ b/arch/riscv/kernel/cpu.c +@@ -27,10 +27,8 @@ int riscv_of_processor_hartid(struct device_node *node, unsigned long *hart) + return -ENODEV; + } + +- if (!of_device_is_available(node)) { +- pr_info("CPU with hartid=%lu is not available\n", *hart); ++ if (!of_device_is_available(node)) + return -ENODEV; +- } + + if (of_property_read_string(node, "riscv,isa", &isa)) { + pr_warn("CPU with hartid=%lu has no \"riscv,isa\" property\n", *hart); +-- +2.51.0 + diff --git a/queue-5.10/risc-v-minimal-parser-for-riscv-isa-strings.patch b/queue-5.10/risc-v-minimal-parser-for-riscv-isa-strings.patch new file mode 100644 index 0000000000..5abf257998 --- /dev/null +++ b/queue-5.10/risc-v-minimal-parser-for-riscv-isa-strings.patch @@ -0,0 +1,145 @@ +From 37334339e71c5a10f92eacdeead0a897538672ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Mar 2022 13:38:41 -0700 +Subject: RISC-V: Minimal parser for "riscv, isa" strings + +From: Tsukasa OI + +[ Upstream commit 2a31c54be097c74344b4fab20ea6104012d2cb8b ] + +Current hart ISA ("riscv,isa") parser don't correctly parse: + +1. Multi-letter extensions +2. Version numbers + +All ISA extensions ratified recently has multi-letter extensions +(except 'H'). The current "riscv,isa" parser that is easily confused +by multi-letter extensions and "p" in version numbers can be a huge +problem for adding new extensions through the device tree. + +Leaving it would create incompatible hacks and would make "riscv,isa" +value unreliable. + +This commit implements minimal parser for "riscv,isa" strings. With this, +we can safely ignore multi-letter extensions and version numbers. + +[Improved commit text and fixed a bug around 's' in base extension] +Signed-off-by: Atish Patra +[Fixed workaround for QEMU] +Signed-off-by: Tsukasa OI +Tested-by: Heiko Stuebner +Reviewed-by: Anup Patel +Signed-off-by: Palmer Dabbelt +Stable-dep-of: d2721bb165b3 ("RISC-V: Don't print details of CPUs disabled in DT") +Signed-off-by: Sasha Levin +--- + arch/riscv/kernel/cpufeature.c | 72 ++++++++++++++++++++++++++++------ + 1 file changed, 61 insertions(+), 11 deletions(-) + +diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c +index ece126dad3547..54d230bdaf976 100644 +--- a/arch/riscv/kernel/cpufeature.c ++++ b/arch/riscv/kernel/cpufeature.c +@@ -7,6 +7,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -66,7 +67,7 @@ void riscv_fill_hwcap(void) + struct device_node *node; + const char *isa; + char print_str[NUM_ALPHA_EXTS + 1]; +- size_t i, j, isa_len; ++ int i, j; + static unsigned long isa2hwcap[256] = {0}; + + isa2hwcap['i'] = isa2hwcap['I'] = COMPAT_HWCAP_ISA_I; +@@ -92,23 +93,72 @@ void riscv_fill_hwcap(void) + continue; + } + +- i = 0; +- isa_len = strlen(isa); + #if IS_ENABLED(CONFIG_32BIT) + if (!strncmp(isa, "rv32", 4)) +- i += 4; ++ isa += 4; + #elif IS_ENABLED(CONFIG_64BIT) + if (!strncmp(isa, "rv64", 4)) +- i += 4; ++ isa += 4; + #endif +- for (; i < isa_len; ++i) { +- this_hwcap |= isa2hwcap[(unsigned char)(isa[i])]; ++ for (; *isa; ++isa) { ++ const char *ext = isa++; ++ const char *ext_end = isa; ++ bool ext_long = false, ext_err = false; ++ ++ switch (*ext) { ++ case 's': ++ /** ++ * Workaround for invalid single-letter 's' & 'u'(QEMU). ++ * No need to set the bit in riscv_isa as 's' & 'u' are ++ * not valid ISA extensions. It works until multi-letter ++ * extension starting with "Su" appears. ++ */ ++ if (ext[-1] != '_' && ext[1] == 'u') { ++ ++isa; ++ ext_err = true; ++ break; ++ } ++ fallthrough; ++ case 'x': ++ case 'z': ++ ext_long = true; ++ /* Multi-letter extension must be delimited */ ++ for (; *isa && *isa != '_'; ++isa) ++ if (!islower(*isa) && !isdigit(*isa)) ++ ext_err = true; ++ break; ++ default: ++ if (unlikely(!islower(*ext))) { ++ ext_err = true; ++ break; ++ } ++ /* Find next extension */ ++ if (!isdigit(*isa)) ++ break; ++ /* Skip the minor version */ ++ while (isdigit(*++isa)) ++ ; ++ if (*isa != 'p') ++ break; ++ if (!isdigit(*++isa)) { ++ --isa; ++ break; ++ } ++ /* Skip the major version */ ++ while (isdigit(*++isa)) ++ ; ++ break; ++ } ++ if (*isa != '_') ++ --isa; + /* +- * TODO: X, Y and Z extension parsing for Host ISA +- * bitmap will be added in-future. ++ * TODO: Full version-aware handling including ++ * multi-letter extensions will be added in-future. + */ +- if ('a' <= isa[i] && isa[i] < 'x') +- this_isa |= (1UL << (isa[i] - 'a')); ++ if (ext_err || ext_long) ++ continue; ++ this_hwcap |= isa2hwcap[(unsigned char)(*ext)]; ++ this_isa |= (1UL << (*ext - 'a')); + } + + /* +-- +2.51.0 + diff --git a/queue-5.10/riscv-cpu-add-64bit-hartid-support-on-rv64.patch b/queue-5.10/riscv-cpu-add-64bit-hartid-support-on-rv64.patch new file mode 100644 index 0000000000..8522a44abc --- /dev/null +++ b/queue-5.10/riscv-cpu-add-64bit-hartid-support-on-rv64.patch @@ -0,0 +1,260 @@ +From 76b3881905903f8e8a1af4fb33bfab80b1998b8e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 May 2022 10:47:42 +0530 +Subject: riscv: cpu: Add 64bit hartid support on RV64 + +From: Sunil V L + +[ Upstream commit ad635e723e17379b192a5ba9c182e3eedfc24d16 ] + +The hartid can be a 64bit value on RV64 platforms. + +Add support for 64bit hartid in riscv_of_processor_hartid() and +update its callers. + +Signed-off-by: Sunil V L +Reviewed-by: Atish Patra +Link: https://lore.kernel.org/r/20220527051743.2829940-5-sunilvl@ventanamicro.com +Signed-off-by: Palmer Dabbelt +Stable-dep-of: d2721bb165b3 ("RISC-V: Don't print details of CPUs disabled in DT") +Signed-off-by: Sasha Levin +--- + arch/riscv/include/asm/processor.h | 4 ++-- + arch/riscv/kernel/cpu.c | 26 +++++++++++++++----------- + arch/riscv/kernel/cpufeature.c | 6 ++++-- + arch/riscv/kernel/smpboot.c | 9 +++++---- + drivers/clocksource/timer-riscv.c | 15 ++++++++------- + drivers/irqchip/irq-riscv-intc.c | 7 ++++--- + drivers/irqchip/irq-sifive-plic.c | 7 ++++--- + 7 files changed, 42 insertions(+), 32 deletions(-) + +diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h +index bdddcd5c1b71d..b5295806643b1 100644 +--- a/arch/riscv/include/asm/processor.h ++++ b/arch/riscv/include/asm/processor.h +@@ -66,8 +66,8 @@ static inline void wait_for_interrupt(void) + } + + struct device_node; +-int riscv_of_processor_hartid(struct device_node *node); +-int riscv_of_parent_hartid(struct device_node *node); ++int riscv_of_processor_hartid(struct device_node *node, unsigned long *hartid); ++int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid); + + extern void riscv_fill_hwcap(void); + +diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c +index f13b2c9ea912d..11d6d6cc61d51 100644 +--- a/arch/riscv/kernel/cpu.c ++++ b/arch/riscv/kernel/cpu.c +@@ -12,37 +12,36 @@ + * Returns the hart ID of the given device tree node, or -ENODEV if the node + * isn't an enabled and valid RISC-V hart node. + */ +-int riscv_of_processor_hartid(struct device_node *node) ++int riscv_of_processor_hartid(struct device_node *node, unsigned long *hart) + { + const char *isa; +- u32 hart; + + if (!of_device_is_compatible(node, "riscv")) { + pr_warn("Found incompatible CPU\n"); + return -ENODEV; + } + +- hart = of_get_cpu_hwid(node, 0); +- if (hart == ~0U) { ++ *hart = (unsigned long) of_get_cpu_hwid(node, 0); ++ if (*hart == ~0UL) { + pr_warn("Found CPU without hart ID\n"); + return -ENODEV; + } + + if (!of_device_is_available(node)) { +- pr_info("CPU with hartid=%d is not available\n", hart); ++ pr_info("CPU with hartid=%lu is not available\n", *hart); + return -ENODEV; + } + + if (of_property_read_string(node, "riscv,isa", &isa)) { +- pr_warn("CPU with hartid=%d has no \"riscv,isa\" property\n", hart); ++ pr_warn("CPU with hartid=%lu has no \"riscv,isa\" property\n", *hart); + return -ENODEV; + } + if (isa[0] != 'r' || isa[1] != 'v') { +- pr_warn("CPU with hartid=%d has an invalid ISA of \"%s\"\n", hart, isa); ++ pr_warn("CPU with hartid=%lu has an invalid ISA of \"%s\"\n", *hart, isa); + return -ENODEV; + } + +- return hart; ++ return 0; + } + + /* +@@ -51,11 +50,16 @@ int riscv_of_processor_hartid(struct device_node *node) + * To achieve this, we walk up the DT tree until we find an active + * RISC-V core (HART) node and extract the cpuid from it. + */ +-int riscv_of_parent_hartid(struct device_node *node) ++int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid) + { ++ int rc; ++ + for (; node; node = node->parent) { +- if (of_device_is_compatible(node, "riscv")) +- return riscv_of_processor_hartid(node); ++ if (of_device_is_compatible(node, "riscv")) { ++ rc = riscv_of_processor_hartid(node, hartid); ++ if (!rc) ++ return 0; ++ } + } + + return -1; +diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c +index 54d230bdaf976..f46efff26e3dc 100644 +--- a/arch/riscv/kernel/cpufeature.c ++++ b/arch/riscv/kernel/cpufeature.c +@@ -67,8 +67,9 @@ void riscv_fill_hwcap(void) + struct device_node *node; + const char *isa; + char print_str[NUM_ALPHA_EXTS + 1]; +- int i, j; ++ int i, j, rc; + static unsigned long isa2hwcap[256] = {0}; ++ unsigned long hartid; + + isa2hwcap['i'] = isa2hwcap['I'] = COMPAT_HWCAP_ISA_I; + isa2hwcap['m'] = isa2hwcap['M'] = COMPAT_HWCAP_ISA_M; +@@ -85,7 +86,8 @@ void riscv_fill_hwcap(void) + unsigned long this_hwcap = 0; + unsigned long this_isa = 0; + +- if (riscv_of_processor_hartid(node) < 0) ++ rc = riscv_of_processor_hartid(node, &hartid); ++ if (rc < 0) + continue; + + if (of_property_read_string(node, "riscv,isa", &isa)) { +diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c +index 0e0aed380e281..9df6413771923 100644 +--- a/arch/riscv/kernel/smpboot.c ++++ b/arch/riscv/kernel/smpboot.c +@@ -67,15 +67,16 @@ void __init smp_prepare_cpus(unsigned int max_cpus) + void __init setup_smp(void) + { + struct device_node *dn; +- int hart; ++ unsigned long hart; + bool found_boot_cpu = false; + int cpuid = 1; ++ int rc; + + cpu_set_ops(0); + + for_each_of_cpu_node(dn) { +- hart = riscv_of_processor_hartid(dn); +- if (hart < 0) ++ rc = riscv_of_processor_hartid(dn, &hart); ++ if (rc < 0) + continue; + + if (hart == cpuid_to_hartid_map(0)) { +@@ -84,7 +85,7 @@ void __init setup_smp(void) + continue; + } + if (cpuid >= NR_CPUS) { +- pr_warn("Invalid cpuid [%d] for hartid [%d]\n", ++ pr_warn("Invalid cpuid [%d] for hartid [%lu]\n", + cpuid, hart); + break; + } +diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c +index c51c5ed15aa75..4930d08c9374a 100644 +--- a/drivers/clocksource/timer-riscv.c ++++ b/drivers/clocksource/timer-riscv.c +@@ -92,20 +92,21 @@ static irqreturn_t riscv_timer_interrupt(int irq, void *dev_id) + + static int __init riscv_timer_init_dt(struct device_node *n) + { +- int cpuid, hartid, error; ++ int cpuid, error; ++ unsigned long hartid; + struct device_node *child; + struct irq_domain *domain; + +- hartid = riscv_of_processor_hartid(n); +- if (hartid < 0) { +- pr_warn("Not valid hartid for node [%pOF] error = [%d]\n", ++ error = riscv_of_processor_hartid(n, &hartid); ++ if (error < 0) { ++ pr_warn("Not valid hartid for node [%pOF] error = [%lu]\n", + n, hartid); +- return hartid; ++ return error; + } + + cpuid = riscv_hartid_to_cpuid(hartid); + if (cpuid < 0) { +- pr_warn("Invalid cpuid for hartid [%d]\n", hartid); ++ pr_warn("Invalid cpuid for hartid [%lu]\n", hartid); + return cpuid; + } + +@@ -131,7 +132,7 @@ static int __init riscv_timer_init_dt(struct device_node *n) + return -ENODEV; + } + +- pr_info("%s: Registering clocksource cpuid [%d] hartid [%d]\n", ++ pr_info("%s: Registering clocksource cpuid [%d] hartid [%lu]\n", + __func__, cpuid, hartid); + error = clocksource_register_hz(&riscv_clocksource, riscv_timebase); + if (error) { +diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c +index 8017f6d32d52b..edbf90a7565f6 100644 +--- a/drivers/irqchip/irq-riscv-intc.c ++++ b/drivers/irqchip/irq-riscv-intc.c +@@ -95,10 +95,11 @@ static const struct irq_domain_ops riscv_intc_domain_ops = { + static int __init riscv_intc_init(struct device_node *node, + struct device_node *parent) + { +- int rc, hartid; ++ int rc; ++ unsigned long hartid; + +- hartid = riscv_of_parent_hartid(node); +- if (hartid < 0) { ++ rc = riscv_of_parent_hartid(node, &hartid); ++ if (rc < 0) { + pr_warn("unable to find hart id for %pOF\n", node); + return 0; + } +diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c +index bd99ee0ae433d..5fdf0eae48f7d 100644 +--- a/drivers/irqchip/irq-sifive-plic.c ++++ b/drivers/irqchip/irq-sifive-plic.c +@@ -315,7 +315,8 @@ static int __init plic_init(struct device_node *node, + for (i = 0; i < nr_contexts; i++) { + struct of_phandle_args parent; + irq_hw_number_t hwirq; +- int cpu, hartid; ++ int cpu; ++ unsigned long hartid; + + if (of_irq_parse_one(node, i, &parent)) { + pr_err("failed to parse parent for context %d.\n", i); +@@ -329,8 +330,8 @@ static int __init plic_init(struct device_node *node, + if (parent.args[0] != RV_IRQ_EXT) + continue; + +- hartid = riscv_of_parent_hartid(parent.np); +- if (hartid < 0) { ++ error = riscv_of_parent_hartid(parent.np, &hartid); ++ if (error < 0) { + pr_warn("failed to parse hart ID for context %d.\n", i); + continue; + } +-- +2.51.0 + diff --git a/queue-5.10/riscv-use-of_get_cpu_hwid.patch b/queue-5.10/riscv-use-of_get_cpu_hwid.patch new file mode 100644 index 0000000000..053db28579 --- /dev/null +++ b/queue-5.10/riscv-use-of_get_cpu_hwid.patch @@ -0,0 +1,41 @@ +From b49cf4ec68dc8e5e449aa8e460f26ad74c390c6b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Oct 2021 11:43:28 -0500 +Subject: riscv: Use of_get_cpu_hwid() + +From: Rob Herring + +[ Upstream commit bd2259ee458e299ec14061da7faddcfb0d54d154 ] + +Replace open coded parsing of CPU nodes' 'reg' property with +of_get_cpu_hwid(). + +Cc: Paul Walmsley +Cc: Palmer Dabbelt +Cc: Albert Ou +Cc: linux-riscv@lists.infradead.org +Signed-off-by: Rob Herring +Link: https://lore.kernel.org/r/20211006164332.1981454-9-robh@kernel.org +Stable-dep-of: d2721bb165b3 ("RISC-V: Don't print details of CPUs disabled in DT") +Signed-off-by: Sasha Levin +--- + arch/riscv/kernel/cpu.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c +index 6d59e6906fddf..f13b2c9ea912d 100644 +--- a/arch/riscv/kernel/cpu.c ++++ b/arch/riscv/kernel/cpu.c +@@ -22,7 +22,8 @@ int riscv_of_processor_hartid(struct device_node *node) + return -ENODEV; + } + +- if (of_property_read_u32(node, "reg", &hart)) { ++ hart = of_get_cpu_hwid(node, 0); ++ if (hart == ~0U) { + pr_warn("Found CPU without hart ID\n"); + return -ENODEV; + } +-- +2.51.0 + diff --git a/queue-5.10/series b/queue-5.10/series index d1c7c03bf1..91e36fc02b 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -277,3 +277,8 @@ net-enetc-correct-the-value-of-enetc_rxb_truesize.patch dpaa2-eth-fix-the-pointer-passed-to-ptr_align-on-tx-.patch arm64-mm-avoid-always-making-pte-dirty-in-pte_mkwrit.patch sctp-avoid-null-dereference-when-chunk-data-buffer-i.patch +riscv-use-of_get_cpu_hwid.patch +risc-v-correctly-print-supported-extensions.patch +risc-v-minimal-parser-for-riscv-isa-strings.patch +riscv-cpu-add-64bit-hartid-support-on-rv64.patch +risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch diff --git a/queue-5.15/risc-v-correctly-print-supported-extensions.patch b/queue-5.15/risc-v-correctly-print-supported-extensions.patch new file mode 100644 index 0000000000..84fba001fc --- /dev/null +++ b/queue-5.15/risc-v-correctly-print-supported-extensions.patch @@ -0,0 +1,70 @@ +From ddcb73be11eb65f25d9bffed15064862f48c79e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Mar 2022 13:38:40 -0700 +Subject: RISC-V: Correctly print supported extensions + +From: Tsukasa OI + +[ Upstream commit 58004f266918912771ee71f46bfb92bf64ab9108 ] + +This commit replaces BITS_PER_LONG with number of alphabet letters. + +Current ISA pretty-printing code expects extension 'a' (bit 0) through +'z' (bit 25). Although bit 26 and higher is not currently used (thus never +cause an issue in practice), it will be an annoying problem if we start to +use those in the future. + +This commit disables printing high bits for now. + +Reviewed-by: Anup Patel +Tested-by: Heiko Stuebner +Signed-off-by: Tsukasa OI +Signed-off-by: Atish Patra +Signed-off-by: Palmer Dabbelt +Stable-dep-of: d2721bb165b3 ("RISC-V: Don't print details of CPUs disabled in DT") +Signed-off-by: Sasha Levin +--- + arch/riscv/kernel/cpufeature.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c +index d959d207a40d6..dd3d57eb4eead 100644 +--- a/arch/riscv/kernel/cpufeature.c ++++ b/arch/riscv/kernel/cpufeature.c +@@ -13,6 +13,8 @@ + #include + #include + ++#define NUM_ALPHA_EXTS ('z' - 'a' + 1) ++ + unsigned long elf_hwcap __read_mostly; + + /* Host ISA bitmap */ +@@ -63,7 +65,7 @@ void __init riscv_fill_hwcap(void) + { + struct device_node *node; + const char *isa; +- char print_str[BITS_PER_LONG + 1]; ++ char print_str[NUM_ALPHA_EXTS + 1]; + size_t i, j, isa_len; + static unsigned long isa2hwcap[256] = {0}; + +@@ -133,13 +135,13 @@ void __init riscv_fill_hwcap(void) + } + + memset(print_str, 0, sizeof(print_str)); +- for (i = 0, j = 0; i < BITS_PER_LONG; i++) ++ for (i = 0, j = 0; i < NUM_ALPHA_EXTS; i++) + if (riscv_isa[0] & BIT_MASK(i)) + print_str[j++] = (char)('a' + i); + pr_info("riscv: ISA extensions %s\n", print_str); + + memset(print_str, 0, sizeof(print_str)); +- for (i = 0, j = 0; i < BITS_PER_LONG; i++) ++ for (i = 0, j = 0; i < NUM_ALPHA_EXTS; i++) + if (elf_hwcap & BIT_MASK(i)) + print_str[j++] = (char)('a' + i); + pr_info("riscv: ELF capabilities %s\n", print_str); +-- +2.51.0 + diff --git a/queue-5.15/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch b/queue-5.15/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch new file mode 100644 index 0000000000..b15dc80af4 --- /dev/null +++ b/queue-5.15/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch @@ -0,0 +1,46 @@ +From 9618dd476d86fea6ef9c76c7106555e01910677d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 22:00:09 +0530 +Subject: RISC-V: Don't print details of CPUs disabled in DT + +From: Anup Patel + +[ Upstream commit d2721bb165b3ee00dd23525885381af07fec852a ] + +Early boot stages may disable CPU DT nodes for unavailable +CPUs based on SKU, pinstraps, eFuse, etc. Currently, the +riscv_early_of_processor_hartid() prints details of a CPU +if it is disabled in DT which has no value and gives a +false impression to the users that there some issue with +the CPU. + +Fixes: e3d794d555cd ("riscv: treat cpu devicetree nodes without status as enabled") +Signed-off-by: Anup Patel +Reviewed-by: Andrew Jones +Reviewed-by: Conor Dooley +Link: https://lore.kernel.org/r/20251014163009.182381-1-apatel@ventanamicro.com +Signed-off-by: Paul Walmsley +Signed-off-by: Sasha Levin +--- + arch/riscv/kernel/cpu.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c +index 11d6d6cc61d51..39013aedbe0ab 100644 +--- a/arch/riscv/kernel/cpu.c ++++ b/arch/riscv/kernel/cpu.c +@@ -27,10 +27,8 @@ int riscv_of_processor_hartid(struct device_node *node, unsigned long *hart) + return -ENODEV; + } + +- if (!of_device_is_available(node)) { +- pr_info("CPU with hartid=%lu is not available\n", *hart); ++ if (!of_device_is_available(node)) + return -ENODEV; +- } + + if (of_property_read_string(node, "riscv,isa", &isa)) { + pr_warn("CPU with hartid=%lu has no \"riscv,isa\" property\n", *hart); +-- +2.51.0 + diff --git a/queue-5.15/risc-v-minimal-parser-for-riscv-isa-strings.patch b/queue-5.15/risc-v-minimal-parser-for-riscv-isa-strings.patch new file mode 100644 index 0000000000..648ca5ba82 --- /dev/null +++ b/queue-5.15/risc-v-minimal-parser-for-riscv-isa-strings.patch @@ -0,0 +1,145 @@ +From 2908b9be2d473ce179ad478adc64fa0e1ee11007 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Mar 2022 13:38:41 -0700 +Subject: RISC-V: Minimal parser for "riscv, isa" strings + +From: Tsukasa OI + +[ Upstream commit 2a31c54be097c74344b4fab20ea6104012d2cb8b ] + +Current hart ISA ("riscv,isa") parser don't correctly parse: + +1. Multi-letter extensions +2. Version numbers + +All ISA extensions ratified recently has multi-letter extensions +(except 'H'). The current "riscv,isa" parser that is easily confused +by multi-letter extensions and "p" in version numbers can be a huge +problem for adding new extensions through the device tree. + +Leaving it would create incompatible hacks and would make "riscv,isa" +value unreliable. + +This commit implements minimal parser for "riscv,isa" strings. With this, +we can safely ignore multi-letter extensions and version numbers. + +[Improved commit text and fixed a bug around 's' in base extension] +Signed-off-by: Atish Patra +[Fixed workaround for QEMU] +Signed-off-by: Tsukasa OI +Tested-by: Heiko Stuebner +Reviewed-by: Anup Patel +Signed-off-by: Palmer Dabbelt +Stable-dep-of: d2721bb165b3 ("RISC-V: Don't print details of CPUs disabled in DT") +Signed-off-by: Sasha Levin +--- + arch/riscv/kernel/cpufeature.c | 72 ++++++++++++++++++++++++++++------ + 1 file changed, 61 insertions(+), 11 deletions(-) + +diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c +index dd3d57eb4eead..72c5f6ef56b5a 100644 +--- a/arch/riscv/kernel/cpufeature.c ++++ b/arch/riscv/kernel/cpufeature.c +@@ -7,6 +7,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -66,7 +67,7 @@ void __init riscv_fill_hwcap(void) + struct device_node *node; + const char *isa; + char print_str[NUM_ALPHA_EXTS + 1]; +- size_t i, j, isa_len; ++ int i, j; + static unsigned long isa2hwcap[256] = {0}; + + isa2hwcap['i'] = isa2hwcap['I'] = COMPAT_HWCAP_ISA_I; +@@ -92,23 +93,72 @@ void __init riscv_fill_hwcap(void) + continue; + } + +- i = 0; +- isa_len = strlen(isa); + #if IS_ENABLED(CONFIG_32BIT) + if (!strncmp(isa, "rv32", 4)) +- i += 4; ++ isa += 4; + #elif IS_ENABLED(CONFIG_64BIT) + if (!strncmp(isa, "rv64", 4)) +- i += 4; ++ isa += 4; + #endif +- for (; i < isa_len; ++i) { +- this_hwcap |= isa2hwcap[(unsigned char)(isa[i])]; ++ for (; *isa; ++isa) { ++ const char *ext = isa++; ++ const char *ext_end = isa; ++ bool ext_long = false, ext_err = false; ++ ++ switch (*ext) { ++ case 's': ++ /** ++ * Workaround for invalid single-letter 's' & 'u'(QEMU). ++ * No need to set the bit in riscv_isa as 's' & 'u' are ++ * not valid ISA extensions. It works until multi-letter ++ * extension starting with "Su" appears. ++ */ ++ if (ext[-1] != '_' && ext[1] == 'u') { ++ ++isa; ++ ext_err = true; ++ break; ++ } ++ fallthrough; ++ case 'x': ++ case 'z': ++ ext_long = true; ++ /* Multi-letter extension must be delimited */ ++ for (; *isa && *isa != '_'; ++isa) ++ if (!islower(*isa) && !isdigit(*isa)) ++ ext_err = true; ++ break; ++ default: ++ if (unlikely(!islower(*ext))) { ++ ext_err = true; ++ break; ++ } ++ /* Find next extension */ ++ if (!isdigit(*isa)) ++ break; ++ /* Skip the minor version */ ++ while (isdigit(*++isa)) ++ ; ++ if (*isa != 'p') ++ break; ++ if (!isdigit(*++isa)) { ++ --isa; ++ break; ++ } ++ /* Skip the major version */ ++ while (isdigit(*++isa)) ++ ; ++ break; ++ } ++ if (*isa != '_') ++ --isa; + /* +- * TODO: X, Y and Z extension parsing for Host ISA +- * bitmap will be added in-future. ++ * TODO: Full version-aware handling including ++ * multi-letter extensions will be added in-future. + */ +- if ('a' <= isa[i] && isa[i] < 'x') +- this_isa |= (1UL << (isa[i] - 'a')); ++ if (ext_err || ext_long) ++ continue; ++ this_hwcap |= isa2hwcap[(unsigned char)(*ext)]; ++ this_isa |= (1UL << (*ext - 'a')); + } + + /* +-- +2.51.0 + diff --git a/queue-5.15/riscv-cpu-add-64bit-hartid-support-on-rv64.patch b/queue-5.15/riscv-cpu-add-64bit-hartid-support-on-rv64.patch new file mode 100644 index 0000000000..dab23038d2 --- /dev/null +++ b/queue-5.15/riscv-cpu-add-64bit-hartid-support-on-rv64.patch @@ -0,0 +1,260 @@ +From 5d6448e7ba77a1095d44c6dddc519f41301ff78a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 May 2022 10:47:42 +0530 +Subject: riscv: cpu: Add 64bit hartid support on RV64 + +From: Sunil V L + +[ Upstream commit ad635e723e17379b192a5ba9c182e3eedfc24d16 ] + +The hartid can be a 64bit value on RV64 platforms. + +Add support for 64bit hartid in riscv_of_processor_hartid() and +update its callers. + +Signed-off-by: Sunil V L +Reviewed-by: Atish Patra +Link: https://lore.kernel.org/r/20220527051743.2829940-5-sunilvl@ventanamicro.com +Signed-off-by: Palmer Dabbelt +Stable-dep-of: d2721bb165b3 ("RISC-V: Don't print details of CPUs disabled in DT") +Signed-off-by: Sasha Levin +--- + arch/riscv/include/asm/processor.h | 4 ++-- + arch/riscv/kernel/cpu.c | 26 +++++++++++++++----------- + arch/riscv/kernel/cpufeature.c | 6 ++++-- + arch/riscv/kernel/smpboot.c | 9 +++++---- + drivers/clocksource/timer-riscv.c | 15 ++++++++------- + drivers/irqchip/irq-riscv-intc.c | 7 ++++--- + drivers/irqchip/irq-sifive-plic.c | 7 ++++--- + 7 files changed, 42 insertions(+), 32 deletions(-) + +diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h +index 0749924d9e552..99fae93985062 100644 +--- a/arch/riscv/include/asm/processor.h ++++ b/arch/riscv/include/asm/processor.h +@@ -75,8 +75,8 @@ static inline void wait_for_interrupt(void) + } + + struct device_node; +-int riscv_of_processor_hartid(struct device_node *node); +-int riscv_of_parent_hartid(struct device_node *node); ++int riscv_of_processor_hartid(struct device_node *node, unsigned long *hartid); ++int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid); + + extern void riscv_fill_hwcap(void); + extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); +diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c +index f13b2c9ea912d..11d6d6cc61d51 100644 +--- a/arch/riscv/kernel/cpu.c ++++ b/arch/riscv/kernel/cpu.c +@@ -12,37 +12,36 @@ + * Returns the hart ID of the given device tree node, or -ENODEV if the node + * isn't an enabled and valid RISC-V hart node. + */ +-int riscv_of_processor_hartid(struct device_node *node) ++int riscv_of_processor_hartid(struct device_node *node, unsigned long *hart) + { + const char *isa; +- u32 hart; + + if (!of_device_is_compatible(node, "riscv")) { + pr_warn("Found incompatible CPU\n"); + return -ENODEV; + } + +- hart = of_get_cpu_hwid(node, 0); +- if (hart == ~0U) { ++ *hart = (unsigned long) of_get_cpu_hwid(node, 0); ++ if (*hart == ~0UL) { + pr_warn("Found CPU without hart ID\n"); + return -ENODEV; + } + + if (!of_device_is_available(node)) { +- pr_info("CPU with hartid=%d is not available\n", hart); ++ pr_info("CPU with hartid=%lu is not available\n", *hart); + return -ENODEV; + } + + if (of_property_read_string(node, "riscv,isa", &isa)) { +- pr_warn("CPU with hartid=%d has no \"riscv,isa\" property\n", hart); ++ pr_warn("CPU with hartid=%lu has no \"riscv,isa\" property\n", *hart); + return -ENODEV; + } + if (isa[0] != 'r' || isa[1] != 'v') { +- pr_warn("CPU with hartid=%d has an invalid ISA of \"%s\"\n", hart, isa); ++ pr_warn("CPU with hartid=%lu has an invalid ISA of \"%s\"\n", *hart, isa); + return -ENODEV; + } + +- return hart; ++ return 0; + } + + /* +@@ -51,11 +50,16 @@ int riscv_of_processor_hartid(struct device_node *node) + * To achieve this, we walk up the DT tree until we find an active + * RISC-V core (HART) node and extract the cpuid from it. + */ +-int riscv_of_parent_hartid(struct device_node *node) ++int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid) + { ++ int rc; ++ + for (; node; node = node->parent) { +- if (of_device_is_compatible(node, "riscv")) +- return riscv_of_processor_hartid(node); ++ if (of_device_is_compatible(node, "riscv")) { ++ rc = riscv_of_processor_hartid(node, hartid); ++ if (!rc) ++ return 0; ++ } + } + + return -1; +diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c +index 72c5f6ef56b5a..5d1af366116b0 100644 +--- a/arch/riscv/kernel/cpufeature.c ++++ b/arch/riscv/kernel/cpufeature.c +@@ -67,8 +67,9 @@ void __init riscv_fill_hwcap(void) + struct device_node *node; + const char *isa; + char print_str[NUM_ALPHA_EXTS + 1]; +- int i, j; ++ int i, j, rc; + static unsigned long isa2hwcap[256] = {0}; ++ unsigned long hartid; + + isa2hwcap['i'] = isa2hwcap['I'] = COMPAT_HWCAP_ISA_I; + isa2hwcap['m'] = isa2hwcap['M'] = COMPAT_HWCAP_ISA_M; +@@ -85,7 +86,8 @@ void __init riscv_fill_hwcap(void) + unsigned long this_hwcap = 0; + unsigned long this_isa = 0; + +- if (riscv_of_processor_hartid(node) < 0) ++ rc = riscv_of_processor_hartid(node, &hartid); ++ if (rc < 0) + continue; + + if (of_property_read_string(node, "riscv,isa", &isa)) { +diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c +index 0f323e935dd89..3d3def84f81c1 100644 +--- a/arch/riscv/kernel/smpboot.c ++++ b/arch/riscv/kernel/smpboot.c +@@ -77,15 +77,16 @@ void __init smp_prepare_cpus(unsigned int max_cpus) + void __init setup_smp(void) + { + struct device_node *dn; +- int hart; ++ unsigned long hart; + bool found_boot_cpu = false; + int cpuid = 1; ++ int rc; + + cpu_set_ops(0); + + for_each_of_cpu_node(dn) { +- hart = riscv_of_processor_hartid(dn); +- if (hart < 0) ++ rc = riscv_of_processor_hartid(dn, &hart); ++ if (rc < 0) + continue; + + if (hart == cpuid_to_hartid_map(0)) { +@@ -95,7 +96,7 @@ void __init setup_smp(void) + continue; + } + if (cpuid >= NR_CPUS) { +- pr_warn("Invalid cpuid [%d] for hartid [%d]\n", ++ pr_warn("Invalid cpuid [%d] for hartid [%lu]\n", + cpuid, hart); + break; + } +diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c +index c51c5ed15aa75..4930d08c9374a 100644 +--- a/drivers/clocksource/timer-riscv.c ++++ b/drivers/clocksource/timer-riscv.c +@@ -92,20 +92,21 @@ static irqreturn_t riscv_timer_interrupt(int irq, void *dev_id) + + static int __init riscv_timer_init_dt(struct device_node *n) + { +- int cpuid, hartid, error; ++ int cpuid, error; ++ unsigned long hartid; + struct device_node *child; + struct irq_domain *domain; + +- hartid = riscv_of_processor_hartid(n); +- if (hartid < 0) { +- pr_warn("Not valid hartid for node [%pOF] error = [%d]\n", ++ error = riscv_of_processor_hartid(n, &hartid); ++ if (error < 0) { ++ pr_warn("Not valid hartid for node [%pOF] error = [%lu]\n", + n, hartid); +- return hartid; ++ return error; + } + + cpuid = riscv_hartid_to_cpuid(hartid); + if (cpuid < 0) { +- pr_warn("Invalid cpuid for hartid [%d]\n", hartid); ++ pr_warn("Invalid cpuid for hartid [%lu]\n", hartid); + return cpuid; + } + +@@ -131,7 +132,7 @@ static int __init riscv_timer_init_dt(struct device_node *n) + return -ENODEV; + } + +- pr_info("%s: Registering clocksource cpuid [%d] hartid [%d]\n", ++ pr_info("%s: Registering clocksource cpuid [%d] hartid [%lu]\n", + __func__, cpuid, hartid); + error = clocksource_register_hz(&riscv_clocksource, riscv_timebase); + if (error) { +diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c +index 54c99441c1b54..ff4a69d276ca6 100644 +--- a/drivers/irqchip/irq-riscv-intc.c ++++ b/drivers/irqchip/irq-riscv-intc.c +@@ -95,10 +95,11 @@ static const struct irq_domain_ops riscv_intc_domain_ops = { + static int __init riscv_intc_init(struct device_node *node, + struct device_node *parent) + { +- int rc, hartid; ++ int rc; ++ unsigned long hartid; + +- hartid = riscv_of_parent_hartid(node); +- if (hartid < 0) { ++ rc = riscv_of_parent_hartid(node, &hartid); ++ if (rc < 0) { + pr_warn("unable to find hart id for %pOF\n", node); + return 0; + } +diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c +index 09cc98266d30f..00b64fb882b18 100644 +--- a/drivers/irqchip/irq-sifive-plic.c ++++ b/drivers/irqchip/irq-sifive-plic.c +@@ -313,7 +313,8 @@ static int __init plic_init(struct device_node *node, + for (i = 0; i < nr_contexts; i++) { + struct of_phandle_args parent; + irq_hw_number_t hwirq; +- int cpu, hartid; ++ int cpu; ++ unsigned long hartid; + + if (of_irq_parse_one(node, i, &parent)) { + pr_err("failed to parse parent for context %d.\n", i); +@@ -327,8 +328,8 @@ static int __init plic_init(struct device_node *node, + if (parent.args[0] != RV_IRQ_EXT) + continue; + +- hartid = riscv_of_parent_hartid(parent.np); +- if (hartid < 0) { ++ error = riscv_of_parent_hartid(parent.np, &hartid); ++ if (error < 0) { + pr_warn("failed to parse hart ID for context %d.\n", i); + continue; + } +-- +2.51.0 + diff --git a/queue-5.15/riscv-use-of_get_cpu_hwid.patch b/queue-5.15/riscv-use-of_get_cpu_hwid.patch new file mode 100644 index 0000000000..6b16896ae3 --- /dev/null +++ b/queue-5.15/riscv-use-of_get_cpu_hwid.patch @@ -0,0 +1,41 @@ +From 39a229d1aca075a66b8f8e81cf91fea61a85f1ac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Oct 2021 11:43:28 -0500 +Subject: riscv: Use of_get_cpu_hwid() + +From: Rob Herring + +[ Upstream commit bd2259ee458e299ec14061da7faddcfb0d54d154 ] + +Replace open coded parsing of CPU nodes' 'reg' property with +of_get_cpu_hwid(). + +Cc: Paul Walmsley +Cc: Palmer Dabbelt +Cc: Albert Ou +Cc: linux-riscv@lists.infradead.org +Signed-off-by: Rob Herring +Link: https://lore.kernel.org/r/20211006164332.1981454-9-robh@kernel.org +Stable-dep-of: d2721bb165b3 ("RISC-V: Don't print details of CPUs disabled in DT") +Signed-off-by: Sasha Levin +--- + arch/riscv/kernel/cpu.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c +index 6d59e6906fddf..f13b2c9ea912d 100644 +--- a/arch/riscv/kernel/cpu.c ++++ b/arch/riscv/kernel/cpu.c +@@ -22,7 +22,8 @@ int riscv_of_processor_hartid(struct device_node *node) + return -ENODEV; + } + +- if (of_property_read_u32(node, "reg", &hart)) { ++ hart = of_get_cpu_hwid(node, 0); ++ if (hart == ~0U) { + pr_warn("Found CPU without hart ID\n"); + return -ENODEV; + } +-- +2.51.0 + diff --git a/queue-5.15/series b/queue-5.15/series index e34f9a297d..6ce0bb83da 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -60,3 +60,8 @@ net-enetc-correct-the-value-of-enetc_rxb_truesize.patch dpaa2-eth-fix-the-pointer-passed-to-ptr_align-on-tx-.patch arm64-mm-avoid-always-making-pte-dirty-in-pte_mkwrit.patch sctp-avoid-null-dereference-when-chunk-data-buffer-i.patch +riscv-use-of_get_cpu_hwid.patch +risc-v-correctly-print-supported-extensions.patch +risc-v-minimal-parser-for-riscv-isa-strings.patch +riscv-cpu-add-64bit-hartid-support-on-rv64.patch +risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch diff --git a/queue-6.1/io_uring-correct-__must_hold-annotation-in-io_instal.patch b/queue-6.1/io_uring-correct-__must_hold-annotation-in-io_instal.patch new file mode 100644 index 0000000000..2dac11dae1 --- /dev/null +++ b/queue-6.1/io_uring-correct-__must_hold-annotation-in-io_instal.patch @@ -0,0 +1,38 @@ +From 2c9794e62a3ad26785d292703ecefd96f2d488fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 04:55:24 -0700 +Subject: io_uring: correct __must_hold annotation in io_install_fixed_file + +From: Alok Tiwari + +[ Upstream commit c5efc6a0b3940381d67887302ddb87a5cf623685 ] + +The __must_hold annotation references &req->ctx->uring_lock, but req +is not in scope in io_install_fixed_file. This change updates the +annotation to reference the correct ctx->uring_lock. +improving code clarity. + +Fixes: f110ed8498af ("io_uring: split out fixed file installation and removal") +Signed-off-by: Alok Tiwari +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/filetable.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/io_uring/filetable.c b/io_uring/filetable.c +index a64b4df0ac9c2..f9e59c650e893 100644 +--- a/io_uring/filetable.c ++++ b/io_uring/filetable.c +@@ -62,7 +62,7 @@ void io_free_file_tables(struct io_file_table *table) + + static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file, + u32 slot_index) +- __must_hold(&req->ctx->uring_lock) ++ __must_hold(&ctx->uring_lock) + { + bool needs_switch = false; + struct io_fixed_file *file_slot; +-- +2.51.0 + diff --git a/queue-6.1/risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch b/queue-6.1/risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch new file mode 100644 index 0000000000..28d346f6c5 --- /dev/null +++ b/queue-6.1/risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch @@ -0,0 +1,48 @@ +From d647ec5b8f5d2bbd0cb3da8ec3cff6609db867bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 21:30:05 -0600 +Subject: RISC-V: Define pgprot_dmacoherent() for non-coherent devices + +From: Anup Patel + +[ Upstream commit ca525d53f994d45c8140968b571372c45f555ac1 ] + +The pgprot_dmacoherent() is used when allocating memory for +non-coherent devices and by default pgprot_dmacoherent() is +same as pgprot_noncached() unless architecture overrides it. + +Currently, there is no pgprot_dmacoherent() definition for +RISC-V hence non-coherent device memory is being mapped as +IO thereby making CPU access to such memory slow. + +Define pgprot_dmacoherent() to be same as pgprot_writecombine() +for RISC-V so that CPU access non-coherent device memory as +NOCACHE which is better than accessing it as IO. + +Fixes: ff689fd21cb1 ("riscv: add RISC-V Svpbmt extension support") +Signed-off-by: Anup Patel +Tested-by: Han Gao +Tested-by: Guo Ren (Alibaba DAMO Academy) +Link: https://lore.kernel.org/r/20250820152316.1012757-1-apatel@ventanamicro.com +Signed-off-by: Paul Walmsley +Signed-off-by: Sasha Levin +--- + arch/riscv/include/asm/pgtable.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h +index bb19a643c5c2a..1a94e633c1445 100644 +--- a/arch/riscv/include/asm/pgtable.h ++++ b/arch/riscv/include/asm/pgtable.h +@@ -555,6 +555,8 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot) + return __pgprot(prot); + } + ++#define pgprot_dmacoherent pgprot_writecombine ++ + /* + * THP functions + */ +-- +2.51.0 + diff --git a/queue-6.1/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch b/queue-6.1/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch new file mode 100644 index 0000000000..9a6838857c --- /dev/null +++ b/queue-6.1/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch @@ -0,0 +1,46 @@ +From 395dc9886374a94e38cc82dbabced49c1fe6b836 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 22:00:09 +0530 +Subject: RISC-V: Don't print details of CPUs disabled in DT + +From: Anup Patel + +[ Upstream commit d2721bb165b3ee00dd23525885381af07fec852a ] + +Early boot stages may disable CPU DT nodes for unavailable +CPUs based on SKU, pinstraps, eFuse, etc. Currently, the +riscv_early_of_processor_hartid() prints details of a CPU +if it is disabled in DT which has no value and gives a +false impression to the users that there some issue with +the CPU. + +Fixes: e3d794d555cd ("riscv: treat cpu devicetree nodes without status as enabled") +Signed-off-by: Anup Patel +Reviewed-by: Andrew Jones +Reviewed-by: Conor Dooley +Link: https://lore.kernel.org/r/20251014163009.182381-1-apatel@ventanamicro.com +Signed-off-by: Paul Walmsley +Signed-off-by: Sasha Levin +--- + arch/riscv/kernel/cpu.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c +index 0f76181dc634d..e642b3dc42d27 100644 +--- a/arch/riscv/kernel/cpu.c ++++ b/arch/riscv/kernel/cpu.c +@@ -32,10 +32,8 @@ int riscv_of_processor_hartid(struct device_node *node, unsigned long *hart) + return -ENODEV; + } + +- if (!of_device_is_available(node)) { +- pr_info("CPU with hartid=%lu is not available\n", *hart); ++ if (!of_device_is_available(node)) + return -ENODEV; +- } + + if (of_property_read_string(node, "riscv,isa", &isa)) { + pr_warn("CPU with hartid=%lu has no \"riscv,isa\" property\n", *hart); +-- +2.51.0 + diff --git a/queue-6.1/series b/queue-6.1/series index 7f3affbbb2..f60aeb44fc 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -88,3 +88,6 @@ net-enetc-correct-the-value-of-enetc_rxb_truesize.patch dpaa2-eth-fix-the-pointer-passed-to-ptr_align-on-tx-.patch arm64-mm-avoid-always-making-pte-dirty-in-pte_mkwrit.patch sctp-avoid-null-dereference-when-chunk-data-buffer-i.patch +risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch +risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch +io_uring-correct-__must_hold-annotation-in-io_instal.patch diff --git a/queue-6.12/arm64-dts-broadcom-bcm2712-add-default-gic-address-c.patch b/queue-6.12/arm64-dts-broadcom-bcm2712-add-default-gic-address-c.patch new file mode 100644 index 0000000000..2b93a739e6 --- /dev/null +++ b/queue-6.12/arm64-dts-broadcom-bcm2712-add-default-gic-address-c.patch @@ -0,0 +1,46 @@ +From 348b53c3692ec06320fedc9a0a95acda76be653a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Aug 2025 15:34:08 +0200 +Subject: arm64: dts: broadcom: bcm2712: Add default GIC address cells + +From: Krzysztof Kozlowski + +[ Upstream commit 278b6cabf18bd804f956b98a2f1068717acdbfe3 ] + +Add missing address-cells 0 to GIC interrupt node to silence W=1 +warning: + + bcm2712.dtsi:494.4-497.31: Warning (interrupt_map): /axi/pcie@1000110000:interrupt-map: + Missing property '#address-cells' in node /soc@107c000000/interrupt-controller@7fff9000, using 0 as fallback + +Value '0' is correct because: +1. GIC interrupt controller does not have children, +2. interrupt-map property (in PCI node) consists of five components and + the fourth component "parent unit address", which size is defined by + '#address-cells' of the node pointed to by the interrupt-parent + component, is not used (=0) + +Signed-off-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20250822133407.312505-2-krzysztof.kozlowski@linaro.org +Signed-off-by: Florian Fainelli +Stable-dep-of: aa960b597600 ("arm64: dts: broadcom: bcm2712: Define VGIC interrupt") +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi +index 447bfa060918c..0f38236501743 100644 +--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi ++++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi +@@ -263,6 +263,7 @@ + <0x7fffc000 0x2000>, + <0x7fffe000 0x2000>; + interrupt-controller; ++ #address-cells = <0>; + #interrupt-cells = <3>; + }; + }; +-- +2.51.0 + diff --git a/queue-6.12/arm64-dts-broadcom-bcm2712-define-vgic-interrupt.patch b/queue-6.12/arm64-dts-broadcom-bcm2712-define-vgic-interrupt.patch new file mode 100644 index 0000000000..989d790928 --- /dev/null +++ b/queue-6.12/arm64-dts-broadcom-bcm2712-define-vgic-interrupt.patch @@ -0,0 +1,40 @@ +From add60c155326d968f7bc9399006c5a80d497ff4d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Sep 2025 09:56:05 +0100 +Subject: arm64: dts: broadcom: bcm2712: Define VGIC interrupt + +From: Peter Robinson + +[ Upstream commit aa960b597600bed80fe171729057dd6aa188b5b5 ] + +Define the interrupt in the GICv2 for vGIC so KVM +can be used, it was missed from the original upstream +DTB for some reason. + +Signed-off-by: Peter Robinson +Cc: Andrea della Porta +Cc: Phil Elwell +Fixes: faa3381267d0 ("arm64: dts: broadcom: Add minimal support for Raspberry Pi 5") +Link: https://lore.kernel.org/r/20250924085612.1039247-1-pbrobinson@gmail.com +Signed-off-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi +index 0f38236501743..209f99b1ceae7 100644 +--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi ++++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi +@@ -264,6 +264,8 @@ + <0x7fffe000 0x2000>; + interrupt-controller; + #address-cells = <0>; ++ interrupts = ; + #interrupt-cells = <3>; + }; + }; +-- +2.51.0 + diff --git a/queue-6.12/drm-panic-fix-drawing-the-logo-on-a-small-narrow-scr.patch b/queue-6.12/drm-panic-fix-drawing-the-logo-on-a-small-narrow-scr.patch new file mode 100644 index 0000000000..3cb03b1975 --- /dev/null +++ b/queue-6.12/drm-panic-fix-drawing-the-logo-on-a-small-narrow-scr.patch @@ -0,0 +1,40 @@ +From eab9f21c9db4bad6283a565679683c466b44075f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 14:24:48 +0200 +Subject: drm/panic: Fix drawing the logo on a small narrow screen + +From: Jocelyn Falempe + +[ Upstream commit 179753aa5b7890b311968c033d08f558f0a7be21 ] + +If the logo width is bigger than the framebuffer width, and the +height is big enough to hold the logo and the message, it will draw +at x coordinate that are higher than the width, and ends up in a +corrupted image. + +Fixes: 4b570ac2eb54 ("drm/rect: Add drm_rect_overlap()") +Reviewed-by: Javier Martinez Canillas +Link: https://lore.kernel.org/r/20251009122955.562888-2-jfalempe@redhat.com +Signed-off-by: Jocelyn Falempe +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_panic.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c +index f128d345b16df..932a54b674794 100644 +--- a/drivers/gpu/drm/drm_panic.c ++++ b/drivers/gpu/drm/drm_panic.c +@@ -306,6 +306,9 @@ static void drm_panic_logo_rect(struct drm_rect *rect, const struct font_desc *f + static void drm_panic_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect *rect, + const struct font_desc *font, u32 fg_color) + { ++ if (rect->x2 > sb->width || rect->y2 > sb->height) ++ return; ++ + if (logo_mono) + drm_panic_blit(sb, rect, logo_mono->data, + DIV_ROUND_UP(drm_rect_width(rect), 8), 1, fg_color); +-- +2.51.0 + diff --git a/queue-6.12/drm-panic-fix-qr_code-ensure-vmargin-is-positive.patch b/queue-6.12/drm-panic-fix-qr_code-ensure-vmargin-is-positive.patch new file mode 100644 index 0000000000..75bb926ba4 --- /dev/null +++ b/queue-6.12/drm-panic-fix-qr_code-ensure-vmargin-is-positive.patch @@ -0,0 +1,43 @@ +From c79d36988f9ba7f9a53cb6c9e17a92d6ae418e1d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 14:24:50 +0200 +Subject: drm/panic: Fix qr_code, ensure vmargin is positive + +From: Jocelyn Falempe + +[ Upstream commit 4fcffb5e5c8c0c8e2ad9c99a22305a0afbecc294 ] + +Depending on qr_code size and screen size, the vertical margin can +be negative, that means there is not enough room to draw the qr_code. + +So abort early, to avoid a segfault by trying to draw at negative +coordinates. + +Fixes: cb5164ac43d0f ("drm/panic: Add a QR code panic screen") +Reviewed-by: Javier Martinez Canillas +Link: https://lore.kernel.org/r/20251009122955.562888-4-jfalempe@redhat.com +Signed-off-by: Jocelyn Falempe +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_panic.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c +index 932a54b674794..0aa87eafdacd5 100644 +--- a/drivers/gpu/drm/drm_panic.c ++++ b/drivers/gpu/drm/drm_panic.c +@@ -618,7 +618,10 @@ static int _draw_panic_static_qr_code(struct drm_scanout_buffer *sb) + pr_debug("QR width %d and scale %d\n", qr_width, scale); + r_qr_canvas = DRM_RECT_INIT(0, 0, qr_canvas_width * scale, qr_canvas_width * scale); + +- v_margin = (sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg)) / 5; ++ v_margin = sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg); ++ if (v_margin < 0) ++ return -ENOSPC; ++ v_margin /= 5; + + drm_rect_translate(&r_qr_canvas, (sb->width - r_qr_canvas.x2) / 2, 2 * v_margin); + r_qr = DRM_RECT_INIT(r_qr_canvas.x1 + QR_MARGIN * scale, r_qr_canvas.y1 + QR_MARGIN * scale, +-- +2.51.0 + diff --git a/queue-6.12/drm-panthor-fix-kernel-panic-on-partial-unmap-of-a-g.patch b/queue-6.12/drm-panthor-fix-kernel-panic-on-partial-unmap-of-a-g.patch new file mode 100644 index 0000000000..e7104752bc --- /dev/null +++ b/queue-6.12/drm-panthor-fix-kernel-panic-on-partial-unmap-of-a-g.patch @@ -0,0 +1,104 @@ +From 6538e24b1ce706f42675005e84e1195a0c2c8069 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 11:29:22 +0100 +Subject: drm/panthor: Fix kernel panic on partial unmap of a GPU VA region + +From: Akash Goel + +[ Upstream commit 4eabd0d8791eaf9a7b114ccbf56eb488aefe7b1f ] + +This commit address a kernel panic issue that can happen if Userspace +tries to partially unmap a GPU virtual region (aka drm_gpuva). +The VM_BIND interface allows partial unmapping of a BO. + +Panthor driver pre-allocates memory for the new drm_gpuva structures +that would be needed for the map/unmap operation, done using drm_gpuvm +layer. It expected that only one new drm_gpuva would be needed on umap +but a partial unmap can require 2 new drm_gpuva and that's why it +ended up doing a NULL pointer dereference causing a kernel panic. + +Following dump was seen when partial unmap was exercised. + Unable to handle kernel NULL pointer dereference at virtual address 0000000000000078 + Mem abort info: + ESR = 0x0000000096000046 + EC = 0x25: DABT (current EL), IL = 32 bits + SET = 0, FnV = 0 + EA = 0, S1PTW = 0 + FSC = 0x06: level 2 translation fault + Data abort info: + ISV = 0, ISS = 0x00000046, ISS2 = 0x00000000 + CM = 0, WnR = 1, TnD = 0, TagAccess = 0 + GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 + user pgtable: 4k pages, 48-bit VAs, pgdp=000000088a863000 + [000000000000078] pgd=080000088a842003, p4d=080000088a842003, pud=0800000884bf5003, pmd=0000000000000000 + Internal error: Oops: 0000000096000046 [#1] PREEMPT SMP + + pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) + pc : panthor_gpuva_sm_step_remap+0xe4/0x330 [panthor] + lr : panthor_gpuva_sm_step_remap+0x6c/0x330 [panthor] + sp : ffff800085d43970 + x29: ffff800085d43970 x28: ffff00080363e440 x27: ffff0008090c6000 + x26: 0000000000000030 x25: ffff800085d439f8 x24: ffff00080d402000 + x23: ffff800085d43b60 x22: ffff800085d439e0 x21: ffff00080abdb180 + x20: 0000000000000000 x19: 0000000000000000 x18: 0000000000000010 + x17: 6e656c202c303030 x16: 3666666666646466 x15: 393d61766f69202c + x14: 312d3d7361203a70 x13: 303030323d6e656c x12: ffff80008324bf58 + x11: 0000000000000003 x10: 0000000000000002 x9 : ffff8000801a6a9c + x8 : ffff00080360b300 x7 : 0000000000000000 x6 : 000000088aa35fc7 + x5 : fff1000080000000 x4 : ffff8000842ddd30 x3 : 0000000000000001 + x2 : 0000000100000000 x1 : 0000000000000001 x0 : 0000000000000078 + Call trace: + panthor_gpuva_sm_step_remap+0xe4/0x330 [panthor] + op_remap_cb.isra.22+0x50/0x80 + __drm_gpuvm_sm_unmap+0x10c/0x1c8 + drm_gpuvm_sm_unmap+0x40/0x60 + panthor_vm_exec_op+0xb4/0x3d0 [panthor] + panthor_vm_bind_exec_sync_op+0x154/0x278 [panthor] + panthor_ioctl_vm_bind+0x160/0x4a0 [panthor] + drm_ioctl_kernel+0xbc/0x138 + drm_ioctl+0x240/0x500 + __arm64_sys_ioctl+0xb0/0xf8 + invoke_syscall+0x4c/0x110 + el0_svc_common.constprop.1+0x98/0xf8 + do_el0_svc+0x24/0x38 + el0_svc+0x40/0xf8 + el0t_64_sync_handler+0xa0/0xc8 + el0t_64_sync+0x174/0x178 + +Signed-off-by: Akash Goel +Reviewed-by: Boris Brezillon +Reviewed-by: Liviu Dudau +Fixes: 647810ec2476 ("drm/panthor: Add the MMU/VM logical block") +Reviewed-by: Steven Price +Signed-off-by: Steven Price +Link: https://lore.kernel.org/r/20251017102922.670084-1-akash.goel@arm.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_mmu.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c +index b57824abeb9ee..2214dbf472fa4 100644 +--- a/drivers/gpu/drm/panthor/panthor_mmu.c ++++ b/drivers/gpu/drm/panthor/panthor_mmu.c +@@ -1168,10 +1168,14 @@ panthor_vm_op_ctx_prealloc_vmas(struct panthor_vm_op_ctx *op_ctx) + break; + + case DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP: +- /* Partial unmaps might trigger a remap with either a prev or a next VA, +- * but not both. ++ /* Two VMAs can be needed for an unmap, as an unmap can happen ++ * in the middle of a drm_gpuva, requiring a remap with both ++ * prev & next VA. Or an unmap can span more than one drm_gpuva ++ * where the first and last ones are covered partially, requring ++ * a remap for the first with a prev VA and remap for the last ++ * with a next VA. + */ +- vma_count = 1; ++ vma_count = 2; + break; + + default: +-- +2.51.0 + diff --git a/queue-6.12/firmware-arm_scmi-account-for-failed-debug-initializ.patch b/queue-6.12/firmware-arm_scmi-account-for-failed-debug-initializ.patch new file mode 100644 index 0000000000..7ad91f5f23 --- /dev/null +++ b/queue-6.12/firmware-arm_scmi-account-for-failed-debug-initializ.patch @@ -0,0 +1,206 @@ +From 58d3e2680bea98d172b1ea48f59082160eee1871 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 12:53:44 +0100 +Subject: firmware: arm_scmi: Account for failed debug initialization + +From: Cristian Marussi + +[ Upstream commit 2290ab43b9d8eafb8046387f10a8dfa2b030ba46 ] + +When the SCMI debug subsystem fails to initialize, the related debug root +will be missing, and the underlying descriptor will be NULL. + +Handle this fault condition in the SCMI debug helpers that maintain +metrics counters. + +Fixes: 0b3d48c4726e ("firmware: arm_scmi: Track basic SCMI communication debug metrics") +Signed-off-by: Cristian Marussi +Message-Id: <20251014115346.2391418-1-cristian.marussi@arm.com> +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_scmi/common.h | 24 ++++++++++++++-- + drivers/firmware/arm_scmi/driver.c | 44 ++++++++++-------------------- + 2 files changed, 35 insertions(+), 33 deletions(-) + +diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h +index cdec50a698a10..87acc795f7436 100644 +--- a/drivers/firmware/arm_scmi/common.h ++++ b/drivers/firmware/arm_scmi/common.h +@@ -297,10 +297,28 @@ enum debug_counters { + SCMI_DEBUG_COUNTERS_LAST + }; + +-static inline void scmi_inc_count(atomic_t *arr, int stat) ++/** ++ * struct scmi_debug_info - Debug common info ++ * @top_dentry: A reference to the top debugfs dentry ++ * @name: Name of this SCMI instance ++ * @type: Type of this SCMI instance ++ * @is_atomic: Flag to state if the transport of this instance is atomic ++ * @counters: An array of atomic_c's used for tracking statistics (if enabled) ++ */ ++struct scmi_debug_info { ++ struct dentry *top_dentry; ++ const char *name; ++ const char *type; ++ bool is_atomic; ++ atomic_t counters[SCMI_DEBUG_COUNTERS_LAST]; ++}; ++ ++static inline void scmi_inc_count(struct scmi_debug_info *dbg, int stat) + { +- if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) +- atomic_inc(&arr[stat]); ++ if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) { ++ if (dbg) ++ atomic_inc(&dbg->counters[stat]); ++ } + } + + enum scmi_bad_msg { +diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c +index f1abe605865ad..5b4df0a27e22f 100644 +--- a/drivers/firmware/arm_scmi/driver.c ++++ b/drivers/firmware/arm_scmi/driver.c +@@ -111,22 +111,6 @@ struct scmi_protocol_instance { + + #define ph_to_pi(h) container_of(h, struct scmi_protocol_instance, ph) + +-/** +- * struct scmi_debug_info - Debug common info +- * @top_dentry: A reference to the top debugfs dentry +- * @name: Name of this SCMI instance +- * @type: Type of this SCMI instance +- * @is_atomic: Flag to state if the transport of this instance is atomic +- * @counters: An array of atomic_c's used for tracking statistics (if enabled) +- */ +-struct scmi_debug_info { +- struct dentry *top_dentry; +- const char *name; +- const char *type; +- bool is_atomic; +- atomic_t counters[SCMI_DEBUG_COUNTERS_LAST]; +-}; +- + /** + * struct scmi_info - Structure representing a SCMI instance + * +@@ -1000,7 +984,7 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr) + spin_unlock_irqrestore(&minfo->xfer_lock, flags); + + scmi_bad_message_trace(cinfo, msg_hdr, MSG_UNEXPECTED); +- scmi_inc_count(info->dbg->counters, ERR_MSG_UNEXPECTED); ++ scmi_inc_count(info->dbg, ERR_MSG_UNEXPECTED); + + return xfer; + } +@@ -1028,7 +1012,7 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr) + msg_type, xfer_id, msg_hdr, xfer->state); + + scmi_bad_message_trace(cinfo, msg_hdr, MSG_INVALID); +- scmi_inc_count(info->dbg->counters, ERR_MSG_INVALID); ++ scmi_inc_count(info->dbg, ERR_MSG_INVALID); + + /* On error the refcount incremented above has to be dropped */ + __scmi_xfer_put(minfo, xfer); +@@ -1073,7 +1057,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, + PTR_ERR(xfer)); + + scmi_bad_message_trace(cinfo, msg_hdr, MSG_NOMEM); +- scmi_inc_count(info->dbg->counters, ERR_MSG_NOMEM); ++ scmi_inc_count(info->dbg, ERR_MSG_NOMEM); + + scmi_clear_channel(info, cinfo); + return; +@@ -1089,7 +1073,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, + trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id, + xfer->hdr.id, "NOTI", xfer->hdr.seq, + xfer->hdr.status, xfer->rx.buf, xfer->rx.len); +- scmi_inc_count(info->dbg->counters, NOTIFICATION_OK); ++ scmi_inc_count(info->dbg, NOTIFICATION_OK); + + scmi_notify(cinfo->handle, xfer->hdr.protocol_id, + xfer->hdr.id, xfer->rx.buf, xfer->rx.len, ts); +@@ -1149,10 +1133,10 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo, + if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP) { + scmi_clear_channel(info, cinfo); + complete(xfer->async_done); +- scmi_inc_count(info->dbg->counters, DELAYED_RESPONSE_OK); ++ scmi_inc_count(info->dbg, DELAYED_RESPONSE_OK); + } else { + complete(&xfer->done); +- scmi_inc_count(info->dbg->counters, RESPONSE_OK); ++ scmi_inc_count(info->dbg, RESPONSE_OK); + } + + if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { +@@ -1261,7 +1245,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, + "timed out in resp(caller: %pS) - polling\n", + (void *)_RET_IP_); + ret = -ETIMEDOUT; +- scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_POLLED_TIMEOUT); ++ scmi_inc_count(info->dbg, XFERS_RESPONSE_POLLED_TIMEOUT); + } + } + +@@ -1286,7 +1270,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, + "RESP" : "resp", + xfer->hdr.seq, xfer->hdr.status, + xfer->rx.buf, xfer->rx.len); +- scmi_inc_count(info->dbg->counters, RESPONSE_POLLED_OK); ++ scmi_inc_count(info->dbg, RESPONSE_POLLED_OK); + + if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { + scmi_raw_message_report(info->raw, xfer, +@@ -1301,7 +1285,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, + dev_err(dev, "timed out in resp(caller: %pS)\n", + (void *)_RET_IP_); + ret = -ETIMEDOUT; +- scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_TIMEOUT); ++ scmi_inc_count(info->dbg, XFERS_RESPONSE_TIMEOUT); + } + } + +@@ -1385,13 +1369,13 @@ static int do_xfer(const struct scmi_protocol_handle *ph, + !is_transport_polling_capable(info->desc)) { + dev_warn_once(dev, + "Polling mode is not supported by transport.\n"); +- scmi_inc_count(info->dbg->counters, SENT_FAIL_POLLING_UNSUPPORTED); ++ scmi_inc_count(info->dbg, SENT_FAIL_POLLING_UNSUPPORTED); + return -EINVAL; + } + + cinfo = idr_find(&info->tx_idr, pi->proto->id); + if (unlikely(!cinfo)) { +- scmi_inc_count(info->dbg->counters, SENT_FAIL_CHANNEL_NOT_FOUND); ++ scmi_inc_count(info->dbg, SENT_FAIL_CHANNEL_NOT_FOUND); + return -EINVAL; + } + /* True ONLY if also supported by transport. */ +@@ -1425,19 +1409,19 @@ static int do_xfer(const struct scmi_protocol_handle *ph, + ret = info->desc->ops->send_message(cinfo, xfer); + if (ret < 0) { + dev_dbg(dev, "Failed to send message %d\n", ret); +- scmi_inc_count(info->dbg->counters, SENT_FAIL); ++ scmi_inc_count(info->dbg, SENT_FAIL); + return ret; + } + + trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id, + xfer->hdr.id, "CMND", xfer->hdr.seq, + xfer->hdr.status, xfer->tx.buf, xfer->tx.len); +- scmi_inc_count(info->dbg->counters, SENT_OK); ++ scmi_inc_count(info->dbg, SENT_OK); + + ret = scmi_wait_for_message_response(cinfo, xfer); + if (!ret && xfer->hdr.status) { + ret = scmi_to_linux_errno(xfer->hdr.status); +- scmi_inc_count(info->dbg->counters, ERR_PROTOCOL); ++ scmi_inc_count(info->dbg, ERR_PROTOCOL); + } + + if (info->desc->ops->mark_txdone) +-- +2.51.0 + diff --git a/queue-6.12/firmware-arm_scmi-fix-premature-scmi_xfer_flag_is_ra.patch b/queue-6.12/firmware-arm_scmi-fix-premature-scmi_xfer_flag_is_ra.patch new file mode 100644 index 0000000000..50efde71db --- /dev/null +++ b/queue-6.12/firmware-arm_scmi-fix-premature-scmi_xfer_flag_is_ra.patch @@ -0,0 +1,54 @@ +From c45957431bb8abe5b3a77bebb592634c5cb97a3c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 12:10:57 +0300 +Subject: firmware: arm_scmi: Fix premature SCMI_XFER_FLAG_IS_RAW clearing in + raw mode + +From: Artem Shimko + +[ Upstream commit 20b93a0088a595bceed4a026d527cbbac4e876c5 ] + +The SCMI_XFER_FLAG_IS_RAW flag was being cleared prematurely in +scmi_xfer_raw_put() before the transfer completion was properly +acknowledged by the raw message handlers. + +Move the clearing of SCMI_XFER_FLAG_IS_RAW and SCMI_XFER_FLAG_CHAN_SET +from scmi_xfer_raw_put() to __scmi_xfer_put() to ensure the flags remain +set throughout the entire raw message processing pipeline until the +transfer is returned to the free pool. + +Fixes: 3095a3e25d8f ("firmware: arm_scmi: Add xfer helpers to provide raw access") +Suggested-by: Cristian Marussi +Signed-off-by: Artem Shimko +Reviewed-by: Cristian Marussi +Message-Id: <20251008091057.1969260-1-a.shimko.dev@gmail.com> +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_scmi/driver.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c +index 5b4df0a27e22f..79866f3b6b3e7 100644 +--- a/drivers/firmware/arm_scmi/driver.c ++++ b/drivers/firmware/arm_scmi/driver.c +@@ -771,6 +771,7 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer) + hash_del(&xfer->node); + xfer->pending = false; + } ++ xfer->flags = 0; + hlist_add_head(&xfer->node, &minfo->free_xfers); + } + spin_unlock_irqrestore(&minfo->xfer_lock, flags); +@@ -789,8 +790,6 @@ void scmi_xfer_raw_put(const struct scmi_handle *handle, struct scmi_xfer *xfer) + { + struct scmi_info *info = handle_to_scmi_info(handle); + +- xfer->flags &= ~SCMI_XFER_FLAG_IS_RAW; +- xfer->flags &= ~SCMI_XFER_FLAG_CHAN_SET; + return __scmi_xfer_put(&info->tx_minfo, xfer); + } + +-- +2.51.0 + diff --git a/queue-6.12/gpio-ljca-fix-duplicated-irq-mapping.patch b/queue-6.12/gpio-ljca-fix-duplicated-irq-mapping.patch new file mode 100644 index 0000000000..66fc31d0ec --- /dev/null +++ b/queue-6.12/gpio-ljca-fix-duplicated-irq-mapping.patch @@ -0,0 +1,59 @@ +From f391be2a2d66c6c85face5a57a09a526c26a7018 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 15:02:30 +0800 +Subject: gpio: ljca: Fix duplicated IRQ mapping + +From: Haotian Zhang + +[ Upstream commit 4c4e6ea4a120cc5ab58e437c6ba123cbfc357d45 ] + +The generic_handle_domain_irq() function resolves the hardware IRQ +internally. The driver performed a duplicative mapping by calling +irq_find_mapping() first, which could lead to an RCU stall. + +Delete the redundant irq_find_mapping() call and pass the hardware IRQ +directly to generic_handle_domain_irq(). + +Fixes: c5a4b6fd31e8 ("gpio: Add support for Intel LJCA USB GPIO driver") +Signed-off-by: Haotian Zhang +Link: https://lore.kernel.org/r/20251023070231.1305-1-vulab@iscas.ac.cn +[Bartosz: remove unused variable] +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-ljca.c | 14 +++----------- + 1 file changed, 3 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpio/gpio-ljca.c b/drivers/gpio/gpio-ljca.c +index c2a9b42539744..c3a595c6f6c72 100644 +--- a/drivers/gpio/gpio-ljca.c ++++ b/drivers/gpio/gpio-ljca.c +@@ -281,22 +281,14 @@ static void ljca_gpio_event_cb(void *context, u8 cmd, const void *evt_data, + { + const struct ljca_gpio_packet *packet = evt_data; + struct ljca_gpio_dev *ljca_gpio = context; +- int i, irq; ++ int i; + + if (cmd != LJCA_GPIO_INT_EVENT) + return; + + for (i = 0; i < packet->num; i++) { +- irq = irq_find_mapping(ljca_gpio->gc.irq.domain, +- packet->item[i].index); +- if (!irq) { +- dev_err(ljca_gpio->gc.parent, +- "gpio_id %u does not mapped to IRQ yet\n", +- packet->item[i].index); +- return; +- } +- +- generic_handle_domain_irq(ljca_gpio->gc.irq.domain, irq); ++ generic_handle_domain_irq(ljca_gpio->gc.irq.domain, ++ packet->item[i].index); + set_bit(packet->item[i].index, ljca_gpio->reenable_irqs); + } + +-- +2.51.0 + diff --git a/queue-6.12/hwmon-sht3x-fix-error-handling.patch b/queue-6.12/hwmon-sht3x-fix-error-handling.patch new file mode 100644 index 0000000000..98f56b33c2 --- /dev/null +++ b/queue-6.12/hwmon-sht3x-fix-error-handling.patch @@ -0,0 +1,99 @@ +From df8d802592388c5a47f5bc8156c266f2a89ab868 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Oct 2025 06:04:57 -0700 +Subject: hwmon: (sht3x) Fix error handling + +From: Guenter Roeck + +[ Upstream commit 8dcc66ad379ec0642fb281c45ccfd7d2d366e53f ] + +Handling of errors when reading status, temperature, and humidity returns +the error number as negative attribute value. Fix it up by returning +the error as return value. + +Fixes: a0ac418c6007c ("hwmon: (sht3x) convert some of sysfs interface to hwmon") +Cc: JuenKit Yip +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/sht3x.c | 27 +++++++++++++++++---------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/drivers/hwmon/sht3x.c b/drivers/hwmon/sht3x.c +index 650b0bcc2359e..94466e28dc56f 100644 +--- a/drivers/hwmon/sht3x.c ++++ b/drivers/hwmon/sht3x.c +@@ -294,24 +294,26 @@ static struct sht3x_data *sht3x_update_client(struct device *dev) + return data; + } + +-static int temp1_input_read(struct device *dev) ++static int temp1_input_read(struct device *dev, long *temp) + { + struct sht3x_data *data = sht3x_update_client(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + +- return data->temperature; ++ *temp = data->temperature; ++ return 0; + } + +-static int humidity1_input_read(struct device *dev) ++static int humidity1_input_read(struct device *dev, long *humidity) + { + struct sht3x_data *data = sht3x_update_client(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + +- return data->humidity; ++ *humidity = data->humidity; ++ return 0; + } + + /* +@@ -709,6 +711,7 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *val) + { + enum sht3x_limits index; ++ int ret; + + switch (type) { + case hwmon_chip: +@@ -723,10 +726,12 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type, + case hwmon_temp: + switch (attr) { + case hwmon_temp_input: +- *val = temp1_input_read(dev); +- break; ++ return temp1_input_read(dev, val); + case hwmon_temp_alarm: +- *val = temp1_alarm_read(dev); ++ ret = temp1_alarm_read(dev); ++ if (ret < 0) ++ return ret; ++ *val = ret; + break; + case hwmon_temp_max: + index = limit_max; +@@ -751,10 +756,12 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type, + case hwmon_humidity: + switch (attr) { + case hwmon_humidity_input: +- *val = humidity1_input_read(dev); +- break; ++ return humidity1_input_read(dev, val); + case hwmon_humidity_alarm: +- *val = humidity1_alarm_read(dev); ++ ret = humidity1_alarm_read(dev); ++ if (ret < 0) ++ return ret; ++ *val = ret; + break; + case hwmon_humidity_max: + index = limit_max; +-- +2.51.0 + diff --git a/queue-6.12/io_uring-correct-__must_hold-annotation-in-io_instal.patch b/queue-6.12/io_uring-correct-__must_hold-annotation-in-io_instal.patch new file mode 100644 index 0000000000..5768f06eba --- /dev/null +++ b/queue-6.12/io_uring-correct-__must_hold-annotation-in-io_instal.patch @@ -0,0 +1,38 @@ +From aae15cb30dd1831a7cda17910e9291edffe4fc9e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 04:55:24 -0700 +Subject: io_uring: correct __must_hold annotation in io_install_fixed_file + +From: Alok Tiwari + +[ Upstream commit c5efc6a0b3940381d67887302ddb87a5cf623685 ] + +The __must_hold annotation references &req->ctx->uring_lock, but req +is not in scope in io_install_fixed_file. This change updates the +annotation to reference the correct ctx->uring_lock. +improving code clarity. + +Fixes: f110ed8498af ("io_uring: split out fixed file installation and removal") +Signed-off-by: Alok Tiwari +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/filetable.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/io_uring/filetable.c b/io_uring/filetable.c +index 997c56d32ee6c..6183d61c7222d 100644 +--- a/io_uring/filetable.c ++++ b/io_uring/filetable.c +@@ -62,7 +62,7 @@ void io_free_file_tables(struct io_file_table *table) + + static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file, + u32 slot_index) +- __must_hold(&req->ctx->uring_lock) ++ __must_hold(&ctx->uring_lock) + { + struct io_fixed_file *file_slot; + int ret; +-- +2.51.0 + diff --git a/queue-6.12/nbd-override-creds-to-kernel-when-calling-sock_-send.patch b/queue-6.12/nbd-override-creds-to-kernel-when-calling-sock_-send.patch new file mode 100644 index 0000000000..f2c887424e --- /dev/null +++ b/queue-6.12/nbd-override-creds-to-kernel-when-calling-sock_-send.patch @@ -0,0 +1,190 @@ +From a65b06a146745e96d52c8ac6b125aa124da3b48b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Oct 2025 10:09:00 +0200 +Subject: nbd: override creds to kernel when calling sock_{send,recv}msg() + +From: Ondrej Mosnacek + +[ Upstream commit 81ccca31214e11ea2b537fd35d4f66d7cf46268e ] + +sock_{send,recv}msg() internally calls security_socket_{send,recv}msg(), +which does security checks (e.g. SELinux) for socket access against the +current task. However, _sock_xmit() in drivers/block/nbd.c may be called +indirectly from a userspace syscall, where the NBD socket access would +be incorrectly checked against the calling userspace task (which simply +tries to read/write a file that happens to reside on an NBD device). + +To fix this, temporarily override creds to kernel ones before calling +the sock_*() functions. This allows the security modules to recognize +this as internal access by the kernel, which will normally be allowed. + +A way to trigger the issue is to do the following (on a system with +SELinux set to enforcing): + + ### Create nbd device: + truncate -s 256M /tmp/testfile + nbd-server localhost:10809 /tmp/testfile + + ### Connect to the nbd server: + nbd-client localhost + + ### Create mdraid array + mdadm --create -l 1 -n 2 /dev/md/testarray /dev/nbd0 missing + +After these steps, assuming the SELinux policy doesn't allow the +unexpected access pattern, errors will be visible on the kernel console: + +[ 142.204243] nbd0: detected capacity change from 0 to 524288 +[ 165.189967] md: async del_gendisk mode will be removed in future, please upgrade to mdadm-4.5+ +[ 165.252299] md/raid1:md127: active with 1 out of 2 mirrors +[ 165.252725] md127: detected capacity change from 0 to 522240 +[ 165.255434] block nbd0: Send control failed (result -13) +[ 165.255718] block nbd0: Request send failed, requeueing +[ 165.256006] block nbd0: Dead connection, failed to find a fallback +[ 165.256041] block nbd0: Receive control failed (result -32) +[ 165.256423] block nbd0: shutting down sockets +[ 165.257196] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.257736] Buffer I/O error on dev md127, logical block 0, async page read +[ 165.258263] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.259376] Buffer I/O error on dev md127, logical block 0, async page read +[ 165.259920] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.260628] Buffer I/O error on dev md127, logical block 0, async page read +[ 165.261661] ldm_validate_partition_table(): Disk read failed. +[ 165.262108] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.262769] Buffer I/O error on dev md127, logical block 0, async page read +[ 165.263697] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.264412] Buffer I/O error on dev md127, logical block 0, async page read +[ 165.265412] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.265872] Buffer I/O error on dev md127, logical block 0, async page read +[ 165.266378] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.267168] Buffer I/O error on dev md127, logical block 0, async page read +[ 165.267564] md127: unable to read partition table +[ 165.269581] I/O error, dev nbd0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.269960] Buffer I/O error on dev nbd0, logical block 0, async page read +[ 165.270316] I/O error, dev nbd0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.270913] Buffer I/O error on dev nbd0, logical block 0, async page read +[ 165.271253] I/O error, dev nbd0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.271809] Buffer I/O error on dev nbd0, logical block 0, async page read +[ 165.272074] ldm_validate_partition_table(): Disk read failed. +[ 165.272360] nbd0: unable to read partition table +[ 165.289004] ldm_validate_partition_table(): Disk read failed. +[ 165.289614] nbd0: unable to read partition table + +The corresponding SELinux denial on Fedora/RHEL will look like this +(assuming it's not silenced): +type=AVC msg=audit(1758104872.510:116): avc: denied { write } for pid=1908 comm="mdadm" laddr=::1 lport=32772 faddr=::1 fport=10809 scontext=system_u:system_r:mdadm_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=tcp_socket permissive=0 + +The respective backtrace looks like this: +@security[mdadm, -13, + handshake_exit+221615650 + handshake_exit+221615650 + handshake_exit+221616465 + security_socket_sendmsg+5 + sock_sendmsg+106 + handshake_exit+221616150 + sock_sendmsg+5 + __sock_xmit+162 + nbd_send_cmd+597 + nbd_handle_cmd+377 + nbd_queue_rq+63 + blk_mq_dispatch_rq_list+653 + __blk_mq_do_dispatch_sched+184 + __blk_mq_sched_dispatch_requests+333 + blk_mq_sched_dispatch_requests+38 + blk_mq_run_hw_queue+239 + blk_mq_dispatch_plug_list+382 + blk_mq_flush_plug_list.part.0+55 + __blk_flush_plug+241 + __submit_bio+353 + submit_bio_noacct_nocheck+364 + submit_bio_wait+84 + __blkdev_direct_IO_simple+232 + blkdev_read_iter+162 + vfs_read+591 + ksys_read+95 + do_syscall_64+92 + entry_SYSCALL_64_after_hwframe+120 +]: 1 + +The issue has started to appear since commit 060406c61c7c ("block: add +plug while submitting IO"). + +Cc: Ming Lei +Link: https://bugzilla.redhat.com/show_bug.cgi?id=2348878 +Fixes: 060406c61c7c ("block: add plug while submitting IO") +Signed-off-by: Ondrej Mosnacek +Acked-by: Paul Moore +Acked-by: Stephen Smalley +Reviewed-by: Ming Lei +Tested-by: Ming Lei +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index de692eed98740..deb298371a6a3 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -52,6 +52,7 @@ + static DEFINE_IDR(nbd_index_idr); + static DEFINE_MUTEX(nbd_index_mutex); + static struct workqueue_struct *nbd_del_wq; ++static struct cred *nbd_cred; + static int nbd_total_devices = 0; + + struct nbd_sock { +@@ -557,6 +558,7 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send, + int result; + struct msghdr msg = {} ; + unsigned int noreclaim_flag; ++ const struct cred *old_cred; + + if (unlikely(!sock)) { + dev_err_ratelimited(disk_to_dev(nbd->disk), +@@ -565,6 +567,8 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send, + return -EINVAL; + } + ++ old_cred = override_creds(nbd_cred); ++ + msg.msg_iter = *iter; + + noreclaim_flag = memalloc_noreclaim_save(); +@@ -589,6 +593,8 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send, + + memalloc_noreclaim_restore(noreclaim_flag); + ++ revert_creds(old_cred); ++ + return result; + } + +@@ -2605,7 +2611,15 @@ static int __init nbd_init(void) + return -ENOMEM; + } + ++ nbd_cred = prepare_kernel_cred(&init_task); ++ if (!nbd_cred) { ++ destroy_workqueue(nbd_del_wq); ++ unregister_blkdev(NBD_MAJOR, "nbd"); ++ return -ENOMEM; ++ } ++ + if (genl_register_family(&nbd_genl_family)) { ++ put_cred(nbd_cred); + destroy_workqueue(nbd_del_wq); + unregister_blkdev(NBD_MAJOR, "nbd"); + return -EINVAL; +@@ -2660,6 +2674,7 @@ static void __exit nbd_cleanup(void) + /* Also wait for nbd_dev_remove_work() completes */ + destroy_workqueue(nbd_del_wq); + ++ put_cred(nbd_cred); + idr_destroy(&nbd_index_idr); + unregister_blkdev(NBD_MAJOR, "nbd"); + } +-- +2.51.0 + diff --git a/queue-6.12/risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch b/queue-6.12/risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch new file mode 100644 index 0000000000..1fd55ed3df --- /dev/null +++ b/queue-6.12/risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch @@ -0,0 +1,48 @@ +From c475f368a902235612a7a2441bd3395ea7eeabd1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 21:30:05 -0600 +Subject: RISC-V: Define pgprot_dmacoherent() for non-coherent devices + +From: Anup Patel + +[ Upstream commit ca525d53f994d45c8140968b571372c45f555ac1 ] + +The pgprot_dmacoherent() is used when allocating memory for +non-coherent devices and by default pgprot_dmacoherent() is +same as pgprot_noncached() unless architecture overrides it. + +Currently, there is no pgprot_dmacoherent() definition for +RISC-V hence non-coherent device memory is being mapped as +IO thereby making CPU access to such memory slow. + +Define pgprot_dmacoherent() to be same as pgprot_writecombine() +for RISC-V so that CPU access non-coherent device memory as +NOCACHE which is better than accessing it as IO. + +Fixes: ff689fd21cb1 ("riscv: add RISC-V Svpbmt extension support") +Signed-off-by: Anup Patel +Tested-by: Han Gao +Tested-by: Guo Ren (Alibaba DAMO Academy) +Link: https://lore.kernel.org/r/20250820152316.1012757-1-apatel@ventanamicro.com +Signed-off-by: Paul Walmsley +Signed-off-by: Sasha Levin +--- + arch/riscv/include/asm/pgtable.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h +index 03881122506a7..87c7d94c71f13 100644 +--- a/arch/riscv/include/asm/pgtable.h ++++ b/arch/riscv/include/asm/pgtable.h +@@ -655,6 +655,8 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot) + return __pgprot(prot); + } + ++#define pgprot_dmacoherent pgprot_writecombine ++ + /* + * THP functions + */ +-- +2.51.0 + diff --git a/queue-6.12/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch b/queue-6.12/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch new file mode 100644 index 0000000000..c5e3185c3a --- /dev/null +++ b/queue-6.12/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch @@ -0,0 +1,46 @@ +From c818603649f85f7b45854af3fed7790e2337655b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 22:00:09 +0530 +Subject: RISC-V: Don't print details of CPUs disabled in DT + +From: Anup Patel + +[ Upstream commit d2721bb165b3ee00dd23525885381af07fec852a ] + +Early boot stages may disable CPU DT nodes for unavailable +CPUs based on SKU, pinstraps, eFuse, etc. Currently, the +riscv_early_of_processor_hartid() prints details of a CPU +if it is disabled in DT which has no value and gives a +false impression to the users that there some issue with +the CPU. + +Fixes: e3d794d555cd ("riscv: treat cpu devicetree nodes without status as enabled") +Signed-off-by: Anup Patel +Reviewed-by: Andrew Jones +Reviewed-by: Conor Dooley +Link: https://lore.kernel.org/r/20251014163009.182381-1-apatel@ventanamicro.com +Signed-off-by: Paul Walmsley +Signed-off-by: Sasha Levin +--- + arch/riscv/kernel/cpu.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c +index f6b13e9f5e6cb..3dbc8cc557dd1 100644 +--- a/arch/riscv/kernel/cpu.c ++++ b/arch/riscv/kernel/cpu.c +@@ -62,10 +62,8 @@ int __init riscv_early_of_processor_hartid(struct device_node *node, unsigned lo + return -ENODEV; + } + +- if (!of_device_is_available(node)) { +- pr_info("CPU with hartid=%lu is not available\n", *hart); ++ if (!of_device_is_available(node)) + return -ENODEV; +- } + + if (of_property_read_string(node, "riscv,isa-base", &isa)) + goto old_interface; +-- +2.51.0 + diff --git a/queue-6.12/riscv-hwprobe-avoid-uninitialized-variable-use-in-hw.patch b/queue-6.12/riscv-hwprobe-avoid-uninitialized-variable-use-in-hw.patch new file mode 100644 index 0000000000..f711bbb5f1 --- /dev/null +++ b/queue-6.12/riscv-hwprobe-avoid-uninitialized-variable-use-in-hw.patch @@ -0,0 +1,59 @@ +From d6409eeb9696d633c25955f4efbc944a3cd294da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Oct 2025 09:32:12 -0600 +Subject: riscv: hwprobe: avoid uninitialized variable use in hwprobe_arch_id() + +From: Paul Walmsley + +[ Upstream commit b7776a802f2f80139f96530a489dd00fd7089eda ] + +Resolve this smatch warning: + + arch/riscv/kernel/sys_hwprobe.c:50 hwprobe_arch_id() error: uninitialized symbol 'cpu_id'. + +This could happen if hwprobe_arch_id() was called with a key ID of +something other than MVENDORID, MIMPID, and MARCHID. This does not +happen in the current codebase. The only caller of hwprobe_arch_id() +is a function that only passes one of those three key IDs. + +For the sake of reducing static analyzer warning noise, and in the +unlikely event that hwprobe_arch_id() is someday called with some +other key ID, validate hwprobe_arch_id()'s input to ensure that +'cpu_id' is always initialized before use. + +Fixes: ea3de9ce8aa280 ("RISC-V: Add a syscall for HW probing") +Cc: Evan Green +Signed-off-by: Paul Walmsley +Link: https://lore.kernel.org/r/cf5a13ec-19d0-9862-059b-943f36107bf3@kernel.org +Signed-off-by: Sasha Levin +--- + arch/riscv/kernel/sys_hwprobe.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c +index cea0ca2bf2a25..fc62548888c58 100644 +--- a/arch/riscv/kernel/sys_hwprobe.c ++++ b/arch/riscv/kernel/sys_hwprobe.c +@@ -25,6 +25,11 @@ static void hwprobe_arch_id(struct riscv_hwprobe *pair, + bool first = true; + int cpu; + ++ if (pair->key != RISCV_HWPROBE_KEY_MVENDORID && ++ pair->key != RISCV_HWPROBE_KEY_MIMPID && ++ pair->key != RISCV_HWPROBE_KEY_MARCHID) ++ goto out; ++ + for_each_cpu(cpu, cpus) { + u64 cpu_id; + +@@ -55,6 +60,7 @@ static void hwprobe_arch_id(struct riscv_hwprobe *pair, + } + } + ++out: + pair->value = id; + } + +-- +2.51.0 + diff --git a/queue-6.12/sched-remove-never-used-code-in-mm_cid_get.patch b/queue-6.12/sched-remove-never-used-code-in-mm_cid_get.patch new file mode 100644 index 0000000000..c88ec394e8 --- /dev/null +++ b/queue-6.12/sched-remove-never-used-code-in-mm_cid_get.patch @@ -0,0 +1,47 @@ +From 87d6b3954328eabb1b80712a6a80d1abbdd6c6c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 11:19:34 +0200 +Subject: sched: Remove never used code in mm_cid_get() + +From: Andy Shevchenko + +[ Upstream commit 53abe3e1c154628cc74e33a1bfcd865656e433a5 ] + +Clang is not happy with set but unused variable (this is visible +with `make W=1` build: + + kernel/sched/sched.h:3744:18: error: variable 'cpumask' set but not used [-Werror,-Wunused-but-set-variable] + +It seems like the variable was never used along with the assignment +that does not have side effects as far as I can see. Remove those +altogether. + +Fixes: 223baf9d17f2 ("sched: Fix performance regression introduced by mm_cid") +Signed-off-by: Andy Shevchenko +Tested-by: Eric Biggers +Reviewed-by: Breno Leitao +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + kernel/sched/sched.h | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h +index a441990fe808d..cf541c4502d92 100644 +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -3731,11 +3731,9 @@ static inline int __mm_cid_get(struct rq *rq, struct mm_struct *mm) + static inline int mm_cid_get(struct rq *rq, struct mm_struct *mm) + { + struct mm_cid __percpu *pcpu_cid = mm->pcpu_cid; +- struct cpumask *cpumask; + int cid; + + lockdep_assert_rq_held(rq); +- cpumask = mm_cidmask(mm); + cid = __this_cpu_read(pcpu_cid->cid); + if (mm_cid_is_valid(cid)) { + mm_cid_snapshot_time(rq, mm); +-- +2.51.0 + diff --git a/queue-6.12/series b/queue-6.12/series index af52b0a957..fe8161c788 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -42,3 +42,24 @@ ptp-ocp-fix-typo-using-index-1-instead-of-i-in-sma-i.patch sctp-avoid-null-dereference-when-chunk-data-buffer-i.patch net-phy-micrel-always-set-shared-phydev-for-lan8814.patch net-mlx5-fix-ipsec-cleanup-over-mpv-device.patch +spi-spi-nxp-fspi-add-extra-delay-after-dll-locked.patch +arm64-dts-broadcom-bcm2712-add-default-gic-address-c.patch +arm64-dts-broadcom-bcm2712-define-vgic-interrupt.patch +firmware-arm_scmi-account-for-failed-debug-initializ.patch +firmware-arm_scmi-fix-premature-scmi_xfer_flag_is_ra.patch +spi-airoha-return-an-error-for-continuous-mode-dirma.patch +spi-airoha-add-support-of-dual-quad-wires-spi-modes-.patch +spi-airoha-do-not-keep-tx-rx-dma-buffer-always-mappe.patch +spi-airoha-switch-back-to-non-dma-mode-in-the-case-o.patch +spi-airoha-fix-reading-writing-of-flashes-with-more-.patch +drm-panthor-fix-kernel-panic-on-partial-unmap-of-a-g.patch +risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch +risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch +riscv-hwprobe-avoid-uninitialized-variable-use-in-hw.patch +hwmon-sht3x-fix-error-handling.patch +nbd-override-creds-to-kernel-when-calling-sock_-send.patch +drm-panic-fix-drawing-the-logo-on-a-small-narrow-scr.patch +drm-panic-fix-qr_code-ensure-vmargin-is-positive.patch +gpio-ljca-fix-duplicated-irq-mapping.patch +io_uring-correct-__must_hold-annotation-in-io_instal.patch +sched-remove-never-used-code-in-mm_cid_get.patch diff --git a/queue-6.12/spi-airoha-add-support-of-dual-quad-wires-spi-modes-.patch b/queue-6.12/spi-airoha-add-support-of-dual-quad-wires-spi-modes-.patch new file mode 100644 index 0000000000..eb0d460e4a --- /dev/null +++ b/queue-6.12/spi-airoha-add-support-of-dual-quad-wires-spi-modes-.patch @@ -0,0 +1,221 @@ +From c093c23806292cbc9d3e1daa4b4c9b2c0a8df434 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 15:16:54 +0300 +Subject: spi: airoha: add support of dual/quad wires spi modes to exec_op() + handler + +From: Mikhail Kshevetskiy + +[ Upstream commit edd2e261b1babb92213089b5feadca12e3459322 ] + +Booting without this patch and disabled dirmap support results in + +[ 2.980719] spi-nand spi0.0: Micron SPI NAND was found. +[ 2.986040] spi-nand spi0.0: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128 +[ 2.994709] 2 fixed-partitions partitions found on MTD device spi0.0 +[ 3.001075] Creating 2 MTD partitions on "spi0.0": +[ 3.005862] 0x000000000000-0x000000020000 : "bl2" +[ 3.011272] 0x000000020000-0x000010000000 : "ubi" +... +[ 6.195594] ubi0: attaching mtd1 +[ 13.338398] ubi0: scanning is finished +[ 13.342188] ubi0 error: ubi_read_volume_table: the layout volume was not found +[ 13.349784] ubi0 error: ubi_attach_mtd_dev: failed to attach mtd1, error -22 +[ 13.356897] UBI error: cannot attach mtd1 + +If dirmap is disabled or not supported in the spi driver, the dirmap requests +will be executed via exec_op() handler. Thus, if the hardware supports +dual/quad spi modes, then corresponding requests will be sent to exec_op() +handler. Current driver does not support such requests, so error is arrised. +As result the flash can't be read/write. + +This patch adds support of dual and quad wires spi modes to exec_op() handler. + +Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver") +Signed-off-by: Mikhail Kshevetskiy +Reviewed-by: AngeloGioacchino Del Regno +Link: https://patch.msgid.link/20251012121707.2296160-4-mikhail.kshevetskiy@iopsys.eu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-airoha-snfi.c | 108 ++++++++++++++++++++++++++-------- + 1 file changed, 82 insertions(+), 26 deletions(-) + +diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c +index 6930dea48f330..a3f766e04202f 100644 +--- a/drivers/spi/spi-airoha-snfi.c ++++ b/drivers/spi/spi-airoha-snfi.c +@@ -192,6 +192,14 @@ + #define SPI_NAND_OP_RESET 0xff + #define SPI_NAND_OP_DIE_SELECT 0xc2 + ++/* SNAND FIFO commands */ ++#define SNAND_FIFO_TX_BUSWIDTH_SINGLE 0x08 ++#define SNAND_FIFO_TX_BUSWIDTH_DUAL 0x09 ++#define SNAND_FIFO_TX_BUSWIDTH_QUAD 0x0a ++#define SNAND_FIFO_RX_BUSWIDTH_SINGLE 0x0c ++#define SNAND_FIFO_RX_BUSWIDTH_DUAL 0x0e ++#define SNAND_FIFO_RX_BUSWIDTH_QUAD 0x0f ++ + #define SPI_NAND_CACHE_SIZE (SZ_4K + SZ_256) + #define SPI_MAX_TRANSFER_SIZE 511 + +@@ -394,10 +402,26 @@ static int airoha_snand_set_mode(struct airoha_snand_ctrl *as_ctrl, + return regmap_write(as_ctrl->regmap_ctrl, REG_SPI_CTRL_DUMMY, 0); + } + +-static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, u8 cmd, +- const u8 *data, int len) ++static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, ++ const u8 *data, int len, int buswidth) + { + int i, data_len; ++ u8 cmd; ++ ++ switch (buswidth) { ++ case 0: ++ case 1: ++ cmd = SNAND_FIFO_TX_BUSWIDTH_SINGLE; ++ break; ++ case 2: ++ cmd = SNAND_FIFO_TX_BUSWIDTH_DUAL; ++ break; ++ case 4: ++ cmd = SNAND_FIFO_TX_BUSWIDTH_QUAD; ++ break; ++ default: ++ return -EINVAL; ++ } + + for (i = 0; i < len; i += data_len) { + int err; +@@ -416,16 +440,32 @@ static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, u8 cmd, + return 0; + } + +-static int airoha_snand_read_data(struct airoha_snand_ctrl *as_ctrl, u8 *data, +- int len) ++static int airoha_snand_read_data(struct airoha_snand_ctrl *as_ctrl, ++ u8 *data, int len, int buswidth) + { + int i, data_len; ++ u8 cmd; ++ ++ switch (buswidth) { ++ case 0: ++ case 1: ++ cmd = SNAND_FIFO_RX_BUSWIDTH_SINGLE; ++ break; ++ case 2: ++ cmd = SNAND_FIFO_RX_BUSWIDTH_DUAL; ++ break; ++ case 4: ++ cmd = SNAND_FIFO_RX_BUSWIDTH_QUAD; ++ break; ++ default: ++ return -EINVAL; ++ } + + for (i = 0; i < len; i += data_len) { + int err; + + data_len = min(len - i, SPI_MAX_TRANSFER_SIZE); +- err = airoha_snand_set_fifo_op(as_ctrl, 0xc, data_len); ++ err = airoha_snand_set_fifo_op(as_ctrl, cmd, data_len); + if (err) + return err; + +@@ -891,12 +931,28 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, + static int airoha_snand_exec_op(struct spi_mem *mem, + const struct spi_mem_op *op) + { +- u8 data[8], cmd, opcode = op->cmd.opcode; + struct airoha_snand_ctrl *as_ctrl; ++ int op_len, addr_len, dummy_len; ++ u8 buf[20], *data; + int i, err; + + as_ctrl = spi_controller_get_devdata(mem->spi->controller); + ++ op_len = op->cmd.nbytes; ++ addr_len = op->addr.nbytes; ++ dummy_len = op->dummy.nbytes; ++ ++ if (op_len + dummy_len + addr_len > sizeof(buf)) ++ return -EIO; ++ ++ data = buf; ++ for (i = 0; i < op_len; i++) ++ *data++ = op->cmd.opcode >> (8 * (op_len - i - 1)); ++ for (i = 0; i < addr_len; i++) ++ *data++ = op->addr.val >> (8 * (addr_len - i - 1)); ++ for (i = 0; i < dummy_len; i++) ++ *data++ = 0xff; ++ + /* switch to manual mode */ + err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); + if (err < 0) +@@ -907,40 +963,40 @@ static int airoha_snand_exec_op(struct spi_mem *mem, + return err; + + /* opcode */ +- err = airoha_snand_write_data(as_ctrl, 0x8, &opcode, sizeof(opcode)); ++ data = buf; ++ err = airoha_snand_write_data(as_ctrl, data, op_len, ++ op->cmd.buswidth); + if (err) + return err; + + /* addr part */ +- cmd = opcode == SPI_NAND_OP_GET_FEATURE ? 0x11 : 0x8; +- put_unaligned_be64(op->addr.val, data); +- +- for (i = ARRAY_SIZE(data) - op->addr.nbytes; +- i < ARRAY_SIZE(data); i++) { +- err = airoha_snand_write_data(as_ctrl, cmd, &data[i], +- sizeof(data[0])); ++ data += op_len; ++ if (addr_len) { ++ err = airoha_snand_write_data(as_ctrl, data, addr_len, ++ op->addr.buswidth); + if (err) + return err; + } + + /* dummy */ +- data[0] = 0xff; +- for (i = 0; i < op->dummy.nbytes; i++) { +- err = airoha_snand_write_data(as_ctrl, 0x8, &data[0], +- sizeof(data[0])); ++ data += addr_len; ++ if (dummy_len) { ++ err = airoha_snand_write_data(as_ctrl, data, dummy_len, ++ op->dummy.buswidth); + if (err) + return err; + } + + /* data */ +- if (op->data.dir == SPI_MEM_DATA_IN) { +- err = airoha_snand_read_data(as_ctrl, op->data.buf.in, +- op->data.nbytes); +- if (err) +- return err; +- } else { +- err = airoha_snand_write_data(as_ctrl, 0x8, op->data.buf.out, +- op->data.nbytes); ++ if (op->data.nbytes) { ++ if (op->data.dir == SPI_MEM_DATA_IN) ++ err = airoha_snand_read_data(as_ctrl, op->data.buf.in, ++ op->data.nbytes, ++ op->data.buswidth); ++ else ++ err = airoha_snand_write_data(as_ctrl, op->data.buf.out, ++ op->data.nbytes, ++ op->data.buswidth); + if (err) + return err; + } +-- +2.51.0 + diff --git a/queue-6.12/spi-airoha-do-not-keep-tx-rx-dma-buffer-always-mappe.patch b/queue-6.12/spi-airoha-do-not-keep-tx-rx-dma-buffer-always-mappe.patch new file mode 100644 index 0000000000..c4227a7467 --- /dev/null +++ b/queue-6.12/spi-airoha-do-not-keep-tx-rx-dma-buffer-always-mappe.patch @@ -0,0 +1,446 @@ +From d42b8b20c22dd8bd7efed3dc6fff3c1c7b2e87c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 22 Sep 2024 19:38:30 +0200 +Subject: spi: airoha: do not keep {tx,rx} dma buffer always mapped + +From: Lorenzo Bianconi + +[ Upstream commit 7a4b3ebf1d60349587fee21872536e7bd6a4cf39 ] + +DMA map txrx_buf on demand in airoha_snand_dirmap_read and +airoha_snand_dirmap_write routines and do not keep it always mapped. +This patch is not fixing any bug or introducing any functional change +to the driver, it just simplifies the code and improve code readability +without introducing any performance degradation according to the results +obtained from the mtd_speedtest kernel module test. + +root@OpenWrt:# insmod mtd_test.ko +root@OpenWrt:# insmod mtd_speedtest.ko dev=5 +[ 49.849869] ================================================= +[ 49.855659] mtd_speedtest: MTD device: 5 +[ 49.859583] mtd_speedtest: MTD device size 8388608, eraseblock size 131072, page size 2048, count of eraseblocks 64, pages per eraseblock 64, OOB size 128 +[ 49.874622] mtd_test: scanning for bad eraseblocks +[ 49.879433] mtd_test: scanned 64 eraseblocks, 0 are bad +[ 50.106372] mtd_speedtest: testing eraseblock write speed +[ 53.083380] mtd_speedtest: eraseblock write speed is 2756 KiB/s +[ 53.089322] mtd_speedtest: testing eraseblock read speed +[ 54.143360] mtd_speedtest: eraseblock read speed is 7811 KiB/s +[ 54.370365] mtd_speedtest: testing page write speed +[ 57.349480] mtd_speedtest: page write speed is 2754 KiB/s +[ 57.354895] mtd_speedtest: testing page read speed +[ 58.410431] mtd_speedtest: page read speed is 7796 KiB/s +[ 58.636805] mtd_speedtest: testing 2 page write speed +[ 61.612427] mtd_speedtest: 2 page write speed is 2757 KiB/s +[ 61.618021] mtd_speedtest: testing 2 page read speed +[ 62.672653] mtd_speedtest: 2 page read speed is 7804 KiB/s +[ 62.678159] mtd_speedtest: Testing erase speed +[ 62.903617] mtd_speedtest: erase speed is 37063 KiB/s +[ 62.908678] mtd_speedtest: Testing 2x multi-block erase speed +[ 63.134083] mtd_speedtest: 2x multi-block erase speed is 37292 KiB/s +[ 63.140442] mtd_speedtest: Testing 4x multi-block erase speed +[ 63.364262] mtd_speedtest: 4x multi-block erase speed is 37566 KiB/s +[ 63.370632] mtd_speedtest: Testing 8x multi-block erase speed +[ 63.595740] mtd_speedtest: 8x multi-block erase speed is 37344 KiB/s +[ 63.602089] mtd_speedtest: Testing 16x multi-block erase speed +[ 63.827426] mtd_speedtest: 16x multi-block erase speed is 37320 KiB/s +[ 63.833860] mtd_speedtest: Testing 32x multi-block erase speed +[ 64.059389] mtd_speedtest: 32x multi-block erase speed is 37288 KiB/s +[ 64.065833] mtd_speedtest: Testing 64x multi-block erase speed +[ 64.290609] mtd_speedtest: 64x multi-block erase speed is 37415 KiB/s +[ 64.297063] mtd_speedtest: finished +[ 64.300555] ================================================= + +Tested-by: Christian Marangi +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20240922-airoha-spi-fixes-v3-1-f958802b3d68@kernel.org +Signed-off-by: Mark Brown +Stable-dep-of: 20d7b236b78c ("spi: airoha: switch back to non-dma mode in the case of error") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-airoha-snfi.c | 154 ++++++++++++++++------------------ + 1 file changed, 71 insertions(+), 83 deletions(-) + +diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c +index a3f766e04202f..0b89dc42545b1 100644 +--- a/drivers/spi/spi-airoha-snfi.c ++++ b/drivers/spi/spi-airoha-snfi.c +@@ -214,13 +214,6 @@ enum airoha_snand_cs { + SPI_CHIP_SEL_LOW, + }; + +-struct airoha_snand_dev { +- size_t buf_len; +- +- u8 *txrx_buf; +- dma_addr_t dma_addr; +-}; +- + struct airoha_snand_ctrl { + struct device *dev; + struct regmap *regmap_ctrl; +@@ -657,9 +650,9 @@ static bool airoha_snand_supports_op(struct spi_mem *mem, + + static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc) + { +- struct airoha_snand_dev *as_dev = spi_get_ctldata(desc->mem->spi); ++ u8 *txrx_buf = spi_get_ctldata(desc->mem->spi); + +- if (!as_dev->txrx_buf) ++ if (!txrx_buf) + return -EINVAL; + + if (desc->info.offset + desc->info.length > U32_MAX) +@@ -678,10 +671,11 @@ static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc) + static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf) + { +- struct spi_device *spi = desc->mem->spi; +- struct airoha_snand_dev *as_dev = spi_get_ctldata(spi); + struct spi_mem_op *op = &desc->info.op_tmpl; ++ struct spi_device *spi = desc->mem->spi; + struct airoha_snand_ctrl *as_ctrl; ++ u8 *txrx_buf = spi_get_ctldata(spi); ++ dma_addr_t dma_addr; + u32 val, rd_mode; + int err; + +@@ -706,14 +700,17 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, + if (err) + return err; + +- dma_sync_single_for_device(as_ctrl->dev, as_dev->dma_addr, +- as_dev->buf_len, DMA_BIDIRECTIONAL); ++ dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE, ++ DMA_FROM_DEVICE); ++ err = dma_mapping_error(as_ctrl->dev, dma_addr); ++ if (err) ++ return err; + + /* set dma addr */ + err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR, +- as_dev->dma_addr); ++ dma_addr); + if (err) +- return err; ++ goto error_dma_unmap; + + /* set cust sec size */ + val = as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num; +@@ -722,58 +719,58 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, + REG_SPI_NFI_SNF_MISC_CTL2, + SPI_NFI_READ_DATA_BYTE_NUM, val); + if (err) +- return err; ++ goto error_dma_unmap; + + /* set read command */ + err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL2, + op->cmd.opcode); + if (err) +- return err; ++ goto error_dma_unmap; + + /* set read mode */ + err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL, + FIELD_PREP(SPI_NFI_DATA_READ_WR_MODE, rd_mode)); + if (err) +- return err; ++ goto error_dma_unmap; + + /* set read addr */ + err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3, 0x0); + if (err) +- return err; ++ goto error_dma_unmap; + + /* set nfi read */ + err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, + SPI_NFI_OPMODE, + FIELD_PREP(SPI_NFI_OPMODE, 6)); + if (err) +- return err; ++ goto error_dma_unmap; + + err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, + SPI_NFI_READ_MODE | SPI_NFI_DMA_MODE); + if (err) +- return err; ++ goto error_dma_unmap; + + err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CMD, 0x0); + if (err) +- return err; ++ goto error_dma_unmap; + + /* trigger dma start read */ + err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, + SPI_NFI_RD_TRIG); + if (err) +- return err; ++ goto error_dma_unmap; + + err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, + SPI_NFI_RD_TRIG); + if (err) +- return err; ++ goto error_dma_unmap; + + err = regmap_read_poll_timeout(as_ctrl->regmap_nfi, + REG_SPI_NFI_SNF_STA_CTL1, val, + (val & SPI_NFI_READ_FROM_CACHE_DONE), + 0, 1 * USEC_PER_SEC); + if (err) +- return err; ++ goto error_dma_unmap; + + /* + * SPI_NFI_READ_FROM_CACHE_DONE bit must be written at the end +@@ -783,35 +780,41 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, + SPI_NFI_READ_FROM_CACHE_DONE, + SPI_NFI_READ_FROM_CACHE_DONE); + if (err) +- return err; ++ goto error_dma_unmap; + + err = regmap_read_poll_timeout(as_ctrl->regmap_nfi, REG_SPI_NFI_INTR, + val, (val & SPI_NFI_AHB_DONE), 0, + 1 * USEC_PER_SEC); + if (err) +- return err; ++ goto error_dma_unmap; + + /* DMA read need delay for data ready from controller to DRAM */ + udelay(1); + +- dma_sync_single_for_cpu(as_ctrl->dev, as_dev->dma_addr, +- as_dev->buf_len, DMA_BIDIRECTIONAL); ++ dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, ++ DMA_FROM_DEVICE); + err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); + if (err < 0) + return err; + +- memcpy(buf, as_dev->txrx_buf + offs, len); ++ memcpy(buf, txrx_buf + offs, len); + + return len; ++ ++error_dma_unmap: ++ dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, ++ DMA_FROM_DEVICE); ++ return err; + } + + static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, const void *buf) + { +- struct spi_device *spi = desc->mem->spi; +- struct airoha_snand_dev *as_dev = spi_get_ctldata(spi); + struct spi_mem_op *op = &desc->info.op_tmpl; ++ struct spi_device *spi = desc->mem->spi; ++ u8 *txrx_buf = spi_get_ctldata(spi); + struct airoha_snand_ctrl *as_ctrl; ++ dma_addr_t dma_addr; + u32 wr_mode, val; + int err; + +@@ -820,19 +823,20 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, + if (err < 0) + return err; + +- dma_sync_single_for_cpu(as_ctrl->dev, as_dev->dma_addr, +- as_dev->buf_len, DMA_BIDIRECTIONAL); +- memcpy(as_dev->txrx_buf + offs, buf, len); +- dma_sync_single_for_device(as_ctrl->dev, as_dev->dma_addr, +- as_dev->buf_len, DMA_BIDIRECTIONAL); ++ memcpy(txrx_buf + offs, buf, len); ++ dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE, ++ DMA_TO_DEVICE); ++ err = dma_mapping_error(as_ctrl->dev, dma_addr); ++ if (err) ++ return err; + + err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA); + if (err < 0) +- return err; ++ goto error_dma_unmap; + + err = airoha_snand_nfi_config(as_ctrl); + if (err) +- return err; ++ goto error_dma_unmap; + + if (op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_QUAD || + op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_RAMDON_QUAD) +@@ -841,9 +845,9 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, + wr_mode = 0; + + err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR, +- as_dev->dma_addr); ++ dma_addr); + if (err) +- return err; ++ goto error_dma_unmap; + + val = FIELD_PREP(SPI_NFI_PROG_LOAD_BYTE_NUM, + as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num); +@@ -851,65 +855,65 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, + REG_SPI_NFI_SNF_MISC_CTL2, + SPI_NFI_PROG_LOAD_BYTE_NUM, val); + if (err) +- return err; ++ goto error_dma_unmap; + + err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL1, + FIELD_PREP(SPI_NFI_PG_LOAD_CMD, + op->cmd.opcode)); + if (err) +- return err; ++ goto error_dma_unmap; + + err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL, + FIELD_PREP(SPI_NFI_DATA_READ_WR_MODE, wr_mode)); + if (err) +- return err; ++ goto error_dma_unmap; + + err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2, 0x0); + if (err) +- return err; ++ goto error_dma_unmap; + + err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, + SPI_NFI_READ_MODE); + if (err) +- return err; ++ goto error_dma_unmap; + + err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, + SPI_NFI_OPMODE, + FIELD_PREP(SPI_NFI_OPMODE, 3)); + if (err) +- return err; ++ goto error_dma_unmap; + + err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, + SPI_NFI_DMA_MODE); + if (err) +- return err; ++ goto error_dma_unmap; + + err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CMD, 0x80); + if (err) +- return err; ++ goto error_dma_unmap; + + err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, + SPI_NFI_WR_TRIG); + if (err) +- return err; ++ goto error_dma_unmap; + + err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, + SPI_NFI_WR_TRIG); + if (err) +- return err; ++ goto error_dma_unmap; + + err = regmap_read_poll_timeout(as_ctrl->regmap_nfi, REG_SPI_NFI_INTR, + val, (val & SPI_NFI_AHB_DONE), 0, + 1 * USEC_PER_SEC); + if (err) +- return err; ++ goto error_dma_unmap; + + err = regmap_read_poll_timeout(as_ctrl->regmap_nfi, + REG_SPI_NFI_SNF_STA_CTL1, val, + (val & SPI_NFI_LOAD_TO_CACHE_DONE), + 0, 1 * USEC_PER_SEC); + if (err) +- return err; ++ goto error_dma_unmap; + + /* + * SPI_NFI_LOAD_TO_CACHE_DONE bit must be written at the end +@@ -919,13 +923,20 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, + SPI_NFI_LOAD_TO_CACHE_DONE, + SPI_NFI_LOAD_TO_CACHE_DONE); + if (err) +- return err; ++ goto error_dma_unmap; + ++ dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, ++ DMA_TO_DEVICE); + err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); + if (err < 0) + return err; + + return len; ++ ++error_dma_unmap: ++ dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, ++ DMA_TO_DEVICE); ++ return err; + } + + static int airoha_snand_exec_op(struct spi_mem *mem, +@@ -1016,42 +1027,20 @@ static const struct spi_controller_mem_ops airoha_snand_mem_ops = { + static int airoha_snand_setup(struct spi_device *spi) + { + struct airoha_snand_ctrl *as_ctrl; +- struct airoha_snand_dev *as_dev; +- +- as_ctrl = spi_controller_get_devdata(spi->controller); +- +- as_dev = devm_kzalloc(as_ctrl->dev, sizeof(*as_dev), GFP_KERNEL); +- if (!as_dev) +- return -ENOMEM; ++ u8 *txrx_buf; + + /* prepare device buffer */ +- as_dev->buf_len = SPI_NAND_CACHE_SIZE; +- as_dev->txrx_buf = devm_kzalloc(as_ctrl->dev, as_dev->buf_len, +- GFP_KERNEL); +- if (!as_dev->txrx_buf) +- return -ENOMEM; +- +- as_dev->dma_addr = dma_map_single(as_ctrl->dev, as_dev->txrx_buf, +- as_dev->buf_len, DMA_BIDIRECTIONAL); +- if (dma_mapping_error(as_ctrl->dev, as_dev->dma_addr)) ++ as_ctrl = spi_controller_get_devdata(spi->controller); ++ txrx_buf = devm_kzalloc(as_ctrl->dev, SPI_NAND_CACHE_SIZE, ++ GFP_KERNEL); ++ if (!txrx_buf) + return -ENOMEM; + +- spi_set_ctldata(spi, as_dev); ++ spi_set_ctldata(spi, txrx_buf); + + return 0; + } + +-static void airoha_snand_cleanup(struct spi_device *spi) +-{ +- struct airoha_snand_dev *as_dev = spi_get_ctldata(spi); +- struct airoha_snand_ctrl *as_ctrl; +- +- as_ctrl = spi_controller_get_devdata(spi->controller); +- dma_unmap_single(as_ctrl->dev, as_dev->dma_addr, +- as_dev->buf_len, DMA_BIDIRECTIONAL); +- spi_set_ctldata(spi, NULL); +-} +- + static int airoha_snand_nfi_setup(struct airoha_snand_ctrl *as_ctrl) + { + u32 val, sec_size, sec_num; +@@ -1153,7 +1142,6 @@ static int airoha_snand_probe(struct platform_device *pdev) + ctrl->bits_per_word_mask = SPI_BPW_MASK(8); + ctrl->mode_bits = SPI_RX_DUAL; + ctrl->setup = airoha_snand_setup; +- ctrl->cleanup = airoha_snand_cleanup; + device_set_node(&ctrl->dev, dev_fwnode(dev)); + + err = airoha_snand_nfi_setup(as_ctrl); +-- +2.51.0 + diff --git a/queue-6.12/spi-airoha-fix-reading-writing-of-flashes-with-more-.patch b/queue-6.12/spi-airoha-fix-reading-writing-of-flashes-with-more-.patch new file mode 100644 index 0000000000..94f7cd7591 --- /dev/null +++ b/queue-6.12/spi-airoha-fix-reading-writing-of-flashes-with-more-.patch @@ -0,0 +1,114 @@ +From 5f8322edaff8a8d755f9d518d02539ec34f4cae5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 15:16:57 +0300 +Subject: spi: airoha: fix reading/writing of flashes with more than one plane + per lun + +From: Mikhail Kshevetskiy + +[ Upstream commit 0b7d9b25e4bc2e478c9d06281a65f930769fca09 ] + +Attaching UBI on the flash with more than one plane per lun will lead to +the following error: + +[ 2.980989] spi-nand spi0.0: Micron SPI NAND was found. +[ 2.986309] spi-nand spi0.0: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128 +[ 2.994978] 2 fixed-partitions partitions found on MTD device spi0.0 +[ 3.001350] Creating 2 MTD partitions on "spi0.0": +[ 3.006159] 0x000000000000-0x000000020000 : "bl2" +[ 3.011663] 0x000000020000-0x000010000000 : "ubi" +... +[ 6.391748] ubi0: attaching mtd1 +[ 6.412545] ubi0 error: ubi_attach: PEB 0 contains corrupted VID header, and the data does not contain all 0xFF +[ 6.422677] ubi0 error: ubi_attach: this may be a non-UBI PEB or a severe VID header corruption which requires manual inspection +[ 6.434249] Volume identifier header dump: +[ 6.438349] magic 55424923 +[ 6.441482] version 1 +[ 6.444007] vol_type 0 +[ 6.446539] copy_flag 0 +[ 6.449068] compat 0 +[ 6.451594] vol_id 0 +[ 6.454120] lnum 1 +[ 6.456651] data_size 4096 +[ 6.459442] used_ebs 1061644134 +[ 6.462748] data_pad 0 +[ 6.465274] sqnum 0 +[ 6.467805] hdr_crc 61169820 +[ 6.470943] Volume identifier header hexdump: +[ 6.475308] hexdump of PEB 0 offset 4096, length 126976 +[ 6.507391] ubi0 warning: ubi_attach: valid VID header but corrupted EC header at PEB 4 +[ 6.515415] ubi0 error: ubi_compare_lebs: unsupported on-flash UBI format +[ 6.522222] ubi0 error: ubi_attach_mtd_dev: failed to attach mtd1, error -22 +[ 6.529294] UBI error: cannot attach mtd1 + +Non dirmap reading works good. Looking to spi_mem_no_dirmap_read() code we'll see: + + static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf) + { + struct spi_mem_op op = desc->info.op_tmpl; + int ret; + +// --- see here --- + op.addr.val = desc->info.offset + offs; +//----------------- + op.data.buf.in = buf; + op.data.nbytes = len; + ret = spi_mem_adjust_op_size(desc->mem, &op); + if (ret) + return ret; + + ret = spi_mem_exec_op(desc->mem, &op); + if (ret) + return ret; + + return op.data.nbytes; + } + +The similar happens for spi_mem_no_dirmap_write(). Thus the address +passed to the flash should take in the account the value of +desc->info.offset. + +This patch fix dirmap reading/writing of flashes with more than one +plane per lun. + +Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver") +Signed-off-by: Mikhail Kshevetskiy +Reviewed-by: AngeloGioacchino Del Regno +Link: https://patch.msgid.link/20251012121707.2296160-7-mikhail.kshevetskiy@iopsys.eu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-airoha-snfi.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c +index 8143fbb0cf4e6..b78163eaed61d 100644 +--- a/drivers/spi/spi-airoha-snfi.c ++++ b/drivers/spi/spi-airoha-snfi.c +@@ -733,8 +733,9 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, + if (err) + goto error_dma_unmap; + +- /* set read addr */ +- err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3, 0x0); ++ /* set read addr: zero page offset + descriptor read offset */ ++ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3, ++ desc->info.offset); + if (err) + goto error_dma_unmap; + +@@ -870,7 +871,9 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, + if (err) + goto error_dma_unmap; + +- err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2, 0x0); ++ /* set write addr: zero page offset + descriptor write offset */ ++ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2, ++ desc->info.offset); + if (err) + goto error_dma_unmap; + +-- +2.51.0 + diff --git a/queue-6.12/spi-airoha-return-an-error-for-continuous-mode-dirma.patch b/queue-6.12/spi-airoha-return-an-error-for-continuous-mode-dirma.patch new file mode 100644 index 0000000000..522a685bd0 --- /dev/null +++ b/queue-6.12/spi-airoha-return-an-error-for-continuous-mode-dirma.patch @@ -0,0 +1,46 @@ +From b18a2fc00d55b5a306b14045a64d58d0d65edab3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 15:16:52 +0300 +Subject: spi: airoha: return an error for continuous mode dirmap creation + cases + +From: Mikhail Kshevetskiy + +[ Upstream commit 4314ffce4eb81a6c18700af1b6e29b6e0c6b9e37 ] + +This driver can accelerate single page operations only, thus +continuous reading mode should not be used. + +Continuous reading will use sizes up to the size of one erase block. +This size is much larger than the size of single flash page. Use this +difference to identify continuous reading and return an error. + +Signed-off-by: Mikhail Kshevetskiy +Reviewed-by: Frieder Schrempf +Reviewed-by: AngeloGioacchino Del Regno +Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver") +Link: https://patch.msgid.link/20251012121707.2296160-2-mikhail.kshevetskiy@iopsys.eu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-airoha-snfi.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c +index 1369691a997bf..6930dea48f330 100644 +--- a/drivers/spi/spi-airoha-snfi.c ++++ b/drivers/spi/spi-airoha-snfi.c +@@ -625,6 +625,10 @@ static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc) + if (desc->info.offset + desc->info.length > U32_MAX) + return -EINVAL; + ++ /* continuous reading is not supported */ ++ if (desc->info.length > SPI_NAND_CACHE_SIZE) ++ return -E2BIG; ++ + if (!airoha_snand_supports_op(desc->mem, &desc->info.op_tmpl)) + return -EOPNOTSUPP; + +-- +2.51.0 + diff --git a/queue-6.12/spi-airoha-switch-back-to-non-dma-mode-in-the-case-o.patch b/queue-6.12/spi-airoha-switch-back-to-non-dma-mode-in-the-case-o.patch new file mode 100644 index 0000000000..2fa2e4e4ca --- /dev/null +++ b/queue-6.12/spi-airoha-switch-back-to-non-dma-mode-in-the-case-o.patch @@ -0,0 +1,65 @@ +From ef4772f5f146ef683b66df81d15ca3953d5797de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 15:16:56 +0300 +Subject: spi: airoha: switch back to non-dma mode in the case of error + +From: Mikhail Kshevetskiy + +[ Upstream commit 20d7b236b78c7ec685a22db5689b9c829975e0c3 ] + +Current dirmap code does not switch back to non-dma mode in the case of +error. This is wrong. + +This patch fixes dirmap read/write error path. + +Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver") +Signed-off-by: Mikhail Kshevetskiy +Acked-by: Lorenzo Bianconi +Reviewed-by: AngeloGioacchino Del Regno +Link: https://patch.msgid.link/20251012121707.2296160-6-mikhail.kshevetskiy@iopsys.eu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-airoha-snfi.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c +index 0b89dc42545b1..8143fbb0cf4e6 100644 +--- a/drivers/spi/spi-airoha-snfi.c ++++ b/drivers/spi/spi-airoha-snfi.c +@@ -698,13 +698,13 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, + + err = airoha_snand_nfi_config(as_ctrl); + if (err) +- return err; ++ goto error_dma_mode_off; + + dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE, + DMA_FROM_DEVICE); + err = dma_mapping_error(as_ctrl->dev, dma_addr); + if (err) +- return err; ++ goto error_dma_mode_off; + + /* set dma addr */ + err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR, +@@ -804,6 +804,8 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, + error_dma_unmap: + dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, + DMA_FROM_DEVICE); ++error_dma_mode_off: ++ airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); + return err; + } + +@@ -936,6 +938,7 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, + error_dma_unmap: + dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, + DMA_TO_DEVICE); ++ airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); + return err; + } + +-- +2.51.0 + diff --git a/queue-6.12/spi-spi-nxp-fspi-add-extra-delay-after-dll-locked.patch b/queue-6.12/spi-spi-nxp-fspi-add-extra-delay-after-dll-locked.patch new file mode 100644 index 0000000000..497d9865c8 --- /dev/null +++ b/queue-6.12/spi-spi-nxp-fspi-add-extra-delay-after-dll-locked.patch @@ -0,0 +1,46 @@ +From f4746f6757588c40f278918e2054c0a0e693e3ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 16:47:14 +0800 +Subject: spi: spi-nxp-fspi: add extra delay after dll locked + +From: Han Xu + +[ Upstream commit b93b4269791fdebbac2a9ad26f324dc2abb9e60f ] + +Due to the erratum ERR050272, the DLL lock status register STS2 +[xREFLOCK, xSLVLOCK] bit may indicate DLL is locked before DLL is +actually locked. Add an extra 4us delay as a workaround. + +refer to ERR050272, on Page 20. +https://www.nxp.com/docs/en/errata/IMX8_1N94W.pdf + +Fixes: 99d822b3adc4 ("spi: spi-nxp-fspi: use DLL calibration when clock rate > 100MHz") +Signed-off-by: Han Xu +Signed-off-by: Haibo Chen +Link: https://patch.msgid.link/20250922-fspi-fix-v1-2-ff4315359d31@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-nxp-fspi.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c +index 5a1e55a01c521..b569302f22e61 100644 +--- a/drivers/spi/spi-nxp-fspi.c ++++ b/drivers/spi/spi-nxp-fspi.c +@@ -665,6 +665,12 @@ static void nxp_fspi_dll_calibration(struct nxp_fspi *f) + 0, POLL_TOUT, true); + if (ret) + dev_warn(f->dev, "DLL lock failed, please fix it!\n"); ++ ++ /* ++ * For ERR050272, DLL lock status bit is not accurate, ++ * wait for 4us more as a workaround. ++ */ ++ udelay(4); + } + + /* +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-broadcom-bcm2712-add-default-gic-address-c.patch b/queue-6.17/arm64-dts-broadcom-bcm2712-add-default-gic-address-c.patch new file mode 100644 index 0000000000..b21ccef22e --- /dev/null +++ b/queue-6.17/arm64-dts-broadcom-bcm2712-add-default-gic-address-c.patch @@ -0,0 +1,46 @@ +From 80e7bd57652bd1bfa4a4ca912fdb34786914f878 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Aug 2025 15:34:08 +0200 +Subject: arm64: dts: broadcom: bcm2712: Add default GIC address cells + +From: Krzysztof Kozlowski + +[ Upstream commit 278b6cabf18bd804f956b98a2f1068717acdbfe3 ] + +Add missing address-cells 0 to GIC interrupt node to silence W=1 +warning: + + bcm2712.dtsi:494.4-497.31: Warning (interrupt_map): /axi/pcie@1000110000:interrupt-map: + Missing property '#address-cells' in node /soc@107c000000/interrupt-controller@7fff9000, using 0 as fallback + +Value '0' is correct because: +1. GIC interrupt controller does not have children, +2. interrupt-map property (in PCI node) consists of five components and + the fourth component "parent unit address", which size is defined by + '#address-cells' of the node pointed to by the interrupt-parent + component, is not used (=0) + +Signed-off-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20250822133407.312505-2-krzysztof.kozlowski@linaro.org +Signed-off-by: Florian Fainelli +Stable-dep-of: aa960b597600 ("arm64: dts: broadcom: bcm2712: Define VGIC interrupt") +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi +index 0a9212d3106f1..940f1c4831988 100644 +--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi ++++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi +@@ -270,6 +270,7 @@ + <0x7fffc000 0x2000>, + <0x7fffe000 0x2000>; + interrupt-controller; ++ #address-cells = <0>; + #interrupt-cells = <3>; + }; + +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-broadcom-bcm2712-define-vgic-interrupt.patch b/queue-6.17/arm64-dts-broadcom-bcm2712-define-vgic-interrupt.patch new file mode 100644 index 0000000000..120b7153b1 --- /dev/null +++ b/queue-6.17/arm64-dts-broadcom-bcm2712-define-vgic-interrupt.patch @@ -0,0 +1,40 @@ +From 081d616975fe49bc0dae220b5a3d2b3024155609 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Sep 2025 09:56:05 +0100 +Subject: arm64: dts: broadcom: bcm2712: Define VGIC interrupt + +From: Peter Robinson + +[ Upstream commit aa960b597600bed80fe171729057dd6aa188b5b5 ] + +Define the interrupt in the GICv2 for vGIC so KVM +can be used, it was missed from the original upstream +DTB for some reason. + +Signed-off-by: Peter Robinson +Cc: Andrea della Porta +Cc: Phil Elwell +Fixes: faa3381267d0 ("arm64: dts: broadcom: Add minimal support for Raspberry Pi 5") +Link: https://lore.kernel.org/r/20250924085612.1039247-1-pbrobinson@gmail.com +Signed-off-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi +index 940f1c4831988..18e73580828a5 100644 +--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi ++++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi +@@ -271,6 +271,8 @@ + <0x7fffe000 0x2000>; + interrupt-controller; + #address-cells = <0>; ++ interrupts = ; + #interrupt-cells = <3>; + }; + +-- +2.51.0 + diff --git a/queue-6.17/block-require-lba-dma_alignment-when-using-pi.patch b/queue-6.17/block-require-lba-dma_alignment-when-using-pi.patch new file mode 100644 index 0000000000..d4e65515ff --- /dev/null +++ b/queue-6.17/block-require-lba-dma_alignment-when-using-pi.patch @@ -0,0 +1,57 @@ +From 101bbf37bc6050c799c21d33bf018785394d7f43 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Oct 2025 10:33:31 +0200 +Subject: block: require LBA dma_alignment when using PI + +From: Christoph Hellwig + +[ Upstream commit 4c8cf6bd28d6fea23819f082ddc8063fd6fa963a ] + +The block layer PI generation / verification code expects the bio_vecs +to have at least LBA size (or more correctly integrity internal) +granularity. With the direct I/O alignment relaxation in 2022, user +space can now feed bios with less alignment than that, leading to +scribbling outside the PI buffers. Apparently this wasn't noticed so far +because none of the tests generate such buffers, but since 851c4c96db00 +("xfs: implement XFS_IOC_DIOINFO in terms of vfs_getattr"), xfstests +generic/013 by default generates such I/O now that the relaxed alignment +is advertised by the XFS_IOC_DIOINFO ioctl. + +Fix this by increasing the required alignment when using PI, although +handling arbitrary alignment in the long run would be even nicer. + +Fixes: bf8d08532bc1 ("iomap: add support for dma aligned direct-io") +Fixes: b1a000d3b8ec ("block: relax direct io memory alignment") +Signed-off-by: Christoph Hellwig +Reviewed-by: Martin K. Petersen +Reviewed-by: Keith Busch +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-settings.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/block/blk-settings.c b/block/blk-settings.c +index 8fa52914e16b0..c3e131f4f9083 100644 +--- a/block/blk-settings.c ++++ b/block/blk-settings.c +@@ -184,6 +184,16 @@ static int blk_validate_integrity_limits(struct queue_limits *lim) + if (!bi->interval_exp) + bi->interval_exp = ilog2(lim->logical_block_size); + ++ /* ++ * The PI generation / validation helpers do not expect intervals to ++ * straddle multiple bio_vecs. Enforce alignment so that those are ++ * never generated, and that each buffer is aligned as expected. ++ */ ++ if (bi->csum_type) { ++ lim->dma_alignment = max(lim->dma_alignment, ++ (1U << bi->interval_exp) - 1); ++ } ++ + return 0; + } + +-- +2.51.0 + diff --git a/queue-6.17/drm-panic-fix-24bit-pixel-crossing-page-boundaries.patch b/queue-6.17/drm-panic-fix-24bit-pixel-crossing-page-boundaries.patch new file mode 100644 index 0000000000..f713ff3ade --- /dev/null +++ b/queue-6.17/drm-panic-fix-24bit-pixel-crossing-page-boundaries.patch @@ -0,0 +1,98 @@ +From d289c7c2aace45e9152b66936e5af99bf619fd14 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 14:24:53 +0200 +Subject: drm/panic: Fix 24bit pixel crossing page boundaries + +From: Jocelyn Falempe + +[ Upstream commit 23437509a69476d4f896891032d62ac868731668 ] + +When using page list framebuffer, and using RGB888 format, some +pixels can cross the page boundaries, and this case was not handled, +leading to writing 1 or 2 bytes on the next virtual address. + +Add a check and a specific function to handle this case. + +Fixes: c9ff2808790f0 ("drm/panic: Add support to scanout buffer as array of pages") +Reviewed-by: Javier Martinez Canillas +Link: https://lore.kernel.org/r/20251009122955.562888-7-jfalempe@redhat.com +Signed-off-by: Jocelyn Falempe +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_panic.c | 46 +++++++++++++++++++++++++++++++++++-- + 1 file changed, 44 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c +index 1bc15c44207b4..f52752880e1c9 100644 +--- a/drivers/gpu/drm/drm_panic.c ++++ b/drivers/gpu/drm/drm_panic.c +@@ -174,6 +174,33 @@ static void drm_panic_write_pixel24(void *vaddr, unsigned int offset, u32 color) + *p = color & 0xff; + } + ++/* ++ * Special case if the pixel crosses page boundaries ++ */ ++static void drm_panic_write_pixel24_xpage(void *vaddr, struct page *next_page, ++ unsigned int offset, u32 color) ++{ ++ u8 *vaddr2; ++ u8 *p = vaddr + offset; ++ ++ vaddr2 = kmap_local_page_try_from_panic(next_page); ++ ++ *p++ = color & 0xff; ++ color >>= 8; ++ ++ if (offset == PAGE_SIZE - 1) ++ p = vaddr2; ++ ++ *p++ = color & 0xff; ++ color >>= 8; ++ ++ if (offset == PAGE_SIZE - 2) ++ p = vaddr2; ++ ++ *p = color & 0xff; ++ kunmap_local(vaddr2); ++} ++ + static void drm_panic_write_pixel32(void *vaddr, unsigned int offset, u32 color) + { + u32 *p = vaddr + offset; +@@ -231,7 +258,14 @@ static void drm_panic_blit_page(struct page **pages, unsigned int dpitch, + page = new_page; + vaddr = kmap_local_page_try_from_panic(pages[page]); + } +- if (vaddr) ++ if (!vaddr) ++ continue; ++ ++ // Special case for 24bit, as a pixel might cross page boundaries ++ if (cpp == 3 && offset + 3 > PAGE_SIZE) ++ drm_panic_write_pixel24_xpage(vaddr, pages[page + 1], ++ offset, fg32); ++ else + drm_panic_write_pixel(vaddr, offset, fg32, cpp); + } + } +@@ -321,7 +355,15 @@ static void drm_panic_fill_page(struct page **pages, unsigned int dpitch, + page = new_page; + vaddr = kmap_local_page_try_from_panic(pages[page]); + } +- drm_panic_write_pixel(vaddr, offset, color, cpp); ++ if (!vaddr) ++ continue; ++ ++ // Special case for 24bit, as a pixel might cross page boundaries ++ if (cpp == 3 && offset + 3 > PAGE_SIZE) ++ drm_panic_write_pixel24_xpage(vaddr, pages[page + 1], ++ offset, color); ++ else ++ drm_panic_write_pixel(vaddr, offset, color, cpp); + } + } + if (vaddr) +-- +2.51.0 + diff --git a/queue-6.17/drm-panic-fix-drawing-the-logo-on-a-small-narrow-scr.patch b/queue-6.17/drm-panic-fix-drawing-the-logo-on-a-small-narrow-scr.patch new file mode 100644 index 0000000000..20acafccfa --- /dev/null +++ b/queue-6.17/drm-panic-fix-drawing-the-logo-on-a-small-narrow-scr.patch @@ -0,0 +1,40 @@ +From 9af2a1f98a9aee8d6e016c37b2f9bec7cd38989b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 14:24:48 +0200 +Subject: drm/panic: Fix drawing the logo on a small narrow screen + +From: Jocelyn Falempe + +[ Upstream commit 179753aa5b7890b311968c033d08f558f0a7be21 ] + +If the logo width is bigger than the framebuffer width, and the +height is big enough to hold the logo and the message, it will draw +at x coordinate that are higher than the width, and ends up in a +corrupted image. + +Fixes: 4b570ac2eb54 ("drm/rect: Add drm_rect_overlap()") +Reviewed-by: Javier Martinez Canillas +Link: https://lore.kernel.org/r/20251009122955.562888-2-jfalempe@redhat.com +Signed-off-by: Jocelyn Falempe +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_panic.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c +index 1d6312fa14293..23ba791c6131b 100644 +--- a/drivers/gpu/drm/drm_panic.c ++++ b/drivers/gpu/drm/drm_panic.c +@@ -429,6 +429,9 @@ static void drm_panic_logo_rect(struct drm_rect *rect, const struct font_desc *f + static void drm_panic_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect *rect, + const struct font_desc *font, u32 fg_color) + { ++ if (rect->x2 > sb->width || rect->y2 > sb->height) ++ return; ++ + if (logo_mono) + drm_panic_blit(sb, rect, logo_mono->data, + DIV_ROUND_UP(drm_rect_width(rect), 8), 1, fg_color); +-- +2.51.0 + diff --git a/queue-6.17/drm-panic-fix-qr_code-ensure-vmargin-is-positive.patch b/queue-6.17/drm-panic-fix-qr_code-ensure-vmargin-is-positive.patch new file mode 100644 index 0000000000..3fb17a6d52 --- /dev/null +++ b/queue-6.17/drm-panic-fix-qr_code-ensure-vmargin-is-positive.patch @@ -0,0 +1,43 @@ +From a47322c2e021cf9f2e4d2d20869f6440fb9d9804 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 14:24:50 +0200 +Subject: drm/panic: Fix qr_code, ensure vmargin is positive + +From: Jocelyn Falempe + +[ Upstream commit 4fcffb5e5c8c0c8e2ad9c99a22305a0afbecc294 ] + +Depending on qr_code size and screen size, the vertical margin can +be negative, that means there is not enough room to draw the qr_code. + +So abort early, to avoid a segfault by trying to draw at negative +coordinates. + +Fixes: cb5164ac43d0f ("drm/panic: Add a QR code panic screen") +Reviewed-by: Javier Martinez Canillas +Link: https://lore.kernel.org/r/20251009122955.562888-4-jfalempe@redhat.com +Signed-off-by: Jocelyn Falempe +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_panic.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c +index 23ba791c6131b..1bc15c44207b4 100644 +--- a/drivers/gpu/drm/drm_panic.c ++++ b/drivers/gpu/drm/drm_panic.c +@@ -736,7 +736,10 @@ static int _draw_panic_static_qr_code(struct drm_scanout_buffer *sb) + pr_debug("QR width %d and scale %d\n", qr_width, scale); + r_qr_canvas = DRM_RECT_INIT(0, 0, qr_canvas_width * scale, qr_canvas_width * scale); + +- v_margin = (sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg)) / 5; ++ v_margin = sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg); ++ if (v_margin < 0) ++ return -ENOSPC; ++ v_margin /= 5; + + drm_rect_translate(&r_qr_canvas, (sb->width - r_qr_canvas.x2) / 2, 2 * v_margin); + r_qr = DRM_RECT_INIT(r_qr_canvas.x1 + QR_MARGIN * scale, r_qr_canvas.y1 + QR_MARGIN * scale, +-- +2.51.0 + diff --git a/queue-6.17/drm-panthor-fix-kernel-panic-on-partial-unmap-of-a-g.patch b/queue-6.17/drm-panthor-fix-kernel-panic-on-partial-unmap-of-a-g.patch new file mode 100644 index 0000000000..f0e466d281 --- /dev/null +++ b/queue-6.17/drm-panthor-fix-kernel-panic-on-partial-unmap-of-a-g.patch @@ -0,0 +1,104 @@ +From 113943fc51162cc3191efda22f9c2a02066f58a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 11:29:22 +0100 +Subject: drm/panthor: Fix kernel panic on partial unmap of a GPU VA region + +From: Akash Goel + +[ Upstream commit 4eabd0d8791eaf9a7b114ccbf56eb488aefe7b1f ] + +This commit address a kernel panic issue that can happen if Userspace +tries to partially unmap a GPU virtual region (aka drm_gpuva). +The VM_BIND interface allows partial unmapping of a BO. + +Panthor driver pre-allocates memory for the new drm_gpuva structures +that would be needed for the map/unmap operation, done using drm_gpuvm +layer. It expected that only one new drm_gpuva would be needed on umap +but a partial unmap can require 2 new drm_gpuva and that's why it +ended up doing a NULL pointer dereference causing a kernel panic. + +Following dump was seen when partial unmap was exercised. + Unable to handle kernel NULL pointer dereference at virtual address 0000000000000078 + Mem abort info: + ESR = 0x0000000096000046 + EC = 0x25: DABT (current EL), IL = 32 bits + SET = 0, FnV = 0 + EA = 0, S1PTW = 0 + FSC = 0x06: level 2 translation fault + Data abort info: + ISV = 0, ISS = 0x00000046, ISS2 = 0x00000000 + CM = 0, WnR = 1, TnD = 0, TagAccess = 0 + GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 + user pgtable: 4k pages, 48-bit VAs, pgdp=000000088a863000 + [000000000000078] pgd=080000088a842003, p4d=080000088a842003, pud=0800000884bf5003, pmd=0000000000000000 + Internal error: Oops: 0000000096000046 [#1] PREEMPT SMP + + pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) + pc : panthor_gpuva_sm_step_remap+0xe4/0x330 [panthor] + lr : panthor_gpuva_sm_step_remap+0x6c/0x330 [panthor] + sp : ffff800085d43970 + x29: ffff800085d43970 x28: ffff00080363e440 x27: ffff0008090c6000 + x26: 0000000000000030 x25: ffff800085d439f8 x24: ffff00080d402000 + x23: ffff800085d43b60 x22: ffff800085d439e0 x21: ffff00080abdb180 + x20: 0000000000000000 x19: 0000000000000000 x18: 0000000000000010 + x17: 6e656c202c303030 x16: 3666666666646466 x15: 393d61766f69202c + x14: 312d3d7361203a70 x13: 303030323d6e656c x12: ffff80008324bf58 + x11: 0000000000000003 x10: 0000000000000002 x9 : ffff8000801a6a9c + x8 : ffff00080360b300 x7 : 0000000000000000 x6 : 000000088aa35fc7 + x5 : fff1000080000000 x4 : ffff8000842ddd30 x3 : 0000000000000001 + x2 : 0000000100000000 x1 : 0000000000000001 x0 : 0000000000000078 + Call trace: + panthor_gpuva_sm_step_remap+0xe4/0x330 [panthor] + op_remap_cb.isra.22+0x50/0x80 + __drm_gpuvm_sm_unmap+0x10c/0x1c8 + drm_gpuvm_sm_unmap+0x40/0x60 + panthor_vm_exec_op+0xb4/0x3d0 [panthor] + panthor_vm_bind_exec_sync_op+0x154/0x278 [panthor] + panthor_ioctl_vm_bind+0x160/0x4a0 [panthor] + drm_ioctl_kernel+0xbc/0x138 + drm_ioctl+0x240/0x500 + __arm64_sys_ioctl+0xb0/0xf8 + invoke_syscall+0x4c/0x110 + el0_svc_common.constprop.1+0x98/0xf8 + do_el0_svc+0x24/0x38 + el0_svc+0x40/0xf8 + el0t_64_sync_handler+0xa0/0xc8 + el0t_64_sync+0x174/0x178 + +Signed-off-by: Akash Goel +Reviewed-by: Boris Brezillon +Reviewed-by: Liviu Dudau +Fixes: 647810ec2476 ("drm/panthor: Add the MMU/VM logical block") +Reviewed-by: Steven Price +Signed-off-by: Steven Price +Link: https://lore.kernel.org/r/20251017102922.670084-1-akash.goel@arm.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_mmu.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c +index 4140f697ba5af..0402f5f734a1b 100644 +--- a/drivers/gpu/drm/panthor/panthor_mmu.c ++++ b/drivers/gpu/drm/panthor/panthor_mmu.c +@@ -1147,10 +1147,14 @@ panthor_vm_op_ctx_prealloc_vmas(struct panthor_vm_op_ctx *op_ctx) + break; + + case DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP: +- /* Partial unmaps might trigger a remap with either a prev or a next VA, +- * but not both. ++ /* Two VMAs can be needed for an unmap, as an unmap can happen ++ * in the middle of a drm_gpuva, requiring a remap with both ++ * prev & next VA. Or an unmap can span more than one drm_gpuva ++ * where the first and last ones are covered partially, requring ++ * a remap for the first with a prev VA and remap for the last ++ * with a next VA. + */ +- vma_count = 1; ++ vma_count = 2; + break; + + default: +-- +2.51.0 + diff --git a/queue-6.17/firmware-arm_ffa-add-support-for-impdef-value-in-the.patch b/queue-6.17/firmware-arm_ffa-add-support-for-impdef-value-in-the.patch new file mode 100644 index 0000000000..fe6325249a --- /dev/null +++ b/queue-6.17/firmware-arm_ffa-add-support-for-impdef-value-in-the.patch @@ -0,0 +1,150 @@ +From cc69779029b5e3fcb0ebe8fd44f077fd34078929 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Sep 2025 16:09:27 +0100 +Subject: firmware: arm_ffa: Add support for IMPDEF value in the memory access + descriptor + +From: Sudeep Holla + +[ Upstream commit 11fb1a82aefa6f7fea6ac82334edb5639b9927df ] + +FF-A v1.2 introduced 16 byte IMPLEMENTATION DEFINED value in the endpoint +memory access descriptor to allow any sender could to specify an its any +custom value for each receiver. Also this value must be specified by the +receiver when retrieving the memory region. The sender must ensure it +informs the receiver of this value via an IMPLEMENTATION DEFINED mechanism +such as a partition message. + +So the FF-A driver can use the message interfaces to communicate the value +and set the same in the ffa_mem_region_attributes structures when using +the memory interfaces. + +The driver ensure that the size of the endpoint memory access descriptors +is set correctly based on the FF-A version. + +Fixes: 9fac08d9d985 ("firmware: arm_ffa: Upgrade FF-A version to v1.2 in the driver") +Reported-by: Lixiang Mao +Tested-by: Lixiang Mao +Message-Id: <20250923150927.1218364-1-sudeep.holla@arm.com> +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_ffa/driver.c | 37 ++++++++++++++++++++++--------- + include/linux/arm_ffa.h | 21 ++++++++++++++++-- + 2 files changed, 46 insertions(+), 12 deletions(-) + +diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c +index 65bf1685350a2..c72ee47565856 100644 +--- a/drivers/firmware/arm_ffa/driver.c ++++ b/drivers/firmware/arm_ffa/driver.c +@@ -649,6 +649,26 @@ static u16 ffa_memory_attributes_get(u32 func_id) + return FFA_MEM_NORMAL | FFA_MEM_WRITE_BACK | FFA_MEM_INNER_SHAREABLE; + } + ++static void ffa_emad_impdef_value_init(u32 version, void *dst, void *src) ++{ ++ struct ffa_mem_region_attributes *ep_mem_access; ++ ++ if (FFA_EMAD_HAS_IMPDEF_FIELD(version)) ++ memcpy(dst, src, sizeof(ep_mem_access->impdef_val)); ++} ++ ++static void ++ffa_mem_region_additional_setup(u32 version, struct ffa_mem_region *mem_region) ++{ ++ if (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET(version)) { ++ mem_region->ep_mem_size = 0; ++ } else { ++ mem_region->ep_mem_size = ffa_emad_size_get(version); ++ mem_region->ep_mem_offset = sizeof(*mem_region); ++ memset(mem_region->reserved, 0, 12); ++ } ++} ++ + static int + ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize, + struct ffa_mem_ops_args *args) +@@ -667,27 +687,24 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize, + mem_region->flags = args->flags; + mem_region->sender_id = drv_info->vm_id; + mem_region->attributes = ffa_memory_attributes_get(func_id); +- ep_mem_access = buffer + +- ffa_mem_desc_offset(buffer, 0, drv_info->version); + composite_offset = ffa_mem_desc_offset(buffer, args->nattrs, + drv_info->version); + +- for (idx = 0; idx < args->nattrs; idx++, ep_mem_access++) { ++ for (idx = 0; idx < args->nattrs; idx++) { ++ ep_mem_access = buffer + ++ ffa_mem_desc_offset(buffer, idx, drv_info->version); + ep_mem_access->receiver = args->attrs[idx].receiver; + ep_mem_access->attrs = args->attrs[idx].attrs; + ep_mem_access->composite_off = composite_offset; + ep_mem_access->flag = 0; + ep_mem_access->reserved = 0; ++ ffa_emad_impdef_value_init(drv_info->version, ++ ep_mem_access->impdef_val, ++ args->attrs[idx].impdef_val); + } + mem_region->handle = 0; + mem_region->ep_count = args->nattrs; +- if (drv_info->version <= FFA_VERSION_1_0) { +- mem_region->ep_mem_size = 0; +- } else { +- mem_region->ep_mem_size = sizeof(*ep_mem_access); +- mem_region->ep_mem_offset = sizeof(*mem_region); +- memset(mem_region->reserved, 0, 12); +- } ++ ffa_mem_region_additional_setup(drv_info->version, mem_region); + + composite = buffer + composite_offset; + composite->total_pg_cnt = ffa_get_num_pages_sg(args->sg); +diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h +index e1634897e159c..effa4d5e0242d 100644 +--- a/include/linux/arm_ffa.h ++++ b/include/linux/arm_ffa.h +@@ -337,6 +337,7 @@ struct ffa_mem_region_attributes { + * an `struct ffa_mem_region_addr_range`. + */ + u32 composite_off; ++ u8 impdef_val[16]; + u64 reserved; + }; + +@@ -416,15 +417,31 @@ struct ffa_mem_region { + #define CONSTITUENTS_OFFSET(x) \ + (offsetof(struct ffa_composite_mem_region, constituents[x])) + ++#define FFA_EMAD_HAS_IMPDEF_FIELD(version) ((version) >= FFA_VERSION_1_2) ++#define FFA_MEM_REGION_HAS_EP_MEM_OFFSET(version) ((version) > FFA_VERSION_1_0) ++ ++static inline u32 ffa_emad_size_get(u32 ffa_version) ++{ ++ u32 sz; ++ struct ffa_mem_region_attributes *ep_mem_access; ++ ++ if (FFA_EMAD_HAS_IMPDEF_FIELD(ffa_version)) ++ sz = sizeof(*ep_mem_access); ++ else ++ sz = sizeof(*ep_mem_access) - sizeof(ep_mem_access->impdef_val); ++ ++ return sz; ++} ++ + static inline u32 + ffa_mem_desc_offset(struct ffa_mem_region *buf, int count, u32 ffa_version) + { +- u32 offset = count * sizeof(struct ffa_mem_region_attributes); ++ u32 offset = count * ffa_emad_size_get(ffa_version); + /* + * Earlier to v1.1, the endpoint memory descriptor array started at + * offset 32(i.e. offset of ep_mem_offset in the current structure) + */ +- if (ffa_version <= FFA_VERSION_1_0) ++ if (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET(ffa_version)) + offset += offsetof(struct ffa_mem_region, ep_mem_offset); + else + offset += sizeof(struct ffa_mem_region); +-- +2.51.0 + diff --git a/queue-6.17/firmware-arm_scmi-account-for-failed-debug-initializ.patch b/queue-6.17/firmware-arm_scmi-account-for-failed-debug-initializ.patch new file mode 100644 index 0000000000..7f6bb218b0 --- /dev/null +++ b/queue-6.17/firmware-arm_scmi-account-for-failed-debug-initializ.patch @@ -0,0 +1,206 @@ +From 75446183128d20614e35e3a3828dce15a8b10ba2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 12:53:44 +0100 +Subject: firmware: arm_scmi: Account for failed debug initialization + +From: Cristian Marussi + +[ Upstream commit 2290ab43b9d8eafb8046387f10a8dfa2b030ba46 ] + +When the SCMI debug subsystem fails to initialize, the related debug root +will be missing, and the underlying descriptor will be NULL. + +Handle this fault condition in the SCMI debug helpers that maintain +metrics counters. + +Fixes: 0b3d48c4726e ("firmware: arm_scmi: Track basic SCMI communication debug metrics") +Signed-off-by: Cristian Marussi +Message-Id: <20251014115346.2391418-1-cristian.marussi@arm.com> +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_scmi/common.h | 24 ++++++++++++++-- + drivers/firmware/arm_scmi/driver.c | 44 ++++++++++-------------------- + 2 files changed, 35 insertions(+), 33 deletions(-) + +diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h +index 07b9e629276d2..21c0b95027c64 100644 +--- a/drivers/firmware/arm_scmi/common.h ++++ b/drivers/firmware/arm_scmi/common.h +@@ -309,10 +309,28 @@ enum debug_counters { + SCMI_DEBUG_COUNTERS_LAST + }; + +-static inline void scmi_inc_count(atomic_t *arr, int stat) ++/** ++ * struct scmi_debug_info - Debug common info ++ * @top_dentry: A reference to the top debugfs dentry ++ * @name: Name of this SCMI instance ++ * @type: Type of this SCMI instance ++ * @is_atomic: Flag to state if the transport of this instance is atomic ++ * @counters: An array of atomic_c's used for tracking statistics (if enabled) ++ */ ++struct scmi_debug_info { ++ struct dentry *top_dentry; ++ const char *name; ++ const char *type; ++ bool is_atomic; ++ atomic_t counters[SCMI_DEBUG_COUNTERS_LAST]; ++}; ++ ++static inline void scmi_inc_count(struct scmi_debug_info *dbg, int stat) + { +- if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) +- atomic_inc(&arr[stat]); ++ if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) { ++ if (dbg) ++ atomic_inc(&dbg->counters[stat]); ++ } + } + + static inline void scmi_dec_count(atomic_t *arr, int stat) +diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c +index bd56a877fdfc8..56419285c0bfd 100644 +--- a/drivers/firmware/arm_scmi/driver.c ++++ b/drivers/firmware/arm_scmi/driver.c +@@ -115,22 +115,6 @@ struct scmi_protocol_instance { + + #define ph_to_pi(h) container_of(h, struct scmi_protocol_instance, ph) + +-/** +- * struct scmi_debug_info - Debug common info +- * @top_dentry: A reference to the top debugfs dentry +- * @name: Name of this SCMI instance +- * @type: Type of this SCMI instance +- * @is_atomic: Flag to state if the transport of this instance is atomic +- * @counters: An array of atomic_c's used for tracking statistics (if enabled) +- */ +-struct scmi_debug_info { +- struct dentry *top_dentry; +- const char *name; +- const char *type; +- bool is_atomic; +- atomic_t counters[SCMI_DEBUG_COUNTERS_LAST]; +-}; +- + /** + * struct scmi_info - Structure representing a SCMI instance + * +@@ -1034,7 +1018,7 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr) + spin_unlock_irqrestore(&minfo->xfer_lock, flags); + + scmi_bad_message_trace(cinfo, msg_hdr, MSG_UNEXPECTED); +- scmi_inc_count(info->dbg->counters, ERR_MSG_UNEXPECTED); ++ scmi_inc_count(info->dbg, ERR_MSG_UNEXPECTED); + + return xfer; + } +@@ -1062,7 +1046,7 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr) + msg_type, xfer_id, msg_hdr, xfer->state); + + scmi_bad_message_trace(cinfo, msg_hdr, MSG_INVALID); +- scmi_inc_count(info->dbg->counters, ERR_MSG_INVALID); ++ scmi_inc_count(info->dbg, ERR_MSG_INVALID); + + /* On error the refcount incremented above has to be dropped */ + __scmi_xfer_put(minfo, xfer); +@@ -1107,7 +1091,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, + PTR_ERR(xfer)); + + scmi_bad_message_trace(cinfo, msg_hdr, MSG_NOMEM); +- scmi_inc_count(info->dbg->counters, ERR_MSG_NOMEM); ++ scmi_inc_count(info->dbg, ERR_MSG_NOMEM); + + scmi_clear_channel(info, cinfo); + return; +@@ -1123,7 +1107,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, + trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id, + xfer->hdr.id, "NOTI", xfer->hdr.seq, + xfer->hdr.status, xfer->rx.buf, xfer->rx.len); +- scmi_inc_count(info->dbg->counters, NOTIFICATION_OK); ++ scmi_inc_count(info->dbg, NOTIFICATION_OK); + + scmi_notify(cinfo->handle, xfer->hdr.protocol_id, + xfer->hdr.id, xfer->rx.buf, xfer->rx.len, ts); +@@ -1183,10 +1167,10 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo, + if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP) { + scmi_clear_channel(info, cinfo); + complete(xfer->async_done); +- scmi_inc_count(info->dbg->counters, DELAYED_RESPONSE_OK); ++ scmi_inc_count(info->dbg, DELAYED_RESPONSE_OK); + } else { + complete(&xfer->done); +- scmi_inc_count(info->dbg->counters, RESPONSE_OK); ++ scmi_inc_count(info->dbg, RESPONSE_OK); + } + + if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { +@@ -1296,7 +1280,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, + "timed out in resp(caller: %pS) - polling\n", + (void *)_RET_IP_); + ret = -ETIMEDOUT; +- scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_POLLED_TIMEOUT); ++ scmi_inc_count(info->dbg, XFERS_RESPONSE_POLLED_TIMEOUT); + } + } + +@@ -1321,7 +1305,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, + "RESP" : "resp", + xfer->hdr.seq, xfer->hdr.status, + xfer->rx.buf, xfer->rx.len); +- scmi_inc_count(info->dbg->counters, RESPONSE_POLLED_OK); ++ scmi_inc_count(info->dbg, RESPONSE_POLLED_OK); + + if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { + scmi_raw_message_report(info->raw, xfer, +@@ -1336,7 +1320,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, + dev_err(dev, "timed out in resp(caller: %pS)\n", + (void *)_RET_IP_); + ret = -ETIMEDOUT; +- scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_TIMEOUT); ++ scmi_inc_count(info->dbg, XFERS_RESPONSE_TIMEOUT); + } + } + +@@ -1420,13 +1404,13 @@ static int do_xfer(const struct scmi_protocol_handle *ph, + !is_transport_polling_capable(info->desc)) { + dev_warn_once(dev, + "Polling mode is not supported by transport.\n"); +- scmi_inc_count(info->dbg->counters, SENT_FAIL_POLLING_UNSUPPORTED); ++ scmi_inc_count(info->dbg, SENT_FAIL_POLLING_UNSUPPORTED); + return -EINVAL; + } + + cinfo = idr_find(&info->tx_idr, pi->proto->id); + if (unlikely(!cinfo)) { +- scmi_inc_count(info->dbg->counters, SENT_FAIL_CHANNEL_NOT_FOUND); ++ scmi_inc_count(info->dbg, SENT_FAIL_CHANNEL_NOT_FOUND); + return -EINVAL; + } + /* True ONLY if also supported by transport. */ +@@ -1461,19 +1445,19 @@ static int do_xfer(const struct scmi_protocol_handle *ph, + ret = info->desc->ops->send_message(cinfo, xfer); + if (ret < 0) { + dev_dbg(dev, "Failed to send message %d\n", ret); +- scmi_inc_count(info->dbg->counters, SENT_FAIL); ++ scmi_inc_count(info->dbg, SENT_FAIL); + return ret; + } + + trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id, + xfer->hdr.id, "CMND", xfer->hdr.seq, + xfer->hdr.status, xfer->tx.buf, xfer->tx.len); +- scmi_inc_count(info->dbg->counters, SENT_OK); ++ scmi_inc_count(info->dbg, SENT_OK); + + ret = scmi_wait_for_message_response(cinfo, xfer); + if (!ret && xfer->hdr.status) { + ret = scmi_to_linux_errno(xfer->hdr.status); +- scmi_inc_count(info->dbg->counters, ERR_PROTOCOL); ++ scmi_inc_count(info->dbg, ERR_PROTOCOL); + } + + if (info->desc->ops->mark_txdone) +-- +2.51.0 + diff --git a/queue-6.17/firmware-arm_scmi-fix-premature-scmi_xfer_flag_is_ra.patch b/queue-6.17/firmware-arm_scmi-fix-premature-scmi_xfer_flag_is_ra.patch new file mode 100644 index 0000000000..3e34430aea --- /dev/null +++ b/queue-6.17/firmware-arm_scmi-fix-premature-scmi_xfer_flag_is_ra.patch @@ -0,0 +1,54 @@ +From 472a6cb37a19c5f5724bf744bbeba79fa6f3e456 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 12:10:57 +0300 +Subject: firmware: arm_scmi: Fix premature SCMI_XFER_FLAG_IS_RAW clearing in + raw mode + +From: Artem Shimko + +[ Upstream commit 20b93a0088a595bceed4a026d527cbbac4e876c5 ] + +The SCMI_XFER_FLAG_IS_RAW flag was being cleared prematurely in +scmi_xfer_raw_put() before the transfer completion was properly +acknowledged by the raw message handlers. + +Move the clearing of SCMI_XFER_FLAG_IS_RAW and SCMI_XFER_FLAG_CHAN_SET +from scmi_xfer_raw_put() to __scmi_xfer_put() to ensure the flags remain +set throughout the entire raw message processing pipeline until the +transfer is returned to the free pool. + +Fixes: 3095a3e25d8f ("firmware: arm_scmi: Add xfer helpers to provide raw access") +Suggested-by: Cristian Marussi +Signed-off-by: Artem Shimko +Reviewed-by: Cristian Marussi +Message-Id: <20251008091057.1969260-1-a.shimko.dev@gmail.com> +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_scmi/driver.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c +index 1cd15412024cd..a8f2247feab9d 100644 +--- a/drivers/firmware/arm_scmi/driver.c ++++ b/drivers/firmware/arm_scmi/driver.c +@@ -805,6 +805,7 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer) + + scmi_dec_count(info->dbg, XFERS_INFLIGHT); + } ++ xfer->flags = 0; + hlist_add_head(&xfer->node, &minfo->free_xfers); + } + spin_unlock_irqrestore(&minfo->xfer_lock, flags); +@@ -823,8 +824,6 @@ void scmi_xfer_raw_put(const struct scmi_handle *handle, struct scmi_xfer *xfer) + { + struct scmi_info *info = handle_to_scmi_info(handle); + +- xfer->flags &= ~SCMI_XFER_FLAG_IS_RAW; +- xfer->flags &= ~SCMI_XFER_FLAG_CHAN_SET; + return __scmi_xfer_put(&info->tx_minfo, xfer); + } + +-- +2.51.0 + diff --git a/queue-6.17/gpio-ljca-fix-duplicated-irq-mapping.patch b/queue-6.17/gpio-ljca-fix-duplicated-irq-mapping.patch new file mode 100644 index 0000000000..bdfbf45aad --- /dev/null +++ b/queue-6.17/gpio-ljca-fix-duplicated-irq-mapping.patch @@ -0,0 +1,59 @@ +From 71b7d8b1c08d73116dccc67ec1f8dc6da4cf32b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 15:02:30 +0800 +Subject: gpio: ljca: Fix duplicated IRQ mapping + +From: Haotian Zhang + +[ Upstream commit 4c4e6ea4a120cc5ab58e437c6ba123cbfc357d45 ] + +The generic_handle_domain_irq() function resolves the hardware IRQ +internally. The driver performed a duplicative mapping by calling +irq_find_mapping() first, which could lead to an RCU stall. + +Delete the redundant irq_find_mapping() call and pass the hardware IRQ +directly to generic_handle_domain_irq(). + +Fixes: c5a4b6fd31e8 ("gpio: Add support for Intel LJCA USB GPIO driver") +Signed-off-by: Haotian Zhang +Link: https://lore.kernel.org/r/20251023070231.1305-1-vulab@iscas.ac.cn +[Bartosz: remove unused variable] +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-ljca.c | 14 +++----------- + 1 file changed, 3 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpio/gpio-ljca.c b/drivers/gpio/gpio-ljca.c +index 3b4f8830c7411..f32d1d237795b 100644 +--- a/drivers/gpio/gpio-ljca.c ++++ b/drivers/gpio/gpio-ljca.c +@@ -286,22 +286,14 @@ static void ljca_gpio_event_cb(void *context, u8 cmd, const void *evt_data, + { + const struct ljca_gpio_packet *packet = evt_data; + struct ljca_gpio_dev *ljca_gpio = context; +- int i, irq; ++ int i; + + if (cmd != LJCA_GPIO_INT_EVENT) + return; + + for (i = 0; i < packet->num; i++) { +- irq = irq_find_mapping(ljca_gpio->gc.irq.domain, +- packet->item[i].index); +- if (!irq) { +- dev_err(ljca_gpio->gc.parent, +- "gpio_id %u does not mapped to IRQ yet\n", +- packet->item[i].index); +- return; +- } +- +- generic_handle_domain_irq(ljca_gpio->gc.irq.domain, irq); ++ generic_handle_domain_irq(ljca_gpio->gc.irq.domain, ++ packet->item[i].index); + set_bit(packet->item[i].index, ljca_gpio->reenable_irqs); + } + +-- +2.51.0 + diff --git a/queue-6.17/hwmon-cgbc-hwmon-add-missing-null-check-after-devm_k.patch b/queue-6.17/hwmon-cgbc-hwmon-add-missing-null-check-after-devm_k.patch new file mode 100644 index 0000000000..721159947c --- /dev/null +++ b/queue-6.17/hwmon-cgbc-hwmon-add-missing-null-check-after-devm_k.patch @@ -0,0 +1,43 @@ +From e41ede00d7d6cd4f2059d9096aabebd73fca0c75 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 14:34:14 +0800 +Subject: hwmon: (cgbc-hwmon) Add missing NULL check after devm_kzalloc() + +From: Li Qiang + +[ Upstream commit a09a5aa8bf258ddc99a22c30f17fe304b96b5350 ] + +The driver allocates memory for sensor data using devm_kzalloc(), but +did not check if the allocation succeeded. In case of memory allocation +failure, dereferencing the NULL pointer would lead to a kernel crash. + +Add a NULL pointer check and return -ENOMEM to handle allocation failure +properly. + +Signed-off-by: Li Qiang +Fixes: 08ebc9def79fc ("hwmon: Add Congatec Board Controller monitoring driver") +Reviewed-by: Thomas Richard +Link: https://lore.kernel.org/r/20251017063414.1557447-1-liqiang01@kylinos.cn +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/cgbc-hwmon.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/hwmon/cgbc-hwmon.c b/drivers/hwmon/cgbc-hwmon.c +index 772f44d56ccff..3aff4e092132f 100644 +--- a/drivers/hwmon/cgbc-hwmon.c ++++ b/drivers/hwmon/cgbc-hwmon.c +@@ -107,6 +107,9 @@ static int cgbc_hwmon_probe_sensors(struct device *dev, struct cgbc_hwmon_data * + nb_sensors = data[0]; + + hwmon->sensors = devm_kzalloc(dev, sizeof(*hwmon->sensors) * nb_sensors, GFP_KERNEL); ++ if (!hwmon->sensors) ++ return -ENOMEM; ++ + sensor = hwmon->sensors; + + for (i = 0; i < nb_sensors; i++) { +-- +2.51.0 + diff --git a/queue-6.17/hwmon-pmbus-isl68137-fix-child-node-reference-leak-o.patch b/queue-6.17/hwmon-pmbus-isl68137-fix-child-node-reference-leak-o.patch new file mode 100644 index 0000000000..42c5613358 --- /dev/null +++ b/queue-6.17/hwmon-pmbus-isl68137-fix-child-node-reference-leak-o.patch @@ -0,0 +1,43 @@ +From aaddcd50f2ecc53c7c418ac4723ef5e9e5dd72b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 21:12:49 +0300 +Subject: hwmon: (pmbus/isl68137) Fix child node reference leak on early return + +From: Erick Karanja + +[ Upstream commit 57f6f47920ef2f598c46d0a04bd9c8984c98e6df ] + +In the case of an early return, the reference to the child node needs +to be released. + +Use for_each_child_of_node_scoped to fix the issue. + +Fixes: 3996187f80a0e ("hwmon: (pmbus/isl68137) add support for voltage divider on Vout") +Signed-off-by: Erick Karanja +Link: https://lore.kernel.org/r/20251012181249.359401-1-karanja99erick@gmail.com +[groeck: Updated subject/description] +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/pmbus/isl68137.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/hwmon/pmbus/isl68137.c b/drivers/hwmon/pmbus/isl68137.c +index c52c55d2e7f48..0c6b31ee755b9 100644 +--- a/drivers/hwmon/pmbus/isl68137.c ++++ b/drivers/hwmon/pmbus/isl68137.c +@@ -334,10 +334,9 @@ static int isl68137_probe_from_dt(struct device *dev, + struct isl68137_data *data) + { + const struct device_node *np = dev->of_node; +- struct device_node *child; + int err; + +- for_each_child_of_node(np, child) { ++ for_each_child_of_node_scoped(np, child) { + if (strcmp(child->name, "channel")) + continue; + +-- +2.51.0 + diff --git a/queue-6.17/hwmon-sht3x-fix-error-handling.patch b/queue-6.17/hwmon-sht3x-fix-error-handling.patch new file mode 100644 index 0000000000..5b508a71dc --- /dev/null +++ b/queue-6.17/hwmon-sht3x-fix-error-handling.patch @@ -0,0 +1,99 @@ +From 4664fd5dad57138b6af5331959a24e1ff33c78eb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Oct 2025 06:04:57 -0700 +Subject: hwmon: (sht3x) Fix error handling + +From: Guenter Roeck + +[ Upstream commit 8dcc66ad379ec0642fb281c45ccfd7d2d366e53f ] + +Handling of errors when reading status, temperature, and humidity returns +the error number as negative attribute value. Fix it up by returning +the error as return value. + +Fixes: a0ac418c6007c ("hwmon: (sht3x) convert some of sysfs interface to hwmon") +Cc: JuenKit Yip +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/sht3x.c | 27 +++++++++++++++++---------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/drivers/hwmon/sht3x.c b/drivers/hwmon/sht3x.c +index 557ad3e7752a9..f36c0229328fa 100644 +--- a/drivers/hwmon/sht3x.c ++++ b/drivers/hwmon/sht3x.c +@@ -291,24 +291,26 @@ static struct sht3x_data *sht3x_update_client(struct device *dev) + return data; + } + +-static int temp1_input_read(struct device *dev) ++static int temp1_input_read(struct device *dev, long *temp) + { + struct sht3x_data *data = sht3x_update_client(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + +- return data->temperature; ++ *temp = data->temperature; ++ return 0; + } + +-static int humidity1_input_read(struct device *dev) ++static int humidity1_input_read(struct device *dev, long *humidity) + { + struct sht3x_data *data = sht3x_update_client(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + +- return data->humidity; ++ *humidity = data->humidity; ++ return 0; + } + + /* +@@ -706,6 +708,7 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *val) + { + enum sht3x_limits index; ++ int ret; + + switch (type) { + case hwmon_chip: +@@ -720,10 +723,12 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type, + case hwmon_temp: + switch (attr) { + case hwmon_temp_input: +- *val = temp1_input_read(dev); +- break; ++ return temp1_input_read(dev, val); + case hwmon_temp_alarm: +- *val = temp1_alarm_read(dev); ++ ret = temp1_alarm_read(dev); ++ if (ret < 0) ++ return ret; ++ *val = ret; + break; + case hwmon_temp_max: + index = limit_max; +@@ -748,10 +753,12 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type, + case hwmon_humidity: + switch (attr) { + case hwmon_humidity_input: +- *val = humidity1_input_read(dev); +- break; ++ return humidity1_input_read(dev, val); + case hwmon_humidity_alarm: +- *val = humidity1_alarm_read(dev); ++ ret = humidity1_alarm_read(dev); ++ if (ret < 0) ++ return ret; ++ *val = ret; + break; + case hwmon_humidity_max: + index = limit_max; +-- +2.51.0 + diff --git a/queue-6.17/include-trace-fix-inflight-count-helper-on-failed-in.patch b/queue-6.17/include-trace-fix-inflight-count-helper-on-failed-in.patch new file mode 100644 index 0000000000..3b77251488 --- /dev/null +++ b/queue-6.17/include-trace-fix-inflight-count-helper-on-failed-in.patch @@ -0,0 +1,77 @@ +From 652c291577ea9c5244c871e2fb3c6ef7ba3403c0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 12:53:45 +0100 +Subject: include: trace: Fix inflight count helper on failed initialization + +From: Cristian Marussi + +[ Upstream commit 289ce7e9a5e1a52ac7e522a3e389dc16be08d7a4 ] + +Add a check to the scmi_inflight_count() helper to handle the case +when the SCMI debug subsystem fails to initialize. + +Fixes: f8e656382b4a ("include: trace: Add tracepoint support for inflight xfer count") +Signed-off-by: Cristian Marussi +Message-Id: <20251014115346.2391418-2-cristian.marussi@arm.com> +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_scmi/common.h | 8 +++++--- + drivers/firmware/arm_scmi/driver.c | 7 +++++-- + 2 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h +index 21c0b95027c64..7c35c95fddbaf 100644 +--- a/drivers/firmware/arm_scmi/common.h ++++ b/drivers/firmware/arm_scmi/common.h +@@ -333,10 +333,12 @@ static inline void scmi_inc_count(struct scmi_debug_info *dbg, int stat) + } + } + +-static inline void scmi_dec_count(atomic_t *arr, int stat) ++static inline void scmi_dec_count(struct scmi_debug_info *dbg, int stat) + { +- if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) +- atomic_dec(&arr[stat]); ++ if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) { ++ if (dbg) ++ atomic_dec(&dbg->counters[stat]); ++ } + } + + enum scmi_bad_msg { +diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c +index 56419285c0bfd..1cd15412024cd 100644 +--- a/drivers/firmware/arm_scmi/driver.c ++++ b/drivers/firmware/arm_scmi/driver.c +@@ -594,7 +594,7 @@ scmi_xfer_inflight_register_unlocked(struct scmi_xfer *xfer, + /* Set in-flight */ + set_bit(xfer->hdr.seq, minfo->xfer_alloc_table); + hash_add(minfo->pending_xfers, &xfer->node, xfer->hdr.seq); +- scmi_inc_count(info->dbg->counters, XFERS_INFLIGHT); ++ scmi_inc_count(info->dbg, XFERS_INFLIGHT); + + xfer->pending = true; + } +@@ -803,7 +803,7 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer) + hash_del(&xfer->node); + xfer->pending = false; + +- scmi_dec_count(info->dbg->counters, XFERS_INFLIGHT); ++ scmi_dec_count(info->dbg, XFERS_INFLIGHT); + } + hlist_add_head(&xfer->node, &minfo->free_xfers); + } +@@ -3407,6 +3407,9 @@ int scmi_inflight_count(const struct scmi_handle *handle) + if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) { + struct scmi_info *info = handle_to_scmi_info(handle); + ++ if (!info->dbg) ++ return 0; ++ + return atomic_read(&info->dbg->counters[XFERS_INFLIGHT]); + } else { + return 0; +-- +2.51.0 + diff --git a/queue-6.17/io_uring-correct-__must_hold-annotation-in-io_instal.patch b/queue-6.17/io_uring-correct-__must_hold-annotation-in-io_instal.patch new file mode 100644 index 0000000000..0846d5202e --- /dev/null +++ b/queue-6.17/io_uring-correct-__must_hold-annotation-in-io_instal.patch @@ -0,0 +1,38 @@ +From e30e4ba072bc623e0e72cefbbd74fc8cf98b0c09 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 04:55:24 -0700 +Subject: io_uring: correct __must_hold annotation in io_install_fixed_file + +From: Alok Tiwari + +[ Upstream commit c5efc6a0b3940381d67887302ddb87a5cf623685 ] + +The __must_hold annotation references &req->ctx->uring_lock, but req +is not in scope in io_install_fixed_file. This change updates the +annotation to reference the correct ctx->uring_lock. +improving code clarity. + +Fixes: f110ed8498af ("io_uring: split out fixed file installation and removal") +Signed-off-by: Alok Tiwari +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/filetable.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/io_uring/filetable.c b/io_uring/filetable.c +index a21660e3145ab..794ef95df293c 100644 +--- a/io_uring/filetable.c ++++ b/io_uring/filetable.c +@@ -57,7 +57,7 @@ void io_free_file_tables(struct io_ring_ctx *ctx, struct io_file_table *table) + + static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file, + u32 slot_index) +- __must_hold(&req->ctx->uring_lock) ++ __must_hold(&ctx->uring_lock) + { + struct io_rsrc_node *node; + +-- +2.51.0 + diff --git a/queue-6.17/io_uring-fix-incorrect-unlikely-usage-in-io_waitid_p.patch b/queue-6.17/io_uring-fix-incorrect-unlikely-usage-in-io_waitid_p.patch new file mode 100644 index 0000000000..9d1c245b0e --- /dev/null +++ b/queue-6.17/io_uring-fix-incorrect-unlikely-usage-in-io_waitid_p.patch @@ -0,0 +1,48 @@ +From efb180409e1a1fcdcd1f8c9e49ea3ad67b22973d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Oct 2025 12:32:54 -0700 +Subject: io_uring: fix incorrect unlikely() usage in io_waitid_prep() + +From: Alok Tiwari + +[ Upstream commit 4ec703ec0c384a2199808c4eb2e9037236285a8d ] + +The negation operator is incorrectly placed outside the unlikely() +macro: + + if (!unlikely(iwa)) + +This inverts the compiler branch prediction hint, marking the NULL case +as likely instead of unlikely. The intent is to indicate that allocation +failures are rare, consistent with common kernel patterns. + + Moving the negation inside unlikely(): + + if (unlikely(!iwa)) + +Fixes: 2b4fc4cd43f2 ("io_uring/waitid: setup async data in the prep handler") +Signed-off-by: Alok Tiwari +Reviewed-by: Gabriel Krisman Bertazi +Reviewed-by: Caleb Sander Mateos +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/waitid.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/io_uring/waitid.c b/io_uring/waitid.c +index 3101ad8ec0cf6..c8ca00e681f77 100644 +--- a/io_uring/waitid.c ++++ b/io_uring/waitid.c +@@ -252,7 +252,7 @@ int io_waitid_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) + return -EINVAL; + + iwa = io_uring_alloc_async_data(NULL, req); +- if (!unlikely(iwa)) ++ if (unlikely(!iwa)) + return -ENOMEM; + iwa->req = req; + +-- +2.51.0 + diff --git a/queue-6.17/nbd-override-creds-to-kernel-when-calling-sock_-send.patch b/queue-6.17/nbd-override-creds-to-kernel-when-calling-sock_-send.patch new file mode 100644 index 0000000000..b69d93dd16 --- /dev/null +++ b/queue-6.17/nbd-override-creds-to-kernel-when-calling-sock_-send.patch @@ -0,0 +1,190 @@ +From d1e09c6841cfa8b03e0fc7c4cc691e9e97367771 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Oct 2025 10:09:00 +0200 +Subject: nbd: override creds to kernel when calling sock_{send,recv}msg() + +From: Ondrej Mosnacek + +[ Upstream commit 81ccca31214e11ea2b537fd35d4f66d7cf46268e ] + +sock_{send,recv}msg() internally calls security_socket_{send,recv}msg(), +which does security checks (e.g. SELinux) for socket access against the +current task. However, _sock_xmit() in drivers/block/nbd.c may be called +indirectly from a userspace syscall, where the NBD socket access would +be incorrectly checked against the calling userspace task (which simply +tries to read/write a file that happens to reside on an NBD device). + +To fix this, temporarily override creds to kernel ones before calling +the sock_*() functions. This allows the security modules to recognize +this as internal access by the kernel, which will normally be allowed. + +A way to trigger the issue is to do the following (on a system with +SELinux set to enforcing): + + ### Create nbd device: + truncate -s 256M /tmp/testfile + nbd-server localhost:10809 /tmp/testfile + + ### Connect to the nbd server: + nbd-client localhost + + ### Create mdraid array + mdadm --create -l 1 -n 2 /dev/md/testarray /dev/nbd0 missing + +After these steps, assuming the SELinux policy doesn't allow the +unexpected access pattern, errors will be visible on the kernel console: + +[ 142.204243] nbd0: detected capacity change from 0 to 524288 +[ 165.189967] md: async del_gendisk mode will be removed in future, please upgrade to mdadm-4.5+ +[ 165.252299] md/raid1:md127: active with 1 out of 2 mirrors +[ 165.252725] md127: detected capacity change from 0 to 522240 +[ 165.255434] block nbd0: Send control failed (result -13) +[ 165.255718] block nbd0: Request send failed, requeueing +[ 165.256006] block nbd0: Dead connection, failed to find a fallback +[ 165.256041] block nbd0: Receive control failed (result -32) +[ 165.256423] block nbd0: shutting down sockets +[ 165.257196] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.257736] Buffer I/O error on dev md127, logical block 0, async page read +[ 165.258263] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.259376] Buffer I/O error on dev md127, logical block 0, async page read +[ 165.259920] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.260628] Buffer I/O error on dev md127, logical block 0, async page read +[ 165.261661] ldm_validate_partition_table(): Disk read failed. +[ 165.262108] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.262769] Buffer I/O error on dev md127, logical block 0, async page read +[ 165.263697] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.264412] Buffer I/O error on dev md127, logical block 0, async page read +[ 165.265412] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.265872] Buffer I/O error on dev md127, logical block 0, async page read +[ 165.266378] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.267168] Buffer I/O error on dev md127, logical block 0, async page read +[ 165.267564] md127: unable to read partition table +[ 165.269581] I/O error, dev nbd0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.269960] Buffer I/O error on dev nbd0, logical block 0, async page read +[ 165.270316] I/O error, dev nbd0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.270913] Buffer I/O error on dev nbd0, logical block 0, async page read +[ 165.271253] I/O error, dev nbd0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 +[ 165.271809] Buffer I/O error on dev nbd0, logical block 0, async page read +[ 165.272074] ldm_validate_partition_table(): Disk read failed. +[ 165.272360] nbd0: unable to read partition table +[ 165.289004] ldm_validate_partition_table(): Disk read failed. +[ 165.289614] nbd0: unable to read partition table + +The corresponding SELinux denial on Fedora/RHEL will look like this +(assuming it's not silenced): +type=AVC msg=audit(1758104872.510:116): avc: denied { write } for pid=1908 comm="mdadm" laddr=::1 lport=32772 faddr=::1 fport=10809 scontext=system_u:system_r:mdadm_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=tcp_socket permissive=0 + +The respective backtrace looks like this: +@security[mdadm, -13, + handshake_exit+221615650 + handshake_exit+221615650 + handshake_exit+221616465 + security_socket_sendmsg+5 + sock_sendmsg+106 + handshake_exit+221616150 + sock_sendmsg+5 + __sock_xmit+162 + nbd_send_cmd+597 + nbd_handle_cmd+377 + nbd_queue_rq+63 + blk_mq_dispatch_rq_list+653 + __blk_mq_do_dispatch_sched+184 + __blk_mq_sched_dispatch_requests+333 + blk_mq_sched_dispatch_requests+38 + blk_mq_run_hw_queue+239 + blk_mq_dispatch_plug_list+382 + blk_mq_flush_plug_list.part.0+55 + __blk_flush_plug+241 + __submit_bio+353 + submit_bio_noacct_nocheck+364 + submit_bio_wait+84 + __blkdev_direct_IO_simple+232 + blkdev_read_iter+162 + vfs_read+591 + ksys_read+95 + do_syscall_64+92 + entry_SYSCALL_64_after_hwframe+120 +]: 1 + +The issue has started to appear since commit 060406c61c7c ("block: add +plug while submitting IO"). + +Cc: Ming Lei +Link: https://bugzilla.redhat.com/show_bug.cgi?id=2348878 +Fixes: 060406c61c7c ("block: add plug while submitting IO") +Signed-off-by: Ondrej Mosnacek +Acked-by: Paul Moore +Acked-by: Stephen Smalley +Reviewed-by: Ming Lei +Tested-by: Ming Lei +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 87b0b78249da3..ad39ab95ea665 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -52,6 +52,7 @@ + static DEFINE_IDR(nbd_index_idr); + static DEFINE_MUTEX(nbd_index_mutex); + static struct workqueue_struct *nbd_del_wq; ++static struct cred *nbd_cred; + static int nbd_total_devices = 0; + + struct nbd_sock { +@@ -554,6 +555,7 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send, + int result; + struct msghdr msg = {} ; + unsigned int noreclaim_flag; ++ const struct cred *old_cred; + + if (unlikely(!sock)) { + dev_err_ratelimited(disk_to_dev(nbd->disk), +@@ -562,6 +564,8 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send, + return -EINVAL; + } + ++ old_cred = override_creds(nbd_cred); ++ + msg.msg_iter = *iter; + + noreclaim_flag = memalloc_noreclaim_save(); +@@ -586,6 +590,8 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send, + + memalloc_noreclaim_restore(noreclaim_flag); + ++ revert_creds(old_cred); ++ + return result; + } + +@@ -2677,7 +2683,15 @@ static int __init nbd_init(void) + return -ENOMEM; + } + ++ nbd_cred = prepare_kernel_cred(&init_task); ++ if (!nbd_cred) { ++ destroy_workqueue(nbd_del_wq); ++ unregister_blkdev(NBD_MAJOR, "nbd"); ++ return -ENOMEM; ++ } ++ + if (genl_register_family(&nbd_genl_family)) { ++ put_cred(nbd_cred); + destroy_workqueue(nbd_del_wq); + unregister_blkdev(NBD_MAJOR, "nbd"); + return -EINVAL; +@@ -2732,6 +2746,7 @@ static void __exit nbd_cleanup(void) + /* Also wait for nbd_dev_remove_work() completes */ + destroy_workqueue(nbd_del_wq); + ++ put_cred(nbd_cred); + idr_destroy(&nbd_index_idr); + unregister_blkdev(NBD_MAJOR, "nbd"); + } +-- +2.51.0 + diff --git a/queue-6.17/of-irq-add-msi-parent-check-to-of_msi_xlate.patch b/queue-6.17/of-irq-add-msi-parent-check-to-of_msi_xlate.patch new file mode 100644 index 0000000000..7e0609ec80 --- /dev/null +++ b/queue-6.17/of-irq-add-msi-parent-check-to-of_msi_xlate.patch @@ -0,0 +1,108 @@ +From dc4ba65d1501a08fa32c61cb472de9b4d5365c7f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 14:40:59 +0200 +Subject: of/irq: Add msi-parent check to of_msi_xlate() + +From: Lorenzo Pieralisi + +[ Upstream commit 119aaeed0b6729293f41ea33be05ecd27a947d48 ] + +In some legacy platforms the MSI controller for a PCI host bridge is +identified by an msi-parent property whose phandle points at an MSI +controller node with no #msi-cells property, that implicitly +means #msi-cells == 0. + +For such platforms, mapping a device ID and retrieving the MSI controller +node becomes simply a matter of checking whether in the device hierarchy +there is an msi-parent property pointing at an MSI controller node with +such characteristics. + +Add a helper function to of_msi_xlate() to check the msi-parent property in +addition to msi-map and retrieve the MSI controller node (with a 1:1 ID +deviceID-IN<->deviceID-OUT mapping) to provide support for deviceID +mapping and MSI controller node retrieval for such platforms. + +Fixes: 57d72196dfc8 ("irqchip/gic-v5: Add GICv5 ITS support") +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Frank Li +Cc: Sascha Bischoff +Cc: Rob Herring +Cc: Marc Zyngier +Link: https://patch.msgid.link/20251021124103.198419-2-lpieralisi@kernel.org +Signed-off-by: Rob Herring (Arm) +Signed-off-by: Sasha Levin +--- + drivers/of/irq.c | 39 ++++++++++++++++++++++++++++++++++++--- + 1 file changed, 36 insertions(+), 3 deletions(-) + +diff --git a/drivers/of/irq.c b/drivers/of/irq.c +index e7c12abd10ab7..3d4afeeb30ed7 100644 +--- a/drivers/of/irq.c ++++ b/drivers/of/irq.c +@@ -670,6 +670,36 @@ void __init of_irq_init(const struct of_device_id *matches) + } + } + ++static int of_check_msi_parent(struct device_node *dev_node, struct device_node **msi_node) ++{ ++ struct of_phandle_args msi_spec; ++ int ret; ++ ++ /* ++ * An msi-parent phandle with a missing or == 0 #msi-cells ++ * property identifies a 1:1 ID translation mapping. ++ * ++ * Set the msi controller node if the firmware matches this ++ * condition. ++ */ ++ ret = of_parse_phandle_with_optional_args(dev_node, "msi-parent", "#msi-cells", ++ 0, &msi_spec); ++ if (ret) ++ return ret; ++ ++ if ((*msi_node && *msi_node != msi_spec.np) || msi_spec.args_count != 0) ++ ret = -EINVAL; ++ ++ if (!ret) { ++ /* Return with a node reference held */ ++ *msi_node = msi_spec.np; ++ return 0; ++ } ++ of_node_put(msi_spec.np); ++ ++ return ret; ++} ++ + /** + * of_msi_xlate - map a MSI ID and find relevant MSI controller node + * @dev: device for which the mapping is to be done. +@@ -677,7 +707,7 @@ void __init of_irq_init(const struct of_device_id *matches) + * @id_in: Device ID. + * + * Walk up the device hierarchy looking for devices with a "msi-map" +- * property. If found, apply the mapping to @id_in. ++ * or "msi-parent" property. If found, apply the mapping to @id_in. + * If @msi_np points to a non-NULL device node pointer, only entries targeting + * that node will be matched; if it points to a NULL value, it will receive the + * device node of the first matching target phandle, with a reference held. +@@ -691,12 +721,15 @@ u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u32 id_in) + + /* + * Walk up the device parent links looking for one with a +- * "msi-map" property. ++ * "msi-map" or an "msi-parent" property. + */ +- for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) ++ for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) { + if (!of_map_id(parent_dev->of_node, id_in, "msi-map", + "msi-map-mask", msi_np, &id_out)) + break; ++ if (!of_check_msi_parent(parent_dev->of_node, msi_np)) ++ break; ++ } + return id_out; + } + +-- +2.51.0 + diff --git a/queue-6.17/of-irq-convert-of_msi_map_id-callers-to-of_msi_xlate.patch b/queue-6.17/of-irq-convert-of_msi_map_id-callers-to-of_msi_xlate.patch new file mode 100644 index 0000000000..d44e3ace59 --- /dev/null +++ b/queue-6.17/of-irq-convert-of_msi_map_id-callers-to-of_msi_xlate.patch @@ -0,0 +1,138 @@ +From 966ee70e2ab6cba93a898fafce9139718a290d9a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Aug 2025 15:34:43 +0200 +Subject: of/irq: Convert of_msi_map_id() callers to of_msi_xlate() + +From: Lorenzo Pieralisi + +[ Upstream commit a576a849d5f33356e0d8fd3eae4fbaf8869417e5 ] + +With the introduction of the of_msi_xlate() function, the OF layer +provides an API to map a device ID and retrieve the MSI controller +node the ID is mapped to with a single call. + +of_msi_map_id() is currently used to map a deviceID to a specific +MSI controller node; of_msi_xlate() can be used for that purpose +too, there is no need to keep the two functions. + +Convert of_msi_map_id() to of_msi_xlate() calls and update the +of_msi_xlate() documentation to describe how the struct device_node +pointer passed in should be set-up to either provide the MSI controller +node target or receive its pointer upon mapping completion. + +Signed-off-by: Lorenzo Pieralisi +Cc: Thomas Gleixner +Cc: Rob Herring +Cc: Marc Zyngier +Acked-by: Thomas Gleixner +Reviewed-by: Frank Li +Link: https://lore.kernel.org/r/20250805133443.936955-1-lpieralisi@kernel.org +Signed-off-by: Rob Herring (Arm) +Stable-dep-of: 119aaeed0b67 ("of/irq: Add msi-parent check to of_msi_xlate()") +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c | 2 +- + drivers/of/irq.c | 25 +++++---------------- + drivers/pci/msi/irqdomain.c | 2 +- + include/linux/of_irq.h | 6 ----- + 4 files changed, 7 insertions(+), 28 deletions(-) + +diff --git a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c +index 11549d85f23b8..b5785472765a3 100644 +--- a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c ++++ b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c +@@ -30,7 +30,7 @@ static u32 fsl_mc_msi_domain_get_msi_id(struct irq_domain *domain, + u32 out_id; + + of_node = irq_domain_get_of_node(domain); +- out_id = of_node ? of_msi_map_id(&mc_dev->dev, of_node, mc_dev->icid) : ++ out_id = of_node ? of_msi_xlate(&mc_dev->dev, &of_node, mc_dev->icid) : + iort_msi_map_id(&mc_dev->dev, mc_dev->icid); + + return out_id; +diff --git a/drivers/of/irq.c b/drivers/of/irq.c +index 74aaea61de13c..e7c12abd10ab7 100644 +--- a/drivers/of/irq.c ++++ b/drivers/of/irq.c +@@ -673,13 +673,14 @@ void __init of_irq_init(const struct of_device_id *matches) + /** + * of_msi_xlate - map a MSI ID and find relevant MSI controller node + * @dev: device for which the mapping is to be done. +- * @msi_np: Pointer to store the MSI controller node ++ * @msi_np: Pointer to target MSI controller node + * @id_in: Device ID. + * + * Walk up the device hierarchy looking for devices with a "msi-map" +- * property. If found, apply the mapping to @id_in. @msi_np pointed +- * value must be NULL on entry, if an MSI controller is found @msi_np is +- * initialized to the MSI controller node with a reference held. ++ * property. If found, apply the mapping to @id_in. ++ * If @msi_np points to a non-NULL device node pointer, only entries targeting ++ * that node will be matched; if it points to a NULL value, it will receive the ++ * device node of the first matching target phandle, with a reference held. + * + * Returns: The mapped MSI id. + */ +@@ -699,22 +700,6 @@ u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u32 id_in) + return id_out; + } + +-/** +- * of_msi_map_id - Map a MSI ID for a device. +- * @dev: device for which the mapping is to be done. +- * @msi_np: device node of the expected msi controller. +- * @id_in: unmapped MSI ID for the device. +- * +- * Walk up the device hierarchy looking for devices with a "msi-map" +- * property. If found, apply the mapping to @id_in. +- * +- * Return: The mapped MSI ID. +- */ +-u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in) +-{ +- return of_msi_xlate(dev, &msi_np, id_in); +-} +- + /** + * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain + * @dev: device for which the mapping is to be done. +diff --git a/drivers/pci/msi/irqdomain.c b/drivers/pci/msi/irqdomain.c +index b11b7f63f0d6f..cbdc83c064d42 100644 +--- a/drivers/pci/msi/irqdomain.c ++++ b/drivers/pci/msi/irqdomain.c +@@ -479,7 +479,7 @@ u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev) + pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); + + of_node = irq_domain_get_of_node(domain); +- rid = of_node ? of_msi_map_id(&pdev->dev, of_node, rid) : ++ rid = of_node ? of_msi_xlate(&pdev->dev, &of_node, rid) : + iort_msi_map_id(&pdev->dev, rid); + + return rid; +diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h +index a480063c9cb19..1db8543dfc8a6 100644 +--- a/include/linux/of_irq.h ++++ b/include/linux/of_irq.h +@@ -55,7 +55,6 @@ extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev, + u32 bus_token); + extern void of_msi_configure(struct device *dev, const struct device_node *np); + extern u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u32 id_in); +-u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in); + #else + static inline void of_irq_init(const struct of_device_id *matches) + { +@@ -105,11 +104,6 @@ static inline u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, + { + return id_in; + } +-static inline u32 of_msi_map_id(struct device *dev, +- struct device_node *msi_np, u32 id_in) +-{ +- return id_in; +-} + #endif + + #if defined(CONFIG_OF_IRQ) || defined(CONFIG_SPARC) +-- +2.51.0 + diff --git a/queue-6.17/risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch b/queue-6.17/risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch new file mode 100644 index 0000000000..20fb1d86f6 --- /dev/null +++ b/queue-6.17/risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch @@ -0,0 +1,48 @@ +From 953ba98525e314e46320c4d964f007cb85983816 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 21:30:05 -0600 +Subject: RISC-V: Define pgprot_dmacoherent() for non-coherent devices + +From: Anup Patel + +[ Upstream commit ca525d53f994d45c8140968b571372c45f555ac1 ] + +The pgprot_dmacoherent() is used when allocating memory for +non-coherent devices and by default pgprot_dmacoherent() is +same as pgprot_noncached() unless architecture overrides it. + +Currently, there is no pgprot_dmacoherent() definition for +RISC-V hence non-coherent device memory is being mapped as +IO thereby making CPU access to such memory slow. + +Define pgprot_dmacoherent() to be same as pgprot_writecombine() +for RISC-V so that CPU access non-coherent device memory as +NOCACHE which is better than accessing it as IO. + +Fixes: ff689fd21cb1 ("riscv: add RISC-V Svpbmt extension support") +Signed-off-by: Anup Patel +Tested-by: Han Gao +Tested-by: Guo Ren (Alibaba DAMO Academy) +Link: https://lore.kernel.org/r/20250820152316.1012757-1-apatel@ventanamicro.com +Signed-off-by: Paul Walmsley +Signed-off-by: Sasha Levin +--- + arch/riscv/include/asm/pgtable.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h +index 8150677429398..4355e8f3670bb 100644 +--- a/arch/riscv/include/asm/pgtable.h ++++ b/arch/riscv/include/asm/pgtable.h +@@ -653,6 +653,8 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot) + return __pgprot(prot); + } + ++#define pgprot_dmacoherent pgprot_writecombine ++ + /* + * Both Svade and Svadu control the hardware behavior when the PTE A/D bits need to be set. By + * default the M-mode firmware enables the hardware updating scheme when only Svadu is present in +-- +2.51.0 + diff --git a/queue-6.17/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch b/queue-6.17/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch new file mode 100644 index 0000000000..4fb3d989df --- /dev/null +++ b/queue-6.17/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch @@ -0,0 +1,46 @@ +From 5a15954d4ad64f14d23c4371e3fd83984723299f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 22:00:09 +0530 +Subject: RISC-V: Don't print details of CPUs disabled in DT + +From: Anup Patel + +[ Upstream commit d2721bb165b3ee00dd23525885381af07fec852a ] + +Early boot stages may disable CPU DT nodes for unavailable +CPUs based on SKU, pinstraps, eFuse, etc. Currently, the +riscv_early_of_processor_hartid() prints details of a CPU +if it is disabled in DT which has no value and gives a +false impression to the users that there some issue with +the CPU. + +Fixes: e3d794d555cd ("riscv: treat cpu devicetree nodes without status as enabled") +Signed-off-by: Anup Patel +Reviewed-by: Andrew Jones +Reviewed-by: Conor Dooley +Link: https://lore.kernel.org/r/20251014163009.182381-1-apatel@ventanamicro.com +Signed-off-by: Paul Walmsley +Signed-off-by: Sasha Levin +--- + arch/riscv/kernel/cpu.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c +index f6b13e9f5e6cb..3dbc8cc557dd1 100644 +--- a/arch/riscv/kernel/cpu.c ++++ b/arch/riscv/kernel/cpu.c +@@ -62,10 +62,8 @@ int __init riscv_early_of_processor_hartid(struct device_node *node, unsigned lo + return -ENODEV; + } + +- if (!of_device_is_available(node)) { +- pr_info("CPU with hartid=%lu is not available\n", *hart); ++ if (!of_device_is_available(node)) + return -ENODEV; +- } + + if (of_property_read_string(node, "riscv,isa-base", &isa)) + goto old_interface; +-- +2.51.0 + diff --git a/queue-6.17/riscv-hwprobe-avoid-uninitialized-variable-use-in-hw.patch b/queue-6.17/riscv-hwprobe-avoid-uninitialized-variable-use-in-hw.patch new file mode 100644 index 0000000000..d05ec0f34a --- /dev/null +++ b/queue-6.17/riscv-hwprobe-avoid-uninitialized-variable-use-in-hw.patch @@ -0,0 +1,59 @@ +From 9b5c932446c4b9828b61aa3ef5e45c769fcdf9f5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Oct 2025 09:32:12 -0600 +Subject: riscv: hwprobe: avoid uninitialized variable use in hwprobe_arch_id() + +From: Paul Walmsley + +[ Upstream commit b7776a802f2f80139f96530a489dd00fd7089eda ] + +Resolve this smatch warning: + + arch/riscv/kernel/sys_hwprobe.c:50 hwprobe_arch_id() error: uninitialized symbol 'cpu_id'. + +This could happen if hwprobe_arch_id() was called with a key ID of +something other than MVENDORID, MIMPID, and MARCHID. This does not +happen in the current codebase. The only caller of hwprobe_arch_id() +is a function that only passes one of those three key IDs. + +For the sake of reducing static analyzer warning noise, and in the +unlikely event that hwprobe_arch_id() is someday called with some +other key ID, validate hwprobe_arch_id()'s input to ensure that +'cpu_id' is always initialized before use. + +Fixes: ea3de9ce8aa280 ("RISC-V: Add a syscall for HW probing") +Cc: Evan Green +Signed-off-by: Paul Walmsley +Link: https://lore.kernel.org/r/cf5a13ec-19d0-9862-059b-943f36107bf3@kernel.org +Signed-off-by: Sasha Levin +--- + arch/riscv/kernel/sys_hwprobe.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c +index 3e9259790816e..5436b9d022e00 100644 +--- a/arch/riscv/kernel/sys_hwprobe.c ++++ b/arch/riscv/kernel/sys_hwprobe.c +@@ -27,6 +27,11 @@ static void hwprobe_arch_id(struct riscv_hwprobe *pair, + bool first = true; + int cpu; + ++ if (pair->key != RISCV_HWPROBE_KEY_MVENDORID && ++ pair->key != RISCV_HWPROBE_KEY_MIMPID && ++ pair->key != RISCV_HWPROBE_KEY_MARCHID) ++ goto out; ++ + for_each_cpu(cpu, cpus) { + u64 cpu_id; + +@@ -57,6 +62,7 @@ static void hwprobe_arch_id(struct riscv_hwprobe *pair, + } + } + ++out: + pair->value = id; + } + +-- +2.51.0 + diff --git a/queue-6.17/sched-remove-never-used-code-in-mm_cid_get.patch b/queue-6.17/sched-remove-never-used-code-in-mm_cid_get.patch new file mode 100644 index 0000000000..17e253163e --- /dev/null +++ b/queue-6.17/sched-remove-never-used-code-in-mm_cid_get.patch @@ -0,0 +1,47 @@ +From 7a91d8ee52f9c049710e7458f338c4ecf182d7ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 11:19:34 +0200 +Subject: sched: Remove never used code in mm_cid_get() + +From: Andy Shevchenko + +[ Upstream commit 53abe3e1c154628cc74e33a1bfcd865656e433a5 ] + +Clang is not happy with set but unused variable (this is visible +with `make W=1` build: + + kernel/sched/sched.h:3744:18: error: variable 'cpumask' set but not used [-Werror,-Wunused-but-set-variable] + +It seems like the variable was never used along with the assignment +that does not have side effects as far as I can see. Remove those +altogether. + +Fixes: 223baf9d17f2 ("sched: Fix performance regression introduced by mm_cid") +Signed-off-by: Andy Shevchenko +Tested-by: Eric Biggers +Reviewed-by: Breno Leitao +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + kernel/sched/sched.h | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h +index cf2109b67f9a3..72fb9129afb6a 100644 +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -3735,11 +3735,9 @@ static inline int mm_cid_get(struct rq *rq, struct task_struct *t, + struct mm_struct *mm) + { + struct mm_cid __percpu *pcpu_cid = mm->pcpu_cid; +- struct cpumask *cpumask; + int cid; + + lockdep_assert_rq_held(rq); +- cpumask = mm_cidmask(mm); + cid = __this_cpu_read(pcpu_cid->cid); + if (mm_cid_is_valid(cid)) { + mm_cid_snapshot_time(rq, mm); +-- +2.51.0 + diff --git a/queue-6.17/series b/queue-6.17/series index 22096c5823..f4596a5e60 100644 --- a/queue-6.17/series +++ b/queue-6.17/series @@ -59,3 +59,38 @@ net-datagram-introduce-datagram_poll_queue-for-custo.patch ovpn-use-datagram_poll_queue-for-socket-readiness-in.patch net-phy-micrel-always-set-shared-phydev-for-lan8814.patch net-mlx5-fix-ipsec-cleanup-over-mpv-device.patch +spi-rockchip-sfc-fix-dma-api-usage.patch +firmware-arm_ffa-add-support-for-impdef-value-in-the.patch +spi-spi-nxp-fspi-add-the-support-for-sample-data-fro.patch +spi-spi-nxp-fspi-re-config-the-clock-rate-when-opera.patch +spi-spi-nxp-fspi-add-extra-delay-after-dll-locked.patch +spi-spi-nxp-fspi-limit-the-clock-rate-for-different-.patch +spi-cadence-quadspi-fix-pm_runtime-unbalance-on-dma-.patch +arm64-dts-broadcom-bcm2712-add-default-gic-address-c.patch +arm64-dts-broadcom-bcm2712-define-vgic-interrupt.patch +firmware-arm_scmi-account-for-failed-debug-initializ.patch +include-trace-fix-inflight-count-helper-on-failed-in.patch +firmware-arm_scmi-fix-premature-scmi_xfer_flag_is_ra.patch +spi-airoha-return-an-error-for-continuous-mode-dirma.patch +spi-airoha-add-support-of-dual-quad-wires-spi-modes-.patch +spi-airoha-switch-back-to-non-dma-mode-in-the-case-o.patch +spi-airoha-fix-reading-writing-of-flashes-with-more-.patch +sysfs-check-visibility-before-changing-group-attribu.patch +drm-panthor-fix-kernel-panic-on-partial-unmap-of-a-g.patch +risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch +risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch +riscv-hwprobe-avoid-uninitialized-variable-use-in-hw.patch +hwmon-pmbus-isl68137-fix-child-node-reference-leak-o.patch +hwmon-cgbc-hwmon-add-missing-null-check-after-devm_k.patch +hwmon-sht3x-fix-error-handling.patch +io_uring-fix-incorrect-unlikely-usage-in-io_waitid_p.patch +nbd-override-creds-to-kernel-when-calling-sock_-send.patch +drm-panic-fix-drawing-the-logo-on-a-small-narrow-scr.patch +drm-panic-fix-qr_code-ensure-vmargin-is-positive.patch +drm-panic-fix-24bit-pixel-crossing-page-boundaries.patch +of-irq-convert-of_msi_map_id-callers-to-of_msi_xlate.patch +of-irq-add-msi-parent-check-to-of_msi_xlate.patch +block-require-lba-dma_alignment-when-using-pi.patch +gpio-ljca-fix-duplicated-irq-mapping.patch +io_uring-correct-__must_hold-annotation-in-io_instal.patch +sched-remove-never-used-code-in-mm_cid_get.patch diff --git a/queue-6.17/spi-airoha-add-support-of-dual-quad-wires-spi-modes-.patch b/queue-6.17/spi-airoha-add-support-of-dual-quad-wires-spi-modes-.patch new file mode 100644 index 0000000000..7914a30913 --- /dev/null +++ b/queue-6.17/spi-airoha-add-support-of-dual-quad-wires-spi-modes-.patch @@ -0,0 +1,221 @@ +From faa8f2d2b8713400e15ba41ae0e3425a60614f67 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 15:16:54 +0300 +Subject: spi: airoha: add support of dual/quad wires spi modes to exec_op() + handler + +From: Mikhail Kshevetskiy + +[ Upstream commit edd2e261b1babb92213089b5feadca12e3459322 ] + +Booting without this patch and disabled dirmap support results in + +[ 2.980719] spi-nand spi0.0: Micron SPI NAND was found. +[ 2.986040] spi-nand spi0.0: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128 +[ 2.994709] 2 fixed-partitions partitions found on MTD device spi0.0 +[ 3.001075] Creating 2 MTD partitions on "spi0.0": +[ 3.005862] 0x000000000000-0x000000020000 : "bl2" +[ 3.011272] 0x000000020000-0x000010000000 : "ubi" +... +[ 6.195594] ubi0: attaching mtd1 +[ 13.338398] ubi0: scanning is finished +[ 13.342188] ubi0 error: ubi_read_volume_table: the layout volume was not found +[ 13.349784] ubi0 error: ubi_attach_mtd_dev: failed to attach mtd1, error -22 +[ 13.356897] UBI error: cannot attach mtd1 + +If dirmap is disabled or not supported in the spi driver, the dirmap requests +will be executed via exec_op() handler. Thus, if the hardware supports +dual/quad spi modes, then corresponding requests will be sent to exec_op() +handler. Current driver does not support such requests, so error is arrised. +As result the flash can't be read/write. + +This patch adds support of dual and quad wires spi modes to exec_op() handler. + +Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver") +Signed-off-by: Mikhail Kshevetskiy +Reviewed-by: AngeloGioacchino Del Regno +Link: https://patch.msgid.link/20251012121707.2296160-4-mikhail.kshevetskiy@iopsys.eu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-airoha-snfi.c | 108 ++++++++++++++++++++++++++-------- + 1 file changed, 82 insertions(+), 26 deletions(-) + +diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c +index 043a03cd90a19..0b89dc42545b1 100644 +--- a/drivers/spi/spi-airoha-snfi.c ++++ b/drivers/spi/spi-airoha-snfi.c +@@ -192,6 +192,14 @@ + #define SPI_NAND_OP_RESET 0xff + #define SPI_NAND_OP_DIE_SELECT 0xc2 + ++/* SNAND FIFO commands */ ++#define SNAND_FIFO_TX_BUSWIDTH_SINGLE 0x08 ++#define SNAND_FIFO_TX_BUSWIDTH_DUAL 0x09 ++#define SNAND_FIFO_TX_BUSWIDTH_QUAD 0x0a ++#define SNAND_FIFO_RX_BUSWIDTH_SINGLE 0x0c ++#define SNAND_FIFO_RX_BUSWIDTH_DUAL 0x0e ++#define SNAND_FIFO_RX_BUSWIDTH_QUAD 0x0f ++ + #define SPI_NAND_CACHE_SIZE (SZ_4K + SZ_256) + #define SPI_MAX_TRANSFER_SIZE 511 + +@@ -387,10 +395,26 @@ static int airoha_snand_set_mode(struct airoha_snand_ctrl *as_ctrl, + return regmap_write(as_ctrl->regmap_ctrl, REG_SPI_CTRL_DUMMY, 0); + } + +-static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, u8 cmd, +- const u8 *data, int len) ++static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, ++ const u8 *data, int len, int buswidth) + { + int i, data_len; ++ u8 cmd; ++ ++ switch (buswidth) { ++ case 0: ++ case 1: ++ cmd = SNAND_FIFO_TX_BUSWIDTH_SINGLE; ++ break; ++ case 2: ++ cmd = SNAND_FIFO_TX_BUSWIDTH_DUAL; ++ break; ++ case 4: ++ cmd = SNAND_FIFO_TX_BUSWIDTH_QUAD; ++ break; ++ default: ++ return -EINVAL; ++ } + + for (i = 0; i < len; i += data_len) { + int err; +@@ -409,16 +433,32 @@ static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, u8 cmd, + return 0; + } + +-static int airoha_snand_read_data(struct airoha_snand_ctrl *as_ctrl, u8 *data, +- int len) ++static int airoha_snand_read_data(struct airoha_snand_ctrl *as_ctrl, ++ u8 *data, int len, int buswidth) + { + int i, data_len; ++ u8 cmd; ++ ++ switch (buswidth) { ++ case 0: ++ case 1: ++ cmd = SNAND_FIFO_RX_BUSWIDTH_SINGLE; ++ break; ++ case 2: ++ cmd = SNAND_FIFO_RX_BUSWIDTH_DUAL; ++ break; ++ case 4: ++ cmd = SNAND_FIFO_RX_BUSWIDTH_QUAD; ++ break; ++ default: ++ return -EINVAL; ++ } + + for (i = 0; i < len; i += data_len) { + int err; + + data_len = min(len - i, SPI_MAX_TRANSFER_SIZE); +- err = airoha_snand_set_fifo_op(as_ctrl, 0xc, data_len); ++ err = airoha_snand_set_fifo_op(as_ctrl, cmd, data_len); + if (err) + return err; + +@@ -902,12 +942,28 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, + static int airoha_snand_exec_op(struct spi_mem *mem, + const struct spi_mem_op *op) + { +- u8 data[8], cmd, opcode = op->cmd.opcode; + struct airoha_snand_ctrl *as_ctrl; ++ int op_len, addr_len, dummy_len; ++ u8 buf[20], *data; + int i, err; + + as_ctrl = spi_controller_get_devdata(mem->spi->controller); + ++ op_len = op->cmd.nbytes; ++ addr_len = op->addr.nbytes; ++ dummy_len = op->dummy.nbytes; ++ ++ if (op_len + dummy_len + addr_len > sizeof(buf)) ++ return -EIO; ++ ++ data = buf; ++ for (i = 0; i < op_len; i++) ++ *data++ = op->cmd.opcode >> (8 * (op_len - i - 1)); ++ for (i = 0; i < addr_len; i++) ++ *data++ = op->addr.val >> (8 * (addr_len - i - 1)); ++ for (i = 0; i < dummy_len; i++) ++ *data++ = 0xff; ++ + /* switch to manual mode */ + err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); + if (err < 0) +@@ -918,40 +974,40 @@ static int airoha_snand_exec_op(struct spi_mem *mem, + return err; + + /* opcode */ +- err = airoha_snand_write_data(as_ctrl, 0x8, &opcode, sizeof(opcode)); ++ data = buf; ++ err = airoha_snand_write_data(as_ctrl, data, op_len, ++ op->cmd.buswidth); + if (err) + return err; + + /* addr part */ +- cmd = opcode == SPI_NAND_OP_GET_FEATURE ? 0x11 : 0x8; +- put_unaligned_be64(op->addr.val, data); +- +- for (i = ARRAY_SIZE(data) - op->addr.nbytes; +- i < ARRAY_SIZE(data); i++) { +- err = airoha_snand_write_data(as_ctrl, cmd, &data[i], +- sizeof(data[0])); ++ data += op_len; ++ if (addr_len) { ++ err = airoha_snand_write_data(as_ctrl, data, addr_len, ++ op->addr.buswidth); + if (err) + return err; + } + + /* dummy */ +- data[0] = 0xff; +- for (i = 0; i < op->dummy.nbytes; i++) { +- err = airoha_snand_write_data(as_ctrl, 0x8, &data[0], +- sizeof(data[0])); ++ data += addr_len; ++ if (dummy_len) { ++ err = airoha_snand_write_data(as_ctrl, data, dummy_len, ++ op->dummy.buswidth); + if (err) + return err; + } + + /* data */ +- if (op->data.dir == SPI_MEM_DATA_IN) { +- err = airoha_snand_read_data(as_ctrl, op->data.buf.in, +- op->data.nbytes); +- if (err) +- return err; +- } else { +- err = airoha_snand_write_data(as_ctrl, 0x8, op->data.buf.out, +- op->data.nbytes); ++ if (op->data.nbytes) { ++ if (op->data.dir == SPI_MEM_DATA_IN) ++ err = airoha_snand_read_data(as_ctrl, op->data.buf.in, ++ op->data.nbytes, ++ op->data.buswidth); ++ else ++ err = airoha_snand_write_data(as_ctrl, op->data.buf.out, ++ op->data.nbytes, ++ op->data.buswidth); + if (err) + return err; + } +-- +2.51.0 + diff --git a/queue-6.17/spi-airoha-fix-reading-writing-of-flashes-with-more-.patch b/queue-6.17/spi-airoha-fix-reading-writing-of-flashes-with-more-.patch new file mode 100644 index 0000000000..714c210945 --- /dev/null +++ b/queue-6.17/spi-airoha-fix-reading-writing-of-flashes-with-more-.patch @@ -0,0 +1,114 @@ +From a6a83c357af5f6f88ecb8963ee2d10f4721c6e20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 15:16:57 +0300 +Subject: spi: airoha: fix reading/writing of flashes with more than one plane + per lun + +From: Mikhail Kshevetskiy + +[ Upstream commit 0b7d9b25e4bc2e478c9d06281a65f930769fca09 ] + +Attaching UBI on the flash with more than one plane per lun will lead to +the following error: + +[ 2.980989] spi-nand spi0.0: Micron SPI NAND was found. +[ 2.986309] spi-nand spi0.0: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128 +[ 2.994978] 2 fixed-partitions partitions found on MTD device spi0.0 +[ 3.001350] Creating 2 MTD partitions on "spi0.0": +[ 3.006159] 0x000000000000-0x000000020000 : "bl2" +[ 3.011663] 0x000000020000-0x000010000000 : "ubi" +... +[ 6.391748] ubi0: attaching mtd1 +[ 6.412545] ubi0 error: ubi_attach: PEB 0 contains corrupted VID header, and the data does not contain all 0xFF +[ 6.422677] ubi0 error: ubi_attach: this may be a non-UBI PEB or a severe VID header corruption which requires manual inspection +[ 6.434249] Volume identifier header dump: +[ 6.438349] magic 55424923 +[ 6.441482] version 1 +[ 6.444007] vol_type 0 +[ 6.446539] copy_flag 0 +[ 6.449068] compat 0 +[ 6.451594] vol_id 0 +[ 6.454120] lnum 1 +[ 6.456651] data_size 4096 +[ 6.459442] used_ebs 1061644134 +[ 6.462748] data_pad 0 +[ 6.465274] sqnum 0 +[ 6.467805] hdr_crc 61169820 +[ 6.470943] Volume identifier header hexdump: +[ 6.475308] hexdump of PEB 0 offset 4096, length 126976 +[ 6.507391] ubi0 warning: ubi_attach: valid VID header but corrupted EC header at PEB 4 +[ 6.515415] ubi0 error: ubi_compare_lebs: unsupported on-flash UBI format +[ 6.522222] ubi0 error: ubi_attach_mtd_dev: failed to attach mtd1, error -22 +[ 6.529294] UBI error: cannot attach mtd1 + +Non dirmap reading works good. Looking to spi_mem_no_dirmap_read() code we'll see: + + static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf) + { + struct spi_mem_op op = desc->info.op_tmpl; + int ret; + +// --- see here --- + op.addr.val = desc->info.offset + offs; +//----------------- + op.data.buf.in = buf; + op.data.nbytes = len; + ret = spi_mem_adjust_op_size(desc->mem, &op); + if (ret) + return ret; + + ret = spi_mem_exec_op(desc->mem, &op); + if (ret) + return ret; + + return op.data.nbytes; + } + +The similar happens for spi_mem_no_dirmap_write(). Thus the address +passed to the flash should take in the account the value of +desc->info.offset. + +This patch fix dirmap reading/writing of flashes with more than one +plane per lun. + +Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver") +Signed-off-by: Mikhail Kshevetskiy +Reviewed-by: AngeloGioacchino Del Regno +Link: https://patch.msgid.link/20251012121707.2296160-7-mikhail.kshevetskiy@iopsys.eu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-airoha-snfi.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c +index 8143fbb0cf4e6..b78163eaed61d 100644 +--- a/drivers/spi/spi-airoha-snfi.c ++++ b/drivers/spi/spi-airoha-snfi.c +@@ -733,8 +733,9 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, + if (err) + goto error_dma_unmap; + +- /* set read addr */ +- err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3, 0x0); ++ /* set read addr: zero page offset + descriptor read offset */ ++ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3, ++ desc->info.offset); + if (err) + goto error_dma_unmap; + +@@ -870,7 +871,9 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, + if (err) + goto error_dma_unmap; + +- err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2, 0x0); ++ /* set write addr: zero page offset + descriptor write offset */ ++ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2, ++ desc->info.offset); + if (err) + goto error_dma_unmap; + +-- +2.51.0 + diff --git a/queue-6.17/spi-airoha-return-an-error-for-continuous-mode-dirma.patch b/queue-6.17/spi-airoha-return-an-error-for-continuous-mode-dirma.patch new file mode 100644 index 0000000000..d6754bc03e --- /dev/null +++ b/queue-6.17/spi-airoha-return-an-error-for-continuous-mode-dirma.patch @@ -0,0 +1,46 @@ +From 0cc5c48f5c004e1ae9931cdf873892d5d9a223a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 15:16:52 +0300 +Subject: spi: airoha: return an error for continuous mode dirmap creation + cases + +From: Mikhail Kshevetskiy + +[ Upstream commit 4314ffce4eb81a6c18700af1b6e29b6e0c6b9e37 ] + +This driver can accelerate single page operations only, thus +continuous reading mode should not be used. + +Continuous reading will use sizes up to the size of one erase block. +This size is much larger than the size of single flash page. Use this +difference to identify continuous reading and return an error. + +Signed-off-by: Mikhail Kshevetskiy +Reviewed-by: Frieder Schrempf +Reviewed-by: AngeloGioacchino Del Regno +Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver") +Link: https://patch.msgid.link/20251012121707.2296160-2-mikhail.kshevetskiy@iopsys.eu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-airoha-snfi.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c +index dbe640986825e..043a03cd90a19 100644 +--- a/drivers/spi/spi-airoha-snfi.c ++++ b/drivers/spi/spi-airoha-snfi.c +@@ -618,6 +618,10 @@ static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc) + if (desc->info.offset + desc->info.length > U32_MAX) + return -EINVAL; + ++ /* continuous reading is not supported */ ++ if (desc->info.length > SPI_NAND_CACHE_SIZE) ++ return -E2BIG; ++ + if (!airoha_snand_supports_op(desc->mem, &desc->info.op_tmpl)) + return -EOPNOTSUPP; + +-- +2.51.0 + diff --git a/queue-6.17/spi-airoha-switch-back-to-non-dma-mode-in-the-case-o.patch b/queue-6.17/spi-airoha-switch-back-to-non-dma-mode-in-the-case-o.patch new file mode 100644 index 0000000000..5a9d6b9ac1 --- /dev/null +++ b/queue-6.17/spi-airoha-switch-back-to-non-dma-mode-in-the-case-o.patch @@ -0,0 +1,65 @@ +From df7866ba7837d55486bfb76f478629a2fee25f9d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 15:16:56 +0300 +Subject: spi: airoha: switch back to non-dma mode in the case of error + +From: Mikhail Kshevetskiy + +[ Upstream commit 20d7b236b78c7ec685a22db5689b9c829975e0c3 ] + +Current dirmap code does not switch back to non-dma mode in the case of +error. This is wrong. + +This patch fixes dirmap read/write error path. + +Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver") +Signed-off-by: Mikhail Kshevetskiy +Acked-by: Lorenzo Bianconi +Reviewed-by: AngeloGioacchino Del Regno +Link: https://patch.msgid.link/20251012121707.2296160-6-mikhail.kshevetskiy@iopsys.eu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-airoha-snfi.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c +index 0b89dc42545b1..8143fbb0cf4e6 100644 +--- a/drivers/spi/spi-airoha-snfi.c ++++ b/drivers/spi/spi-airoha-snfi.c +@@ -698,13 +698,13 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, + + err = airoha_snand_nfi_config(as_ctrl); + if (err) +- return err; ++ goto error_dma_mode_off; + + dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE, + DMA_FROM_DEVICE); + err = dma_mapping_error(as_ctrl->dev, dma_addr); + if (err) +- return err; ++ goto error_dma_mode_off; + + /* set dma addr */ + err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR, +@@ -804,6 +804,8 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, + error_dma_unmap: + dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, + DMA_FROM_DEVICE); ++error_dma_mode_off: ++ airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); + return err; + } + +@@ -936,6 +938,7 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, + error_dma_unmap: + dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, + DMA_TO_DEVICE); ++ airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); + return err; + } + +-- +2.51.0 + diff --git a/queue-6.17/spi-cadence-quadspi-fix-pm_runtime-unbalance-on-dma-.patch b/queue-6.17/spi-cadence-quadspi-fix-pm_runtime-unbalance-on-dma-.patch new file mode 100644 index 0000000000..9f6e5ac896 --- /dev/null +++ b/queue-6.17/spi-cadence-quadspi-fix-pm_runtime-unbalance-on-dma-.patch @@ -0,0 +1,61 @@ +From ef88b99d0731b232914ce0243ddd0cc04a5d52ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 09:10:38 +0200 +Subject: spi: cadence-quadspi: Fix pm_runtime unbalance on dma EPROBE_DEFER + +From: Mattijs Korpershoek + +[ Upstream commit 8735696acea24ac1f9d4490992418c71941ca68c ] + +In csqspi_probe(), when cqspi_request_mmap_dma() returns -EPROBE_DEFER, +we handle the error by jumping to probe_setup_failed. +In that label, we call pm_runtime_disable(), even if we never called +pm_runtime_enable() before. + +Because of this, the driver cannot probe: + +[ 2.690018] cadence-qspi 47040000.spi: No Rx DMA available +[ 2.699735] spi-nor spi0.0: resume failed with -13 +[ 2.699741] spi-nor: probe of spi0.0 failed with error -13 + +Only call pm_runtime_disable() if it was enabled by adding a new +label to handle cqspi_request_mmap_dma() failures. + +Fixes: b07f349d1864 ("spi: spi-cadence-quadspi: Fix pm runtime unbalance") +Signed-off-by: Mattijs Korpershoek +Reviewed-by: Dan Carpenter +Link: https://patch.msgid.link/20251009-cadence-quadspi-fix-pm-runtime-v2-1-8bdfefc43902@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-cadence-quadspi.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c +index d1a59120d3845..ce0f605ab688b 100644 +--- a/drivers/spi/spi-cadence-quadspi.c ++++ b/drivers/spi/spi-cadence-quadspi.c +@@ -1995,7 +1995,7 @@ static int cqspi_probe(struct platform_device *pdev) + if (cqspi->use_direct_mode) { + ret = cqspi_request_mmap_dma(cqspi); + if (ret == -EPROBE_DEFER) +- goto probe_setup_failed; ++ goto probe_dma_failed; + } + + if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) { +@@ -2019,9 +2019,10 @@ static int cqspi_probe(struct platform_device *pdev) + + return 0; + probe_setup_failed: +- cqspi_controller_enable(cqspi, 0); + if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) + pm_runtime_disable(dev); ++probe_dma_failed: ++ cqspi_controller_enable(cqspi, 0); + probe_reset_failed: + if (cqspi->is_jh7110) + cqspi_jh7110_disable_clk(pdev, cqspi); +-- +2.51.0 + diff --git a/queue-6.17/spi-rockchip-sfc-fix-dma-api-usage.patch b/queue-6.17/spi-rockchip-sfc-fix-dma-api-usage.patch new file mode 100644 index 0000000000..a7b38ac2a8 --- /dev/null +++ b/queue-6.17/spi-rockchip-sfc-fix-dma-api-usage.patch @@ -0,0 +1,88 @@ +From 4926c4660250380f56198d7ca85d92db982198f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 13:42:39 +0200 +Subject: spi: rockchip-sfc: Fix DMA-API usage + +From: Marek Szyprowski + +[ Upstream commit ee795e82e10197c070efd380dc9615c73dffad6c ] + +Use DMA-API dma_map_single() call for getting the DMA address of the +transfer buffer instead of hacking with virt_to_phys(). + +This fixes the following DMA-API debug warning: +------------[ cut here ]------------ +DMA-API: rockchip-sfc fe300000.spi: device driver tries to sync DMA memory it has not allocated [device address=0x000000000cf70000] [size=288 bytes] +WARNING: kernel/dma/debug.c:1106 at check_sync+0x1d8/0x690, CPU#2: systemd-udevd/151 +Modules linked in: ... +Hardware name: Hardkernel ODROID-M1 (DT) +pstate: 604000c9 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) +pc : check_sync+0x1d8/0x690 +lr : check_sync+0x1d8/0x690 +.. +Call trace: + check_sync+0x1d8/0x690 (P) + debug_dma_sync_single_for_cpu+0x84/0x8c + __dma_sync_single_for_cpu+0x88/0x234 + rockchip_sfc_exec_mem_op+0x4a0/0x798 [spi_rockchip_sfc] + spi_mem_exec_op+0x408/0x498 + spi_nor_read_data+0x170/0x184 + spi_nor_read_sfdp+0x74/0xe4 + spi_nor_parse_sfdp+0x120/0x11f0 + spi_nor_sfdp_init_params_deprecated+0x3c/0x8c + spi_nor_scan+0x690/0xf88 + spi_nor_probe+0xe4/0x304 + spi_mem_probe+0x6c/0xa8 + spi_probe+0x94/0xd4 + really_probe+0xbc/0x298 + ... + +Fixes: b69386fcbc60 ("spi: rockchip-sfc: Using normal memory for dma") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251003114239.431114-1-m.szyprowski@samsung.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-rockchip-sfc.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-rockchip-sfc.c b/drivers/spi/spi-rockchip-sfc.c +index 9eba5c0a60f23..b3c2b03b11535 100644 +--- a/drivers/spi/spi-rockchip-sfc.c ++++ b/drivers/spi/spi-rockchip-sfc.c +@@ -704,7 +704,12 @@ static int rockchip_sfc_probe(struct platform_device *pdev) + ret = -ENOMEM; + goto err_dma; + } +- sfc->dma_buffer = virt_to_phys(sfc->buffer); ++ sfc->dma_buffer = dma_map_single(dev, sfc->buffer, ++ sfc->max_iosize, DMA_BIDIRECTIONAL); ++ if (dma_mapping_error(dev, sfc->dma_buffer)) { ++ ret = -ENOMEM; ++ goto err_dma_map; ++ } + } + + ret = devm_spi_register_controller(dev, host); +@@ -715,6 +720,9 @@ static int rockchip_sfc_probe(struct platform_device *pdev) + + return 0; + err_register: ++ dma_unmap_single(dev, sfc->dma_buffer, sfc->max_iosize, ++ DMA_BIDIRECTIONAL); ++err_dma_map: + free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize)); + err_dma: + pm_runtime_get_sync(dev); +@@ -736,6 +744,8 @@ static void rockchip_sfc_remove(struct platform_device *pdev) + struct spi_controller *host = sfc->host; + + spi_unregister_controller(host); ++ dma_unmap_single(&pdev->dev, sfc->dma_buffer, sfc->max_iosize, ++ DMA_BIDIRECTIONAL); + free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize)); + + clk_disable_unprepare(sfc->clk); +-- +2.51.0 + diff --git a/queue-6.17/spi-spi-nxp-fspi-add-extra-delay-after-dll-locked.patch b/queue-6.17/spi-spi-nxp-fspi-add-extra-delay-after-dll-locked.patch new file mode 100644 index 0000000000..8e9fd5dc3e --- /dev/null +++ b/queue-6.17/spi-spi-nxp-fspi-add-extra-delay-after-dll-locked.patch @@ -0,0 +1,46 @@ +From ef364cd7867e3e5ed5261ea0bef440bb9e08945e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 16:47:14 +0800 +Subject: spi: spi-nxp-fspi: add extra delay after dll locked + +From: Han Xu + +[ Upstream commit b93b4269791fdebbac2a9ad26f324dc2abb9e60f ] + +Due to the erratum ERR050272, the DLL lock status register STS2 +[xREFLOCK, xSLVLOCK] bit may indicate DLL is locked before DLL is +actually locked. Add an extra 4us delay as a workaround. + +refer to ERR050272, on Page 20. +https://www.nxp.com/docs/en/errata/IMX8_1N94W.pdf + +Fixes: 99d822b3adc4 ("spi: spi-nxp-fspi: use DLL calibration when clock rate > 100MHz") +Signed-off-by: Han Xu +Signed-off-by: Haibo Chen +Link: https://patch.msgid.link/20250922-fspi-fix-v1-2-ff4315359d31@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-nxp-fspi.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c +index 542d6f57c1aef..bde6d131ab8b7 100644 +--- a/drivers/spi/spi-nxp-fspi.c ++++ b/drivers/spi/spi-nxp-fspi.c +@@ -709,6 +709,12 @@ static void nxp_fspi_dll_calibration(struct nxp_fspi *f) + 0, POLL_TOUT, true); + if (ret) + dev_warn(f->dev, "DLL lock failed, please fix it!\n"); ++ ++ /* ++ * For ERR050272, DLL lock status bit is not accurate, ++ * wait for 4us more as a workaround. ++ */ ++ udelay(4); + } + + /* +-- +2.51.0 + diff --git a/queue-6.17/spi-spi-nxp-fspi-add-the-support-for-sample-data-fro.patch b/queue-6.17/spi-spi-nxp-fspi-add-the-support-for-sample-data-fro.patch new file mode 100644 index 0000000000..5687d1cf8e --- /dev/null +++ b/queue-6.17/spi-spi-nxp-fspi-add-the-support-for-sample-data-fro.patch @@ -0,0 +1,136 @@ +From 6ea69e010ee2dfb405b0e2bcbcef0631e1c16c6d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 Sep 2025 15:27:09 +0800 +Subject: spi: spi-nxp-fspi: add the support for sample data from DQS pad + +From: Haibo Chen + +[ Upstream commit c07f270323175b83779c2c2b80b360ed476baec5 ] + +flexspi define four mode for sample clock source selection. +Here is the list of modes: +mode 0: Dummy Read strobe generated by FlexSPI Controller and loopback + internally +mode 1: Dummy Read strobe generated by FlexSPI Controller and loopback + from DQS pad +mode 2: Reserved +mode 3: Flash provided Read strobe and input from DQS pad + +In default, flexspi use mode 0 after reset. And for DTR mode, flexspi +only support 8D-8D-8D mode. For 8D-8D-8D mode, IC suggest to use mode 3, +otherwise read always get incorrect data. + +For DTR mode, flexspi will automatically div 2 of the root clock +and output to device. the formula is: + device_clock = root_clock / (is_dtr ? 2 : 1) +So correct the clock rate setting for DTR mode to get the max +performance. + +Signed-off-by: Haibo Chen +Reviewed-by: Frank Li +Link: https://patch.msgid.link/20250917-flexspi-ddr-v2-4-bb9fe2a01889@nxp.com +Signed-off-by: Mark Brown +Stable-dep-of: a89103f67112 ("spi: spi-nxp-fspi: re-config the clock rate when operation require new clock rate") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-nxp-fspi.c | 56 ++++++++++++++++++++++++++++++++++++-- + 1 file changed, 53 insertions(+), 3 deletions(-) + +diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c +index b92bfef47371f..7cbe774f1f39b 100644 +--- a/drivers/spi/spi-nxp-fspi.c ++++ b/drivers/spi/spi-nxp-fspi.c +@@ -399,7 +399,8 @@ struct nxp_fspi { + struct mutex lock; + struct pm_qos_request pm_qos_req; + int selected; +-#define FSPI_NEED_INIT (1 << 0) ++#define FSPI_NEED_INIT BIT(0) ++#define FSPI_DTR_MODE BIT(1) + int flags; + }; + +@@ -645,6 +646,40 @@ static void nxp_fspi_clk_disable_unprep(struct nxp_fspi *f) + return; + } + ++/* ++ * Sample Clock source selection for Flash Reading ++ * Four modes defined by fspi: ++ * mode 0: Dummy Read strobe generated by FlexSPI Controller ++ * and loopback internally ++ * mode 1: Dummy Read strobe generated by FlexSPI Controller ++ * and loopback from DQS pad ++ * mode 2: Reserved ++ * mode 3: Flash provided Read strobe and input from DQS pad ++ * ++ * fspi default use mode 0 after reset ++ */ ++static void nxp_fspi_select_rx_sample_clk_source(struct nxp_fspi *f, ++ bool op_is_dtr) ++{ ++ u32 reg; ++ ++ /* ++ * For 8D-8D-8D mode, need to use mode 3 (Flash provided Read ++ * strobe and input from DQS pad), otherwise read operaton may ++ * meet issue. ++ * This mode require flash device connect the DQS pad on board. ++ * For other modes, still use mode 0, keep align with before. ++ * spi_nor_suspend will disable 8D-8D-8D mode, also need to ++ * change the mode back to mode 0. ++ */ ++ reg = fspi_readl(f, f->iobase + FSPI_MCR0); ++ if (op_is_dtr) ++ reg |= FSPI_MCR0_RXCLKSRC(3); ++ else /*select mode 0 */ ++ reg &= ~FSPI_MCR0_RXCLKSRC(3); ++ fspi_writel(f, reg, f->iobase + FSPI_MCR0); ++} ++ + static void nxp_fspi_dll_calibration(struct nxp_fspi *f) + { + int ret; +@@ -715,15 +750,18 @@ static void nxp_fspi_dll_calibration(struct nxp_fspi *f) + static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi, + const struct spi_mem_op *op) + { ++ /* flexspi only support one DTR mode: 8D-8D-8D */ ++ bool op_is_dtr = op->cmd.dtr && op->addr.dtr && op->dummy.dtr && op->data.dtr; + unsigned long rate = op->max_freq; + int ret; + uint64_t size_kb; + + /* + * Return, if previously selected target device is same as current +- * requested target device. ++ * requested target device. Also the DTR or STR mode do not change. + */ +- if (f->selected == spi_get_chipselect(spi, 0)) ++ if ((f->selected == spi_get_chipselect(spi, 0)) && ++ (!!(f->flags & FSPI_DTR_MODE) == op_is_dtr)) + return; + + /* Reset FLSHxxCR0 registers */ +@@ -740,6 +778,18 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi, + + dev_dbg(f->dev, "Target device [CS:%x] selected\n", spi_get_chipselect(spi, 0)); + ++ nxp_fspi_select_rx_sample_clk_source(f, op_is_dtr); ++ ++ if (op_is_dtr) { ++ f->flags |= FSPI_DTR_MODE; ++ /* For DTR mode, flexspi will default div 2 and output to device. ++ * so here to config the root clock to 2 * device rate. ++ */ ++ rate = rate * 2; ++ } else { ++ f->flags &= ~FSPI_DTR_MODE; ++ } ++ + nxp_fspi_clk_disable_unprep(f); + + ret = clk_set_rate(f->clk, rate); +-- +2.51.0 + diff --git a/queue-6.17/spi-spi-nxp-fspi-limit-the-clock-rate-for-different-.patch b/queue-6.17/spi-spi-nxp-fspi-limit-the-clock-rate-for-different-.patch new file mode 100644 index 0000000000..62e6dbe823 --- /dev/null +++ b/queue-6.17/spi-spi-nxp-fspi-limit-the-clock-rate-for-different-.patch @@ -0,0 +1,70 @@ +From 75d2b5386a554394500ea2f690ad347b8dd1f2e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 16:47:15 +0800 +Subject: spi: spi-nxp-fspi: limit the clock rate for different sample clock + source selection + +From: Haibo Chen + +[ Upstream commit f43579ef3500527649b1c233be7cf633806353aa ] + +For different sample clock source selection, the max frequency +flexspi supported are different. For mode 0, max frequency is 66MHz. +For mode 3, the max frequency is 166MHz. + +Refer to 3.9.9 FlexSPI timing parameters on page 65. +https://www.nxp.com/docs/en/data-sheet/IMX8MNCEC.pdf + +Though flexspi maybe still work under higher frequency, but can't +guarantee the stability. IC suggest to add this limitation on all +SoCs which contain flexspi. + +Fixes: c07f27032317 ("spi: spi-nxp-fspi: add the support for sample data from DQS pad") +Signed-off-by: Haibo Chen +Link: https://patch.msgid.link/20250922-fspi-fix-v1-3-ff4315359d31@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-nxp-fspi.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c +index bde6d131ab8b7..ab13f11242c3c 100644 +--- a/drivers/spi/spi-nxp-fspi.c ++++ b/drivers/spi/spi-nxp-fspi.c +@@ -404,6 +404,8 @@ struct nxp_fspi { + int flags; + /* save the previous operation clock rate */ + unsigned long pre_op_rate; ++ /* the max clock rate fspi output to device */ ++ unsigned long max_rate; + }; + + static inline int needs_ip_only(struct nxp_fspi *f) +@@ -675,10 +677,13 @@ static void nxp_fspi_select_rx_sample_clk_source(struct nxp_fspi *f, + * change the mode back to mode 0. + */ + reg = fspi_readl(f, f->iobase + FSPI_MCR0); +- if (op_is_dtr) ++ if (op_is_dtr) { + reg |= FSPI_MCR0_RXCLKSRC(3); +- else /*select mode 0 */ ++ f->max_rate = 166000000; ++ } else { /*select mode 0 */ + reg &= ~FSPI_MCR0_RXCLKSRC(3); ++ f->max_rate = 66000000; ++ } + fspi_writel(f, reg, f->iobase + FSPI_MCR0); + } + +@@ -793,6 +798,7 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi, + dev_dbg(f->dev, "Target device [CS:%x] selected\n", spi_get_chipselect(spi, 0)); + + nxp_fspi_select_rx_sample_clk_source(f, op_is_dtr); ++ rate = min(f->max_rate, op->max_freq); + + if (op_is_dtr) { + f->flags |= FSPI_DTR_MODE; +-- +2.51.0 + diff --git a/queue-6.17/spi-spi-nxp-fspi-re-config-the-clock-rate-when-opera.patch b/queue-6.17/spi-spi-nxp-fspi-re-config-the-clock-rate-when-opera.patch new file mode 100644 index 0000000000..7d8ba905fe --- /dev/null +++ b/queue-6.17/spi-spi-nxp-fspi-re-config-the-clock-rate-when-opera.patch @@ -0,0 +1,68 @@ +From 2413585fd3efaf09fa87c0836d0365e619314b39 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 16:47:13 +0800 +Subject: spi: spi-nxp-fspi: re-config the clock rate when operation require + new clock rate + +From: Haibo Chen + +[ Upstream commit a89103f67112453fa36c9513e951c19eed9d2d92 ] + +Current operation contain the max_freq, so new coming operation may use +new clock rate, need to re-config the clock rate to match the requirement. + +Fixes: 26851cf65ffc ("spi: nxp-fspi: Support per spi-mem operation frequency switches") +Signed-off-by: Haibo Chen +Link: https://patch.msgid.link/20250922-fspi-fix-v1-1-ff4315359d31@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-nxp-fspi.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c +index 7cbe774f1f39b..542d6f57c1aef 100644 +--- a/drivers/spi/spi-nxp-fspi.c ++++ b/drivers/spi/spi-nxp-fspi.c +@@ -402,6 +402,8 @@ struct nxp_fspi { + #define FSPI_NEED_INIT BIT(0) + #define FSPI_DTR_MODE BIT(1) + int flags; ++ /* save the previous operation clock rate */ ++ unsigned long pre_op_rate; + }; + + static inline int needs_ip_only(struct nxp_fspi *f) +@@ -757,11 +759,17 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi, + uint64_t size_kb; + + /* +- * Return, if previously selected target device is same as current +- * requested target device. Also the DTR or STR mode do not change. ++ * Return when following condition all meet, ++ * 1, if previously selected target device is same as current ++ * requested target device. ++ * 2, the DTR or STR mode do not change. ++ * 3, previous operation max rate equals current one. ++ * ++ * For other case, need to re-config. + */ + if ((f->selected == spi_get_chipselect(spi, 0)) && +- (!!(f->flags & FSPI_DTR_MODE) == op_is_dtr)) ++ (!!(f->flags & FSPI_DTR_MODE) == op_is_dtr) && ++ (f->pre_op_rate == op->max_freq)) + return; + + /* Reset FLSHxxCR0 registers */ +@@ -807,6 +815,8 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi, + if (rate > 100000000) + nxp_fspi_dll_calibration(f); + ++ f->pre_op_rate = op->max_freq; ++ + f->selected = spi_get_chipselect(spi, 0); + } + +-- +2.51.0 + diff --git a/queue-6.17/sysfs-check-visibility-before-changing-group-attribu.patch b/queue-6.17/sysfs-check-visibility-before-changing-group-attribu.patch new file mode 100644 index 0000000000..7ec7783e16 --- /dev/null +++ b/queue-6.17/sysfs-check-visibility-before-changing-group-attribu.patch @@ -0,0 +1,136 @@ +From 019831271dae4bb829597661ef0214273e05aba3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Oct 2025 12:14:56 +0200 +Subject: sysfs: check visibility before changing group attribute ownership + +From: Fernando Fernandez Mancera + +[ Upstream commit c7fbb8218b4ad35fec0bd2256d2b9c8d60331f33 ] + +Since commit 0c17270f9b92 ("net: sysfs: Implement is_visible for +phys_(port_id, port_name, switch_id)"), __dev_change_net_namespace() can +hit WARN_ON() when trying to change owner of a file that isn't visible. +See the trace below: + + WARNING: CPU: 6 PID: 2938 at net/core/dev.c:12410 __dev_change_net_namespace+0xb89/0xc30 + CPU: 6 UID: 0 PID: 2938 Comm: incusd Not tainted 6.17.1-1-mainline #1 PREEMPT(full) 4b783b4a638669fb644857f484487d17cb45ed1f + Hardware name: Framework Laptop 13 (AMD Ryzen 7040Series)/FRANMDCP07, BIOS 03.07 02/19/2025 + RIP: 0010:__dev_change_net_namespace+0xb89/0xc30 + [...] + Call Trace: + + ? if6_seq_show+0x30/0x50 + do_setlink.isra.0+0xc7/0x1270 + ? __nla_validate_parse+0x5c/0xcc0 + ? security_capable+0x94/0x1a0 + rtnl_newlink+0x858/0xc20 + ? update_curr+0x8e/0x1c0 + ? update_entity_lag+0x71/0x80 + ? sched_balance_newidle+0x358/0x450 + ? psi_task_switch+0x113/0x2a0 + ? __pfx_rtnl_newlink+0x10/0x10 + rtnetlink_rcv_msg+0x346/0x3e0 + ? sched_clock+0x10/0x30 + ? __pfx_rtnetlink_rcv_msg+0x10/0x10 + netlink_rcv_skb+0x59/0x110 + netlink_unicast+0x285/0x3c0 + ? __alloc_skb+0xdb/0x1a0 + netlink_sendmsg+0x20d/0x430 + ____sys_sendmsg+0x39f/0x3d0 + ? import_iovec+0x2f/0x40 + ___sys_sendmsg+0x99/0xe0 + __sys_sendmsg+0x8a/0xf0 + do_syscall_64+0x81/0x970 + ? __sys_bind+0xe3/0x110 + ? syscall_exit_work+0x143/0x1b0 + ? do_syscall_64+0x244/0x970 + ? sock_alloc_file+0x63/0xc0 + ? syscall_exit_work+0x143/0x1b0 + ? do_syscall_64+0x244/0x970 + ? alloc_fd+0x12e/0x190 + ? put_unused_fd+0x2a/0x70 + ? do_sys_openat2+0xa2/0xe0 + ? syscall_exit_work+0x143/0x1b0 + ? do_syscall_64+0x244/0x970 + ? exc_page_fault+0x7e/0x1a0 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + [...] + + +Fix this by checking is_visible() before trying to touch the attribute. + +Fixes: 303a42769c4c ("sysfs: add sysfs_group{s}_change_owner()") +Fixes: 0c17270f9b92 ("net: sysfs: Implement is_visible for phys_(port_id, port_name, switch_id)") +Reported-by: Cynthia +Closes: https://lore.kernel.org/netdev/01070199e22de7f8-28f711ab-d3f1-46d9-b9a0-048ab05eb09b-000000@eu-central-1.amazonses.com/ +Signed-off-by: Fernando Fernandez Mancera +Reviewed-by: Jakub Kicinski +Link: https://lore.kernel.org/r/20251016101456.4087-1-fmancera@suse.de +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + fs/sysfs/group.c | 26 +++++++++++++++++++++----- + 1 file changed, 21 insertions(+), 5 deletions(-) + +diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c +index 2d78e94072a0d..e142bac4f9f80 100644 +--- a/fs/sysfs/group.c ++++ b/fs/sysfs/group.c +@@ -498,17 +498,26 @@ int compat_only_sysfs_link_entry_to_kobj(struct kobject *kobj, + } + EXPORT_SYMBOL_GPL(compat_only_sysfs_link_entry_to_kobj); + +-static int sysfs_group_attrs_change_owner(struct kernfs_node *grp_kn, ++static int sysfs_group_attrs_change_owner(struct kobject *kobj, ++ struct kernfs_node *grp_kn, + const struct attribute_group *grp, + struct iattr *newattrs) + { + struct kernfs_node *kn; +- int error; ++ int error, i; ++ umode_t mode; + + if (grp->attrs) { + struct attribute *const *attr; + +- for (attr = grp->attrs; *attr; attr++) { ++ for (i = 0, attr = grp->attrs; *attr; i++, attr++) { ++ if (grp->is_visible) { ++ mode = grp->is_visible(kobj, *attr, i); ++ if (mode & SYSFS_GROUP_INVISIBLE) ++ break; ++ if (!mode) ++ continue; ++ } + kn = kernfs_find_and_get(grp_kn, (*attr)->name); + if (!kn) + return -ENOENT; +@@ -523,7 +532,14 @@ static int sysfs_group_attrs_change_owner(struct kernfs_node *grp_kn, + if (grp->bin_attrs) { + const struct bin_attribute *const *bin_attr; + +- for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) { ++ for (i = 0, bin_attr = grp->bin_attrs; *bin_attr; i++, bin_attr++) { ++ if (grp->is_bin_visible) { ++ mode = grp->is_bin_visible(kobj, *bin_attr, i); ++ if (mode & SYSFS_GROUP_INVISIBLE) ++ break; ++ if (!mode) ++ continue; ++ } + kn = kernfs_find_and_get(grp_kn, (*bin_attr)->attr.name); + if (!kn) + return -ENOENT; +@@ -573,7 +589,7 @@ int sysfs_group_change_owner(struct kobject *kobj, + + error = kernfs_setattr(grp_kn, &newattrs); + if (!error) +- error = sysfs_group_attrs_change_owner(grp_kn, grp, &newattrs); ++ error = sysfs_group_attrs_change_owner(kobj, grp_kn, grp, &newattrs); + + kernfs_put(grp_kn); + +-- +2.51.0 + diff --git a/queue-6.6/firmware-arm_scmi-account-for-failed-debug-initializ.patch b/queue-6.6/firmware-arm_scmi-account-for-failed-debug-initializ.patch new file mode 100644 index 0000000000..5f544c0a58 --- /dev/null +++ b/queue-6.6/firmware-arm_scmi-account-for-failed-debug-initializ.patch @@ -0,0 +1,206 @@ +From 30c89140a4ddce8425bab82946256f5feea17e9e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 12:53:44 +0100 +Subject: firmware: arm_scmi: Account for failed debug initialization + +From: Cristian Marussi + +[ Upstream commit 2290ab43b9d8eafb8046387f10a8dfa2b030ba46 ] + +When the SCMI debug subsystem fails to initialize, the related debug root +will be missing, and the underlying descriptor will be NULL. + +Handle this fault condition in the SCMI debug helpers that maintain +metrics counters. + +Fixes: 0b3d48c4726e ("firmware: arm_scmi: Track basic SCMI communication debug metrics") +Signed-off-by: Cristian Marussi +Message-Id: <20251014115346.2391418-1-cristian.marussi@arm.com> +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_scmi/common.h | 24 ++++++++++++++-- + drivers/firmware/arm_scmi/driver.c | 44 ++++++++++-------------------- + 2 files changed, 35 insertions(+), 33 deletions(-) + +diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h +index 6c22348712154..dc95652fff400 100644 +--- a/drivers/firmware/arm_scmi/common.h ++++ b/drivers/firmware/arm_scmi/common.h +@@ -321,10 +321,28 @@ enum debug_counters { + SCMI_DEBUG_COUNTERS_LAST + }; + +-static inline void scmi_inc_count(atomic_t *arr, int stat) ++/** ++ * struct scmi_debug_info - Debug common info ++ * @top_dentry: A reference to the top debugfs dentry ++ * @name: Name of this SCMI instance ++ * @type: Type of this SCMI instance ++ * @is_atomic: Flag to state if the transport of this instance is atomic ++ * @counters: An array of atomic_c's used for tracking statistics (if enabled) ++ */ ++struct scmi_debug_info { ++ struct dentry *top_dentry; ++ const char *name; ++ const char *type; ++ bool is_atomic; ++ atomic_t counters[SCMI_DEBUG_COUNTERS_LAST]; ++}; ++ ++static inline void scmi_inc_count(struct scmi_debug_info *dbg, int stat) + { +- if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) +- atomic_inc(&arr[stat]); ++ if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) { ++ if (dbg) ++ atomic_inc(&dbg->counters[stat]); ++ } + } + + enum scmi_bad_msg { +diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c +index d1fd2e492909e..9d4c983a27547 100644 +--- a/drivers/firmware/arm_scmi/driver.c ++++ b/drivers/firmware/arm_scmi/driver.c +@@ -102,22 +102,6 @@ struct scmi_protocol_instance { + + #define ph_to_pi(h) container_of(h, struct scmi_protocol_instance, ph) + +-/** +- * struct scmi_debug_info - Debug common info +- * @top_dentry: A reference to the top debugfs dentry +- * @name: Name of this SCMI instance +- * @type: Type of this SCMI instance +- * @is_atomic: Flag to state if the transport of this instance is atomic +- * @counters: An array of atomic_c's used for tracking statistics (if enabled) +- */ +-struct scmi_debug_info { +- struct dentry *top_dentry; +- const char *name; +- const char *type; +- bool is_atomic; +- atomic_t counters[SCMI_DEBUG_COUNTERS_LAST]; +-}; +- + /** + * struct scmi_info - Structure representing a SCMI instance + * +@@ -856,7 +840,7 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr) + spin_unlock_irqrestore(&minfo->xfer_lock, flags); + + scmi_bad_message_trace(cinfo, msg_hdr, MSG_UNEXPECTED); +- scmi_inc_count(info->dbg->counters, ERR_MSG_UNEXPECTED); ++ scmi_inc_count(info->dbg, ERR_MSG_UNEXPECTED); + + return xfer; + } +@@ -884,7 +868,7 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr) + msg_type, xfer_id, msg_hdr, xfer->state); + + scmi_bad_message_trace(cinfo, msg_hdr, MSG_INVALID); +- scmi_inc_count(info->dbg->counters, ERR_MSG_INVALID); ++ scmi_inc_count(info->dbg, ERR_MSG_INVALID); + + + /* On error the refcount incremented above has to be dropped */ +@@ -930,7 +914,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, + PTR_ERR(xfer)); + + scmi_bad_message_trace(cinfo, msg_hdr, MSG_NOMEM); +- scmi_inc_count(info->dbg->counters, ERR_MSG_NOMEM); ++ scmi_inc_count(info->dbg, ERR_MSG_NOMEM); + + scmi_clear_channel(info, cinfo); + return; +@@ -946,7 +930,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, + trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id, + xfer->hdr.id, "NOTI", xfer->hdr.seq, + xfer->hdr.status, xfer->rx.buf, xfer->rx.len); +- scmi_inc_count(info->dbg->counters, NOTIFICATION_OK); ++ scmi_inc_count(info->dbg, NOTIFICATION_OK); + + scmi_notify(cinfo->handle, xfer->hdr.protocol_id, + xfer->hdr.id, xfer->rx.buf, xfer->rx.len, ts); +@@ -1006,10 +990,10 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo, + if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP) { + scmi_clear_channel(info, cinfo); + complete(xfer->async_done); +- scmi_inc_count(info->dbg->counters, DELAYED_RESPONSE_OK); ++ scmi_inc_count(info->dbg, DELAYED_RESPONSE_OK); + } else { + complete(&xfer->done); +- scmi_inc_count(info->dbg->counters, RESPONSE_OK); ++ scmi_inc_count(info->dbg, RESPONSE_OK); + } + + if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { +@@ -1117,7 +1101,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, + "timed out in resp(caller: %pS) - polling\n", + (void *)_RET_IP_); + ret = -ETIMEDOUT; +- scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_POLLED_TIMEOUT); ++ scmi_inc_count(info->dbg, XFERS_RESPONSE_POLLED_TIMEOUT); + } + } + +@@ -1142,7 +1126,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, + "RESP" : "resp", + xfer->hdr.seq, xfer->hdr.status, + xfer->rx.buf, xfer->rx.len); +- scmi_inc_count(info->dbg->counters, RESPONSE_POLLED_OK); ++ scmi_inc_count(info->dbg, RESPONSE_POLLED_OK); + + if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { + struct scmi_info *info = +@@ -1160,7 +1144,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, + dev_err(dev, "timed out in resp(caller: %pS)\n", + (void *)_RET_IP_); + ret = -ETIMEDOUT; +- scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_TIMEOUT); ++ scmi_inc_count(info->dbg, XFERS_RESPONSE_TIMEOUT); + } + } + +@@ -1244,13 +1228,13 @@ static int do_xfer(const struct scmi_protocol_handle *ph, + !is_transport_polling_capable(info->desc)) { + dev_warn_once(dev, + "Polling mode is not supported by transport.\n"); +- scmi_inc_count(info->dbg->counters, SENT_FAIL_POLLING_UNSUPPORTED); ++ scmi_inc_count(info->dbg, SENT_FAIL_POLLING_UNSUPPORTED); + return -EINVAL; + } + + cinfo = idr_find(&info->tx_idr, pi->proto->id); + if (unlikely(!cinfo)) { +- scmi_inc_count(info->dbg->counters, SENT_FAIL_CHANNEL_NOT_FOUND); ++ scmi_inc_count(info->dbg, SENT_FAIL_CHANNEL_NOT_FOUND); + return -EINVAL; + } + /* True ONLY if also supported by transport. */ +@@ -1284,19 +1268,19 @@ static int do_xfer(const struct scmi_protocol_handle *ph, + ret = info->desc->ops->send_message(cinfo, xfer); + if (ret < 0) { + dev_dbg(dev, "Failed to send message %d\n", ret); +- scmi_inc_count(info->dbg->counters, SENT_FAIL); ++ scmi_inc_count(info->dbg, SENT_FAIL); + return ret; + } + + trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id, + xfer->hdr.id, "CMND", xfer->hdr.seq, + xfer->hdr.status, xfer->tx.buf, xfer->tx.len); +- scmi_inc_count(info->dbg->counters, SENT_OK); ++ scmi_inc_count(info->dbg, SENT_OK); + + ret = scmi_wait_for_message_response(cinfo, xfer); + if (!ret && xfer->hdr.status) { + ret = scmi_to_linux_errno(xfer->hdr.status); +- scmi_inc_count(info->dbg->counters, ERR_PROTOCOL); ++ scmi_inc_count(info->dbg, ERR_PROTOCOL); + } + + if (info->desc->ops->mark_txdone) +-- +2.51.0 + diff --git a/queue-6.6/firmware-arm_scmi-fix-premature-scmi_xfer_flag_is_ra.patch b/queue-6.6/firmware-arm_scmi-fix-premature-scmi_xfer_flag_is_ra.patch new file mode 100644 index 0000000000..ca23a44baf --- /dev/null +++ b/queue-6.6/firmware-arm_scmi-fix-premature-scmi_xfer_flag_is_ra.patch @@ -0,0 +1,54 @@ +From c097920d87933213e3449868e8d5215eea749346 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 12:10:57 +0300 +Subject: firmware: arm_scmi: Fix premature SCMI_XFER_FLAG_IS_RAW clearing in + raw mode + +From: Artem Shimko + +[ Upstream commit 20b93a0088a595bceed4a026d527cbbac4e876c5 ] + +The SCMI_XFER_FLAG_IS_RAW flag was being cleared prematurely in +scmi_xfer_raw_put() before the transfer completion was properly +acknowledged by the raw message handlers. + +Move the clearing of SCMI_XFER_FLAG_IS_RAW and SCMI_XFER_FLAG_CHAN_SET +from scmi_xfer_raw_put() to __scmi_xfer_put() to ensure the flags remain +set throughout the entire raw message processing pipeline until the +transfer is returned to the free pool. + +Fixes: 3095a3e25d8f ("firmware: arm_scmi: Add xfer helpers to provide raw access") +Suggested-by: Cristian Marussi +Signed-off-by: Artem Shimko +Reviewed-by: Cristian Marussi +Message-Id: <20251008091057.1969260-1-a.shimko.dev@gmail.com> +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_scmi/driver.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c +index 9d4c983a27547..fbe893734411c 100644 +--- a/drivers/firmware/arm_scmi/driver.c ++++ b/drivers/firmware/arm_scmi/driver.c +@@ -627,6 +627,7 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer) + hash_del(&xfer->node); + xfer->pending = false; + } ++ xfer->flags = 0; + hlist_add_head(&xfer->node, &minfo->free_xfers); + } + spin_unlock_irqrestore(&minfo->xfer_lock, flags); +@@ -645,8 +646,6 @@ void scmi_xfer_raw_put(const struct scmi_handle *handle, struct scmi_xfer *xfer) + { + struct scmi_info *info = handle_to_scmi_info(handle); + +- xfer->flags &= ~SCMI_XFER_FLAG_IS_RAW; +- xfer->flags &= ~SCMI_XFER_FLAG_CHAN_SET; + return __scmi_xfer_put(&info->tx_minfo, xfer); + } + +-- +2.51.0 + diff --git a/queue-6.6/gpio-ljca-fix-duplicated-irq-mapping.patch b/queue-6.6/gpio-ljca-fix-duplicated-irq-mapping.patch new file mode 100644 index 0000000000..f882d5f704 --- /dev/null +++ b/queue-6.6/gpio-ljca-fix-duplicated-irq-mapping.patch @@ -0,0 +1,59 @@ +From 6e8798cc9a84c115dcccf1fc0ddc9994699916c7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 15:02:30 +0800 +Subject: gpio: ljca: Fix duplicated IRQ mapping + +From: Haotian Zhang + +[ Upstream commit 4c4e6ea4a120cc5ab58e437c6ba123cbfc357d45 ] + +The generic_handle_domain_irq() function resolves the hardware IRQ +internally. The driver performed a duplicative mapping by calling +irq_find_mapping() first, which could lead to an RCU stall. + +Delete the redundant irq_find_mapping() call and pass the hardware IRQ +directly to generic_handle_domain_irq(). + +Fixes: c5a4b6fd31e8 ("gpio: Add support for Intel LJCA USB GPIO driver") +Signed-off-by: Haotian Zhang +Link: https://lore.kernel.org/r/20251023070231.1305-1-vulab@iscas.ac.cn +[Bartosz: remove unused variable] +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-ljca.c | 14 +++----------- + 1 file changed, 3 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpio/gpio-ljca.c b/drivers/gpio/gpio-ljca.c +index dfec9fbfc7a9b..ddd73b8b790e7 100644 +--- a/drivers/gpio/gpio-ljca.c ++++ b/drivers/gpio/gpio-ljca.c +@@ -281,22 +281,14 @@ static void ljca_gpio_event_cb(void *context, u8 cmd, const void *evt_data, + { + const struct ljca_gpio_packet *packet = evt_data; + struct ljca_gpio_dev *ljca_gpio = context; +- int i, irq; ++ int i; + + if (cmd != LJCA_GPIO_INT_EVENT) + return; + + for (i = 0; i < packet->num; i++) { +- irq = irq_find_mapping(ljca_gpio->gc.irq.domain, +- packet->item[i].index); +- if (!irq) { +- dev_err(ljca_gpio->gc.parent, +- "gpio_id %u does not mapped to IRQ yet\n", +- packet->item[i].index); +- return; +- } +- +- generic_handle_domain_irq(ljca_gpio->gc.irq.domain, irq); ++ generic_handle_domain_irq(ljca_gpio->gc.irq.domain, ++ packet->item[i].index); + set_bit(packet->item[i].index, ljca_gpio->reenable_irqs); + } + +-- +2.51.0 + diff --git a/queue-6.6/gpio-update-intel-ljca-usb-gpio-driver.patch b/queue-6.6/gpio-update-intel-ljca-usb-gpio-driver.patch new file mode 100644 index 0000000000..4099afb683 --- /dev/null +++ b/queue-6.6/gpio-update-intel-ljca-usb-gpio-driver.patch @@ -0,0 +1,539 @@ +From 2420f273b4a8a094d39c632d8a988ecd17989941 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 14:33:25 +0800 +Subject: gpio: update Intel LJCA USB GPIO driver + +From: Wentong Wu + +[ Upstream commit 1034cc423f1b4a7a9a56d310ca980fcd2753e11d ] + +This driver communicate with LJCA GPIO module with specific +protocol through interfaces exported by LJCA USB driver. +Update the driver according to LJCA USB driver's changes. + +Signed-off-by: Wentong Wu +Reviewed-by: Sakari Ailus +Acked-by: Linus Walleij +Acked-by: Bartosz Golaszewski +Tested-by: Hans de Goede +Link: https://lore.kernel.org/r/1696833205-16716-5-git-send-email-wentong.wu@intel.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 4c4e6ea4a120 ("gpio: ljca: Fix duplicated IRQ mapping") +Signed-off-by: Sasha Levin +--- + drivers/gpio/Kconfig | 4 +- + drivers/gpio/gpio-ljca.c | 246 +++++++++++++++++++++++---------------- + 2 files changed, 145 insertions(+), 105 deletions(-) + +diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig +index ebd4e113dc265..de051a085e63f 100644 +--- a/drivers/gpio/Kconfig ++++ b/drivers/gpio/Kconfig +@@ -1313,9 +1313,9 @@ config GPIO_KEMPLD + + config GPIO_LJCA + tristate "INTEL La Jolla Cove Adapter GPIO support" +- depends on MFD_LJCA ++ depends on USB_LJCA + select GPIOLIB_IRQCHIP +- default MFD_LJCA ++ default USB_LJCA + help + Select this option to enable GPIO driver for the INTEL + La Jolla Cove Adapter (LJCA) board. +diff --git a/drivers/gpio/gpio-ljca.c b/drivers/gpio/gpio-ljca.c +index 87863f0230f5c..dfec9fbfc7a9b 100644 +--- a/drivers/gpio/gpio-ljca.c ++++ b/drivers/gpio/gpio-ljca.c +@@ -6,6 +6,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -13,19 +14,18 @@ + #include + #include + #include +-#include + #include +-#include + #include + #include ++#include + + /* GPIO commands */ +-#define LJCA_GPIO_CONFIG 1 +-#define LJCA_GPIO_READ 2 +-#define LJCA_GPIO_WRITE 3 +-#define LJCA_GPIO_INT_EVENT 4 +-#define LJCA_GPIO_INT_MASK 5 +-#define LJCA_GPIO_INT_UNMASK 6 ++#define LJCA_GPIO_CONFIG 1 ++#define LJCA_GPIO_READ 2 ++#define LJCA_GPIO_WRITE 3 ++#define LJCA_GPIO_INT_EVENT 4 ++#define LJCA_GPIO_INT_MASK 5 ++#define LJCA_GPIO_INT_UNMASK 6 + + #define LJCA_GPIO_CONF_DISABLE BIT(0) + #define LJCA_GPIO_CONF_INPUT BIT(1) +@@ -36,45 +36,49 @@ + #define LJCA_GPIO_CONF_INTERRUPT BIT(6) + #define LJCA_GPIO_INT_TYPE BIT(7) + +-#define LJCA_GPIO_CONF_EDGE FIELD_PREP(LJCA_GPIO_INT_TYPE, 1) +-#define LJCA_GPIO_CONF_LEVEL FIELD_PREP(LJCA_GPIO_INT_TYPE, 0) ++#define LJCA_GPIO_CONF_EDGE FIELD_PREP(LJCA_GPIO_INT_TYPE, 1) ++#define LJCA_GPIO_CONF_LEVEL FIELD_PREP(LJCA_GPIO_INT_TYPE, 0) + + /* Intentional overlap with PULLUP / PULLDOWN */ +-#define LJCA_GPIO_CONF_SET BIT(3) +-#define LJCA_GPIO_CONF_CLR BIT(4) ++#define LJCA_GPIO_CONF_SET BIT(3) ++#define LJCA_GPIO_CONF_CLR BIT(4) + +-struct gpio_op { ++#define LJCA_GPIO_BUF_SIZE 60u ++ ++struct ljca_gpio_op { + u8 index; + u8 value; + } __packed; + +-struct gpio_packet { ++struct ljca_gpio_packet { + u8 num; +- struct gpio_op item[]; ++ struct ljca_gpio_op item[] __counted_by(num); + } __packed; + +-#define LJCA_GPIO_BUF_SIZE 60 + struct ljca_gpio_dev { +- struct platform_device *pdev; ++ struct ljca_client *ljca; + struct gpio_chip gc; + struct ljca_gpio_info *gpio_info; + DECLARE_BITMAP(unmasked_irqs, LJCA_MAX_GPIO_NUM); + DECLARE_BITMAP(enabled_irqs, LJCA_MAX_GPIO_NUM); + DECLARE_BITMAP(reenable_irqs, LJCA_MAX_GPIO_NUM); ++ DECLARE_BITMAP(output_enabled, LJCA_MAX_GPIO_NUM); + u8 *connect_mode; +- /* mutex to protect irq bus */ ++ /* protect irq bus */ + struct mutex irq_lock; + struct work_struct work; +- /* lock to protect package transfer to Hardware */ ++ /* protect package transfer to hardware */ + struct mutex trans_lock; + + u8 obuf[LJCA_GPIO_BUF_SIZE]; + u8 ibuf[LJCA_GPIO_BUF_SIZE]; + }; + +-static int gpio_config(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id, u8 config) ++static int ljca_gpio_config(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id, ++ u8 config) + { +- struct gpio_packet *packet = (struct gpio_packet *)ljca_gpio->obuf; ++ struct ljca_gpio_packet *packet = ++ (struct ljca_gpio_packet *)ljca_gpio->obuf; + int ret; + + mutex_lock(&ljca_gpio->trans_lock); +@@ -82,43 +86,43 @@ static int gpio_config(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id, u8 config) + packet->item[0].value = config | ljca_gpio->connect_mode[gpio_id]; + packet->num = 1; + +- ret = ljca_transfer(ljca_gpio->gpio_info->ljca, LJCA_GPIO_CONFIG, packet, +- struct_size(packet, item, packet->num), NULL, NULL); ++ ret = ljca_transfer(ljca_gpio->ljca, LJCA_GPIO_CONFIG, (u8 *)packet, ++ struct_size(packet, item, packet->num), NULL, 0); + mutex_unlock(&ljca_gpio->trans_lock); +- return ret; ++ ++ return ret < 0 ? ret : 0; + } + + static int ljca_gpio_read(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id) + { +- struct gpio_packet *packet = (struct gpio_packet *)ljca_gpio->obuf; +- struct gpio_packet *ack_packet = (struct gpio_packet *)ljca_gpio->ibuf; +- unsigned int ibuf_len = LJCA_GPIO_BUF_SIZE; ++ struct ljca_gpio_packet *ack_packet = ++ (struct ljca_gpio_packet *)ljca_gpio->ibuf; ++ struct ljca_gpio_packet *packet = ++ (struct ljca_gpio_packet *)ljca_gpio->obuf; + int ret; + + mutex_lock(&ljca_gpio->trans_lock); + packet->num = 1; + packet->item[0].index = gpio_id; +- ret = ljca_transfer(ljca_gpio->gpio_info->ljca, LJCA_GPIO_READ, packet, +- struct_size(packet, item, packet->num), ljca_gpio->ibuf, &ibuf_len); +- if (ret) +- goto out_unlock; +- +- if (!ibuf_len || ack_packet->num != packet->num) { +- dev_err(&ljca_gpio->pdev->dev, "failed gpio_id:%u %u", gpio_id, ack_packet->num); +- ret = -EIO; ++ ret = ljca_transfer(ljca_gpio->ljca, LJCA_GPIO_READ, (u8 *)packet, ++ struct_size(packet, item, packet->num), ++ ljca_gpio->ibuf, LJCA_GPIO_BUF_SIZE); ++ ++ if (ret <= 0 || ack_packet->num != packet->num) { ++ dev_err(&ljca_gpio->ljca->auxdev.dev, ++ "read package error, gpio_id: %u num: %u ret: %d\n", ++ gpio_id, ack_packet->num, ret); ++ ret = ret < 0 ? ret : -EIO; + } +- +-out_unlock: + mutex_unlock(&ljca_gpio->trans_lock); +- if (ret) +- return ret; +- return ack_packet->item[0].value > 0; ++ ++ return ret < 0 ? ret : ack_packet->item[0].value > 0; + } + +-static int ljca_gpio_write(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id, +- int value) ++static int ljca_gpio_write(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id, int value) + { +- struct gpio_packet *packet = (struct gpio_packet *)ljca_gpio->obuf; ++ struct ljca_gpio_packet *packet = ++ (struct ljca_gpio_packet *)ljca_gpio->obuf; + int ret; + + mutex_lock(&ljca_gpio->trans_lock); +@@ -126,10 +130,11 @@ static int ljca_gpio_write(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id, + packet->item[0].index = gpio_id; + packet->item[0].value = value & 1; + +- ret = ljca_transfer(ljca_gpio->gpio_info->ljca, LJCA_GPIO_WRITE, packet, +- struct_size(packet, item, packet->num), NULL, NULL); ++ ret = ljca_transfer(ljca_gpio->ljca, LJCA_GPIO_WRITE, (u8 *)packet, ++ struct_size(packet, item, packet->num), NULL, 0); + mutex_unlock(&ljca_gpio->trans_lock); +- return ret; ++ ++ return ret < 0 ? ret : 0; + } + + static int ljca_gpio_get_value(struct gpio_chip *chip, unsigned int offset) +@@ -147,16 +152,24 @@ static void ljca_gpio_set_value(struct gpio_chip *chip, unsigned int offset, + + ret = ljca_gpio_write(ljca_gpio, offset, val); + if (ret) +- dev_err(chip->parent, "offset:%u val:%d set value failed %d\n", offset, val, ret); ++ dev_err(chip->parent, ++ "set value failed offset: %u val: %d ret: %d\n", ++ offset, val, ret); + } + +-static int ljca_gpio_direction_input(struct gpio_chip *chip, +- unsigned int offset) ++static int ljca_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) + { + struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(chip); + u8 config = LJCA_GPIO_CONF_INPUT | LJCA_GPIO_CONF_CLR; ++ int ret; + +- return gpio_config(ljca_gpio, offset, config); ++ ret = ljca_gpio_config(ljca_gpio, offset, config); ++ if (ret) ++ return ret; ++ ++ clear_bit(offset, ljca_gpio->output_enabled); ++ ++ return 0; + } + + static int ljca_gpio_direction_output(struct gpio_chip *chip, +@@ -166,14 +179,26 @@ static int ljca_gpio_direction_output(struct gpio_chip *chip, + u8 config = LJCA_GPIO_CONF_OUTPUT | LJCA_GPIO_CONF_CLR; + int ret; + +- ret = gpio_config(ljca_gpio, offset, config); ++ ret = ljca_gpio_config(ljca_gpio, offset, config); + if (ret) + return ret; + + ljca_gpio_set_value(chip, offset, val); ++ set_bit(offset, ljca_gpio->output_enabled); ++ + return 0; + } + ++static int ljca_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) ++{ ++ struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(chip); ++ ++ if (test_bit(offset, ljca_gpio->output_enabled)) ++ return GPIO_LINE_DIRECTION_OUT; ++ ++ return GPIO_LINE_DIRECTION_IN; ++} ++ + static int ljca_gpio_set_config(struct gpio_chip *chip, unsigned int offset, + unsigned long config) + { +@@ -197,7 +222,8 @@ static int ljca_gpio_set_config(struct gpio_chip *chip, unsigned int offset, + return 0; + } + +-static int ljca_gpio_init_valid_mask(struct gpio_chip *chip, unsigned long *valid_mask, ++static int ljca_gpio_init_valid_mask(struct gpio_chip *chip, ++ unsigned long *valid_mask, + unsigned int ngpios) + { + struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(chip); +@@ -208,15 +234,18 @@ static int ljca_gpio_init_valid_mask(struct gpio_chip *chip, unsigned long *vali + return 0; + } + +-static void ljca_gpio_irq_init_valid_mask(struct gpio_chip *chip, unsigned long *valid_mask, ++static void ljca_gpio_irq_init_valid_mask(struct gpio_chip *chip, ++ unsigned long *valid_mask, + unsigned int ngpios) + { + ljca_gpio_init_valid_mask(chip, valid_mask, ngpios); + } + +-static int ljca_enable_irq(struct ljca_gpio_dev *ljca_gpio, int gpio_id, bool enable) ++static int ljca_enable_irq(struct ljca_gpio_dev *ljca_gpio, int gpio_id, ++ bool enable) + { +- struct gpio_packet *packet = (struct gpio_packet *)ljca_gpio->obuf; ++ struct ljca_gpio_packet *packet = ++ (struct ljca_gpio_packet *)ljca_gpio->obuf; + int ret; + + mutex_lock(&ljca_gpio->trans_lock); +@@ -224,18 +253,20 @@ static int ljca_enable_irq(struct ljca_gpio_dev *ljca_gpio, int gpio_id, bool en + packet->item[0].index = gpio_id; + packet->item[0].value = 0; + +- ret = ljca_transfer(ljca_gpio->gpio_info->ljca, +- enable ? LJCA_GPIO_INT_UNMASK : LJCA_GPIO_INT_MASK, packet, +- struct_size(packet, item, packet->num), NULL, NULL); ++ ret = ljca_transfer(ljca_gpio->ljca, ++ enable ? LJCA_GPIO_INT_UNMASK : LJCA_GPIO_INT_MASK, ++ (u8 *)packet, struct_size(packet, item, packet->num), ++ NULL, 0); + mutex_unlock(&ljca_gpio->trans_lock); +- return ret; ++ ++ return ret < 0 ? ret : 0; + } + + static void ljca_gpio_async(struct work_struct *work) + { +- struct ljca_gpio_dev *ljca_gpio = container_of(work, struct ljca_gpio_dev, work); +- int gpio_id; +- int unmasked; ++ struct ljca_gpio_dev *ljca_gpio = ++ container_of(work, struct ljca_gpio_dev, work); ++ int gpio_id, unmasked; + + for_each_set_bit(gpio_id, ljca_gpio->reenable_irqs, ljca_gpio->gc.ngpio) { + clear_bit(gpio_id, ljca_gpio->reenable_irqs); +@@ -245,20 +276,22 @@ static void ljca_gpio_async(struct work_struct *work) + } + } + +-static void ljca_gpio_event_cb(void *context, u8 cmd, const void *evt_data, int len) ++static void ljca_gpio_event_cb(void *context, u8 cmd, const void *evt_data, ++ int len) + { +- const struct gpio_packet *packet = evt_data; ++ const struct ljca_gpio_packet *packet = evt_data; + struct ljca_gpio_dev *ljca_gpio = context; +- int i; +- int irq; ++ int i, irq; + + if (cmd != LJCA_GPIO_INT_EVENT) + return; + + for (i = 0; i < packet->num; i++) { +- irq = irq_find_mapping(ljca_gpio->gc.irq.domain, packet->item[i].index); ++ irq = irq_find_mapping(ljca_gpio->gc.irq.domain, ++ packet->item[i].index); + if (!irq) { +- dev_err(ljca_gpio->gc.parent, "gpio_id %u does not mapped to IRQ yet\n", ++ dev_err(ljca_gpio->gc.parent, ++ "gpio_id %u does not mapped to IRQ yet\n", + packet->item[i].index); + return; + } +@@ -299,18 +332,22 @@ static int ljca_irq_set_type(struct irq_data *irqd, unsigned int type) + ljca_gpio->connect_mode[gpio_id] = LJCA_GPIO_CONF_INTERRUPT; + switch (type) { + case IRQ_TYPE_LEVEL_HIGH: +- ljca_gpio->connect_mode[gpio_id] |= (LJCA_GPIO_CONF_LEVEL | LJCA_GPIO_CONF_PULLUP); ++ ljca_gpio->connect_mode[gpio_id] |= ++ (LJCA_GPIO_CONF_LEVEL | LJCA_GPIO_CONF_PULLUP); + break; + case IRQ_TYPE_LEVEL_LOW: +- ljca_gpio->connect_mode[gpio_id] |= (LJCA_GPIO_CONF_LEVEL | LJCA_GPIO_CONF_PULLDOWN); ++ ljca_gpio->connect_mode[gpio_id] |= ++ (LJCA_GPIO_CONF_LEVEL | LJCA_GPIO_CONF_PULLDOWN); + break; + case IRQ_TYPE_EDGE_BOTH: + break; + case IRQ_TYPE_EDGE_RISING: +- ljca_gpio->connect_mode[gpio_id] |= (LJCA_GPIO_CONF_EDGE | LJCA_GPIO_CONF_PULLUP); ++ ljca_gpio->connect_mode[gpio_id] |= ++ (LJCA_GPIO_CONF_EDGE | LJCA_GPIO_CONF_PULLUP); + break; + case IRQ_TYPE_EDGE_FALLING: +- ljca_gpio->connect_mode[gpio_id] |= (LJCA_GPIO_CONF_EDGE | LJCA_GPIO_CONF_PULLDOWN); ++ ljca_gpio->connect_mode[gpio_id] |= ++ (LJCA_GPIO_CONF_EDGE | LJCA_GPIO_CONF_PULLDOWN); + break; + default: + return -EINVAL; +@@ -332,15 +369,14 @@ static void ljca_irq_bus_unlock(struct irq_data *irqd) + struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); + struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(gc); + int gpio_id = irqd_to_hwirq(irqd); +- int enabled; +- int unmasked; ++ int enabled, unmasked; + + enabled = test_bit(gpio_id, ljca_gpio->enabled_irqs); + unmasked = test_bit(gpio_id, ljca_gpio->unmasked_irqs); + + if (enabled != unmasked) { + if (unmasked) { +- gpio_config(ljca_gpio, gpio_id, 0); ++ ljca_gpio_config(ljca_gpio, gpio_id, 0); + ljca_enable_irq(ljca_gpio, gpio_id, true); + set_bit(gpio_id, ljca_gpio->enabled_irqs); + } else { +@@ -363,43 +399,48 @@ static const struct irq_chip ljca_gpio_irqchip = { + GPIOCHIP_IRQ_RESOURCE_HELPERS, + }; + +-static int ljca_gpio_probe(struct platform_device *pdev) ++static int ljca_gpio_probe(struct auxiliary_device *auxdev, ++ const struct auxiliary_device_id *aux_dev_id) + { ++ struct ljca_client *ljca = auxiliary_dev_to_ljca_client(auxdev); + struct ljca_gpio_dev *ljca_gpio; + struct gpio_irq_chip *girq; + int ret; + +- ljca_gpio = devm_kzalloc(&pdev->dev, sizeof(*ljca_gpio), GFP_KERNEL); ++ ljca_gpio = devm_kzalloc(&auxdev->dev, sizeof(*ljca_gpio), GFP_KERNEL); + if (!ljca_gpio) + return -ENOMEM; + +- ljca_gpio->gpio_info = dev_get_platdata(&pdev->dev); +- ljca_gpio->connect_mode = devm_kcalloc(&pdev->dev, ljca_gpio->gpio_info->num, +- sizeof(*ljca_gpio->connect_mode), GFP_KERNEL); ++ ljca_gpio->ljca = ljca; ++ ljca_gpio->gpio_info = dev_get_platdata(&auxdev->dev); ++ ljca_gpio->connect_mode = devm_kcalloc(&auxdev->dev, ++ ljca_gpio->gpio_info->num, ++ sizeof(*ljca_gpio->connect_mode), ++ GFP_KERNEL); + if (!ljca_gpio->connect_mode) + return -ENOMEM; + + mutex_init(&ljca_gpio->irq_lock); + mutex_init(&ljca_gpio->trans_lock); +- ljca_gpio->pdev = pdev; + ljca_gpio->gc.direction_input = ljca_gpio_direction_input; + ljca_gpio->gc.direction_output = ljca_gpio_direction_output; ++ ljca_gpio->gc.get_direction = ljca_gpio_get_direction; + ljca_gpio->gc.get = ljca_gpio_get_value; + ljca_gpio->gc.set = ljca_gpio_set_value; + ljca_gpio->gc.set_config = ljca_gpio_set_config; + ljca_gpio->gc.init_valid_mask = ljca_gpio_init_valid_mask; + ljca_gpio->gc.can_sleep = true; +- ljca_gpio->gc.parent = &pdev->dev; ++ ljca_gpio->gc.parent = &auxdev->dev; + + ljca_gpio->gc.base = -1; + ljca_gpio->gc.ngpio = ljca_gpio->gpio_info->num; +- ljca_gpio->gc.label = ACPI_COMPANION(&pdev->dev) ? +- acpi_dev_name(ACPI_COMPANION(&pdev->dev)) : +- dev_name(&pdev->dev); ++ ljca_gpio->gc.label = ACPI_COMPANION(&auxdev->dev) ? ++ acpi_dev_name(ACPI_COMPANION(&auxdev->dev)) : ++ dev_name(&auxdev->dev); + ljca_gpio->gc.owner = THIS_MODULE; + +- platform_set_drvdata(pdev, ljca_gpio); +- ljca_register_event_cb(ljca_gpio->gpio_info->ljca, ljca_gpio_event_cb, ljca_gpio); ++ auxiliary_set_drvdata(auxdev, ljca_gpio); ++ ljca_register_event_cb(ljca, ljca_gpio_event_cb, ljca_gpio); + + girq = &ljca_gpio->gc.irq; + gpio_irq_chip_set_chip(girq, &ljca_gpio_irqchip); +@@ -413,7 +454,7 @@ static int ljca_gpio_probe(struct platform_device *pdev) + INIT_WORK(&ljca_gpio->work, ljca_gpio_async); + ret = gpiochip_add_data(&ljca_gpio->gc, ljca_gpio); + if (ret) { +- ljca_unregister_event_cb(ljca_gpio->gpio_info->ljca); ++ ljca_unregister_event_cb(ljca); + mutex_destroy(&ljca_gpio->irq_lock); + mutex_destroy(&ljca_gpio->trans_lock); + } +@@ -421,34 +462,33 @@ static int ljca_gpio_probe(struct platform_device *pdev) + return ret; + } + +-static int ljca_gpio_remove(struct platform_device *pdev) ++static void ljca_gpio_remove(struct auxiliary_device *auxdev) + { +- struct ljca_gpio_dev *ljca_gpio = platform_get_drvdata(pdev); ++ struct ljca_gpio_dev *ljca_gpio = auxiliary_get_drvdata(auxdev); + + gpiochip_remove(&ljca_gpio->gc); +- ljca_unregister_event_cb(ljca_gpio->gpio_info->ljca); ++ ljca_unregister_event_cb(ljca_gpio->ljca); ++ cancel_work_sync(&ljca_gpio->work); + mutex_destroy(&ljca_gpio->irq_lock); + mutex_destroy(&ljca_gpio->trans_lock); +- return 0; + } + +-#define LJCA_GPIO_DRV_NAME "ljca-gpio" +-static const struct platform_device_id ljca_gpio_id[] = { +- { LJCA_GPIO_DRV_NAME, 0 }, +- { /* sentinel */ } ++static const struct auxiliary_device_id ljca_gpio_id_table[] = { ++ { "usb_ljca.ljca-gpio", 0 }, ++ { /* sentinel */ }, + }; +-MODULE_DEVICE_TABLE(platform, ljca_gpio_id); ++MODULE_DEVICE_TABLE(auxiliary, ljca_gpio_id_table); + +-static struct platform_driver ljca_gpio_driver = { +- .driver.name = LJCA_GPIO_DRV_NAME, ++static struct auxiliary_driver ljca_gpio_driver = { + .probe = ljca_gpio_probe, + .remove = ljca_gpio_remove, ++ .id_table = ljca_gpio_id_table, + }; +-module_platform_driver(ljca_gpio_driver); ++module_auxiliary_driver(ljca_gpio_driver); + +-MODULE_AUTHOR("Ye Xiang "); +-MODULE_AUTHOR("Wang Zhifeng "); +-MODULE_AUTHOR("Zhang Lixu "); ++MODULE_AUTHOR("Wentong Wu "); ++MODULE_AUTHOR("Zhifeng Wang "); ++MODULE_AUTHOR("Lixu Zhang "); + MODULE_DESCRIPTION("Intel La Jolla Cove Adapter USB-GPIO driver"); + MODULE_LICENSE("GPL"); + MODULE_IMPORT_NS(LJCA); +-- +2.51.0 + diff --git a/queue-6.6/hwmon-sht3x-fix-error-handling.patch b/queue-6.6/hwmon-sht3x-fix-error-handling.patch new file mode 100644 index 0000000000..8c9707eda9 --- /dev/null +++ b/queue-6.6/hwmon-sht3x-fix-error-handling.patch @@ -0,0 +1,99 @@ +From f03437f936c061e2594f520eff9058342a6e387f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Oct 2025 06:04:57 -0700 +Subject: hwmon: (sht3x) Fix error handling + +From: Guenter Roeck + +[ Upstream commit 8dcc66ad379ec0642fb281c45ccfd7d2d366e53f ] + +Handling of errors when reading status, temperature, and humidity returns +the error number as negative attribute value. Fix it up by returning +the error as return value. + +Fixes: a0ac418c6007c ("hwmon: (sht3x) convert some of sysfs interface to hwmon") +Cc: JuenKit Yip +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/sht3x.c | 27 +++++++++++++++++---------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/drivers/hwmon/sht3x.c b/drivers/hwmon/sht3x.c +index 79657910b79e6..d8a86e60cf8c1 100644 +--- a/drivers/hwmon/sht3x.c ++++ b/drivers/hwmon/sht3x.c +@@ -288,24 +288,26 @@ static struct sht3x_data *sht3x_update_client(struct device *dev) + return data; + } + +-static int temp1_input_read(struct device *dev) ++static int temp1_input_read(struct device *dev, long *temp) + { + struct sht3x_data *data = sht3x_update_client(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + +- return data->temperature; ++ *temp = data->temperature; ++ return 0; + } + +-static int humidity1_input_read(struct device *dev) ++static int humidity1_input_read(struct device *dev, long *humidity) + { + struct sht3x_data *data = sht3x_update_client(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + +- return data->humidity; ++ *humidity = data->humidity; ++ return 0; + } + + /* +@@ -703,6 +705,7 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *val) + { + enum sht3x_limits index; ++ int ret; + + switch (type) { + case hwmon_chip: +@@ -717,10 +720,12 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type, + case hwmon_temp: + switch (attr) { + case hwmon_temp_input: +- *val = temp1_input_read(dev); +- break; ++ return temp1_input_read(dev, val); + case hwmon_temp_alarm: +- *val = temp1_alarm_read(dev); ++ ret = temp1_alarm_read(dev); ++ if (ret < 0) ++ return ret; ++ *val = ret; + break; + case hwmon_temp_max: + index = limit_max; +@@ -745,10 +750,12 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type, + case hwmon_humidity: + switch (attr) { + case hwmon_humidity_input: +- *val = humidity1_input_read(dev); +- break; ++ return humidity1_input_read(dev, val); + case hwmon_humidity_alarm: +- *val = humidity1_alarm_read(dev); ++ ret = humidity1_alarm_read(dev); ++ if (ret < 0) ++ return ret; ++ *val = ret; + break; + case hwmon_humidity_max: + index = limit_max; +-- +2.51.0 + diff --git a/queue-6.6/io_uring-correct-__must_hold-annotation-in-io_instal.patch b/queue-6.6/io_uring-correct-__must_hold-annotation-in-io_instal.patch new file mode 100644 index 0000000000..ecb765cbfc --- /dev/null +++ b/queue-6.6/io_uring-correct-__must_hold-annotation-in-io_instal.patch @@ -0,0 +1,38 @@ +From a5fdbed4f3e985f3ee6b9bb1a4534a01f7e8de92 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 04:55:24 -0700 +Subject: io_uring: correct __must_hold annotation in io_install_fixed_file + +From: Alok Tiwari + +[ Upstream commit c5efc6a0b3940381d67887302ddb87a5cf623685 ] + +The __must_hold annotation references &req->ctx->uring_lock, but req +is not in scope in io_install_fixed_file. This change updates the +annotation to reference the correct ctx->uring_lock. +improving code clarity. + +Fixes: f110ed8498af ("io_uring: split out fixed file installation and removal") +Signed-off-by: Alok Tiwari +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/filetable.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/io_uring/filetable.c b/io_uring/filetable.c +index 6e86e6188dbee..ff74d41d9e53c 100644 +--- a/io_uring/filetable.c ++++ b/io_uring/filetable.c +@@ -62,7 +62,7 @@ void io_free_file_tables(struct io_file_table *table) + + static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file, + u32 slot_index) +- __must_hold(&req->ctx->uring_lock) ++ __must_hold(&ctx->uring_lock) + { + struct io_fixed_file *file_slot; + int ret; +-- +2.51.0 + diff --git a/queue-6.6/risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch b/queue-6.6/risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch new file mode 100644 index 0000000000..a5fe7b1df8 --- /dev/null +++ b/queue-6.6/risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch @@ -0,0 +1,48 @@ +From 4e3a4ee3fefa3e784ac9df40b934c34b0280c12e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 21:30:05 -0600 +Subject: RISC-V: Define pgprot_dmacoherent() for non-coherent devices + +From: Anup Patel + +[ Upstream commit ca525d53f994d45c8140968b571372c45f555ac1 ] + +The pgprot_dmacoherent() is used when allocating memory for +non-coherent devices and by default pgprot_dmacoherent() is +same as pgprot_noncached() unless architecture overrides it. + +Currently, there is no pgprot_dmacoherent() definition for +RISC-V hence non-coherent device memory is being mapped as +IO thereby making CPU access to such memory slow. + +Define pgprot_dmacoherent() to be same as pgprot_writecombine() +for RISC-V so that CPU access non-coherent device memory as +NOCACHE which is better than accessing it as IO. + +Fixes: ff689fd21cb1 ("riscv: add RISC-V Svpbmt extension support") +Signed-off-by: Anup Patel +Tested-by: Han Gao +Tested-by: Guo Ren (Alibaba DAMO Academy) +Link: https://lore.kernel.org/r/20250820152316.1012757-1-apatel@ventanamicro.com +Signed-off-by: Paul Walmsley +Signed-off-by: Sasha Levin +--- + arch/riscv/include/asm/pgtable.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h +index 332a6bf72b1d5..987cfe87e7825 100644 +--- a/arch/riscv/include/asm/pgtable.h ++++ b/arch/riscv/include/asm/pgtable.h +@@ -618,6 +618,8 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot) + return __pgprot(prot); + } + ++#define pgprot_dmacoherent pgprot_writecombine ++ + /* + * THP functions + */ +-- +2.51.0 + diff --git a/queue-6.6/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch b/queue-6.6/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch new file mode 100644 index 0000000000..5aeded63d5 --- /dev/null +++ b/queue-6.6/risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch @@ -0,0 +1,46 @@ +From eacd6c5ff807674b54d0d099830a60b9907ed633 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 22:00:09 +0530 +Subject: RISC-V: Don't print details of CPUs disabled in DT + +From: Anup Patel + +[ Upstream commit d2721bb165b3ee00dd23525885381af07fec852a ] + +Early boot stages may disable CPU DT nodes for unavailable +CPUs based on SKU, pinstraps, eFuse, etc. Currently, the +riscv_early_of_processor_hartid() prints details of a CPU +if it is disabled in DT which has no value and gives a +false impression to the users that there some issue with +the CPU. + +Fixes: e3d794d555cd ("riscv: treat cpu devicetree nodes without status as enabled") +Signed-off-by: Anup Patel +Reviewed-by: Andrew Jones +Reviewed-by: Conor Dooley +Link: https://lore.kernel.org/r/20251014163009.182381-1-apatel@ventanamicro.com +Signed-off-by: Paul Walmsley +Signed-off-by: Sasha Levin +--- + arch/riscv/kernel/cpu.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c +index 88732abecd023..93e794d0e5231 100644 +--- a/arch/riscv/kernel/cpu.c ++++ b/arch/riscv/kernel/cpu.c +@@ -61,10 +61,8 @@ int __init riscv_early_of_processor_hartid(struct device_node *node, unsigned lo + return -ENODEV; + } + +- if (!of_device_is_available(node)) { +- pr_info("CPU with hartid=%lu is not available\n", *hart); ++ if (!of_device_is_available(node)) + return -ENODEV; +- } + + if (of_property_read_string(node, "riscv,isa-base", &isa)) + goto old_interface; +-- +2.51.0 + diff --git a/queue-6.6/sched-remove-never-used-code-in-mm_cid_get.patch b/queue-6.6/sched-remove-never-used-code-in-mm_cid_get.patch new file mode 100644 index 0000000000..61e6320fde --- /dev/null +++ b/queue-6.6/sched-remove-never-used-code-in-mm_cid_get.patch @@ -0,0 +1,47 @@ +From 825df7217d429b597f05953cedf8bc377b4de17c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 11:19:34 +0200 +Subject: sched: Remove never used code in mm_cid_get() + +From: Andy Shevchenko + +[ Upstream commit 53abe3e1c154628cc74e33a1bfcd865656e433a5 ] + +Clang is not happy with set but unused variable (this is visible +with `make W=1` build: + + kernel/sched/sched.h:3744:18: error: variable 'cpumask' set but not used [-Werror,-Wunused-but-set-variable] + +It seems like the variable was never used along with the assignment +that does not have side effects as far as I can see. Remove those +altogether. + +Fixes: 223baf9d17f2 ("sched: Fix performance regression introduced by mm_cid") +Signed-off-by: Andy Shevchenko +Tested-by: Eric Biggers +Reviewed-by: Breno Leitao +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + kernel/sched/sched.h | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h +index f7cb505ab337a..64634314a89ce 100644 +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -3435,11 +3435,9 @@ static inline int __mm_cid_get(struct rq *rq, struct mm_struct *mm) + static inline int mm_cid_get(struct rq *rq, struct mm_struct *mm) + { + struct mm_cid __percpu *pcpu_cid = mm->pcpu_cid; +- struct cpumask *cpumask; + int cid; + + lockdep_assert_rq_held(rq); +- cpumask = mm_cidmask(mm); + cid = __this_cpu_read(pcpu_cid->cid); + if (mm_cid_is_valid(cid)) { + mm_cid_snapshot_time(rq, mm); +-- +2.51.0 + diff --git a/queue-6.6/series b/queue-6.6/series index 66e9485306..08e3efaa18 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -28,3 +28,13 @@ net-mlx5e-rx-fix-generating-skb-from-non-linear-xdp_.patch net-mlx5e-rx-fix-generating-skb-from-non-linear-xdp_.patch-5039 arm64-mm-avoid-always-making-pte-dirty-in-pte_mkwrit.patch sctp-avoid-null-dereference-when-chunk-data-buffer-i.patch +spi-spi-nxp-fspi-add-extra-delay-after-dll-locked.patch +firmware-arm_scmi-account-for-failed-debug-initializ.patch +firmware-arm_scmi-fix-premature-scmi_xfer_flag_is_ra.patch +risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch +risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch +hwmon-sht3x-fix-error-handling.patch +gpio-update-intel-ljca-usb-gpio-driver.patch +gpio-ljca-fix-duplicated-irq-mapping.patch +io_uring-correct-__must_hold-annotation-in-io_instal.patch +sched-remove-never-used-code-in-mm_cid_get.patch diff --git a/queue-6.6/spi-spi-nxp-fspi-add-extra-delay-after-dll-locked.patch b/queue-6.6/spi-spi-nxp-fspi-add-extra-delay-after-dll-locked.patch new file mode 100644 index 0000000000..b097dec64d --- /dev/null +++ b/queue-6.6/spi-spi-nxp-fspi-add-extra-delay-after-dll-locked.patch @@ -0,0 +1,46 @@ +From c79cc7ac845ae1c78727be08ad2f3607769ee3bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 16:47:14 +0800 +Subject: spi: spi-nxp-fspi: add extra delay after dll locked + +From: Han Xu + +[ Upstream commit b93b4269791fdebbac2a9ad26f324dc2abb9e60f ] + +Due to the erratum ERR050272, the DLL lock status register STS2 +[xREFLOCK, xSLVLOCK] bit may indicate DLL is locked before DLL is +actually locked. Add an extra 4us delay as a workaround. + +refer to ERR050272, on Page 20. +https://www.nxp.com/docs/en/errata/IMX8_1N94W.pdf + +Fixes: 99d822b3adc4 ("spi: spi-nxp-fspi: use DLL calibration when clock rate > 100MHz") +Signed-off-by: Han Xu +Signed-off-by: Haibo Chen +Link: https://patch.msgid.link/20250922-fspi-fix-v1-2-ff4315359d31@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-nxp-fspi.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c +index bc6c086ddd43f..731504ec7ef8b 100644 +--- a/drivers/spi/spi-nxp-fspi.c ++++ b/drivers/spi/spi-nxp-fspi.c +@@ -665,6 +665,12 @@ static void nxp_fspi_dll_calibration(struct nxp_fspi *f) + 0, POLL_TOUT, true); + if (ret) + dev_warn(f->dev, "DLL lock failed, please fix it!\n"); ++ ++ /* ++ * For ERR050272, DLL lock status bit is not accurate, ++ * wait for 4us more as a workaround. ++ */ ++ udelay(4); + } + + /* +-- +2.51.0 +