]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 11 Sep 2023 06:58:03 +0000 (08:58 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 11 Sep 2023 06:58:03 +0000 (08:58 +0200)
added patches:
clk-mark-a-fwnode-as-initialized-when-using-clk_of_declare-macro.patch
md-fix-regression-for-null-ptr-deference-in-__md_stop.patch
treewide-fix-probing-of-devices-in-dt-overlays.patch

queue-6.1/clk-mark-a-fwnode-as-initialized-when-using-clk_of_declare-macro.patch [new file with mode: 0644]
queue-6.1/md-fix-regression-for-null-ptr-deference-in-__md_stop.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/treewide-fix-probing-of-devices-in-dt-overlays.patch [new file with mode: 0644]

diff --git a/queue-6.1/clk-mark-a-fwnode-as-initialized-when-using-clk_of_declare-macro.patch b/queue-6.1/clk-mark-a-fwnode-as-initialized-when-using-clk_of_declare-macro.patch
new file mode 100644 (file)
index 0000000..700447a
--- /dev/null
@@ -0,0 +1,82 @@
+From c28cd1f3433c7e339315d1ddacaeacf0fdfbe252 Mon Sep 17 00:00:00 2001
+From: Saravana Kannan <saravanak@google.com>
+Date: Wed, 1 Mar 2023 17:46:38 -0800
+Subject: clk: Mark a fwnode as initialized when using CLK_OF_DECLARE() macro
+
+From: Saravana Kannan <saravanak@google.com>
+
+commit c28cd1f3433c7e339315d1ddacaeacf0fdfbe252 upstream.
+
+We already mark fwnodes as initialized when they are registered as clock
+providers. We do this so that fw_devlink can tell when a clock driver
+doesn't use the driver core framework to probe/initialize its device.
+This ensures fw_devlink doesn't block the consumers of such a clock
+provider indefinitely.
+
+However, some users of CLK_OF_DECLARE() macros don't use the same node
+that matches the macro as the node for the clock provider, but they
+initialize the entire node. To cover these cases, also mark the nodes
+that match the macros as initialized when the init callback function is
+called.
+
+An example of this is "stericsson,u8500-clks" that's handled using
+CLK_OF_DECLARE() and looks something like this:
+
+clocks {
+       compatible = "stericsson,u8500-clks";
+
+       prcmu_clk: prcmu-clock {
+               #clock-cells = <1>;
+       };
+
+       prcc_pclk: prcc-periph-clock {
+               #clock-cells = <2>;
+       };
+
+       prcc_kclk: prcc-kernel-clock {
+               #clock-cells = <2>;
+       };
+
+       prcc_reset: prcc-reset-controller {
+               #reset-cells = <2>;
+       };
+       ...
+};
+
+This patch makes sure that "clocks" is marked as initialized so that
+fw_devlink knows that all nodes under it have been initialized. If the
+driver creates struct devices for some of the subnodes, fw_devlink is
+smart enough to know to wait for those devices to probe, so no special
+handling is required for those cases.
+
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Reported-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/lkml/CACRpkdamxDX6EBVjKX5=D3rkHp17f5pwGdBVhzFU90-0MHY6dQ@mail.gmail.com/
+Fixes: 4a032827daa8 ("of: property: Simplify of_link_to_phandle()")
+Signed-off-by: Saravana Kannan <saravanak@google.com>
+Link: https://lore.kernel.org/r/20230302014639.297514-1-saravanak@google.com
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Tested-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/clk-provider.h |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/include/linux/clk-provider.h
++++ b/include/linux/clk-provider.h
+@@ -1361,7 +1361,13 @@ struct clk_hw_onecell_data {
+       struct clk_hw *hws[];
+ };
+-#define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn)
++#define CLK_OF_DECLARE(name, compat, fn) \
++      static void __init name##_of_clk_init_declare(struct device_node *np) \
++      {                                                               \
++              fn(np);                                                 \
++              fwnode_dev_initialized(of_fwnode_handle(np), true);     \
++      }                                                               \
++      OF_DECLARE_1(clk, name, compat, name##_of_clk_init_declare)
+ /*
+  * Use this macro when you have a driver that requires two initialization
diff --git a/queue-6.1/md-fix-regression-for-null-ptr-deference-in-__md_stop.patch b/queue-6.1/md-fix-regression-for-null-ptr-deference-in-__md_stop.patch
new file mode 100644 (file)
index 0000000..ca3f3b8
--- /dev/null
@@ -0,0 +1,108 @@
+From 433279beba1d4872da10b7b60a539e0cb828b32b Mon Sep 17 00:00:00 2001
+From: Yu Kuai <yukuai3@huawei.com>
+Date: Tue, 28 Mar 2023 17:44:00 +0800
+Subject: md: fix regression for null-ptr-deference in __md_stop()
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+commit 433279beba1d4872da10b7b60a539e0cb828b32b upstream.
+
+Commit 3e453522593d ("md: Free resources in __md_stop") tried to fix
+null-ptr-deference for 'active_io' by moving percpu_ref_exit() to
+__md_stop(), however, the commit also moving 'writes_pending' to
+__md_stop(), and this will cause mdadm tests broken:
+
+BUG: kernel NULL pointer dereference, address: 0000000000000038
+Oops: 0000 [#1] PREEMPT SMP
+CPU: 15 PID: 17830 Comm: mdadm Not tainted 6.3.0-rc3-next-20230324-00009-g520d37
+RIP: 0010:free_percpu+0x465/0x670
+Call Trace:
+ <TASK>
+ __percpu_ref_exit+0x48/0x70
+ percpu_ref_exit+0x1a/0x90
+ __md_stop+0xe9/0x170
+ do_md_stop+0x1e1/0x7b0
+ md_ioctl+0x90c/0x1aa0
+ blkdev_ioctl+0x19b/0x400
+ vfs_ioctl+0x20/0x50
+ __x64_sys_ioctl+0xba/0xe0
+ do_syscall_64+0x6c/0xe0
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+And the problem can be reporduced 100% by following test:
+
+mdadm -CR /dev/md0 -l1 -n1 /dev/sda --force
+echo inactive > /sys/block/md0/md/array_state
+echo read-auto  > /sys/block/md0/md/array_state
+echo inactive > /sys/block/md0/md/array_state
+
+Root cause:
+
+// start raid
+raid1_run
+ mddev_init_writes_pending
+  percpu_ref_init
+
+// inactive raid
+array_state_store
+ do_md_stop
+  __md_stop
+   percpu_ref_exit
+
+// start raid again
+array_state_store
+ do_md_run
+  raid1_run
+   mddev_init_writes_pending
+    if (mddev->writes_pending.percpu_count_ptr)
+    // won't reinit
+
+// inactive raid again
+...
+percpu_ref_exit
+-> null-ptr-deference
+
+Before the commit, 'writes_pending' is exited when mddev is freed, and
+it's safe to restart raid because mddev_init_writes_pending() already make
+sure that 'writes_pending' will only be initialized once.
+
+Fix the prblem by moving 'writes_pending' back, it's a litter hard to find
+the relationship between alloc memory and free memory, however, code
+changes is much less and we lived with this for a long time already.
+
+Fixes: 3e453522593d ("md: Free resources in __md_stop")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Reviewed-by: Xiao Ni <xni@redhat.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20230328094400.1448955-1-yukuai1@huaweicloud.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/md/md.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -6278,7 +6278,6 @@ static void __md_stop(struct mddev *mdde
+       module_put(pers->owner);
+       clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+-      percpu_ref_exit(&mddev->writes_pending);
+       percpu_ref_exit(&mddev->active_io);
+       bioset_exit(&mddev->bio_set);
+       bioset_exit(&mddev->sync_set);
+@@ -6293,6 +6292,7 @@ void md_stop(struct mddev *mddev)
+        */
+       __md_stop_writes(mddev);
+       __md_stop(mddev);
++      percpu_ref_exit(&mddev->writes_pending);
+ }
+ EXPORT_SYMBOL_GPL(md_stop);
+@@ -7859,6 +7859,7 @@ static void md_free_disk(struct gendisk
+ {
+       struct mddev *mddev = disk->private_data;
++      percpu_ref_exit(&mddev->writes_pending);
+       mddev_free(mddev);
+ }
index 841853851465e2bda27898c89c003def262ba033..7903dd804bae8ebd9a3e3182a12b2222ff39fd8d 100644 (file)
@@ -594,3 +594,6 @@ revert-drm-amd-display-do-not-set-drr-on-pipe-commit.patch
 md-free-resources-in-__md_stop.patch
 nfsv4.2-fix-a-potential-double-free-with-read_plus.patch
 nfsv4.2-rework-scratch-handling-for-read_plus-again.patch
+md-fix-regression-for-null-ptr-deference-in-__md_stop.patch
+clk-mark-a-fwnode-as-initialized-when-using-clk_of_declare-macro.patch
+treewide-fix-probing-of-devices-in-dt-overlays.patch
diff --git a/queue-6.1/treewide-fix-probing-of-devices-in-dt-overlays.patch b/queue-6.1/treewide-fix-probing-of-devices-in-dt-overlays.patch
new file mode 100644 (file)
index 0000000..f7fe6a4
--- /dev/null
@@ -0,0 +1,125 @@
+From 1a50d9403fb90cbe4dea0ec9fd0351d2ecbd8924 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Thu, 30 Mar 2023 15:26:13 +0200
+Subject: treewide: Fix probing of devices in DT overlays
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+commit 1a50d9403fb90cbe4dea0ec9fd0351d2ecbd8924 upstream.
+
+When loading a DT overlay that creates a device, the device is not
+probed, unless the DT overlay is unloaded and reloaded again.
+
+After the recent refactoring to improve fw_devlink, it no longer depends
+on the "compatible" property to identify which device tree nodes will
+become struct devices.   fw_devlink now picks up dangling consumers
+(consumers pointing to descendent device tree nodes of a device that
+aren't converted to child devices) when a device is successfully bound
+to a driver.  See __fw_devlink_pickup_dangling_consumers().
+
+However, during DT overlay, a device's device tree node can have
+sub-nodes added/removed without unbinding/rebinding the driver.  This
+difference in behavior between the normal device instantiation and
+probing flow vs. the DT overlay flow has a bunch of implications that
+are pointed out elsewhere[1].  One of them is that the fw_devlink logic
+to pick up dangling consumers is never exercised.
+
+This patch solves the fw_devlink issue by marking all DT nodes added by
+DT overlays with FWNODE_FLAG_NOT_DEVICE (fwnode that won't become
+device), and by clearing the flag when a struct device is actually
+created for the DT node.  This way, fw_devlink knows not to have
+consumers waiting on these newly added DT nodes, and to propagate the
+dependency to an ancestor DT node that has the corresponding struct
+device.
+
+Based on a patch by Saravana Kannan, which covered only platform and spi
+devices.
+
+[1] https://lore.kernel.org/r/CAGETcx_bkuFaLCiPrAWCPQz+w79ccDp6=9e881qmK=vx3hBMyg@mail.gmail.com
+
+Fixes: 4a032827daa89350 ("of: property: Simplify of_link_to_phandle()")
+Link: https://lore.kernel.org/r/CAGETcx_+rhHvaC_HJXGrr5_WAd2+k5f=rWYnkCZ6z5bGX-wj4w@mail.gmail.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Acked-by: Mark Brown <broonie@kernel.org>
+Acked-by: Wolfram Sang <wsa@kernel.org> # for I2C
+Acked-by: Shawn Guo <shawnguo@kernel.org>
+Acked-by: Saravana Kannan <saravanak@google.com>
+Tested-by: Ivan Bornyakov <i.bornyakov@metrotek.ru>
+Link: https://lore.kernel.org/r/e1fa546682ea4c8474ff997ab6244c5e11b6f8bc.1680182615.git.geert+renesas@glider.be
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bus/imx-weim.c    |    6 ++++++
+ drivers/i2c/i2c-core-of.c |    5 +++++
+ drivers/of/dynamic.c      |    1 +
+ drivers/of/platform.c     |    5 +++++
+ drivers/spi/spi.c         |    5 +++++
+ 5 files changed, 22 insertions(+)
+
+--- a/drivers/bus/imx-weim.c
++++ b/drivers/bus/imx-weim.c
+@@ -331,6 +331,12 @@ static int of_weim_notify(struct notifie
+                                "Failed to setup timing for '%pOF'\n", rd->dn);
+               if (!of_node_check_flag(rd->dn, OF_POPULATED)) {
++                      /*
++                       * Clear the flag before adding the device so that
++                       * fw_devlink doesn't skip adding consumers to this
++                       * device.
++                       */
++                      rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
+                       if (!of_platform_device_create(rd->dn, NULL, &pdev->dev)) {
+                               dev_err(&pdev->dev,
+                                       "Failed to create child device '%pOF'\n",
+--- a/drivers/i2c/i2c-core-of.c
++++ b/drivers/i2c/i2c-core-of.c
+@@ -244,6 +244,11 @@ static int of_i2c_notify(struct notifier
+                       return NOTIFY_OK;
+               }
++              /*
++               * Clear the flag before adding the device so that fw_devlink
++               * doesn't skip adding consumers to this device.
++               */
++              rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
+               client = of_i2c_register_device(adap, rd->dn);
+               if (IS_ERR(client)) {
+                       dev_err(&adap->dev, "failed to create client for '%pOF'\n",
+--- a/drivers/of/dynamic.c
++++ b/drivers/of/dynamic.c
+@@ -225,6 +225,7 @@ static void __of_attach_node(struct devi
+       np->sibling = np->parent->child;
+       np->parent->child = np;
+       of_node_clear_flag(np, OF_DETACHED);
++      np->fwnode.flags |= FWNODE_FLAG_NOT_DEVICE;
+ }
+ /**
+--- a/drivers/of/platform.c
++++ b/drivers/of/platform.c
+@@ -741,6 +741,11 @@ static int of_platform_notify(struct not
+               if (of_node_check_flag(rd->dn, OF_POPULATED))
+                       return NOTIFY_OK;
++              /*
++               * Clear the flag before adding the device so that fw_devlink
++               * doesn't skip adding consumers to this device.
++               */
++              rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
+               /* pdev_parent may be NULL when no bus platform device */
+               pdev_parent = of_find_device_by_node(rd->dn->parent);
+               pdev = of_platform_device_create(rd->dn, NULL,
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -4370,6 +4370,11 @@ static int of_spi_notify(struct notifier
+                       return NOTIFY_OK;
+               }
++              /*
++               * Clear the flag before adding the device so that fw_devlink
++               * doesn't skip adding consumers to this device.
++               */
++              rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
+               spi = of_register_spi_device(ctlr, rd->dn);
+               put_device(&ctlr->dev);