]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 5 Jan 2026 10:42:58 +0000 (11:42 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 5 Jan 2026 10:42:58 +0000 (11:42 +0100)
added patches:
arm64-dts-ti-k3-j721e-sk-fix-pinmux-for-pin-y1-used-by-power-regulator.patch
block-clear-blk_zone_wplug_plugged-when-aborting-plugged-bios.patch
clk-samsung-exynos-clkout-assign-.num-before-accessing-.hws.patch
fgraph-check-ftrace_pids_enabled-on-registration-for-early-filtering.patch
fgraph-initialize-ftrace_ops-private-for-function-graph-ops.patch
leds-leds-cros_ec-skip-leds-without-color-components.patch
leds-leds-lp50xx-allow-led-0-to-be-added-to-module-bank.patch
leds-leds-lp50xx-enable-chip-before-any-communication.patch
leds-leds-lp50xx-lp5009-supports-3-modules-for-a-total-of-9-leds.patch
media-rc-st_rc-fix-reset-control-resource-leak.patch
media-verisilicon-fix-cpu-stalls-on-g2-bus-error.patch
mfd-altera-sysmgr-fix-device-leak-on-sysmgr-regmap-lookup.patch
mfd-max77620-fix-potential-irq-chip-conflict-when-probing-two-devices.patch
pci-pm-reinstate-clearing-state_saved-in-legacy-and-pm-codepaths.patch
powerpc-64s-slb-fix-slb-multihit-issue-during-slb-preload.patch
powerpc-mm-fix-mprotect-on-book3s-32-bit.patch

17 files changed:
queue-6.12/arm64-dts-ti-k3-j721e-sk-fix-pinmux-for-pin-y1-used-by-power-regulator.patch [new file with mode: 0644]
queue-6.12/block-clear-blk_zone_wplug_plugged-when-aborting-plugged-bios.patch [new file with mode: 0644]
queue-6.12/clk-samsung-exynos-clkout-assign-.num-before-accessing-.hws.patch [new file with mode: 0644]
queue-6.12/fgraph-check-ftrace_pids_enabled-on-registration-for-early-filtering.patch [new file with mode: 0644]
queue-6.12/fgraph-initialize-ftrace_ops-private-for-function-graph-ops.patch [new file with mode: 0644]
queue-6.12/leds-leds-cros_ec-skip-leds-without-color-components.patch [new file with mode: 0644]
queue-6.12/leds-leds-lp50xx-allow-led-0-to-be-added-to-module-bank.patch [new file with mode: 0644]
queue-6.12/leds-leds-lp50xx-enable-chip-before-any-communication.patch [new file with mode: 0644]
queue-6.12/leds-leds-lp50xx-lp5009-supports-3-modules-for-a-total-of-9-leds.patch [new file with mode: 0644]
queue-6.12/media-rc-st_rc-fix-reset-control-resource-leak.patch [new file with mode: 0644]
queue-6.12/media-verisilicon-fix-cpu-stalls-on-g2-bus-error.patch [new file with mode: 0644]
queue-6.12/mfd-altera-sysmgr-fix-device-leak-on-sysmgr-regmap-lookup.patch [new file with mode: 0644]
queue-6.12/mfd-max77620-fix-potential-irq-chip-conflict-when-probing-two-devices.patch [new file with mode: 0644]
queue-6.12/pci-pm-reinstate-clearing-state_saved-in-legacy-and-pm-codepaths.patch [new file with mode: 0644]
queue-6.12/powerpc-64s-slb-fix-slb-multihit-issue-during-slb-preload.patch [new file with mode: 0644]
queue-6.12/powerpc-mm-fix-mprotect-on-book3s-32-bit.patch [new file with mode: 0644]
queue-6.12/series

diff --git a/queue-6.12/arm64-dts-ti-k3-j721e-sk-fix-pinmux-for-pin-y1-used-by-power-regulator.patch b/queue-6.12/arm64-dts-ti-k3-j721e-sk-fix-pinmux-for-pin-y1-used-by-power-regulator.patch
new file mode 100644 (file)
index 0000000..5d4b446
--- /dev/null
@@ -0,0 +1,62 @@
+From 51f89c488f2ecc020f82bfedd77482584ce8027a Mon Sep 17 00:00:00 2001
+From: Siddharth Vadapalli <s-vadapalli@ti.com>
+Date: Wed, 19 Nov 2025 21:31:05 +0530
+Subject: arm64: dts: ti: k3-j721e-sk: Fix pinmux for pin Y1 used by power regulator
+
+From: Siddharth Vadapalli <s-vadapalli@ti.com>
+
+commit 51f89c488f2ecc020f82bfedd77482584ce8027a upstream.
+
+The SoC pin Y1 is incorrectly defined in the WKUP Pinmux device-tree node
+(pinctrl@4301c000) leading to the following silent failure:
+
+    pinctrl-single 4301c000.pinctrl: mux offset out of range: 0x1dc (0x178)
+
+According to the datasheet for the J721E SoC [0], the pin Y1 belongs to the
+MAIN Pinmux device-tree node (pinctrl@11c000). This is confirmed by the
+address of the pinmux register for it on page 142 of the datasheet which is
+0x00011C1DC.
+
+Hence fix it.
+
+[0]: https://www.ti.com/lit/ds/symlink/tda4vm.pdf
+
+Fixes: 97b67cc102dc ("arm64: dts: ti: k3-j721e-sk: Add DT nodes for power regulators")
+Cc: stable@vger.kernel.org
+Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>
+Reviewed-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
+Link: https://patch.msgid.link/20251119160148.2752616-1-s-vadapalli@ti.com
+Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/boot/dts/ti/k3-j721e-sk.dts |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
++++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
+@@ -572,6 +572,12 @@
+                       J721E_IOPAD(0x234, PIN_INPUT, 7) /* (U3) EXT_REFCLK1.GPIO1_12 */
+               >;
+       };
++
++      vdd_sd_dv_pins_default: vdd-sd-dv-default-pins {
++              pinctrl-single,pins = <
++                      J721E_IOPAD(0x1dc, PIN_OUTPUT, 7) /* (Y1) SPI1_CLK.GPIO0_118 */
++              >;
++      };
+ };
+ &wkup_pmx0 {
+@@ -633,12 +639,6 @@
+               >;
+       };
+-      vdd_sd_dv_pins_default: vdd-sd-dv-default-pins {
+-              pinctrl-single,pins = <
+-                      J721E_IOPAD(0x1dc, PIN_OUTPUT, 7) /* (Y1) SPI1_CLK.GPIO0_118 */
+-              >;
+-      };
+-
+       wkup_uart0_pins_default: wkup-uart0-default-pins {
+               pinctrl-single,pins = <
+                       J721E_WKUP_IOPAD(0xa0, PIN_INPUT, 0) /* (J29) WKUP_UART0_RXD */
diff --git a/queue-6.12/block-clear-blk_zone_wplug_plugged-when-aborting-plugged-bios.patch b/queue-6.12/block-clear-blk_zone_wplug_plugged-when-aborting-plugged-bios.patch
new file mode 100644 (file)
index 0000000..f75fa44
--- /dev/null
@@ -0,0 +1,57 @@
+From 552c1149af7ac0cffab6fccd13feeaf816dd1f53 Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <dlemoal@kernel.org>
+Date: Thu, 4 Dec 2025 19:59:52 +0900
+Subject: block: Clear BLK_ZONE_WPLUG_PLUGGED when aborting plugged BIOs
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+commit 552c1149af7ac0cffab6fccd13feeaf816dd1f53 upstream.
+
+Commit fe0418eb9bd6 ("block: Prevent potential deadlocks in zone write
+plug error recovery") added a WARN check in disk_put_zone_wplug() to
+verify that when the last reference to a zone write plug is dropped,
+this zone write plug does not have the BLK_ZONE_WPLUG_PLUGGED flag set,
+that is, that it is not plugged.
+
+However, the function disk_zone_wplug_abort(), which is called for zone
+reset and zone finish operations, does not clear this flag after
+emptying a zone write plug BIO list. This can result in the
+disk_put_zone_wplug() warning to trigger if the user (erroneously as
+that is bad pratcice) issues zone reset or zone finish operations while
+the target zone still has plugged BIOs.
+
+Modify disk_put_zone_wplug() to clear the BLK_ZONE_WPLUG_PLUGGED flag.
+And while at it, also add a lockdep annotation to ensure that this
+function is called with the zone write plug spinlock held.
+
+Fixes: fe0418eb9bd6 ("block: Prevent potential deadlocks in zone write plug error recovery")
+Cc: stable@vger.kernel.org
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Niklas Cassel <cassel@kernel.org>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ block/blk-zoned.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/block/blk-zoned.c
++++ b/block/blk-zoned.c
+@@ -621,6 +621,8 @@ static void disk_zone_wplug_abort(struct
+ {
+       struct bio *bio;
++      lockdep_assert_held(&zwplug->lock);
++
+       if (bio_list_empty(&zwplug->bio_list))
+               return;
+@@ -628,6 +630,8 @@ static void disk_zone_wplug_abort(struct
+                           zwplug->disk->disk_name, zwplug->zone_no);
+       while ((bio = bio_list_pop(&zwplug->bio_list)))
+               blk_zone_wplug_bio_io_error(zwplug, bio);
++
++      zwplug->flags &= ~BLK_ZONE_WPLUG_PLUGGED;
+ }
+ /*
diff --git a/queue-6.12/clk-samsung-exynos-clkout-assign-.num-before-accessing-.hws.patch b/queue-6.12/clk-samsung-exynos-clkout-assign-.num-before-accessing-.hws.patch
new file mode 100644 (file)
index 0000000..4a52802
--- /dev/null
@@ -0,0 +1,59 @@
+From cf33f0b7df13685234ccea7be7bfe316b60db4db Mon Sep 17 00:00:00 2001
+From: Nathan Chancellor <nathan@kernel.org>
+Date: Mon, 24 Nov 2025 12:11:06 -0700
+Subject: clk: samsung: exynos-clkout: Assign .num before accessing .hws
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+commit cf33f0b7df13685234ccea7be7bfe316b60db4db upstream.
+
+Commit f316cdff8d67 ("clk: Annotate struct clk_hw_onecell_data with
+__counted_by") annotated the hws member of 'struct clk_hw_onecell_data'
+with __counted_by, which informs the bounds sanitizer (UBSAN_BOUNDS)
+about the number of elements in .hws[], so that it can warn when .hws[]
+is accessed out of bounds. As noted in that change, the __counted_by
+member must be initialized with the number of elements before the first
+array access happens, otherwise there will be a warning from each access
+prior to the initialization because the number of elements is zero. This
+occurs in exynos_clkout_probe() due to .num being assigned after .hws[]
+has been accessed:
+
+  UBSAN: array-index-out-of-bounds in drivers/clk/samsung/clk-exynos-clkout.c:178:18
+  index 0 is out of range for type 'clk_hw *[*]'
+
+Move the .num initialization to before the first access of .hws[],
+clearing up the warning.
+
+Cc: stable@vger.kernel.org
+Fixes: f316cdff8d67 ("clk: Annotate struct clk_hw_onecell_data with __counted_by")
+Reported-by: Jochen Sprickerhof <jochen@sprickerhof.de>
+Closes: https://lore.kernel.org/aSIYDN5eyKFKoXKL@eldamar.lan/
+Tested-by: Jochen Sprickerhof <jochen@sprickerhof.de>
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Reviewed-by: Kees Cook <kees@kernel.org>
+Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/clk/samsung/clk-exynos-clkout.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clk/samsung/clk-exynos-clkout.c
++++ b/drivers/clk/samsung/clk-exynos-clkout.c
+@@ -174,6 +174,7 @@ static int exynos_clkout_probe(struct pl
+       clkout->mux.shift = EXYNOS_CLKOUT_MUX_SHIFT;
+       clkout->mux.lock = &clkout->slock;
++      clkout->data.num = EXYNOS_CLKOUT_NR_CLKS;
+       clkout->data.hws[0] = clk_hw_register_composite(NULL, "clkout",
+                               parent_names, parent_count, &clkout->mux.hw,
+                               &clk_mux_ops, NULL, NULL, &clkout->gate.hw,
+@@ -184,7 +185,6 @@ static int exynos_clkout_probe(struct pl
+               goto err_unmap;
+       }
+-      clkout->data.num = EXYNOS_CLKOUT_NR_CLKS;
+       ret = of_clk_add_hw_provider(clkout->np, of_clk_hw_onecell_get, &clkout->data);
+       if (ret)
+               goto err_clk_unreg;
diff --git a/queue-6.12/fgraph-check-ftrace_pids_enabled-on-registration-for-early-filtering.patch b/queue-6.12/fgraph-check-ftrace_pids_enabled-on-registration-for-early-filtering.patch
new file mode 100644 (file)
index 0000000..bcb4268
--- /dev/null
@@ -0,0 +1,54 @@
+From 1650a1b6cb1ae6cb99bb4fce21b30ebdf9fc238e Mon Sep 17 00:00:00 2001
+From: Shengming Hu <hu.shengming@zte.com.cn>
+Date: Wed, 26 Nov 2025 17:33:31 +0800
+Subject: fgraph: Check ftrace_pids_enabled on registration for early filtering
+
+From: Shengming Hu <hu.shengming@zte.com.cn>
+
+commit 1650a1b6cb1ae6cb99bb4fce21b30ebdf9fc238e upstream.
+
+When registering ftrace_graph, check if ftrace_pids_enabled is active.
+If enabled, assign entryfunc to fgraph_pid_func to ensure filtering
+is performed before executing the saved original entry function.
+
+Cc: stable@vger.kernel.org
+Cc: <wang.yaxin@zte.com.cn>
+Cc: <mhiramat@kernel.org>
+Cc: <mark.rutland@arm.com>
+Cc: <mathieu.desnoyers@efficios.com>
+Cc: <zhang.run@zte.com.cn>
+Cc: <yang.yang29@zte.com.cn>
+Link: https://patch.msgid.link/20251126173331679XGVF98NLhyLJRdtNkVZ6w@zte.com.cn
+Fixes: df3ec5da6a1e7 ("function_graph: Add pid tracing back to function graph tracer")
+Signed-off-by: Shengming Hu <hu.shengming@zte.com.cn>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/fgraph.c |    9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/kernel/trace/fgraph.c
++++ b/kernel/trace/fgraph.c
+@@ -1286,6 +1286,13 @@ int register_ftrace_graph(struct fgraph_
+       ftrace_graph_active++;
++      /* Always save the function, and reset at unregistering */
++      gops->saved_func = gops->entryfunc;
++#ifdef CONFIG_DYNAMIC_FTRACE
++      if (ftrace_pids_enabled(&gops->ops))
++              gops->entryfunc = fgraph_pid_func;
++#endif
++
+       if (ftrace_graph_active == 2)
+               ftrace_graph_disable_direct(true);
+@@ -1305,8 +1312,6 @@ int register_ftrace_graph(struct fgraph_
+       } else {
+               init_task_vars(gops->idx);
+       }
+-      /* Always save the function, and reset at unregistering */
+-      gops->saved_func = gops->entryfunc;
+       ret = ftrace_startup_subops(&graph_ops, &gops->ops, command);
+       if (!ret)
diff --git a/queue-6.12/fgraph-initialize-ftrace_ops-private-for-function-graph-ops.patch b/queue-6.12/fgraph-initialize-ftrace_ops-private-for-function-graph-ops.patch
new file mode 100644 (file)
index 0000000..71f3aa7
--- /dev/null
@@ -0,0 +1,43 @@
+From b5d6d3f73d0bac4a7e3a061372f6da166fc6ee5c Mon Sep 17 00:00:00 2001
+From: Shengming Hu <hu.shengming@zte.com.cn>
+Date: Wed, 26 Nov 2025 17:29:26 +0800
+Subject: fgraph: Initialize ftrace_ops->private for function graph ops
+
+From: Shengming Hu <hu.shengming@zte.com.cn>
+
+commit b5d6d3f73d0bac4a7e3a061372f6da166fc6ee5c upstream.
+
+The ftrace_pids_enabled(op) check relies on op->private being properly
+initialized, but fgraph_ops's underlying ftrace_ops->private was left
+uninitialized. This caused ftrace_pids_enabled() to always return false,
+effectively disabling PID filtering for function graph tracing.
+
+Fix this by copying src_ops->private to dst_ops->private in
+fgraph_init_ops(), ensuring PID filter state is correctly propagated.
+
+Cc: stable@vger.kernel.org
+Cc: <wang.yaxin@zte.com.cn>
+Cc: <mhiramat@kernel.org>
+Cc: <mark.rutland@arm.com>
+Cc: <mathieu.desnoyers@efficios.com>
+Cc: <zhang.run@zte.com.cn>
+Cc: <yang.yang29@zte.com.cn>
+Fixes: c132be2c4fcc1 ("function_graph: Have the instances use their own ftrace_ops for filtering")
+Link: https://patch.msgid.link/20251126172926004y3hC8QyU4WFOjBkU_UxLC@zte.com.cn
+Signed-off-by: Shengming Hu <hu.shengming@zte.com.cn>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/fgraph.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/kernel/trace/fgraph.c
++++ b/kernel/trace/fgraph.c
+@@ -943,6 +943,7 @@ void fgraph_init_ops(struct ftrace_ops *
+               mutex_init(&dst_ops->local_hash.regex_lock);
+               INIT_LIST_HEAD(&dst_ops->subop_list);
+               dst_ops->flags |= FTRACE_OPS_FL_INITIALIZED;
++              dst_ops->private = src_ops->private;
+       }
+ #endif
+ }
diff --git a/queue-6.12/leds-leds-cros_ec-skip-leds-without-color-components.patch b/queue-6.12/leds-leds-cros_ec-skip-leds-without-color-components.patch
new file mode 100644 (file)
index 0000000..0a8d0a5
--- /dev/null
@@ -0,0 +1,62 @@
+From 4dbf066d965cd3299fb396f1375d10423c9c625c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <linux@weissschuh.net>
+Date: Tue, 28 Oct 2025 16:31:03 +0100
+Subject: leds: leds-cros_ec: Skip LEDs without color components
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Weißschuh <linux@weissschuh.net>
+
+commit 4dbf066d965cd3299fb396f1375d10423c9c625c upstream.
+
+A user reports that on their Lenovo Corsola Magneton with EC firmware
+steelix-15194.270.0 the driver probe fails with EINVAL. It turns out
+that the power LED does not contain any color components as indicated
+by the following "ectool led power query" output:
+
+Brightness range for LED 1:
+        red     : 0x0
+        green   : 0x0
+        blue    : 0x0
+        yellow  : 0x0
+        white   : 0x0
+        amber   : 0x0
+
+The LED also does not react to commands sent manually through ectool and
+is generally non-functional.
+
+Instead of failing the probe for all LEDs managed by the EC when one
+without color components is encountered, silently skip those.
+
+Cc: stable@vger.kernel.org
+Fixes: 8d6ce6f3ec9d ("leds: Add ChromeOS EC driver")
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Link: https://patch.msgid.link/20251028-cros_ec-leds-no-colors-v1-1-ebe13a02022a@weissschuh.net
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/leds/leds-cros_ec.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/leds/leds-cros_ec.c
++++ b/drivers/leds/leds-cros_ec.c
+@@ -155,9 +155,6 @@ static int cros_ec_led_count_subleds(str
+               }
+       }
+-      if (!num_subleds)
+-              return -EINVAL;
+-
+       *max_brightness = common_range;
+       return num_subleds;
+ }
+@@ -202,6 +199,8 @@ static int cros_ec_led_probe_one(struct
+                                               &priv->led_mc_cdev.led_cdev.max_brightness);
+       if (num_subleds < 0)
+               return num_subleds;
++      if (num_subleds == 0)
++              return 0; /* LED without any colors, skip */
+       priv->cros_ec = cros_ec;
+       priv->led_id = id;
diff --git a/queue-6.12/leds-leds-lp50xx-allow-led-0-to-be-added-to-module-bank.patch b/queue-6.12/leds-leds-lp50xx-allow-led-0-to-be-added-to-module-bank.patch
new file mode 100644 (file)
index 0000000..63af823
--- /dev/null
@@ -0,0 +1,61 @@
+From 26fe74d598c32e7bc6f150edfc4aa43e1bee55db Mon Sep 17 00:00:00 2001
+From: Christian Hitz <christian.hitz@bbv.ch>
+Date: Wed, 8 Oct 2025 14:32:21 +0200
+Subject: leds: leds-lp50xx: Allow LED 0 to be added to module bank
+
+From: Christian Hitz <christian.hitz@bbv.ch>
+
+commit 26fe74d598c32e7bc6f150edfc4aa43e1bee55db upstream.
+
+led_banks contains LED module number(s) that should be grouped into the
+module bank. led_banks is 0-initialized.
+By checking the led_banks entries for 0, un-set entries are detected.
+But a 0-entry also indicates that LED module 0 should be grouped into the
+module bank.
+
+By only iterating over the available entries no check for unused entries
+is required and LED module 0 can be added to bank.
+
+Cc: stable@vger.kernel.org
+Fixes: 242b81170fb8 ("leds: lp50xx: Add the LP50XX family of the RGB LED driver")
+Signed-off-by: Christian Hitz <christian.hitz@bbv.ch>
+Reviewed-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
+Link: https://patch.msgid.link/20251008123222.1117331-1-christian@klarinett.li
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/leds/leds-lp50xx.c |   10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+--- a/drivers/leds/leds-lp50xx.c
++++ b/drivers/leds/leds-lp50xx.c
+@@ -343,17 +343,15 @@ out:
+       return ret;
+ }
+-static int lp50xx_set_banks(struct lp50xx *priv, u32 led_banks[])
++static int lp50xx_set_banks(struct lp50xx *priv, u32 led_banks[], int num_leds)
+ {
+       u8 led_config_lo, led_config_hi;
+       u32 bank_enable_mask = 0;
+       int ret;
+       int i;
+-      for (i = 0; i < priv->chip_info->max_modules; i++) {
+-              if (led_banks[i])
+-                      bank_enable_mask |= (1 << led_banks[i]);
+-      }
++      for (i = 0; i < num_leds; i++)
++              bank_enable_mask |= (1 << led_banks[i]);
+       led_config_lo = bank_enable_mask;
+       led_config_hi = bank_enable_mask >> 8;
+@@ -407,7 +405,7 @@ static int lp50xx_probe_leds(struct fwno
+                       return ret;
+               }
+-              ret = lp50xx_set_banks(priv, led_banks);
++              ret = lp50xx_set_banks(priv, led_banks, num_leds);
+               if (ret) {
+                       dev_err(priv->dev, "Cannot setup banked LEDs\n");
+                       return ret;
diff --git a/queue-6.12/leds-leds-lp50xx-enable-chip-before-any-communication.patch b/queue-6.12/leds-leds-lp50xx-enable-chip-before-any-communication.patch
new file mode 100644 (file)
index 0000000..3fa64a5
--- /dev/null
@@ -0,0 +1,150 @@
+From 434959618c47efe9e5f2e20f4a850caac4f6b823 Mon Sep 17 00:00:00 2001
+From: Christian Hitz <christian.hitz@bbv.ch>
+Date: Tue, 28 Oct 2025 16:51:40 +0100
+Subject: leds: leds-lp50xx: Enable chip before any communication
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christian Hitz <christian.hitz@bbv.ch>
+
+commit 434959618c47efe9e5f2e20f4a850caac4f6b823 upstream.
+
+If a GPIO is used to control the chip's enable pin, it needs to be pulled
+high before any i2c communication is attempted.
+
+Currently, the enable GPIO handling is not correct.
+
+Assume the enable GPIO is low when the probe function is entered. In this
+case the device is in SHUTDOWN mode and does not react to i2c commands.
+
+During probe the following sequence happens:
+ 1. The call to lp50xx_reset() on line 548 has no effect as i2c is not
+    possible yet.
+ 2. Then - on line 552 - lp50xx_enable_disable() is called. As
+    "priv->enable_gpio“ has not yet been initialized, setting the GPIO has
+    no effect. Also the i2c enable command is not executed as the device
+    is still in SHUTDOWN.
+ 3. On line 556 the call to lp50xx_probe_dt() finally parses the rest of
+    the DT and the configured priv->enable_gpio is set up.
+
+As a result the device is still in SHUTDOWN mode and not ready for
+operation.
+
+Split lp50xx_enable_disable() into distinct enable and disable functions
+to enforce correct ordering between enable_gpio manipulations and i2c
+commands.
+Read enable_gpio configuration from DT before attempting to manipulate
+enable_gpio.
+Add delays to observe correct wait timing after manipulating enable_gpio
+and before any i2c communication.
+
+Cc: stable@vger.kernel.org
+Fixes: 242b81170fb8 ("leds: lp50xx: Add the LP50XX family of the RGB LED driver")
+Signed-off-by: Christian Hitz <christian.hitz@bbv.ch>
+Link: https://patch.msgid.link/20251028155141.1603193-1-christian@klarinett.li
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/leds/leds-lp50xx.c |   55 ++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 40 insertions(+), 15 deletions(-)
+
+--- a/drivers/leds/leds-lp50xx.c
++++ b/drivers/leds/leds-lp50xx.c
+@@ -52,6 +52,12 @@
+ #define LP50XX_SW_RESET               0xff
+ #define LP50XX_CHIP_EN                BIT(6)
++#define LP50XX_CHIP_DISABLE   0x00
++#define LP50XX_START_TIME_US  500
++#define LP50XX_RESET_TIME_US  3
++
++#define LP50XX_EN_GPIO_LOW    0
++#define LP50XX_EN_GPIO_HIGH   1
+ /* There are 3 LED outputs per bank */
+ #define LP50XX_LEDS_PER_MODULE        3
+@@ -371,19 +377,42 @@ static int lp50xx_reset(struct lp50xx *p
+       return regmap_write(priv->regmap, priv->chip_info->reset_reg, LP50XX_SW_RESET);
+ }
+-static int lp50xx_enable_disable(struct lp50xx *priv, int enable_disable)
++static int lp50xx_enable(struct lp50xx *priv)
+ {
+       int ret;
+-      ret = gpiod_direction_output(priv->enable_gpio, enable_disable);
++      if (priv->enable_gpio) {
++              ret = gpiod_direction_output(priv->enable_gpio, LP50XX_EN_GPIO_HIGH);
++              if (ret)
++                      return ret;
++
++              udelay(LP50XX_START_TIME_US);
++      }
++
++      ret = lp50xx_reset(priv);
+       if (ret)
+               return ret;
+-      if (enable_disable)
+-              return regmap_write(priv->regmap, LP50XX_DEV_CFG0, LP50XX_CHIP_EN);
+-      else
+-              return regmap_write(priv->regmap, LP50XX_DEV_CFG0, 0);
++      return regmap_write(priv->regmap, LP50XX_DEV_CFG0, LP50XX_CHIP_EN);
++}
++static int lp50xx_disable(struct lp50xx *priv)
++{
++      int ret;
++
++      ret = regmap_write(priv->regmap, LP50XX_DEV_CFG0, LP50XX_CHIP_DISABLE);
++      if (ret)
++              return ret;
++
++      if (priv->enable_gpio) {
++              ret = gpiod_direction_output(priv->enable_gpio, LP50XX_EN_GPIO_LOW);
++              if (ret)
++                      return ret;
++
++              udelay(LP50XX_RESET_TIME_US);
++      }
++
++      return 0;
+ }
+ static int lp50xx_probe_leds(struct fwnode_handle *child, struct lp50xx *priv,
+@@ -448,6 +477,10 @@ static int lp50xx_probe_dt(struct lp50xx
+               return dev_err_probe(priv->dev, PTR_ERR(priv->enable_gpio),
+                                    "Failed to get enable GPIO\n");
++      ret = lp50xx_enable(priv);
++      if (ret)
++              return ret;
++
+       priv->regulator = devm_regulator_get(priv->dev, "vled");
+       if (IS_ERR(priv->regulator))
+               priv->regulator = NULL;
+@@ -554,14 +587,6 @@ static int lp50xx_probe(struct i2c_clien
+               return ret;
+       }
+-      ret = lp50xx_reset(led);
+-      if (ret)
+-              return ret;
+-
+-      ret = lp50xx_enable_disable(led, 1);
+-      if (ret)
+-              return ret;
+-
+       return lp50xx_probe_dt(led);
+ }
+@@ -570,7 +595,7 @@ static void lp50xx_remove(struct i2c_cli
+       struct lp50xx *led = i2c_get_clientdata(client);
+       int ret;
+-      ret = lp50xx_enable_disable(led, 0);
++      ret = lp50xx_disable(led);
+       if (ret)
+               dev_err(led->dev, "Failed to disable chip\n");
diff --git a/queue-6.12/leds-leds-lp50xx-lp5009-supports-3-modules-for-a-total-of-9-leds.patch b/queue-6.12/leds-leds-lp50xx-lp5009-supports-3-modules-for-a-total-of-9-leds.patch
new file mode 100644 (file)
index 0000000..a2cf3dd
--- /dev/null
@@ -0,0 +1,32 @@
+From 5246e3673eeeccb4f5bf4f42375dd495d465ac15 Mon Sep 17 00:00:00 2001
+From: Christian Hitz <christian.hitz@bbv.ch>
+Date: Wed, 22 Oct 2025 08:33:04 +0200
+Subject: leds: leds-lp50xx: LP5009 supports 3 modules for a total of 9 LEDs
+
+From: Christian Hitz <christian.hitz@bbv.ch>
+
+commit 5246e3673eeeccb4f5bf4f42375dd495d465ac15 upstream.
+
+LP5009 supports 9 LED outputs that are grouped into 3 modules.
+
+Cc: stable@vger.kernel.org
+Fixes: 242b81170fb8 ("leds: lp50xx: Add the LP50XX family of the RGB LED driver")
+Signed-off-by: Christian Hitz <christian.hitz@bbv.ch>
+Link: https://patch.msgid.link/20251022063305.972190-1-christian@klarinett.li
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/leds/leds-lp50xx.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/leds/leds-lp50xx.c
++++ b/drivers/leds/leds-lp50xx.c
+@@ -56,7 +56,7 @@
+ /* There are 3 LED outputs per bank */
+ #define LP50XX_LEDS_PER_MODULE        3
+-#define LP5009_MAX_LED_MODULES        2
++#define LP5009_MAX_LED_MODULES        3
+ #define LP5012_MAX_LED_MODULES        4
+ #define LP5018_MAX_LED_MODULES        6
+ #define LP5024_MAX_LED_MODULES        8
diff --git a/queue-6.12/media-rc-st_rc-fix-reset-control-resource-leak.patch b/queue-6.12/media-rc-st_rc-fix-reset-control-resource-leak.patch
new file mode 100644 (file)
index 0000000..9b061e9
--- /dev/null
@@ -0,0 +1,39 @@
+From 1240abf4b71f632f0117b056e22488e4d9808938 Mon Sep 17 00:00:00 2001
+From: Haotian Zhang <vulab@iscas.ac.cn>
+Date: Fri, 31 Oct 2025 14:03:32 +0800
+Subject: media: rc: st_rc: Fix reset control resource leak
+
+From: Haotian Zhang <vulab@iscas.ac.cn>
+
+commit 1240abf4b71f632f0117b056e22488e4d9808938 upstream.
+
+The driver calls reset_control_get_optional_exclusive() but never calls
+reset_control_put() in error paths or in the remove function. This causes
+a resource leak when probe fails after successfully acquiring the reset
+control, or when the driver is unloaded.
+
+Switch to devm_reset_control_get_optional_exclusive() to automatically
+manage the reset control resource.
+
+Fixes: a4b80242d046 ("media: st-rc: explicitly request exclusive reset control")
+Cc: stable@vger.kernel.org
+Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
+Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/media/rc/st_rc.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/media/rc/st_rc.c
++++ b/drivers/media/rc/st_rc.c
+@@ -284,7 +284,7 @@ static int st_rc_probe(struct platform_d
+       else
+               rc_dev->rx_base = rc_dev->base;
+-      rc_dev->rstc = reset_control_get_optional_exclusive(dev, NULL);
++      rc_dev->rstc = devm_reset_control_get_optional_exclusive(dev, NULL);
+       if (IS_ERR(rc_dev->rstc)) {
+               ret = PTR_ERR(rc_dev->rstc);
+               goto err;
diff --git a/queue-6.12/media-verisilicon-fix-cpu-stalls-on-g2-bus-error.patch b/queue-6.12/media-verisilicon-fix-cpu-stalls-on-g2-bus-error.patch
new file mode 100644 (file)
index 0000000..c3128ba
--- /dev/null
@@ -0,0 +1,235 @@
+From 19c286b755072a22a063052f530a6b1fac8a1f63 Mon Sep 17 00:00:00 2001
+From: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Date: Mon, 22 Sep 2025 14:43:38 -0400
+Subject: media: verisilicon: Fix CPU stalls on G2 bus error
+
+From: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+
+commit 19c286b755072a22a063052f530a6b1fac8a1f63 upstream.
+
+In some seek stress tests, we are getting IRQ from the G2 decoder where
+the dec_bus_int and the dec_e bits are high, meaning the decoder is
+still running despite the error.
+
+Fix this by reworking the IRQ handler to only finish the job once we
+have reached completion and move the software reset to when our software
+watchdog triggers.
+
+This way, we let the hardware continue on errors when it did not self
+reset and in worse case scenario the hardware timeout will
+automatically stop it. The actual error will be fixed in a follow up
+patch.
+
+Fixes: 3385c514ecc5a ("media: hantro: Convert imx8m_vpu_g2_irq to helper")
+Cc: stable@vger.kernel.org
+Reviewed-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/media/platform/verisilicon/hantro_g2.c          |   84 ++++++++++++----
+ drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c |    2 
+ drivers/media/platform/verisilicon/hantro_g2_regs.h     |   13 ++
+ drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c  |    2 
+ drivers/media/platform/verisilicon/hantro_hw.h          |    1 
+ drivers/media/platform/verisilicon/imx8m_vpu_hw.c       |    2 
+ 6 files changed, 83 insertions(+), 21 deletions(-)
+
+--- a/drivers/media/platform/verisilicon/hantro_g2.c
++++ b/drivers/media/platform/verisilicon/hantro_g2.c
+@@ -5,43 +5,93 @@
+  * Copyright (C) 2021 Collabora Ltd, Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+  */
++#include <linux/delay.h>
+ #include "hantro_hw.h"
+ #include "hantro_g2_regs.h"
+ #define G2_ALIGN      16
+-void hantro_g2_check_idle(struct hantro_dev *vpu)
++static bool hantro_g2_active(struct hantro_ctx *ctx)
+ {
+-      int i;
++      struct hantro_dev *vpu = ctx->dev;
++      u32 status;
++
++      status = vdpu_read(vpu, G2_REG_INTERRUPT);
++
++      return (status & G2_REG_INTERRUPT_DEC_E);
++}
+-      for (i = 0; i < 3; i++) {
+-              u32 status;
++/**
++ * hantro_g2_reset:
++ * @ctx: the hantro context
++ *
++ * Emulates a reset using Hantro abort function. Failing this procedure would
++ * results in programming a running IP which leads to CPU hang.
++ *
++ * Using a hard reset procedure instead is prefferred.
++ */
++void hantro_g2_reset(struct hantro_ctx *ctx)
++{
++      struct hantro_dev *vpu = ctx->dev;
++      u32 status;
+-              /* Make sure the VPU is idle */
+-              status = vdpu_read(vpu, G2_REG_INTERRUPT);
+-              if (status & G2_REG_INTERRUPT_DEC_E) {
+-                      dev_warn(vpu->dev, "device still running, aborting");
+-                      status |= G2_REG_INTERRUPT_DEC_ABORT_E | G2_REG_INTERRUPT_DEC_IRQ_DIS;
+-                      vdpu_write(vpu, status, G2_REG_INTERRUPT);
+-              }
++      status = vdpu_read(vpu, G2_REG_INTERRUPT);
++      if (status & G2_REG_INTERRUPT_DEC_E) {
++              dev_warn_ratelimited(vpu->dev, "device still running, aborting");
++              status |= G2_REG_INTERRUPT_DEC_ABORT_E | G2_REG_INTERRUPT_DEC_IRQ_DIS;
++              vdpu_write(vpu, status, G2_REG_INTERRUPT);
++
++              do {
++                      mdelay(1);
++              } while (hantro_g2_active(ctx));
+       }
+ }
+ irqreturn_t hantro_g2_irq(int irq, void *dev_id)
+ {
+       struct hantro_dev *vpu = dev_id;
+-      enum vb2_buffer_state state;
+       u32 status;
+       status = vdpu_read(vpu, G2_REG_INTERRUPT);
+-      state = (status & G2_REG_INTERRUPT_DEC_RDY_INT) ?
+-               VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
+-      vdpu_write(vpu, 0, G2_REG_INTERRUPT);
+-      vdpu_write(vpu, G2_REG_CONFIG_DEC_CLK_GATE_E, G2_REG_CONFIG);
++      if (!(status & G2_REG_INTERRUPT_DEC_IRQ))
++              return IRQ_NONE;
++
++      hantro_reg_write(vpu, &g2_dec_irq, 0);
++      hantro_reg_write(vpu, &g2_dec_int_stat, 0);
++      hantro_reg_write(vpu, &g2_clk_gate_e, 1);
++
++      if (status & G2_REG_INTERRUPT_DEC_RDY_INT) {
++              hantro_irq_done(vpu, VB2_BUF_STATE_DONE);
++              return IRQ_HANDLED;
++      }
++
++      if (status & G2_REG_INTERRUPT_DEC_ABORT_INT) {
++              /* disabled on abort, though lets be safe and handle it */
++              dev_warn_ratelimited(vpu->dev, "decode operation aborted.");
++              return IRQ_HANDLED;
++      }
++
++      if (status & G2_REG_INTERRUPT_DEC_LAST_SLICE_INT)
++              dev_warn_ratelimited(vpu->dev, "not all macroblocks were decoded.");
++
++      if (status & G2_REG_INTERRUPT_DEC_BUS_INT)
++              dev_warn_ratelimited(vpu->dev, "bus error detected.");
++
++      if (status & G2_REG_INTERRUPT_DEC_ERROR_INT)
++              dev_warn_ratelimited(vpu->dev, "decode error detected.");
+-      hantro_irq_done(vpu, state);
++      if (status & G2_REG_INTERRUPT_DEC_TIMEOUT)
++              dev_warn_ratelimited(vpu->dev, "frame decode timed out.");
++
++      /**
++       * If the decoding haven't stopped, let it continue. The hardware timeout
++       * will trigger if it is trully stuck.
++       */
++      if (status & G2_REG_INTERRUPT_DEC_E)
++              return IRQ_HANDLED;
++      hantro_irq_done(vpu, VB2_BUF_STATE_ERROR);
+       return IRQ_HANDLED;
+ }
+--- a/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c
++++ b/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c
+@@ -582,8 +582,6 @@ int hantro_g2_hevc_dec_run(struct hantro
+       struct hantro_dev *vpu = ctx->dev;
+       int ret;
+-      hantro_g2_check_idle(vpu);
+-
+       /* Prepare HEVC decoder context. */
+       ret = hantro_hevc_dec_prepare_run(ctx);
+       if (ret)
+--- a/drivers/media/platform/verisilicon/hantro_g2_regs.h
++++ b/drivers/media/platform/verisilicon/hantro_g2_regs.h
+@@ -22,7 +22,14 @@
+ #define G2_REG_VERSION                        G2_SWREG(0)
+ #define G2_REG_INTERRUPT              G2_SWREG(1)
++#define G2_REG_INTERRUPT_DEC_LAST_SLICE_INT   BIT(19)
++#define G2_REG_INTERRUPT_DEC_TIMEOUT  BIT(18)
++#define G2_REG_INTERRUPT_DEC_ERROR_INT        BIT(16)
++#define G2_REG_INTERRUPT_DEC_BUF_INT  BIT(14)
++#define G2_REG_INTERRUPT_DEC_BUS_INT  BIT(13)
+ #define G2_REG_INTERRUPT_DEC_RDY_INT  BIT(12)
++#define G2_REG_INTERRUPT_DEC_ABORT_INT        BIT(11)
++#define G2_REG_INTERRUPT_DEC_IRQ      BIT(8)
+ #define G2_REG_INTERRUPT_DEC_ABORT_E  BIT(5)
+ #define G2_REG_INTERRUPT_DEC_IRQ_DIS  BIT(4)
+ #define G2_REG_INTERRUPT_DEC_E                BIT(0)
+@@ -35,6 +42,9 @@
+ #define BUS_WIDTH_128                 2
+ #define BUS_WIDTH_256                 3
++#define g2_dec_int_stat               G2_DEC_REG(1, 11, 0xf)
++#define g2_dec_irq            G2_DEC_REG(1, 8, 0x1)
++
+ #define g2_strm_swap          G2_DEC_REG(2, 28, 0xf)
+ #define g2_strm_swap_old      G2_DEC_REG(2, 27, 0x1f)
+ #define g2_pic_swap           G2_DEC_REG(2, 22, 0x1f)
+@@ -225,6 +235,9 @@
+ #define vp9_filt_level_seg5   G2_DEC_REG(19,  8, 0x3f)
+ #define vp9_quant_seg5                G2_DEC_REG(19,  0, 0xff)
++#define g2_timemout_override_e        G2_DEC_REG(45, 31, 0x1)
++#define g2_timemout_cycles    G2_DEC_REG(45, 0, 0x7fffffff)
++
+ #define hevc_cur_poc_00               G2_DEC_REG(46, 24, 0xff)
+ #define hevc_cur_poc_01               G2_DEC_REG(46, 16, 0xff)
+ #define hevc_cur_poc_02               G2_DEC_REG(46, 8,  0xff)
+--- a/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c
++++ b/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c
+@@ -893,8 +893,6 @@ int hantro_g2_vp9_dec_run(struct hantro_
+       struct vb2_v4l2_buffer *dst;
+       int ret;
+-      hantro_g2_check_idle(ctx->dev);
+-
+       ret = start_prepare_run(ctx, &decode_params);
+       if (ret) {
+               hantro_end_prepare_run(ctx);
+--- a/drivers/media/platform/verisilicon/hantro_hw.h
++++ b/drivers/media/platform/verisilicon/hantro_hw.h
+@@ -583,6 +583,7 @@ void hantro_g2_vp9_dec_done(struct hantr
+ int hantro_vp9_dec_init(struct hantro_ctx *ctx);
+ void hantro_vp9_dec_exit(struct hantro_ctx *ctx);
+ void hantro_g2_check_idle(struct hantro_dev *vpu);
++void hantro_g2_reset(struct hantro_ctx *ctx);
+ irqreturn_t hantro_g2_irq(int irq, void *dev_id);
+ #endif /* HANTRO_HW_H_ */
+--- a/drivers/media/platform/verisilicon/imx8m_vpu_hw.c
++++ b/drivers/media/platform/verisilicon/imx8m_vpu_hw.c
+@@ -312,11 +312,13 @@ static const struct hantro_codec_ops imx
+ static const struct hantro_codec_ops imx8mq_vpu_g2_codec_ops[] = {
+       [HANTRO_MODE_HEVC_DEC] = {
+               .run = hantro_g2_hevc_dec_run,
++              .reset = hantro_g2_reset,
+               .init = hantro_hevc_dec_init,
+               .exit = hantro_hevc_dec_exit,
+       },
+       [HANTRO_MODE_VP9_DEC] = {
+               .run = hantro_g2_vp9_dec_run,
++              .reset = hantro_g2_reset,
+               .done = hantro_g2_vp9_dec_done,
+               .init = hantro_vp9_dec_init,
+               .exit = hantro_vp9_dec_exit,
diff --git a/queue-6.12/mfd-altera-sysmgr-fix-device-leak-on-sysmgr-regmap-lookup.patch b/queue-6.12/mfd-altera-sysmgr-fix-device-leak-on-sysmgr-regmap-lookup.patch
new file mode 100644 (file)
index 0000000..33c52a0
--- /dev/null
@@ -0,0 +1,35 @@
+From ccb7cd3218e48665f3c7e19eede0da5f069c323d Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 25 Sep 2025 17:02:19 +0200
+Subject: mfd: altera-sysmgr: Fix device leak on sysmgr regmap lookup
+
+From: Johan Hovold <johan@kernel.org>
+
+commit ccb7cd3218e48665f3c7e19eede0da5f069c323d upstream.
+
+Make sure to drop the reference taken to the sysmgr platform device when
+retrieving its driver data.
+
+Note that holding a reference to a device does not prevent its driver
+data from going away.
+
+Fixes: f36e789a1f8d ("mfd: altera-sysmgr: Add SOCFPGA System Manager")
+Cc: stable@vger.kernel.org     # 5.2
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mfd/altera-sysmgr.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/mfd/altera-sysmgr.c
++++ b/drivers/mfd/altera-sysmgr.c
+@@ -117,6 +117,8 @@ struct regmap *altr_sysmgr_regmap_lookup
+       sysmgr = dev_get_drvdata(dev);
++      put_device(dev);
++
+       return sysmgr->regmap;
+ }
+ EXPORT_SYMBOL_GPL(altr_sysmgr_regmap_lookup_by_phandle);
diff --git a/queue-6.12/mfd-max77620-fix-potential-irq-chip-conflict-when-probing-two-devices.patch b/queue-6.12/mfd-max77620-fix-potential-irq-chip-conflict-when-probing-two-devices.patch
new file mode 100644 (file)
index 0000000..5765234
--- /dev/null
@@ -0,0 +1,81 @@
+From 2bac49bad1f3553cc3b3bfb22cc194e9bd9e8427 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Thu, 23 Oct 2025 12:19:40 +0200
+Subject: mfd: max77620: Fix potential IRQ chip conflict when probing two devices
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+commit 2bac49bad1f3553cc3b3bfb22cc194e9bd9e8427 upstream.
+
+MAX77620 is most likely always a single device on the board, however
+nothing stops board designers to have two of them, thus same device
+driver could probe twice. Or user could manually try to probing second
+time.
+
+Device driver is not ready for that case, because it allocates
+statically 'struct regmap_irq_chip' as non-const and stores during
+probe in 'irq_drv_data' member a pointer to per-probe state
+container ('struct max77620_chip').  devm_regmap_add_irq_chip() does not
+make a copy of 'struct regmap_irq_chip' but store the pointer.
+
+Second probe - either successful or failure - would overwrite the
+'irq_drv_data' from previous device probe, so interrupts would be
+executed in a wrong context.
+
+Cc: stable@vger.kernel.org
+Fixes: 3df140d11c6d ("mfd: max77620: Mask/unmask interrupt before/after servicing it")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://patch.msgid.link/20251023101939.67991-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mfd/max77620.c |   15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/drivers/mfd/max77620.c
++++ b/drivers/mfd/max77620.c
+@@ -253,7 +253,7 @@ static int max77620_irq_global_unmask(vo
+       return ret;
+ }
+-static struct regmap_irq_chip max77620_top_irq_chip = {
++static const struct regmap_irq_chip max77620_top_irq_chip = {
+       .name = "max77620-top",
+       .irqs = max77620_top_irqs,
+       .num_irqs = ARRAY_SIZE(max77620_top_irqs),
+@@ -497,6 +497,7 @@ static int max77620_probe(struct i2c_cli
+       const struct i2c_device_id *id = i2c_client_get_device_id(client);
+       const struct regmap_config *rmap_config;
+       struct max77620_chip *chip;
++      struct regmap_irq_chip *chip_desc;
+       const struct mfd_cell *mfd_cells;
+       int n_mfd_cells;
+       bool pm_off;
+@@ -507,6 +508,14 @@ static int max77620_probe(struct i2c_cli
+               return -ENOMEM;
+       i2c_set_clientdata(client, chip);
++
++      chip_desc = devm_kmemdup(&client->dev, &max77620_top_irq_chip,
++                               sizeof(max77620_top_irq_chip),
++                               GFP_KERNEL);
++      if (!chip_desc)
++              return -ENOMEM;
++      chip_desc->irq_drv_data = chip;
++
+       chip->dev = &client->dev;
+       chip->chip_irq = client->irq;
+       chip->chip_id = (enum max77620_chip_id)id->driver_data;
+@@ -543,11 +552,9 @@ static int max77620_probe(struct i2c_cli
+       if (ret < 0)
+               return ret;
+-      max77620_top_irq_chip.irq_drv_data = chip;
+       ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq,
+                                      IRQF_ONESHOT | IRQF_SHARED, 0,
+-                                     &max77620_top_irq_chip,
+-                                     &chip->top_irq_data);
++                                     chip_desc, &chip->top_irq_data);
+       if (ret < 0) {
+               dev_err(chip->dev, "Failed to add regmap irq: %d\n", ret);
+               return ret;
diff --git a/queue-6.12/pci-pm-reinstate-clearing-state_saved-in-legacy-and-pm-codepaths.patch b/queue-6.12/pci-pm-reinstate-clearing-state_saved-in-legacy-and-pm-codepaths.patch
new file mode 100644 (file)
index 0000000..1218495
--- /dev/null
@@ -0,0 +1,88 @@
+From 894f475f88e06c0f352c829849560790dbdedbe5 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Wed, 19 Nov 2025 09:50:01 +0100
+Subject: PCI/PM: Reinstate clearing state_saved in legacy and !PM codepaths
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 894f475f88e06c0f352c829849560790dbdedbe5 upstream.
+
+When a PCI device is suspended, it is normally the PCI core's job to save
+Config Space and put the device into a low power state.  However drivers
+are allowed to assume these responsibilities.  When they do, the PCI core
+can tell by looking at the state_saved flag in struct pci_dev:  The flag
+is cleared before commencing the suspend sequence and it is set when
+pci_save_state() is called.  If the PCI core finds the flag set late in
+the suspend sequence, it refrains from calling pci_save_state() itself.
+
+But there are two corner cases where the PCI core neglects to clear the
+flag before commencing the suspend sequence:
+
+* If a driver has legacy PCI PM callbacks, pci_legacy_suspend() neglects
+  to clear the flag.  The (stale) flag is subsequently queried by
+  pci_legacy_suspend() itself and pci_legacy_suspend_late().
+
+* If a device has no driver or its driver has no PCI PM callbacks,
+  pci_pm_freeze() neglects to clear the flag.  The (stale) flag is
+  subsequently queried by pci_pm_freeze_noirq().
+
+The flag may be set prior to suspend if the device went through error
+recovery:  Drivers commonly invoke pci_restore_state() + pci_save_state()
+to restore Config Space after reset.
+
+The flag may also be set if drivers call pci_save_state() on probe to
+allow for recovery from subsequent errors.
+
+The result is that pci_legacy_suspend_late() and pci_pm_freeze_noirq()
+don't call pci_save_state() and so the state that will be restored on
+resume is the one recorded on last error recovery or on probe, not the one
+that the device had on suspend.  If the two states happen to be identical,
+there's no problem.
+
+Reinstate clearing the flag in pci_legacy_suspend() and pci_pm_freeze().
+The two functions used to do that until commit 4b77b0a2ba27 ("PCI: Clear
+saved_state after the state has been restored") deemed it unnecessary
+because it assumed that it's sufficient to clear the flag on resume in
+pci_restore_state().  The commit seemingly did not take into account that
+pci_save_state() and pci_restore_state() are not only used by power
+management code, but also for error recovery.
+
+Devices without driver or whose driver has no PCI PM callbacks may be in
+runtime suspend when pci_pm_freeze() is called.  Their state has already
+been saved, so don't clear the flag to skip a pointless pci_save_state()
+in pci_pm_freeze_noirq().
+
+None of the drivers with legacy PCI PM callbacks seem to use runtime PM,
+so clear the flag unconditionally in their case.
+
+Fixes: 4b77b0a2ba27 ("PCI: Clear saved_state after the state has been restored")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>
+Cc: stable@vger.kernel.org # v2.6.32+
+Link: https://patch.msgid.link/094f2aad64418710daf0940112abe5a0afdc6bce.1763483367.git.lukas@wunner.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/pci-driver.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/pci/pci-driver.c
++++ b/drivers/pci/pci-driver.c
+@@ -635,6 +635,8 @@ static int pci_legacy_suspend(struct dev
+       struct pci_dev *pci_dev = to_pci_dev(dev);
+       struct pci_driver *drv = pci_dev->driver;
++      pci_dev->state_saved = false;
++
+       if (drv && drv->suspend) {
+               pci_power_t prev = pci_dev->current_state;
+               int error;
+@@ -1039,6 +1041,8 @@ static int pci_pm_freeze(struct device *
+       if (!pm) {
+               pci_pm_default_suspend(pci_dev);
++              if (!pm_runtime_suspended(dev))
++                      pci_dev->state_saved = false;
+               return 0;
+       }
diff --git a/queue-6.12/powerpc-64s-slb-fix-slb-multihit-issue-during-slb-preload.patch b/queue-6.12/powerpc-64s-slb-fix-slb-multihit-issue-during-slb-preload.patch
new file mode 100644 (file)
index 0000000..edbb5c3
--- /dev/null
@@ -0,0 +1,323 @@
+From 00312419f0863964625d6dcda8183f96849412c6 Mon Sep 17 00:00:00 2001
+From: Donet Tom <donettom@linux.ibm.com>
+Date: Thu, 30 Oct 2025 20:27:26 +0530
+Subject: powerpc/64s/slb: Fix SLB multihit issue during SLB preload
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Donet Tom <donettom@linux.ibm.com>
+
+commit 00312419f0863964625d6dcda8183f96849412c6 upstream.
+
+On systems using the hash MMU, there is a software SLB preload cache that
+mirrors the entries loaded into the hardware SLB buffer. This preload
+cache is subject to periodic eviction — typically after every 256 context
+switches — to remove old entry.
+
+To optimize performance, the kernel skips switch_mmu_context() in
+switch_mm_irqs_off() when the prev and next mm_struct are the same.
+However, on hash MMU systems, this can lead to inconsistencies between
+the hardware SLB and the software preload cache.
+
+If an SLB entry for a process is evicted from the software cache on one
+CPU, and the same process later runs on another CPU without executing
+switch_mmu_context(), the hardware SLB may retain stale entries. If the
+kernel then attempts to reload that entry, it can trigger an SLB
+multi-hit error.
+
+The following timeline shows how stale SLB entries are created and can
+cause a multi-hit error when a process moves between CPUs without a
+MMU context switch.
+
+CPU 0                                   CPU 1
+-----                                    -----
+Process P
+exec                                    swapper/1
+ load_elf_binary
+  begin_new_exc
+    activate_mm
+     switch_mm_irqs_off
+      switch_mmu_context
+       switch_slb
+       /*
+        * This invalidates all
+        * the entries in the HW
+        * and setup the new HW
+        * SLB entries as per the
+        * preload cache.
+        */
+context_switch
+sched_migrate_task migrates process P to cpu-1
+
+Process swapper/0                       context switch (to process P)
+(uses mm_struct of Process P)           switch_mm_irqs_off()
+                                         switch_slb
+                                           load_slb++
+                                            /*
+                                            * load_slb becomes 0 here
+                                            * and we evict an entry from
+                                            * the preload cache with
+                                            * preload_age(). We still
+                                            * keep HW SLB and preload
+                                            * cache in sync, that is
+                                            * because all HW SLB entries
+                                            * anyways gets evicted in
+                                            * switch_slb during SLBIA.
+                                            * We then only add those
+                                            * entries back in HW SLB,
+                                            * which are currently
+                                            * present in preload_cache
+                                            * (after eviction).
+                                            */
+                                        load_elf_binary continues...
+                                         setup_new_exec()
+                                          slb_setup_new_exec()
+
+                                        sched_switch event
+                                        sched_migrate_task migrates
+                                        process P to cpu-0
+
+context_switch from swapper/0 to Process P
+ switch_mm_irqs_off()
+  /*
+   * Since both prev and next mm struct are same we don't call
+   * switch_mmu_context(). This will cause the HW SLB and SW preload
+   * cache to go out of sync in preload_new_slb_context. Because there
+   * was an SLB entry which was evicted from both HW and preload cache
+   * on cpu-1. Now later in preload_new_slb_context(), when we will try
+   * to add the same preload entry again, we will add this to the SW
+   * preload cache and then will add it to the HW SLB. Since on cpu-0
+   * this entry was never invalidated, hence adding this entry to the HW
+   * SLB will cause a SLB multi-hit error.
+   */
+load_elf_binary continues...
+ START_THREAD
+  start_thread
+   preload_new_slb_context
+   /*
+    * This tries to add a new EA to preload cache which was earlier
+    * evicted from both cpu-1 HW SLB and preload cache. This caused the
+    * HW SLB of cpu-0 to go out of sync with the SW preload cache. The
+    * reason for this was, that when we context switched back on CPU-0,
+    * we should have ideally called switch_mmu_context() which will
+    * bring the HW SLB entries on CPU-0 in sync with SW preload cache
+    * entries by setting up the mmu context properly. But we didn't do
+    * that since the prev mm_struct running on cpu-0 was same as the
+    * next mm_struct (which is true for swapper / kernel threads). So
+    * now when we try to add this new entry into the HW SLB of cpu-0,
+    * we hit a SLB multi-hit error.
+    */
+
+WARNING: CPU: 0 PID: 1810970 at arch/powerpc/mm/book3s64/slb.c:62
+assert_slb_presence+0x2c/0x50(48 results) 02:47:29 [20157/42149]
+Modules linked in:
+CPU: 0 UID: 0 PID: 1810970 Comm: dd Not tainted 6.16.0-rc3-dirty #12
+VOLUNTARY
+Hardware name: IBM pSeries (emulated by qemu) POWER8 (architected)
+0x4d0200 0xf000004 of:SLOF,HEAD hv:linux,kvm pSeries
+NIP:  c00000000015426c LR: c0000000001543b4 CTR: 0000000000000000
+REGS: c0000000497c77e0 TRAP: 0700   Not tainted  (6.16.0-rc3-dirty)
+MSR:  8000000002823033 <SF,VEC,VSX,FP,ME,IR,DR,RI,LE>  CR: 28888482  XER: 00000000
+CFAR: c0000000001543b0 IRQMASK: 3
+<...>
+NIP [c00000000015426c] assert_slb_presence+0x2c/0x50
+LR [c0000000001543b4] slb_insert_entry+0x124/0x390
+Call Trace:
+  0x7fffceb5ffff (unreliable)
+  preload_new_slb_context+0x100/0x1a0
+  start_thread+0x26c/0x420
+  load_elf_binary+0x1b04/0x1c40
+  bprm_execve+0x358/0x680
+  do_execveat_common+0x1f8/0x240
+  sys_execve+0x58/0x70
+  system_call_exception+0x114/0x300
+  system_call_common+0x160/0x2c4
+
+>From the above analysis, during early exec the hardware SLB is cleared,
+and entries from the software preload cache are reloaded into hardware
+by switch_slb. However, preload_new_slb_context and slb_setup_new_exec
+also attempt to load some of the same entries, which can trigger a
+multi-hit. In most cases, these additional preloads simply hit existing
+entries and add nothing new. Removing these functions avoids redundant
+preloads and eliminates the multi-hit issue. This patch removes these
+two functions.
+
+We tested process switching performance using the context_switch
+benchmark on POWER9/hash, and observed no regression.
+
+Without this patch: 129041 ops/sec
+With this patch:    129341 ops/sec
+
+We also measured SLB faults during boot, and the counts are essentially
+the same with and without this patch.
+
+SLB faults without this patch: 19727
+SLB faults with this patch:    19786
+
+Fixes: 5434ae74629a ("powerpc/64s/hash: Add a SLB preload cache")
+cc: stable@vger.kernel.org
+Suggested-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Donet Tom <donettom@linux.ibm.com>
+Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/0ac694ae683494fe8cadbd911a1a5018d5d3c541.1761834163.git.ritesh.list@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/include/asm/book3s/64/mmu-hash.h |    1 
+ arch/powerpc/kernel/process.c                 |    5 -
+ arch/powerpc/mm/book3s64/internal.h           |    2 
+ arch/powerpc/mm/book3s64/mmu_context.c        |    2 
+ arch/powerpc/mm/book3s64/slb.c                |   88 --------------------------
+ 5 files changed, 98 deletions(-)
+
+--- a/arch/powerpc/include/asm/book3s/64/mmu-hash.h
++++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h
+@@ -524,7 +524,6 @@ void slb_save_contents(struct slb_entry
+ void slb_dump_contents(struct slb_entry *slb_ptr);
+ extern void slb_vmalloc_update(void);
+-void preload_new_slb_context(unsigned long start, unsigned long sp);
+ #ifdef CONFIG_PPC_64S_HASH_MMU
+ void slb_set_size(u16 size);
+--- a/arch/powerpc/kernel/process.c
++++ b/arch/powerpc/kernel/process.c
+@@ -1897,8 +1897,6 @@ int copy_thread(struct task_struct *p, c
+       return 0;
+ }
+-void preload_new_slb_context(unsigned long start, unsigned long sp);
+-
+ /*
+  * Set up a thread for executing a new program
+  */
+@@ -1906,9 +1904,6 @@ void start_thread(struct pt_regs *regs,
+ {
+ #ifdef CONFIG_PPC64
+       unsigned long load_addr = regs->gpr[2]; /* saved by ELF_PLAT_INIT */
+-
+-      if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !radix_enabled())
+-              preload_new_slb_context(start, sp);
+ #endif
+ #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+--- a/arch/powerpc/mm/book3s64/internal.h
++++ b/arch/powerpc/mm/book3s64/internal.h
+@@ -24,8 +24,6 @@ static inline bool stress_hpt(void)
+ void hpt_do_stress(unsigned long ea, unsigned long hpte_group);
+-void slb_setup_new_exec(void);
+-
+ void exit_lazy_flush_tlb(struct mm_struct *mm, bool always_flush);
+ #endif /* ARCH_POWERPC_MM_BOOK3S64_INTERNAL_H */
+--- a/arch/powerpc/mm/book3s64/mmu_context.c
++++ b/arch/powerpc/mm/book3s64/mmu_context.c
+@@ -150,8 +150,6 @@ static int hash__init_new_context(struct
+ void hash__setup_new_exec(void)
+ {
+       slice_setup_new_exec();
+-
+-      slb_setup_new_exec();
+ }
+ #else
+ static inline int hash__init_new_context(struct mm_struct *mm)
+--- a/arch/powerpc/mm/book3s64/slb.c
++++ b/arch/powerpc/mm/book3s64/slb.c
+@@ -328,94 +328,6 @@ static void preload_age(struct thread_in
+       ti->slb_preload_tail = (ti->slb_preload_tail + 1) % SLB_PRELOAD_NR;
+ }
+-void slb_setup_new_exec(void)
+-{
+-      struct thread_info *ti = current_thread_info();
+-      struct mm_struct *mm = current->mm;
+-      unsigned long exec = 0x10000000;
+-
+-      WARN_ON(irqs_disabled());
+-
+-      /*
+-       * preload cache can only be used to determine whether a SLB
+-       * entry exists if it does not start to overflow.
+-       */
+-      if (ti->slb_preload_nr + 2 > SLB_PRELOAD_NR)
+-              return;
+-
+-      hard_irq_disable();
+-
+-      /*
+-       * We have no good place to clear the slb preload cache on exec,
+-       * flush_thread is about the earliest arch hook but that happens
+-       * after we switch to the mm and have already preloaded the SLBEs.
+-       *
+-       * For the most part that's probably okay to use entries from the
+-       * previous exec, they will age out if unused. It may turn out to
+-       * be an advantage to clear the cache before switching to it,
+-       * however.
+-       */
+-
+-      /*
+-       * preload some userspace segments into the SLB.
+-       * Almost all 32 and 64bit PowerPC executables are linked at
+-       * 0x10000000 so it makes sense to preload this segment.
+-       */
+-      if (!is_kernel_addr(exec)) {
+-              if (preload_add(ti, exec))
+-                      slb_allocate_user(mm, exec);
+-      }
+-
+-      /* Libraries and mmaps. */
+-      if (!is_kernel_addr(mm->mmap_base)) {
+-              if (preload_add(ti, mm->mmap_base))
+-                      slb_allocate_user(mm, mm->mmap_base);
+-      }
+-
+-      /* see switch_slb */
+-      asm volatile("isync" : : : "memory");
+-
+-      local_irq_enable();
+-}
+-
+-void preload_new_slb_context(unsigned long start, unsigned long sp)
+-{
+-      struct thread_info *ti = current_thread_info();
+-      struct mm_struct *mm = current->mm;
+-      unsigned long heap = mm->start_brk;
+-
+-      WARN_ON(irqs_disabled());
+-
+-      /* see above */
+-      if (ti->slb_preload_nr + 3 > SLB_PRELOAD_NR)
+-              return;
+-
+-      hard_irq_disable();
+-
+-      /* Userspace entry address. */
+-      if (!is_kernel_addr(start)) {
+-              if (preload_add(ti, start))
+-                      slb_allocate_user(mm, start);
+-      }
+-
+-      /* Top of stack, grows down. */
+-      if (!is_kernel_addr(sp)) {
+-              if (preload_add(ti, sp))
+-                      slb_allocate_user(mm, sp);
+-      }
+-
+-      /* Bottom of heap, grows up. */
+-      if (heap && !is_kernel_addr(heap)) {
+-              if (preload_add(ti, heap))
+-                      slb_allocate_user(mm, heap);
+-      }
+-
+-      /* see switch_slb */
+-      asm volatile("isync" : : : "memory");
+-
+-      local_irq_enable();
+-}
+-
+ static void slb_cache_slbie_kernel(unsigned int index)
+ {
+       unsigned long slbie_data = get_paca()->slb_cache[index];
diff --git a/queue-6.12/powerpc-mm-fix-mprotect-on-book3s-32-bit.patch b/queue-6.12/powerpc-mm-fix-mprotect-on-book3s-32-bit.patch
new file mode 100644 (file)
index 0000000..e5473d1
--- /dev/null
@@ -0,0 +1,75 @@
+From 78fc63ffa7813e33681839bb33826c24195f0eb7 Mon Sep 17 00:00:00 2001
+From: Dave Vasilevsky <dave@vasilevsky.ca>
+Date: Sun, 16 Nov 2025 01:40:46 -0500
+Subject: powerpc, mm: Fix mprotect on book3s 32-bit
+
+From: Dave Vasilevsky <dave@vasilevsky.ca>
+
+commit 78fc63ffa7813e33681839bb33826c24195f0eb7 upstream.
+
+On 32-bit book3s with hash-MMUs, tlb_flush() was a no-op. This was
+unnoticed because all uses until recently were for unmaps, and thus
+handled by __tlb_remove_tlb_entry().
+
+After commit 4a18419f71cd ("mm/mprotect: use mmu_gather") in kernel 5.19,
+tlb_gather_mmu() started being used for mprotect as well. This caused
+mprotect to simply not work on these machines:
+
+  int *ptr = mmap(NULL, 4096, PROT_READ|PROT_WRITE,
+                  MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+  *ptr = 1; // force HPTE to be created
+  mprotect(ptr, 4096, PROT_READ);
+  *ptr = 2; // should segfault, but succeeds
+
+Fixed by making tlb_flush() actually flush TLB pages. This finally
+agrees with the behaviour of boot3s64's tlb_flush().
+
+Fixes: 4a18419f71cd ("mm/mprotect: use mmu_gather")
+Cc: stable@vger.kernel.org
+Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
+Signed-off-by: Dave Vasilevsky <dave@vasilevsky.ca>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20251116-vasi-mprotect-g3-v3-1-59a9bd33ba00@vasilevsky.ca
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/include/asm/book3s/32/tlbflush.h |    5 ++++-
+ arch/powerpc/mm/book3s32/tlb.c                |    9 +++++++++
+ 2 files changed, 13 insertions(+), 1 deletion(-)
+
+--- a/arch/powerpc/include/asm/book3s/32/tlbflush.h
++++ b/arch/powerpc/include/asm/book3s/32/tlbflush.h
+@@ -11,6 +11,7 @@
+ void hash__flush_tlb_mm(struct mm_struct *mm);
+ void hash__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
+ void hash__flush_range(struct mm_struct *mm, unsigned long start, unsigned long end);
++void hash__flush_gather(struct mmu_gather *tlb);
+ #ifdef CONFIG_SMP
+ void _tlbie(unsigned long address);
+@@ -29,7 +30,9 @@ void _tlbia(void);
+ static inline void tlb_flush(struct mmu_gather *tlb)
+ {
+       /* 603 needs to flush the whole TLB here since it doesn't use a hash table. */
+-      if (!mmu_has_feature(MMU_FTR_HPTE_TABLE))
++      if (mmu_has_feature(MMU_FTR_HPTE_TABLE))
++              hash__flush_gather(tlb);
++      else
+               _tlbia();
+ }
+--- a/arch/powerpc/mm/book3s32/tlb.c
++++ b/arch/powerpc/mm/book3s32/tlb.c
+@@ -105,3 +105,12 @@ void hash__flush_tlb_page(struct vm_area
+               flush_hash_pages(mm->context.id, vmaddr, pmd_val(*pmd), 1);
+ }
+ EXPORT_SYMBOL(hash__flush_tlb_page);
++
++void hash__flush_gather(struct mmu_gather *tlb)
++{
++      if (tlb->fullmm || tlb->need_flush_all)
++              hash__flush_tlb_mm(tlb->mm);
++      else
++              hash__flush_range(tlb->mm, tlb->start, tlb->end);
++}
++EXPORT_SYMBOL(hash__flush_gather);
index 426bb2f0fedcb3102bff6ce166944c5f18b50026..d0dd2d1358e9492ab9027e04baa14b5252670913 100644 (file)
@@ -365,3 +365,19 @@ iommu-sun50i-fix-device-leak-on-of_xlate.patch
 iommu-tegra-fix-device-leak-on-probe_device.patch
 iommu-disable-sva-when-config_x86-is-set.patch
 hid-logitech-dj-remove-duplicate-error-logging.patch
+fgraph-initialize-ftrace_ops-private-for-function-graph-ops.patch
+fgraph-check-ftrace_pids_enabled-on-registration-for-early-filtering.patch
+pci-pm-reinstate-clearing-state_saved-in-legacy-and-pm-codepaths.patch
+arm64-dts-ti-k3-j721e-sk-fix-pinmux-for-pin-y1-used-by-power-regulator.patch
+powerpc-mm-fix-mprotect-on-book3s-32-bit.patch
+powerpc-64s-slb-fix-slb-multihit-issue-during-slb-preload.patch
+leds-leds-cros_ec-skip-leds-without-color-components.patch
+leds-leds-lp50xx-allow-led-0-to-be-added-to-module-bank.patch
+leds-leds-lp50xx-lp5009-supports-3-modules-for-a-total-of-9-leds.patch
+leds-leds-lp50xx-enable-chip-before-any-communication.patch
+block-clear-blk_zone_wplug_plugged-when-aborting-plugged-bios.patch
+clk-samsung-exynos-clkout-assign-.num-before-accessing-.hws.patch
+mfd-altera-sysmgr-fix-device-leak-on-sysmgr-regmap-lookup.patch
+mfd-max77620-fix-potential-irq-chip-conflict-when-probing-two-devices.patch
+media-rc-st_rc-fix-reset-control-resource-leak.patch
+media-verisilicon-fix-cpu-stalls-on-g2-bus-error.patch