]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.14
authorSasha Levin <sashal@kernel.org>
Wed, 7 May 2025 15:36:14 +0000 (11:36 -0400)
committerSasha Levin <sashal@kernel.org>
Wed, 7 May 2025 15:36:14 +0000 (11:36 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
18 files changed:
queue-6.14/arm-dts-opos6ul-add-ksz8081-phy-properties.patch [new file with mode: 0644]
queue-6.14/arm64-dts-imx95-correct-the-range-of-pcie-app-reg-re.patch [new file with mode: 0644]
queue-6.14/arm64-dts-st-adjust-interrupt-controller-for-stm32mp.patch [new file with mode: 0644]
queue-6.14/arm64-dts-st-use-128kb-size-for-aliased-gic400-regis.patch [new file with mode: 0644]
queue-6.14/block-introduce-zone-capacity-helper.patch [new file with mode: 0644]
queue-6.14/btrfs-expose-per-inode-stable-writes-flag.patch [new file with mode: 0644]
queue-6.14/btrfs-fix-the-inode-leak-in-btrfs_iget.patch [new file with mode: 0644]
queue-6.14/btrfs-pass-struct-btrfs_inode-to-btrfs_iget_locked.patch [new file with mode: 0644]
queue-6.14/btrfs-pass-struct-btrfs_inode-to-btrfs_read_locked_i.patch [new file with mode: 0644]
queue-6.14/btrfs-zoned-skip-reporting-zone-for-new-block-group.patch [new file with mode: 0644]
queue-6.14/drivers-base-handle-module_kobject-creation.patch [new file with mode: 0644]
queue-6.14/drm-amd-display-add-scoped-mutexes-for-amdgpu_dm_dhc.patch [new file with mode: 0644]
queue-6.14/drm-amd-display-fix-slab-use-after-free-in-hdcp.patch [new file with mode: 0644]
queue-6.14/firmware-arm_ffa-skip-rx-buffer-ownership-release-if.patch [new file with mode: 0644]
queue-6.14/firmware-arm_scmi-balance-device-refcount-when-destr.patch [new file with mode: 0644]
queue-6.14/kernel-globalize-lookup_or_create_module_kobject.patch [new file with mode: 0644]
queue-6.14/kernel-param-rename-locate_module_kobject.patch [new file with mode: 0644]
queue-6.14/series

diff --git a/queue-6.14/arm-dts-opos6ul-add-ksz8081-phy-properties.patch b/queue-6.14/arm-dts-opos6ul-add-ksz8081-phy-properties.patch
new file mode 100644 (file)
index 0000000..9ff8792
--- /dev/null
@@ -0,0 +1,44 @@
+From f4464e5f3e0d79713175050d62ee2c431234cad2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 17:20:38 +0100
+Subject: ARM: dts: opos6ul: add ksz8081 phy properties
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sébastien Szymanski <sebastien.szymanski@armadeus.com>
+
+[ Upstream commit 6e1a7bc8382b0d4208258f7d2a4474fae788dd90 ]
+
+Commit c7e73b5051d6 ("ARM: imx: mach-imx6ul: remove 14x14 EVK specific
+PHY fixup") removed a PHY fixup that setted the clock mode and the LED
+mode.
+Make the Ethernet interface work again by doing as advised in the
+commit's log, set clock mode and the LED mode in the device tree.
+
+Fixes: c7e73b5051d6 ("ARM: imx: mach-imx6ul: remove 14x14 EVK specific PHY fixup")
+Signed-off-by: Sébastien Szymanski <sebastien.szymanski@armadeus.com>
+Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6ul.dtsi | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6ul.dtsi
+index f2386dcb9ff2c..dda4fa91b2f2c 100644
+--- a/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6ul.dtsi
++++ b/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6ul.dtsi
+@@ -40,6 +40,9 @@
+                       reg = <1>;
+                       interrupt-parent = <&gpio4>;
+                       interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
++                      micrel,led-mode = <1>;
++                      clocks = <&clks IMX6UL_CLK_ENET_REF>;
++                      clock-names = "rmii-ref";
+                       status = "okay";
+               };
+       };
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-imx95-correct-the-range-of-pcie-app-reg-re.patch b/queue-6.14/arm64-dts-imx95-correct-the-range-of-pcie-app-reg-re.patch
new file mode 100644 (file)
index 0000000..8f73134
--- /dev/null
@@ -0,0 +1,64 @@
+From d3e4f6b078703c08c5ac9d5966b50de6fbf1d2b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 14:01:04 +0800
+Subject: arm64: dts: imx95: Correct the range of PCIe app-reg region
+
+From: Richard Zhu <hongxing.zhu@nxp.com>
+
+[ Upstream commit 02e4232998db357bb8199778722d81ffcff0cb98 ]
+
+Correct the range of PCIe app-reg region from 0x2000 to 0x4000 refer to
+SerDes_SS memory map of i.MX95 Rerference Manual.
+
+Fixes: 3b1d5deb29ff ("arm64: dts: imx95: add pcie[0,1] and pcie-ep[0,1] support")
+Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx95.dtsi | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
+index 6b8470cb3461a..0e6a9e639d769 100644
+--- a/arch/arm64/boot/dts/freescale/imx95.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
+@@ -1542,7 +1542,7 @@
+                       reg = <0 0x4c300000 0 0x10000>,
+                             <0 0x60100000 0 0xfe00000>,
+                             <0 0x4c360000 0 0x10000>,
+-                            <0 0x4c340000 0 0x2000>;
++                            <0 0x4c340000 0 0x4000>;
+                       reg-names = "dbi", "config", "atu", "app";
+                       ranges = <0x81000000 0x0 0x00000000 0x0 0x6ff00000 0 0x00100000>,
+                                <0x82000000 0x0 0x10000000 0x9 0x10000000 0 0x10000000>;
+@@ -1582,7 +1582,7 @@
+                       reg = <0 0x4c300000 0 0x10000>,
+                             <0 0x4c360000 0 0x1000>,
+                             <0 0x4c320000 0 0x1000>,
+-                            <0 0x4c340000 0 0x2000>,
++                            <0 0x4c340000 0 0x4000>,
+                             <0 0x4c370000 0 0x10000>,
+                             <0x9 0 1 0>;
+                       reg-names = "dbi","atu", "dbi2", "app", "dma", "addr_space";
+@@ -1609,7 +1609,7 @@
+                       reg = <0 0x4c380000 0 0x10000>,
+                             <8 0x80100000 0 0xfe00000>,
+                             <0 0x4c3e0000 0 0x10000>,
+-                            <0 0x4c3c0000 0 0x2000>;
++                            <0 0x4c3c0000 0 0x4000>;
+                       reg-names = "dbi", "config", "atu", "app";
+                       ranges = <0x81000000 0 0x00000000 0x8 0x8ff00000 0 0x00100000>,
+                                <0x82000000 0 0x10000000 0xa 0x10000000 0 0x10000000>;
+@@ -1649,7 +1649,7 @@
+                       reg = <0 0x4c380000 0 0x10000>,
+                             <0 0x4c3e0000 0 0x1000>,
+                             <0 0x4c3a0000 0 0x1000>,
+-                            <0 0x4c3c0000 0 0x2000>,
++                            <0 0x4c3c0000 0 0x4000>,
+                             <0 0x4c3f0000 0 0x10000>,
+                             <0xa 0 1 0>;
+                       reg-names = "dbi", "atu", "dbi2", "app", "dma", "addr_space";
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-st-adjust-interrupt-controller-for-stm32mp.patch b/queue-6.14/arm64-dts-st-adjust-interrupt-controller-for-stm32mp.patch
new file mode 100644 (file)
index 0000000..3602eca
--- /dev/null
@@ -0,0 +1,39 @@
+From 4a45c9da5b544275cebdb94dbe5e54de2c1c01ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 14:06:58 +0200
+Subject: arm64: dts: st: Adjust interrupt-controller for stm32mp25 SoCs
+
+From: Christian Bruel <christian.bruel@foss.st.com>
+
+[ Upstream commit de2b2107d5a41a91ab603e135fb6e408abbee28e ]
+
+Use gic-400 compatible and remove address-cells = <1> on aarch64
+
+Fixes: 5d30d03aaf785 ("arm64: dts: st: introduce stm32mp25 SoCs family")
+Signed-off-by: Christian Bruel <christian.bruel@foss.st.com>
+Link: https://lore.kernel.org/r/20250415111654.2103767-2-christian.bruel@foss.st.com
+Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/st/stm32mp251.dtsi | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
+index f3c6cdfd7008c..379e290313dc0 100644
+--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
++++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
+@@ -115,9 +115,8 @@
+       };
+       intc: interrupt-controller@4ac00000 {
+-              compatible = "arm,cortex-a7-gic";
++              compatible = "arm,gic-400";
+               #interrupt-cells = <3>;
+-              #address-cells = <1>;
+               interrupt-controller;
+               reg = <0x0 0x4ac10000 0x0 0x1000>,
+                     <0x0 0x4ac20000 0x0 0x2000>,
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-st-use-128kb-size-for-aliased-gic400-regis.patch b/queue-6.14/arm64-dts-st-use-128kb-size-for-aliased-gic400-regis.patch
new file mode 100644 (file)
index 0000000..c3ac755
--- /dev/null
@@ -0,0 +1,48 @@
+From 601e9de9e5078b6823a4ce554116a482680f92f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 14:06:59 +0200
+Subject: arm64: dts: st: Use 128kB size for aliased GIC400 register access on
+ stm32mp25 SoCs
+
+From: Christian Bruel <christian.bruel@foss.st.com>
+
+[ Upstream commit 06c231fe953a26f4bc9d7a37ba1b9b288a59c7c2 ]
+
+Adjust the size of 8kB GIC regions to 128kB so that each 4kB is mapped 16
+times over a 64kB region.
+The offset is then adjusted in the irq-gic driver.
+
+see commit 12e14066f4835 ("irqchip/GIC: Add workaround for aliased GIC400")
+
+Fixes: 5d30d03aaf785 ("arm64: dts: st: introduce stm32mp25 SoCs family")
+Suggested-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Christian Bruel <christian.bruel@foss.st.com>
+Acked-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20250415111654.2103767-3-christian.bruel@foss.st.com
+Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/st/stm32mp251.dtsi | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
+index 379e290313dc0..87110f91e4895 100644
+--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
++++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
+@@ -119,9 +119,9 @@
+               #interrupt-cells = <3>;
+               interrupt-controller;
+               reg = <0x0 0x4ac10000 0x0 0x1000>,
+-                    <0x0 0x4ac20000 0x0 0x2000>,
+-                    <0x0 0x4ac40000 0x0 0x2000>,
+-                    <0x0 0x4ac60000 0x0 0x2000>;
++                    <0x0 0x4ac20000 0x0 0x20000>,
++                    <0x0 0x4ac40000 0x0 0x20000>,
++                    <0x0 0x4ac60000 0x0 0x20000>;
+       };
+       psci {
+-- 
+2.39.5
+
diff --git a/queue-6.14/block-introduce-zone-capacity-helper.patch b/queue-6.14/block-introduce-zone-capacity-helper.patch
new file mode 100644 (file)
index 0000000..d17a708
--- /dev/null
@@ -0,0 +1,121 @@
+From f8b08d67d9cf4f4bdef0e3e71b16f8418ad5a794 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Mar 2025 10:49:16 +0900
+Subject: block: introduce zone capacity helper
+
+From: Naohiro Aota <naohiro.aota@wdc.com>
+
+[ Upstream commit c1a79b1a583654f24b17da81ba868b0064077243 ]
+
+{bdev,disk}_zone_capacity() takes block_device or gendisk and sector position
+and returns the zone capacity of the corresponding zone.
+
+With that, move disk_nr_zones() and blk_zone_plug_bio() to consolidate them in
+the same #ifdef block.
+
+Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: 866bafae59ec ("btrfs: zoned: skip reporting zone for new block group")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/blkdev.h | 67 ++++++++++++++++++++++++++++--------------
+ 1 file changed, 45 insertions(+), 22 deletions(-)
+
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 6aa67e9b2ec08..0fec27d6b986c 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -691,23 +691,6 @@ static inline bool blk_queue_is_zoned(struct request_queue *q)
+               (q->limits.features & BLK_FEAT_ZONED);
+ }
+-#ifdef CONFIG_BLK_DEV_ZONED
+-static inline unsigned int disk_nr_zones(struct gendisk *disk)
+-{
+-      return disk->nr_zones;
+-}
+-bool blk_zone_plug_bio(struct bio *bio, unsigned int nr_segs);
+-#else /* CONFIG_BLK_DEV_ZONED */
+-static inline unsigned int disk_nr_zones(struct gendisk *disk)
+-{
+-      return 0;
+-}
+-static inline bool blk_zone_plug_bio(struct bio *bio, unsigned int nr_segs)
+-{
+-      return false;
+-}
+-#endif /* CONFIG_BLK_DEV_ZONED */
+-
+ static inline unsigned int disk_zone_no(struct gendisk *disk, sector_t sector)
+ {
+       if (!blk_queue_is_zoned(disk->queue))
+@@ -715,11 +698,6 @@ static inline unsigned int disk_zone_no(struct gendisk *disk, sector_t sector)
+       return sector >> ilog2(disk->queue->limits.chunk_sectors);
+ }
+-static inline unsigned int bdev_nr_zones(struct block_device *bdev)
+-{
+-      return disk_nr_zones(bdev->bd_disk);
+-}
+-
+ static inline unsigned int bdev_max_open_zones(struct block_device *bdev)
+ {
+       return bdev->bd_disk->queue->limits.max_open_zones;
+@@ -826,6 +804,51 @@ static inline u64 sb_bdev_nr_blocks(struct super_block *sb)
+               (sb->s_blocksize_bits - SECTOR_SHIFT);
+ }
++#ifdef CONFIG_BLK_DEV_ZONED
++static inline unsigned int disk_nr_zones(struct gendisk *disk)
++{
++      return disk->nr_zones;
++}
++bool blk_zone_plug_bio(struct bio *bio, unsigned int nr_segs);
++
++/**
++ * disk_zone_capacity - returns the zone capacity of zone containing @sector
++ * @disk:     disk to work with
++ * @sector:   sector number within the querying zone
++ *
++ * Returns the zone capacity of a zone containing @sector. @sector can be any
++ * sector in the zone.
++ */
++static inline unsigned int disk_zone_capacity(struct gendisk *disk,
++                                            sector_t sector)
++{
++      sector_t zone_sectors = disk->queue->limits.chunk_sectors;
++
++      if (sector + zone_sectors >= get_capacity(disk))
++              return disk->last_zone_capacity;
++      return disk->zone_capacity;
++}
++static inline unsigned int bdev_zone_capacity(struct block_device *bdev,
++                                            sector_t pos)
++{
++      return disk_zone_capacity(bdev->bd_disk, pos);
++}
++#else /* CONFIG_BLK_DEV_ZONED */
++static inline unsigned int disk_nr_zones(struct gendisk *disk)
++{
++      return 0;
++}
++static inline bool blk_zone_plug_bio(struct bio *bio, unsigned int nr_segs)
++{
++      return false;
++}
++#endif /* CONFIG_BLK_DEV_ZONED */
++
++static inline unsigned int bdev_nr_zones(struct block_device *bdev)
++{
++      return disk_nr_zones(bdev->bd_disk);
++}
++
+ int bdev_disk_changed(struct gendisk *disk, bool invalidate);
+ void put_disk(struct gendisk *disk);
+-- 
+2.39.5
+
diff --git a/queue-6.14/btrfs-expose-per-inode-stable-writes-flag.patch b/queue-6.14/btrfs-expose-per-inode-stable-writes-flag.patch
new file mode 100644 (file)
index 0000000..15a5953
--- /dev/null
@@ -0,0 +1,114 @@
+From e794eaca7ec6f8d9187a23be8676bb438752639e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jan 2025 09:48:18 +1030
+Subject: btrfs: expose per-inode stable writes flag
+
+From: Qu Wenruo <wqu@suse.com>
+
+[ Upstream commit ecde48a1a6b3256bd49db8780bf37556b157783c ]
+
+The address space flag AS_STABLE_WRITES determine if FGP_STABLE for will
+wait for the folio to finish its writeback.
+
+For btrfs, due to the default data checksum behavior, if we modify the
+folio while it's still under writeback, it will cause data checksum
+mismatch.  Thus for quite some call sites we manually call
+folio_wait_writeback() to prevent such problem from happening.
+
+Currently there is only one call site inside btrfs really utilizing
+FGP_STABLE, and in that case we also manually call folio_wait_writeback()
+to do the waiting.
+
+But it's better to properly expose the stable writes flag to a per-inode
+basis, to allow call sites to fully benefit from FGP_STABLE flag.
+E.g. for inodes with NODATASUM allowing beginning dirtying the page
+without waiting for writeback.
+
+This involves:
+
+- Update the mapping's stable write flag when setting/clearing NODATASUM
+  inode flag using ioctl
+  This only works for empty files, so it should be fine.
+
+- Update the mapping's stable write flag when reading an inode from disk
+
+- Remove the explicit folio_wait_writeback() for FGP_BEGINWRITE call
+  site
+
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: 48c1d1bb525b ("btrfs: fix the inode leak in btrfs_iget()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/btrfs_inode.h | 8 ++++++++
+ fs/btrfs/file.c        | 1 -
+ fs/btrfs/inode.c       | 2 ++
+ fs/btrfs/ioctl.c       | 1 +
+ 4 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
+index b2fa33911c280..029fba82b81da 100644
+--- a/fs/btrfs/btrfs_inode.h
++++ b/fs/btrfs/btrfs_inode.h
+@@ -516,6 +516,14 @@ static inline void btrfs_assert_inode_locked(struct btrfs_inode *inode)
+       lockdep_assert_held(&inode->vfs_inode.i_rwsem);
+ }
++static inline void btrfs_update_inode_mapping_flags(struct btrfs_inode *inode)
++{
++      if (inode->flags & BTRFS_INODE_NODATASUM)
++              mapping_clear_stable_writes(inode->vfs_inode.i_mapping);
++      else
++              mapping_set_stable_writes(inode->vfs_inode.i_mapping);
++}
++
+ /* Array of bytes with variable length, hexadecimal format 0x1234 */
+ #define CSUM_FMT                              "0x%*phN"
+ #define CSUM_FMT_VALUE(size, bytes)           size, bytes
+diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
+index a92997a583bd2..cd4e40a719186 100644
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -874,7 +874,6 @@ static noinline int prepare_one_folio(struct inode *inode, struct folio **folio_
+                       ret = PTR_ERR(folio);
+               return ret;
+       }
+-      folio_wait_writeback(folio);
+       /* Only support page sized folio yet. */
+       ASSERT(folio_order(folio) == 0);
+       ret = set_folio_extent_mapped(folio);
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index 0db50d19b9a1f..90782fd9f37b8 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -3925,6 +3925,7 @@ static int btrfs_read_locked_inode(struct inode *inode, struct btrfs_path *path)
+       btrfs_inode_split_flags(btrfs_inode_flags(leaf, inode_item),
+                               &BTRFS_I(inode)->flags, &BTRFS_I(inode)->ro_flags);
++      btrfs_update_inode_mapping_flags(BTRFS_I(inode));
+ cache_index:
+       /*
+@@ -6340,6 +6341,7 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans,
+               if (btrfs_test_opt(fs_info, NODATACOW))
+                       BTRFS_I(inode)->flags |= BTRFS_INODE_NODATACOW |
+                               BTRFS_INODE_NODATASUM;
++              btrfs_update_inode_mapping_flags(BTRFS_I(inode));
+       }
+       ret = btrfs_insert_inode_locked(inode);
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index e666c141cae0b..10a97f0af8d4b 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -393,6 +393,7 @@ int btrfs_fileattr_set(struct mnt_idmap *idmap,
+ update_flags:
+       binode->flags = binode_flags;
++      btrfs_update_inode_mapping_flags(binode);
+       btrfs_sync_inode_flags_to_i_flags(inode);
+       inode_inc_iversion(inode);
+       inode_set_ctime_current(inode);
+-- 
+2.39.5
+
diff --git a/queue-6.14/btrfs-fix-the-inode-leak-in-btrfs_iget.patch b/queue-6.14/btrfs-fix-the-inode-leak-in-btrfs_iget.patch
new file mode 100644 (file)
index 0000000..3cdcc15
--- /dev/null
@@ -0,0 +1,86 @@
+From dd9d62bff68983147c4b1554f5cda5a12af4b852 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 08:40:29 -0700
+Subject: btrfs: fix the inode leak in btrfs_iget()
+
+From: Penglei Jiang <superman.xpt@gmail.com>
+
+[ Upstream commit 48c1d1bb525b1c44b8bdc8e7ec5629cb6c2b9fc4 ]
+
+[BUG]
+There is a bug report that a syzbot reproducer can lead to the following
+busy inode at unmount time:
+
+  BTRFS info (device loop1): last unmount of filesystem 1680000e-3c1e-4c46-84b6-56bd3909af50
+  VFS: Busy inodes after unmount of loop1 (btrfs)
+  ------------[ cut here ]------------
+  kernel BUG at fs/super.c:650!
+  Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
+  CPU: 0 UID: 0 PID: 48168 Comm: syz-executor Not tainted 6.15.0-rc2-00471-g119009db2674 #2 PREEMPT(full)
+  Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+  RIP: 0010:generic_shutdown_super+0x2e9/0x390 fs/super.c:650
+  Call Trace:
+   <TASK>
+   kill_anon_super+0x3a/0x60 fs/super.c:1237
+   btrfs_kill_super+0x3b/0x50 fs/btrfs/super.c:2099
+   deactivate_locked_super+0xbe/0x1a0 fs/super.c:473
+   deactivate_super fs/super.c:506 [inline]
+   deactivate_super+0xe2/0x100 fs/super.c:502
+   cleanup_mnt+0x21f/0x440 fs/namespace.c:1435
+   task_work_run+0x14d/0x240 kernel/task_work.c:227
+   resume_user_mode_work include/linux/resume_user_mode.h:50 [inline]
+   exit_to_user_mode_loop kernel/entry/common.c:114 [inline]
+   exit_to_user_mode_prepare include/linux/entry-common.h:329 [inline]
+   __syscall_exit_to_user_mode_work kernel/entry/common.c:207 [inline]
+   syscall_exit_to_user_mode+0x269/0x290 kernel/entry/common.c:218
+   do_syscall_64+0xd4/0x250 arch/x86/entry/syscall_64.c:100
+   entry_SYSCALL_64_after_hwframe+0x77/0x7f
+   </TASK>
+
+[CAUSE]
+When btrfs_alloc_path() failed, btrfs_iget() directly returned without
+releasing the inode already allocated by btrfs_iget_locked().
+
+This results the above busy inode and trigger the kernel BUG.
+
+[FIX]
+Fix it by calling iget_failed() if btrfs_alloc_path() failed.
+
+If we hit error inside btrfs_read_locked_inode(), it will properly call
+iget_failed(), so nothing to worry about.
+
+Although the iget_failed() cleanup inside btrfs_read_locked_inode() is a
+break of the normal error handling scheme, let's fix the obvious bug
+and backport first, then rework the error handling later.
+
+Reported-by: Penglei Jiang <superman.xpt@gmail.com>
+Link: https://lore.kernel.org/linux-btrfs/20250421102425.44431-1-superman.xpt@gmail.com/
+Fixes: 7c855e16ab72 ("btrfs: remove conditional path allocation in btrfs_read_locked_inode()")
+CC: stable@vger.kernel.org # 6.13+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Penglei Jiang <superman.xpt@gmail.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/inode.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index f6fc4c9ace28c..3be6f8e8e157d 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -5660,8 +5660,10 @@ struct inode *btrfs_iget(u64 ino, struct btrfs_root *root)
+               return &inode->vfs_inode;
+       path = btrfs_alloc_path();
+-      if (!path)
++      if (!path) {
++              iget_failed(&inode->vfs_inode);
+               return ERR_PTR(-ENOMEM);
++      }
+       ret = btrfs_read_locked_inode(inode, path);
+       btrfs_free_path(path);
+-- 
+2.39.5
+
diff --git a/queue-6.14/btrfs-pass-struct-btrfs_inode-to-btrfs_iget_locked.patch b/queue-6.14/btrfs-pass-struct-btrfs_inode-to-btrfs_iget_locked.patch
new file mode 100644 (file)
index 0000000..6ac2aee
--- /dev/null
@@ -0,0 +1,111 @@
+From f9103454ef09f4e95ec1f0667dc7c77f4f4283ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 22:36:17 +0100
+Subject: btrfs: pass struct btrfs_inode to btrfs_iget_locked()
+
+From: David Sterba <dsterba@suse.com>
+
+[ Upstream commit 4ea2fb9c628b55929bbc380d8c18733d1d027f1d ]
+
+Pass a struct btrfs_inode to btrfs_inode() as it's an internal
+interface, allowing to remove some use of BTRFS_I.
+
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: 48c1d1bb525b ("btrfs: fix the inode leak in btrfs_iget()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/inode.c | 30 ++++++++++++++++--------------
+ 1 file changed, 16 insertions(+), 14 deletions(-)
+
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index 6d9d1c255285d..f6fc4c9ace28c 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -5601,7 +5601,7 @@ static int btrfs_find_actor(struct inode *inode, void *opaque)
+               args->root == BTRFS_I(inode)->root;
+ }
+-static struct inode *btrfs_iget_locked(u64 ino, struct btrfs_root *root)
++static struct btrfs_inode *btrfs_iget_locked(u64 ino, struct btrfs_root *root)
+ {
+       struct inode *inode;
+       struct btrfs_iget_args args;
+@@ -5613,7 +5613,9 @@ static struct inode *btrfs_iget_locked(u64 ino, struct btrfs_root *root)
+       inode = iget5_locked_rcu(root->fs_info->sb, hashval, btrfs_find_actor,
+                            btrfs_init_locked_inode,
+                            (void *)&args);
+-      return inode;
++      if (!inode)
++              return NULL;
++      return BTRFS_I(inode);
+ }
+ /*
+@@ -5623,22 +5625,22 @@ static struct inode *btrfs_iget_locked(u64 ino, struct btrfs_root *root)
+ struct inode *btrfs_iget_path(u64 ino, struct btrfs_root *root,
+                             struct btrfs_path *path)
+ {
+-      struct inode *inode;
++      struct btrfs_inode *inode;
+       int ret;
+       inode = btrfs_iget_locked(ino, root);
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+-      if (!(inode->i_state & I_NEW))
+-              return inode;
++      if (!(inode->vfs_inode.i_state & I_NEW))
++              return &inode->vfs_inode;
+-      ret = btrfs_read_locked_inode(BTRFS_I(inode), path);
++      ret = btrfs_read_locked_inode(inode, path);
+       if (ret)
+               return ERR_PTR(ret);
+-      unlock_new_inode(inode);
+-      return inode;
++      unlock_new_inode(&inode->vfs_inode);
++      return &inode->vfs_inode;
+ }
+ /*
+@@ -5646,7 +5648,7 @@ struct inode *btrfs_iget_path(u64 ino, struct btrfs_root *root,
+  */
+ struct inode *btrfs_iget(u64 ino, struct btrfs_root *root)
+ {
+-      struct inode *inode;
++      struct btrfs_inode *inode;
+       struct btrfs_path *path;
+       int ret;
+@@ -5654,20 +5656,20 @@ struct inode *btrfs_iget(u64 ino, struct btrfs_root *root)
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+-      if (!(inode->i_state & I_NEW))
+-              return inode;
++      if (!(inode->vfs_inode.i_state & I_NEW))
++              return &inode->vfs_inode;
+       path = btrfs_alloc_path();
+       if (!path)
+               return ERR_PTR(-ENOMEM);
+-      ret = btrfs_read_locked_inode(BTRFS_I(inode), path);
++      ret = btrfs_read_locked_inode(inode, path);
+       btrfs_free_path(path);
+       if (ret)
+               return ERR_PTR(ret);
+-      unlock_new_inode(inode);
+-      return inode;
++      unlock_new_inode(&inode->vfs_inode);
++      return &inode->vfs_inode;
+ }
+ static struct inode *new_simple_dir(struct inode *dir,
+-- 
+2.39.5
+
diff --git a/queue-6.14/btrfs-pass-struct-btrfs_inode-to-btrfs_read_locked_i.patch b/queue-6.14/btrfs-pass-struct-btrfs_inode-to-btrfs_read_locked_i.patch
new file mode 100644 (file)
index 0000000..a27cda5
--- /dev/null
@@ -0,0 +1,274 @@
+From a061f07d7d2d1d29f10360ae9632f18e34456733 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 22:29:45 +0100
+Subject: btrfs: pass struct btrfs_inode to btrfs_read_locked_inode()
+
+From: David Sterba <dsterba@suse.com>
+
+[ Upstream commit d36f84a849c7685099594815a1e5a48db62c243d ]
+
+Pass a struct btrfs_inode to btrfs_read_locked_inode() as it's an
+internal interface, allowing to remove some use of BTRFS_I.
+
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: 48c1d1bb525b ("btrfs: fix the inode leak in btrfs_iget()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/inode.c | 119 +++++++++++++++++++++++------------------------
+ 1 file changed, 58 insertions(+), 61 deletions(-)
+
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index 90782fd9f37b8..6d9d1c255285d 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -3846,12 +3846,13 @@ static int btrfs_add_inode_to_root(struct btrfs_inode *inode, bool prealloc)
+  *
+  * On failure clean up the inode.
+  */
+-static int btrfs_read_locked_inode(struct inode *inode, struct btrfs_path *path)
++static int btrfs_read_locked_inode(struct btrfs_inode *inode, struct btrfs_path *path)
+ {
+-      struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
++      struct btrfs_root *root = inode->root;
++      struct btrfs_fs_info *fs_info = root->fs_info;
+       struct extent_buffer *leaf;
+       struct btrfs_inode_item *inode_item;
+-      struct btrfs_root *root = BTRFS_I(inode)->root;
++      struct inode *vfs_inode = &inode->vfs_inode;
+       struct btrfs_key location;
+       unsigned long ptr;
+       int maybe_acls;
+@@ -3860,17 +3861,17 @@ static int btrfs_read_locked_inode(struct inode *inode, struct btrfs_path *path)
+       bool filled = false;
+       int first_xattr_slot;
+-      ret = btrfs_init_file_extent_tree(BTRFS_I(inode));
++      ret = btrfs_init_file_extent_tree(inode);
+       if (ret)
+               goto out;
+-      ret = btrfs_fill_inode(inode, &rdev);
++      ret = btrfs_fill_inode(vfs_inode, &rdev);
+       if (!ret)
+               filled = true;
+       ASSERT(path);
+-      btrfs_get_inode_key(BTRFS_I(inode), &location);
++      btrfs_get_inode_key(inode, &location);
+       ret = btrfs_lookup_inode(NULL, root, path, &location, 0);
+       if (ret) {
+@@ -3890,42 +3891,41 @@ static int btrfs_read_locked_inode(struct inode *inode, struct btrfs_path *path)
+       inode_item = btrfs_item_ptr(leaf, path->slots[0],
+                                   struct btrfs_inode_item);
+-      inode->i_mode = btrfs_inode_mode(leaf, inode_item);
+-      set_nlink(inode, btrfs_inode_nlink(leaf, inode_item));
+-      i_uid_write(inode, btrfs_inode_uid(leaf, inode_item));
+-      i_gid_write(inode, btrfs_inode_gid(leaf, inode_item));
+-      btrfs_i_size_write(BTRFS_I(inode), btrfs_inode_size(leaf, inode_item));
+-      btrfs_inode_set_file_extent_range(BTRFS_I(inode), 0,
+-                      round_up(i_size_read(inode), fs_info->sectorsize));
+-
+-      inode_set_atime(inode, btrfs_timespec_sec(leaf, &inode_item->atime),
++      vfs_inode->i_mode = btrfs_inode_mode(leaf, inode_item);
++      set_nlink(vfs_inode, btrfs_inode_nlink(leaf, inode_item));
++      i_uid_write(vfs_inode, btrfs_inode_uid(leaf, inode_item));
++      i_gid_write(vfs_inode, btrfs_inode_gid(leaf, inode_item));
++      btrfs_i_size_write(inode, btrfs_inode_size(leaf, inode_item));
++      btrfs_inode_set_file_extent_range(inode, 0,
++                      round_up(i_size_read(vfs_inode), fs_info->sectorsize));
++
++      inode_set_atime(vfs_inode, btrfs_timespec_sec(leaf, &inode_item->atime),
+                       btrfs_timespec_nsec(leaf, &inode_item->atime));
+-      inode_set_mtime(inode, btrfs_timespec_sec(leaf, &inode_item->mtime),
++      inode_set_mtime(vfs_inode, btrfs_timespec_sec(leaf, &inode_item->mtime),
+                       btrfs_timespec_nsec(leaf, &inode_item->mtime));
+-      inode_set_ctime(inode, btrfs_timespec_sec(leaf, &inode_item->ctime),
++      inode_set_ctime(vfs_inode, btrfs_timespec_sec(leaf, &inode_item->ctime),
+                       btrfs_timespec_nsec(leaf, &inode_item->ctime));
+-      BTRFS_I(inode)->i_otime_sec = btrfs_timespec_sec(leaf, &inode_item->otime);
+-      BTRFS_I(inode)->i_otime_nsec = btrfs_timespec_nsec(leaf, &inode_item->otime);
++      inode->i_otime_sec = btrfs_timespec_sec(leaf, &inode_item->otime);
++      inode->i_otime_nsec = btrfs_timespec_nsec(leaf, &inode_item->otime);
+-      inode_set_bytes(inode, btrfs_inode_nbytes(leaf, inode_item));
+-      BTRFS_I(inode)->generation = btrfs_inode_generation(leaf, inode_item);
+-      BTRFS_I(inode)->last_trans = btrfs_inode_transid(leaf, inode_item);
++      inode_set_bytes(vfs_inode, btrfs_inode_nbytes(leaf, inode_item));
++      inode->generation = btrfs_inode_generation(leaf, inode_item);
++      inode->last_trans = btrfs_inode_transid(leaf, inode_item);
+-      inode_set_iversion_queried(inode,
+-                                 btrfs_inode_sequence(leaf, inode_item));
+-      inode->i_generation = BTRFS_I(inode)->generation;
+-      inode->i_rdev = 0;
++      inode_set_iversion_queried(vfs_inode, btrfs_inode_sequence(leaf, inode_item));
++      vfs_inode->i_generation = inode->generation;
++      vfs_inode->i_rdev = 0;
+       rdev = btrfs_inode_rdev(leaf, inode_item);
+-      if (S_ISDIR(inode->i_mode))
+-              BTRFS_I(inode)->index_cnt = (u64)-1;
++      if (S_ISDIR(vfs_inode->i_mode))
++              inode->index_cnt = (u64)-1;
+       btrfs_inode_split_flags(btrfs_inode_flags(leaf, inode_item),
+-                              &BTRFS_I(inode)->flags, &BTRFS_I(inode)->ro_flags);
+-      btrfs_update_inode_mapping_flags(BTRFS_I(inode));
++                              &inode->flags, &inode->ro_flags);
++      btrfs_update_inode_mapping_flags(inode);
+ cache_index:
+       /*
+@@ -3937,9 +3937,8 @@ static int btrfs_read_locked_inode(struct inode *inode, struct btrfs_path *path)
+        * This is required for both inode re-read from disk and delayed inode
+        * in the delayed_nodes xarray.
+        */
+-      if (BTRFS_I(inode)->last_trans == btrfs_get_fs_generation(fs_info))
+-              set_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+-                      &BTRFS_I(inode)->runtime_flags);
++      if (inode->last_trans == btrfs_get_fs_generation(fs_info))
++              set_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &inode->runtime_flags);
+       /*
+        * We don't persist the id of the transaction where an unlink operation
+@@ -3968,7 +3967,7 @@ static int btrfs_read_locked_inode(struct inode *inode, struct btrfs_path *path)
+        * transaction commits on fsync if our inode is a directory, or if our
+        * inode is not a directory, logging its parent unnecessarily.
+        */
+-      BTRFS_I(inode)->last_unlink_trans = BTRFS_I(inode)->last_trans;
++      inode->last_unlink_trans = inode->last_trans;
+       /*
+        * Same logic as for last_unlink_trans. We don't persist the generation
+@@ -3976,15 +3975,15 @@ static int btrfs_read_locked_inode(struct inode *inode, struct btrfs_path *path)
+        * operation, so after eviction and reloading the inode we must be
+        * pessimistic and assume the last transaction that modified the inode.
+        */
+-      BTRFS_I(inode)->last_reflink_trans = BTRFS_I(inode)->last_trans;
++      inode->last_reflink_trans = inode->last_trans;
+       path->slots[0]++;
+-      if (inode->i_nlink != 1 ||
++      if (vfs_inode->i_nlink != 1 ||
+           path->slots[0] >= btrfs_header_nritems(leaf))
+               goto cache_acl;
+       btrfs_item_key_to_cpu(leaf, &location, path->slots[0]);
+-      if (location.objectid != btrfs_ino(BTRFS_I(inode)))
++      if (location.objectid != btrfs_ino(inode))
+               goto cache_acl;
+       ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
+@@ -3992,13 +3991,12 @@ static int btrfs_read_locked_inode(struct inode *inode, struct btrfs_path *path)
+               struct btrfs_inode_ref *ref;
+               ref = (struct btrfs_inode_ref *)ptr;
+-              BTRFS_I(inode)->dir_index = btrfs_inode_ref_index(leaf, ref);
++              inode->dir_index = btrfs_inode_ref_index(leaf, ref);
+       } else if (location.type == BTRFS_INODE_EXTREF_KEY) {
+               struct btrfs_inode_extref *extref;
+               extref = (struct btrfs_inode_extref *)ptr;
+-              BTRFS_I(inode)->dir_index = btrfs_inode_extref_index(leaf,
+-                                                                   extref);
++              inode->dir_index = btrfs_inode_extref_index(leaf, extref);
+       }
+ cache_acl:
+       /*
+@@ -4006,50 +4004,49 @@ static int btrfs_read_locked_inode(struct inode *inode, struct btrfs_path *path)
+        * any xattrs or acls
+        */
+       maybe_acls = acls_after_inode_item(leaf, path->slots[0],
+-                      btrfs_ino(BTRFS_I(inode)), &first_xattr_slot);
++                                         btrfs_ino(inode), &first_xattr_slot);
+       if (first_xattr_slot != -1) {
+               path->slots[0] = first_xattr_slot;
+-              ret = btrfs_load_inode_props(inode, path);
++              ret = btrfs_load_inode_props(vfs_inode, path);
+               if (ret)
+                       btrfs_err(fs_info,
+                                 "error loading props for ino %llu (root %llu): %d",
+-                                btrfs_ino(BTRFS_I(inode)),
+-                                btrfs_root_id(root), ret);
++                                btrfs_ino(inode), btrfs_root_id(root), ret);
+       }
+       if (!maybe_acls)
+-              cache_no_acl(inode);
++              cache_no_acl(vfs_inode);
+-      switch (inode->i_mode & S_IFMT) {
++      switch (vfs_inode->i_mode & S_IFMT) {
+       case S_IFREG:
+-              inode->i_mapping->a_ops = &btrfs_aops;
+-              inode->i_fop = &btrfs_file_operations;
+-              inode->i_op = &btrfs_file_inode_operations;
++              vfs_inode->i_mapping->a_ops = &btrfs_aops;
++              vfs_inode->i_fop = &btrfs_file_operations;
++              vfs_inode->i_op = &btrfs_file_inode_operations;
+               break;
+       case S_IFDIR:
+-              inode->i_fop = &btrfs_dir_file_operations;
+-              inode->i_op = &btrfs_dir_inode_operations;
++              vfs_inode->i_fop = &btrfs_dir_file_operations;
++              vfs_inode->i_op = &btrfs_dir_inode_operations;
+               break;
+       case S_IFLNK:
+-              inode->i_op = &btrfs_symlink_inode_operations;
+-              inode_nohighmem(inode);
+-              inode->i_mapping->a_ops = &btrfs_aops;
++              vfs_inode->i_op = &btrfs_symlink_inode_operations;
++              inode_nohighmem(vfs_inode);
++              vfs_inode->i_mapping->a_ops = &btrfs_aops;
+               break;
+       default:
+-              inode->i_op = &btrfs_special_inode_operations;
+-              init_special_inode(inode, inode->i_mode, rdev);
++              vfs_inode->i_op = &btrfs_special_inode_operations;
++              init_special_inode(vfs_inode, vfs_inode->i_mode, rdev);
+               break;
+       }
+-      btrfs_sync_inode_flags_to_i_flags(inode);
++      btrfs_sync_inode_flags_to_i_flags(vfs_inode);
+-      ret = btrfs_add_inode_to_root(BTRFS_I(inode), true);
++      ret = btrfs_add_inode_to_root(inode, true);
+       if (ret)
+               goto out;
+       return 0;
+ out:
+-      iget_failed(inode);
++      iget_failed(vfs_inode);
+       return ret;
+ }
+@@ -5636,7 +5633,7 @@ struct inode *btrfs_iget_path(u64 ino, struct btrfs_root *root,
+       if (!(inode->i_state & I_NEW))
+               return inode;
+-      ret = btrfs_read_locked_inode(inode, path);
++      ret = btrfs_read_locked_inode(BTRFS_I(inode), path);
+       if (ret)
+               return ERR_PTR(ret);
+@@ -5664,7 +5661,7 @@ struct inode *btrfs_iget(u64 ino, struct btrfs_root *root)
+       if (!path)
+               return ERR_PTR(-ENOMEM);
+-      ret = btrfs_read_locked_inode(inode, path);
++      ret = btrfs_read_locked_inode(BTRFS_I(inode), path);
+       btrfs_free_path(path);
+       if (ret)
+               return ERR_PTR(ret);
+-- 
+2.39.5
+
diff --git a/queue-6.14/btrfs-zoned-skip-reporting-zone-for-new-block-group.patch b/queue-6.14/btrfs-zoned-skip-reporting-zone-for-new-block-group.patch
new file mode 100644 (file)
index 0000000..b2fa96e
--- /dev/null
@@ -0,0 +1,286 @@
+From ec6609f1b26edeede768fd8db6a3b42150778f39 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Mar 2025 10:49:17 +0900
+Subject: btrfs: zoned: skip reporting zone for new block group
+
+From: Naohiro Aota <naohiro.aota@wdc.com>
+
+[ Upstream commit 866bafae59ecffcf1840d846cd79740be29f21d6 ]
+
+There is a potential deadlock if we do report zones in an IO context, detailed
+in below lockdep report. When one process do a report zones and another process
+freezes the block device, the report zones side cannot allocate a tag because
+the freeze is already started. This can thus result in new block group creation
+to hang forever, blocking the write path.
+
+Thankfully, a new block group should be created on empty zones. So, reporting
+the zones is not necessary and we can set the write pointer = 0 and load the
+zone capacity from the block layer using bdev_zone_capacity() helper.
+
+ ======================================================
+ WARNING: possible circular locking dependency detected
+ 6.14.0-rc1 #252 Not tainted
+ ------------------------------------------------------
+ modprobe/1110 is trying to acquire lock:
+ ffff888100ac83e0 ((work_completion)(&(&wb->dwork)->work)){+.+.}-{0:0}, at: __flush_work+0x38f/0xb60
+
+ but task is already holding lock:
+ ffff8881205b6f20 (&q->q_usage_counter(queue)#16){++++}-{0:0}, at: sd_remove+0x85/0x130
+
+ which lock already depends on the new lock.
+
+ the existing dependency chain (in reverse order) is:
+
+ -> #3 (&q->q_usage_counter(queue)#16){++++}-{0:0}:
+        blk_queue_enter+0x3d9/0x500
+        blk_mq_alloc_request+0x47d/0x8e0
+        scsi_execute_cmd+0x14f/0xb80
+        sd_zbc_do_report_zones+0x1c1/0x470
+        sd_zbc_report_zones+0x362/0xd60
+        blkdev_report_zones+0x1b1/0x2e0
+        btrfs_get_dev_zones+0x215/0x7e0 [btrfs]
+        btrfs_load_block_group_zone_info+0x6d2/0x2c10 [btrfs]
+        btrfs_make_block_group+0x36b/0x870 [btrfs]
+        btrfs_create_chunk+0x147d/0x2320 [btrfs]
+        btrfs_chunk_alloc+0x2ce/0xcf0 [btrfs]
+        start_transaction+0xce6/0x1620 [btrfs]
+        btrfs_uuid_scan_kthread+0x4ee/0x5b0 [btrfs]
+        kthread+0x39d/0x750
+        ret_from_fork+0x30/0x70
+        ret_from_fork_asm+0x1a/0x30
+
+ -> #2 (&fs_info->dev_replace.rwsem){++++}-{4:4}:
+        down_read+0x9b/0x470
+        btrfs_map_block+0x2ce/0x2ce0 [btrfs]
+        btrfs_submit_chunk+0x2d4/0x16c0 [btrfs]
+        btrfs_submit_bbio+0x16/0x30 [btrfs]
+        btree_write_cache_pages+0xb5a/0xf90 [btrfs]
+        do_writepages+0x17f/0x7b0
+        __writeback_single_inode+0x114/0xb00
+        writeback_sb_inodes+0x52b/0xe00
+        wb_writeback+0x1a7/0x800
+        wb_workfn+0x12a/0xbd0
+        process_one_work+0x85a/0x1460
+        worker_thread+0x5e2/0xfc0
+        kthread+0x39d/0x750
+        ret_from_fork+0x30/0x70
+        ret_from_fork_asm+0x1a/0x30
+
+ -> #1 (&fs_info->zoned_meta_io_lock){+.+.}-{4:4}:
+        __mutex_lock+0x1aa/0x1360
+        btree_write_cache_pages+0x252/0xf90 [btrfs]
+        do_writepages+0x17f/0x7b0
+        __writeback_single_inode+0x114/0xb00
+        writeback_sb_inodes+0x52b/0xe00
+        wb_writeback+0x1a7/0x800
+        wb_workfn+0x12a/0xbd0
+        process_one_work+0x85a/0x1460
+        worker_thread+0x5e2/0xfc0
+        kthread+0x39d/0x750
+        ret_from_fork+0x30/0x70
+        ret_from_fork_asm+0x1a/0x30
+
+ -> #0 ((work_completion)(&(&wb->dwork)->work)){+.+.}-{0:0}:
+        __lock_acquire+0x2f52/0x5ea0
+        lock_acquire+0x1b1/0x540
+        __flush_work+0x3ac/0xb60
+        wb_shutdown+0x15b/0x1f0
+        bdi_unregister+0x172/0x5b0
+        del_gendisk+0x841/0xa20
+        sd_remove+0x85/0x130
+        device_release_driver_internal+0x368/0x520
+        bus_remove_device+0x1f1/0x3f0
+        device_del+0x3bd/0x9c0
+        __scsi_remove_device+0x272/0x340
+        scsi_forget_host+0xf7/0x170
+        scsi_remove_host+0xd2/0x2a0
+        sdebug_driver_remove+0x52/0x2f0 [scsi_debug]
+        device_release_driver_internal+0x368/0x520
+        bus_remove_device+0x1f1/0x3f0
+        device_del+0x3bd/0x9c0
+        device_unregister+0x13/0xa0
+        sdebug_do_remove_host+0x1fb/0x290 [scsi_debug]
+        scsi_debug_exit+0x17/0x70 [scsi_debug]
+        __do_sys_delete_module.isra.0+0x321/0x520
+        do_syscall_64+0x93/0x180
+        entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+ other info that might help us debug this:
+
+ Chain exists of:
+   (work_completion)(&(&wb->dwork)->work) --> &fs_info->dev_replace.rwsem --> &q->q_usage_counter(queue)#16
+
+  Possible unsafe locking scenario:
+
+        CPU0                    CPU1
+        ----                    ----
+   lock(&q->q_usage_counter(queue)#16);
+                                lock(&fs_info->dev_replace.rwsem);
+                                lock(&q->q_usage_counter(queue)#16);
+   lock((work_completion)(&(&wb->dwork)->work));
+
+  *** DEADLOCK ***
+
+ 5 locks held by modprobe/1110:
+  #0: ffff88811f7bc108 (&dev->mutex){....}-{4:4}, at: device_release_driver_internal+0x8f/0x520
+  #1: ffff8881022ee0e0 (&shost->scan_mutex){+.+.}-{4:4}, at: scsi_remove_host+0x20/0x2a0
+  #2: ffff88811b4c4378 (&dev->mutex){....}-{4:4}, at: device_release_driver_internal+0x8f/0x520
+  #3: ffff8881205b6f20 (&q->q_usage_counter(queue)#16){++++}-{0:0}, at: sd_remove+0x85/0x130
+  #4: ffffffffa3284360 (rcu_read_lock){....}-{1:3}, at: __flush_work+0xda/0xb60
+
+ stack backtrace:
+ CPU: 0 UID: 0 PID: 1110 Comm: modprobe Not tainted 6.14.0-rc1 #252
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-3.fc41 04/01/2014
+ Call Trace:
+  <TASK>
+  dump_stack_lvl+0x6a/0x90
+  print_circular_bug.cold+0x1e0/0x274
+  check_noncircular+0x306/0x3f0
+  ? __pfx_check_noncircular+0x10/0x10
+  ? mark_lock+0xf5/0x1650
+  ? __pfx_check_irq_usage+0x10/0x10
+  ? lockdep_lock+0xca/0x1c0
+  ? __pfx_lockdep_lock+0x10/0x10
+  __lock_acquire+0x2f52/0x5ea0
+  ? __pfx___lock_acquire+0x10/0x10
+  ? __pfx_mark_lock+0x10/0x10
+  lock_acquire+0x1b1/0x540
+  ? __flush_work+0x38f/0xb60
+  ? __pfx_lock_acquire+0x10/0x10
+  ? __pfx_lock_release+0x10/0x10
+  ? mark_held_locks+0x94/0xe0
+  ? __flush_work+0x38f/0xb60
+  __flush_work+0x3ac/0xb60
+  ? __flush_work+0x38f/0xb60
+  ? __pfx_mark_lock+0x10/0x10
+  ? __pfx___flush_work+0x10/0x10
+  ? __pfx_wq_barrier_func+0x10/0x10
+  ? __pfx___might_resched+0x10/0x10
+  ? mark_held_locks+0x94/0xe0
+  wb_shutdown+0x15b/0x1f0
+  bdi_unregister+0x172/0x5b0
+  ? __pfx_bdi_unregister+0x10/0x10
+  ? up_write+0x1ba/0x510
+  del_gendisk+0x841/0xa20
+  ? __pfx_del_gendisk+0x10/0x10
+  ? _raw_spin_unlock_irqrestore+0x35/0x60
+  ? __pm_runtime_resume+0x79/0x110
+  sd_remove+0x85/0x130
+  device_release_driver_internal+0x368/0x520
+  ? kobject_put+0x5d/0x4a0
+  bus_remove_device+0x1f1/0x3f0
+  device_del+0x3bd/0x9c0
+  ? __pfx_device_del+0x10/0x10
+  __scsi_remove_device+0x272/0x340
+  scsi_forget_host+0xf7/0x170
+  scsi_remove_host+0xd2/0x2a0
+  sdebug_driver_remove+0x52/0x2f0 [scsi_debug]
+  ? kernfs_remove_by_name_ns+0xc0/0xf0
+  device_release_driver_internal+0x368/0x520
+  ? kobject_put+0x5d/0x4a0
+  bus_remove_device+0x1f1/0x3f0
+  device_del+0x3bd/0x9c0
+  ? __pfx_device_del+0x10/0x10
+  ? __pfx___mutex_unlock_slowpath+0x10/0x10
+  device_unregister+0x13/0xa0
+  sdebug_do_remove_host+0x1fb/0x290 [scsi_debug]
+  scsi_debug_exit+0x17/0x70 [scsi_debug]
+  __do_sys_delete_module.isra.0+0x321/0x520
+  ? __pfx___do_sys_delete_module.isra.0+0x10/0x10
+  ? __pfx_slab_free_after_rcu_debug+0x10/0x10
+  ? kasan_save_stack+0x2c/0x50
+  ? kasan_record_aux_stack+0xa3/0xb0
+  ? __call_rcu_common.constprop.0+0xc4/0xfb0
+  ? kmem_cache_free+0x3a0/0x590
+  ? __x64_sys_close+0x78/0xd0
+  do_syscall_64+0x93/0x180
+  ? lock_is_held_type+0xd5/0x130
+  ? __call_rcu_common.constprop.0+0x3c0/0xfb0
+  ? lockdep_hardirqs_on+0x78/0x100
+  ? __call_rcu_common.constprop.0+0x3c0/0xfb0
+  ? __pfx___call_rcu_common.constprop.0+0x10/0x10
+  ? kmem_cache_free+0x3a0/0x590
+  ? lockdep_hardirqs_on_prepare+0x16d/0x400
+  ? do_syscall_64+0x9f/0x180
+  ? lockdep_hardirqs_on+0x78/0x100
+  ? do_syscall_64+0x9f/0x180
+  ? __pfx___x64_sys_openat+0x10/0x10
+  ? lockdep_hardirqs_on_prepare+0x16d/0x400
+  ? do_syscall_64+0x9f/0x180
+  ? lockdep_hardirqs_on+0x78/0x100
+  ? do_syscall_64+0x9f/0x180
+  entry_SYSCALL_64_after_hwframe+0x76/0x7e
+ RIP: 0033:0x7f436712b68b
+ RSP: 002b:00007ffe9f1a8658 EFLAGS: 00000206 ORIG_RAX: 00000000000000b0
+ RAX: ffffffffffffffda RBX: 00005559b367fd80 RCX: 00007f436712b68b
+ RDX: 0000000000000000 RSI: 0000000000000800 RDI: 00005559b367fde8
+ RBP: 00007ffe9f1a8680 R08: 1999999999999999 R09: 0000000000000000
+ R10: 00007f43671a5fe0 R11: 0000000000000206 R12: 0000000000000000
+ R13: 00007ffe9f1a86b0 R14: 0000000000000000 R15: 0000000000000000
+  </TASK>
+
+Reported-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+CC: <stable@vger.kernel.org> # 6.13+
+Tested-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/zoned.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
+index 978a57da8b4f5..f39656668967c 100644
+--- a/fs/btrfs/zoned.c
++++ b/fs/btrfs/zoned.c
+@@ -1277,7 +1277,7 @@ struct zone_info {
+ static int btrfs_load_zone_info(struct btrfs_fs_info *fs_info, int zone_idx,
+                               struct zone_info *info, unsigned long *active,
+-                              struct btrfs_chunk_map *map)
++                              struct btrfs_chunk_map *map, bool new)
+ {
+       struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
+       struct btrfs_device *device;
+@@ -1307,6 +1307,8 @@ static int btrfs_load_zone_info(struct btrfs_fs_info *fs_info, int zone_idx,
+               return 0;
+       }
++      ASSERT(!new || btrfs_dev_is_empty_zone(device, info->physical));
++
+       /* This zone will be used for allocation, so mark this zone non-empty. */
+       btrfs_dev_clear_zone_empty(device, info->physical);
+@@ -1319,6 +1321,18 @@ static int btrfs_load_zone_info(struct btrfs_fs_info *fs_info, int zone_idx,
+        * to determine the allocation offset within the zone.
+        */
+       WARN_ON(!IS_ALIGNED(info->physical, fs_info->zone_size));
++
++      if (new) {
++              sector_t capacity;
++
++              capacity = bdev_zone_capacity(device->bdev, info->physical >> SECTOR_SHIFT);
++              up_read(&dev_replace->rwsem);
++              info->alloc_offset = 0;
++              info->capacity = capacity << SECTOR_SHIFT;
++
++              return 0;
++      }
++
+       nofs_flag = memalloc_nofs_save();
+       ret = btrfs_get_dev_zone(device, info->physical, &zone);
+       memalloc_nofs_restore(nofs_flag);
+@@ -1588,7 +1602,7 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new)
+       }
+       for (i = 0; i < map->num_stripes; i++) {
+-              ret = btrfs_load_zone_info(fs_info, i, &zone_info[i], active, map);
++              ret = btrfs_load_zone_info(fs_info, i, &zone_info[i], active, map, new);
+               if (ret)
+                       goto out;
+-- 
+2.39.5
+
diff --git a/queue-6.14/drivers-base-handle-module_kobject-creation.patch b/queue-6.14/drivers-base-handle-module_kobject-creation.patch
new file mode 100644 (file)
index 0000000..e627139
--- /dev/null
@@ -0,0 +1,65 @@
+From 06c4fc04277b0bffed5b44f4477324749e1a8da2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 10:49:30 -0800
+Subject: drivers: base: handle module_kobject creation
+
+From: Shyam Saini <shyamsaini@linux.microsoft.com>
+
+[ Upstream commit f95bbfe18512c5c018720468959edac056a17196 ]
+
+module_add_driver() relies on module_kset list for
+/sys/module/<built-in-module>/drivers directory creation.
+
+Since,
+commit 96a1a2412acba ("kernel/params.c: defer most of param_sysfs_init() to late_initcall time")
+drivers which are initialized from subsys_initcall() or any other
+higher precedence initcall couldn't find the related kobject entry
+in the module_kset list because module_kset is not fully populated
+by the time module_add_driver() refers it. As a consequence,
+module_add_driver() returns early without calling make_driver_name().
+Therefore, /sys/module/<built-in-module>/drivers is never created.
+
+Fix this issue by letting module_add_driver() handle module_kobject
+creation itself.
+
+Fixes: 96a1a2412acb ("kernel/params.c: defer most of param_sysfs_init() to late_initcall time")
+Cc: stable@vger.kernel.org # requires all other patches from the series
+Suggested-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Signed-off-by: Shyam Saini <shyamsaini@linux.microsoft.com>
+Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://lore.kernel.org/r/20250227184930.34163-5-shyamsaini@linux.microsoft.com
+Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/module.c | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/base/module.c b/drivers/base/module.c
+index 5bc71bea883a0..218aaa0964552 100644
+--- a/drivers/base/module.c
++++ b/drivers/base/module.c
+@@ -42,16 +42,13 @@ int module_add_driver(struct module *mod, const struct device_driver *drv)
+       if (mod)
+               mk = &mod->mkobj;
+       else if (drv->mod_name) {
+-              struct kobject *mkobj;
+-
+-              /* Lookup built-in module entry in /sys/modules */
+-              mkobj = kset_find_obj(module_kset, drv->mod_name);
+-              if (mkobj) {
+-                      mk = container_of(mkobj, struct module_kobject, kobj);
++              /* Lookup or create built-in module entry in /sys/modules */
++              mk = lookup_or_create_module_kobject(drv->mod_name);
++              if (mk) {
+                       /* remember our module structure */
+                       drv->p->mkobj = mk;
+-                      /* kset_find_obj took a reference */
+-                      kobject_put(mkobj);
++                      /* lookup_or_create_module_kobject took a reference */
++                      kobject_put(&mk->kobj);
+               }
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-amd-display-add-scoped-mutexes-for-amdgpu_dm_dhc.patch b/queue-6.14/drm-amd-display-add-scoped-mutexes-for-amdgpu_dm_dhc.patch
new file mode 100644 (file)
index 0000000..2746f7e
--- /dev/null
@@ -0,0 +1,205 @@
+From b25444923cd506525a2fa062ee2d7221e5792660 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Feb 2025 13:30:01 -0600
+Subject: drm/amd/display: Add scoped mutexes for amdgpu_dm_dhcp
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit 6b675ab8efbf2bcee25be29e865455c56e246401 ]
+
+[Why]
+Guards automatically release mutex when it goes out of scope making
+code easier to follow.
+
+[How]
+Replace all use of mutex_lock()/mutex_unlock() with guard(mutex).
+
+Reviewed-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Tom Chung <chiahsuan.chung@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: be593d9d91c5 ("drm/amd/display: Fix slab-use-after-free in hdcp")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c    | 37 +++++--------------
+ 1 file changed, 10 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
+index c0dc232440490..53796a74b7a65 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
+@@ -172,7 +172,7 @@ void hdcp_update_display(struct hdcp_workqueue *hdcp_work,
+       struct mod_hdcp_display_adjustment display_adjust;
+       unsigned int conn_index = aconnector->base.index;
+-      mutex_lock(&hdcp_w->mutex);
++      guard(mutex)(&hdcp_w->mutex);
+       hdcp_w->aconnector[conn_index] = aconnector;
+       memset(&link_adjust, 0, sizeof(link_adjust));
+@@ -209,7 +209,6 @@ void hdcp_update_display(struct hdcp_workqueue *hdcp_work,
+       mod_hdcp_update_display(&hdcp_w->hdcp, conn_index, &link_adjust, &display_adjust, &hdcp_w->output);
+       process_output(hdcp_w);
+-      mutex_unlock(&hdcp_w->mutex);
+ }
+ static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work,
+@@ -220,7 +219,7 @@ static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work,
+       struct drm_connector_state *conn_state = aconnector->base.state;
+       unsigned int conn_index = aconnector->base.index;
+-      mutex_lock(&hdcp_w->mutex);
++      guard(mutex)(&hdcp_w->mutex);
+       hdcp_w->aconnector[conn_index] = aconnector;
+       /* the removal of display will invoke auth reset -> hdcp destroy and
+@@ -239,7 +238,6 @@ static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work,
+       mod_hdcp_remove_display(&hdcp_w->hdcp, aconnector->base.index, &hdcp_w->output);
+       process_output(hdcp_w);
+-      mutex_unlock(&hdcp_w->mutex);
+ }
+ void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index)
+@@ -247,7 +245,7 @@ void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_inde
+       struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
+       unsigned int conn_index;
+-      mutex_lock(&hdcp_w->mutex);
++      guard(mutex)(&hdcp_w->mutex);
+       mod_hdcp_reset_connection(&hdcp_w->hdcp,  &hdcp_w->output);
+@@ -259,8 +257,6 @@ void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_inde
+       }
+       process_output(hdcp_w);
+-
+-      mutex_unlock(&hdcp_w->mutex);
+ }
+ void hdcp_handle_cpirq(struct hdcp_workqueue *hdcp_work, unsigned int link_index)
+@@ -277,7 +273,7 @@ static void event_callback(struct work_struct *work)
+       hdcp_work = container_of(to_delayed_work(work), struct hdcp_workqueue,
+                                callback_dwork);
+-      mutex_lock(&hdcp_work->mutex);
++      guard(mutex)(&hdcp_work->mutex);
+       cancel_delayed_work(&hdcp_work->callback_dwork);
+@@ -285,8 +281,6 @@ static void event_callback(struct work_struct *work)
+                              &hdcp_work->output);
+       process_output(hdcp_work);
+-
+-      mutex_unlock(&hdcp_work->mutex);
+ }
+ static void event_property_update(struct work_struct *work)
+@@ -323,7 +317,7 @@ static void event_property_update(struct work_struct *work)
+                       continue;
+               drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+-              mutex_lock(&hdcp_work->mutex);
++              guard(mutex)(&hdcp_work->mutex);
+               if (conn_state->commit) {
+                       ret = wait_for_completion_interruptible_timeout(&conn_state->commit->hw_done,
+@@ -355,7 +349,6 @@ static void event_property_update(struct work_struct *work)
+                       drm_hdcp_update_content_protection(connector,
+                                                          DRM_MODE_CONTENT_PROTECTION_DESIRED);
+               }
+-              mutex_unlock(&hdcp_work->mutex);
+               drm_modeset_unlock(&dev->mode_config.connection_mutex);
+       }
+ }
+@@ -368,7 +361,7 @@ static void event_property_validate(struct work_struct *work)
+       struct amdgpu_dm_connector *aconnector;
+       unsigned int conn_index;
+-      mutex_lock(&hdcp_work->mutex);
++      guard(mutex)(&hdcp_work->mutex);
+       for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_INDEX;
+            conn_index++) {
+@@ -408,8 +401,6 @@ static void event_property_validate(struct work_struct *work)
+                       schedule_work(&hdcp_work->property_update_work);
+               }
+       }
+-
+-      mutex_unlock(&hdcp_work->mutex);
+ }
+ static void event_watchdog_timer(struct work_struct *work)
+@@ -420,7 +411,7 @@ static void event_watchdog_timer(struct work_struct *work)
+                                struct hdcp_workqueue,
+                                     watchdog_timer_dwork);
+-      mutex_lock(&hdcp_work->mutex);
++      guard(mutex)(&hdcp_work->mutex);
+       cancel_delayed_work(&hdcp_work->watchdog_timer_dwork);
+@@ -429,8 +420,6 @@ static void event_watchdog_timer(struct work_struct *work)
+                              &hdcp_work->output);
+       process_output(hdcp_work);
+-
+-      mutex_unlock(&hdcp_work->mutex);
+ }
+ static void event_cpirq(struct work_struct *work)
+@@ -439,13 +428,11 @@ static void event_cpirq(struct work_struct *work)
+       hdcp_work = container_of(work, struct hdcp_workqueue, cpirq_work);
+-      mutex_lock(&hdcp_work->mutex);
++      guard(mutex)(&hdcp_work->mutex);
+       mod_hdcp_process_event(&hdcp_work->hdcp, MOD_HDCP_EVENT_CPIRQ, &hdcp_work->output);
+       process_output(hdcp_work);
+-
+-      mutex_unlock(&hdcp_work->mutex);
+ }
+ void hdcp_destroy(struct kobject *kobj, struct hdcp_workqueue *hdcp_work)
+@@ -479,7 +466,7 @@ static bool enable_assr(void *handle, struct dc_link *link)
+       dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf;
+-      mutex_lock(&psp->dtm_context.mutex);
++      guard(mutex)(&psp->dtm_context.mutex);
+       memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));
+       dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_ASSR_ENABLE;
+@@ -494,8 +481,6 @@ static bool enable_assr(void *handle, struct dc_link *link)
+               res = false;
+       }
+-      mutex_unlock(&psp->dtm_context.mutex);
+-
+       return res;
+ }
+@@ -557,13 +542,11 @@ static void update_config(void *handle, struct cp_psp_stream_config *config)
+                        (!!aconnector->base.state) ?
+                        aconnector->base.state->hdcp_content_type : -1);
+-      mutex_lock(&hdcp_w->mutex);
++      guard(mutex)(&hdcp_w->mutex);
+       mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output);
+       process_output(hdcp_w);
+-      mutex_unlock(&hdcp_w->mutex);
+-
+ }
+ /**
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-amd-display-fix-slab-use-after-free-in-hdcp.patch b/queue-6.14/drm-amd-display-fix-slab-use-after-free-in-hdcp.patch
new file mode 100644 (file)
index 0000000..ff50d0b
--- /dev/null
@@ -0,0 +1,177 @@
+From 8da95b8d0da1069c285f541e9ea6e269075392ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 16:50:05 -0500
+Subject: drm/amd/display: Fix slab-use-after-free in hdcp
+
+From: Chris Bainbridge <chris.bainbridge@gmail.com>
+
+[ Upstream commit be593d9d91c5a3a363d456b9aceb71029aeb3f1d ]
+
+The HDCP code in amdgpu_dm_hdcp.c copies pointers to amdgpu_dm_connector
+objects without incrementing the kref reference counts. When using a
+USB-C dock, and the dock is unplugged, the corresponding
+amdgpu_dm_connector objects are freed, creating dangling pointers in the
+HDCP code. When the dock is plugged back, the dangling pointers are
+dereferenced, resulting in a slab-use-after-free:
+
+[   66.775837] BUG: KASAN: slab-use-after-free in event_property_validate+0x42f/0x6c0 [amdgpu]
+[   66.776171] Read of size 4 at addr ffff888127804120 by task kworker/0:1/10
+
+[   66.776179] CPU: 0 UID: 0 PID: 10 Comm: kworker/0:1 Not tainted 6.14.0-rc7-00180-g54505f727a38-dirty #233
+[   66.776183] Hardware name: HP HP Pavilion Aero Laptop 13-be0xxx/8916, BIOS F.17 12/18/2024
+[   66.776186] Workqueue: events event_property_validate [amdgpu]
+[   66.776494] Call Trace:
+[   66.776496]  <TASK>
+[   66.776497]  dump_stack_lvl+0x70/0xa0
+[   66.776504]  print_report+0x175/0x555
+[   66.776507]  ? __virt_addr_valid+0x243/0x450
+[   66.776510]  ? kasan_complete_mode_report_info+0x66/0x1c0
+[   66.776515]  kasan_report+0xeb/0x1c0
+[   66.776518]  ? event_property_validate+0x42f/0x6c0 [amdgpu]
+[   66.776819]  ? event_property_validate+0x42f/0x6c0 [amdgpu]
+[   66.777121]  __asan_report_load4_noabort+0x14/0x20
+[   66.777124]  event_property_validate+0x42f/0x6c0 [amdgpu]
+[   66.777342]  ? __lock_acquire+0x6b40/0x6b40
+[   66.777347]  ? enable_assr+0x250/0x250 [amdgpu]
+[   66.777571]  process_one_work+0x86b/0x1510
+[   66.777575]  ? pwq_dec_nr_in_flight+0xcf0/0xcf0
+[   66.777578]  ? assign_work+0x16b/0x280
+[   66.777580]  ? lock_is_held_type+0xa3/0x130
+[   66.777583]  worker_thread+0x5c0/0xfa0
+[   66.777587]  ? process_one_work+0x1510/0x1510
+[   66.777588]  kthread+0x3a2/0x840
+[   66.777591]  ? kthread_is_per_cpu+0xd0/0xd0
+[   66.777594]  ? trace_hardirqs_on+0x4f/0x60
+[   66.777597]  ? _raw_spin_unlock_irq+0x27/0x60
+[   66.777599]  ? calculate_sigpending+0x77/0xa0
+[   66.777602]  ? kthread_is_per_cpu+0xd0/0xd0
+[   66.777605]  ret_from_fork+0x40/0x90
+[   66.777607]  ? kthread_is_per_cpu+0xd0/0xd0
+[   66.777609]  ret_from_fork_asm+0x11/0x20
+[   66.777614]  </TASK>
+
+[   66.777643] Allocated by task 10:
+[   66.777646]  kasan_save_stack+0x39/0x60
+[   66.777649]  kasan_save_track+0x14/0x40
+[   66.777652]  kasan_save_alloc_info+0x37/0x50
+[   66.777655]  __kasan_kmalloc+0xbb/0xc0
+[   66.777658]  __kmalloc_cache_noprof+0x1c8/0x4b0
+[   66.777661]  dm_dp_add_mst_connector+0xdd/0x5c0 [amdgpu]
+[   66.777880]  drm_dp_mst_port_add_connector+0x47e/0x770 [drm_display_helper]
+[   66.777892]  drm_dp_send_link_address+0x1554/0x2bf0 [drm_display_helper]
+[   66.777901]  drm_dp_check_and_send_link_address+0x187/0x1f0 [drm_display_helper]
+[   66.777909]  drm_dp_mst_link_probe_work+0x2b8/0x410 [drm_display_helper]
+[   66.777917]  process_one_work+0x86b/0x1510
+[   66.777919]  worker_thread+0x5c0/0xfa0
+[   66.777922]  kthread+0x3a2/0x840
+[   66.777925]  ret_from_fork+0x40/0x90
+[   66.777927]  ret_from_fork_asm+0x11/0x20
+
+[   66.777932] Freed by task 1713:
+[   66.777935]  kasan_save_stack+0x39/0x60
+[   66.777938]  kasan_save_track+0x14/0x40
+[   66.777940]  kasan_save_free_info+0x3b/0x60
+[   66.777944]  __kasan_slab_free+0x52/0x70
+[   66.777946]  kfree+0x13f/0x4b0
+[   66.777949]  dm_dp_mst_connector_destroy+0xfa/0x150 [amdgpu]
+[   66.778179]  drm_connector_free+0x7d/0xb0
+[   66.778184]  drm_mode_object_put.part.0+0xee/0x160
+[   66.778188]  drm_mode_object_put+0x37/0x50
+[   66.778191]  drm_atomic_state_default_clear+0x220/0xd60
+[   66.778194]  __drm_atomic_state_free+0x16e/0x2a0
+[   66.778197]  drm_mode_atomic_ioctl+0x15ed/0x2ba0
+[   66.778200]  drm_ioctl_kernel+0x17a/0x310
+[   66.778203]  drm_ioctl+0x584/0xd10
+[   66.778206]  amdgpu_drm_ioctl+0xd2/0x1c0 [amdgpu]
+[   66.778375]  __x64_sys_ioctl+0x139/0x1a0
+[   66.778378]  x64_sys_call+0xee7/0xfb0
+[   66.778381]  do_syscall_64+0x87/0x140
+[   66.778385]  entry_SYSCALL_64_after_hwframe+0x4b/0x53
+
+Fix this by properly incrementing and decrementing the reference counts
+when making and deleting copies of the amdgpu_dm_connector pointers.
+
+(Mario: rebase on current code and update fixes tag)
+
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4006
+Signed-off-by: Chris Bainbridge <chris.bainbridge@gmail.com>
+Fixes: da3fd7ac0bcf3 ("drm/amd/display: Update CP property based on HW query")
+Reviewed-by: Alex Hung <alex.hung@amd.com>
+Link: https://lore.kernel.org/r/20250417215005.37964-1-mario.limonciello@amd.com
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit d4673f3c3b3dcb74e36e53cdfc880baa7a87b330)
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c    | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
+index 53796a74b7a65..10ba4d7bf6325 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
+@@ -173,6 +173,9 @@ void hdcp_update_display(struct hdcp_workqueue *hdcp_work,
+       unsigned int conn_index = aconnector->base.index;
+       guard(mutex)(&hdcp_w->mutex);
++      drm_connector_get(&aconnector->base);
++      if (hdcp_w->aconnector[conn_index])
++              drm_connector_put(&hdcp_w->aconnector[conn_index]->base);
+       hdcp_w->aconnector[conn_index] = aconnector;
+       memset(&link_adjust, 0, sizeof(link_adjust));
+@@ -220,7 +223,6 @@ static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work,
+       unsigned int conn_index = aconnector->base.index;
+       guard(mutex)(&hdcp_w->mutex);
+-      hdcp_w->aconnector[conn_index] = aconnector;
+       /* the removal of display will invoke auth reset -> hdcp destroy and
+        * we'd expect the Content Protection (CP) property changed back to
+@@ -236,7 +238,10 @@ static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work,
+       }
+       mod_hdcp_remove_display(&hdcp_w->hdcp, aconnector->base.index, &hdcp_w->output);
+-
++      if (hdcp_w->aconnector[conn_index]) {
++              drm_connector_put(&hdcp_w->aconnector[conn_index]->base);
++              hdcp_w->aconnector[conn_index] = NULL;
++      }
+       process_output(hdcp_w);
+ }
+@@ -254,6 +259,10 @@ void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_inde
+       for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_INDEX; conn_index++) {
+               hdcp_w->encryption_status[conn_index] =
+                       MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
++              if (hdcp_w->aconnector[conn_index]) {
++                      drm_connector_put(&hdcp_w->aconnector[conn_index]->base);
++                      hdcp_w->aconnector[conn_index] = NULL;
++              }
+       }
+       process_output(hdcp_w);
+@@ -489,6 +498,7 @@ static void update_config(void *handle, struct cp_psp_stream_config *config)
+       struct hdcp_workqueue *hdcp_work = handle;
+       struct amdgpu_dm_connector *aconnector = config->dm_stream_ctx;
+       int link_index = aconnector->dc_link->link_index;
++      unsigned int conn_index = aconnector->base.index;
+       struct mod_hdcp_display *display = &hdcp_work[link_index].display;
+       struct mod_hdcp_link *link = &hdcp_work[link_index].link;
+       struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
+@@ -545,7 +555,10 @@ static void update_config(void *handle, struct cp_psp_stream_config *config)
+       guard(mutex)(&hdcp_w->mutex);
+       mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output);
+-
++      drm_connector_get(&aconnector->base);
++      if (hdcp_w->aconnector[conn_index])
++              drm_connector_put(&hdcp_w->aconnector[conn_index]->base);
++      hdcp_w->aconnector[conn_index] = aconnector;
+       process_output(hdcp_w);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/firmware-arm_ffa-skip-rx-buffer-ownership-release-if.patch b/queue-6.14/firmware-arm_ffa-skip-rx-buffer-ownership-release-if.patch
new file mode 100644 (file)
index 0000000..f2b1703
--- /dev/null
@@ -0,0 +1,52 @@
+From 5e6b209e901e4402cc3f51761d0853fb73bce662 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 11:57:00 +0000
+Subject: firmware: arm_ffa: Skip Rx buffer ownership release if not acquired
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sudeep Holla <sudeep.holla@arm.com>
+
+[ Upstream commit 4567bdaaaaa1744da3d7da07d9aca2f941f5b4e5 ]
+
+Completion of the FFA_PARTITION_INFO_GET ABI transfers the ownership of
+the caller’s Rx buffer from the producer(typically partition mnager) to
+the consumer(this driver/OS). FFA_RX_RELEASE transfers the ownership
+from the consumer back to the producer.
+
+However, when we set the flag to just return the count of partitions
+deployed in the system corresponding to the specified UUID while
+invoking FFA_PARTITION_INFO_GET, the Rx buffer ownership shouldn't be
+transferred to this driver. We must be able to skip transferring back
+the ownership to the partition manager when we request just to get the
+count of the partitions as the buffers are not acquired in this case.
+
+Firmware may return FFA_RET_DENIED or other error for the ffa_rx_release()
+in such cases.
+
+Fixes: bb1be7498500 ("firmware: arm_ffa: Add v1.1 get_partition_info support")
+Message-Id: <20250321115700.3525197-1-sudeep.holla@arm.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index 655672a880959..03d22cbb2ad47 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -280,7 +280,8 @@ __ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3,
+                       memcpy(buffer + idx, drv_info->rx_buffer + idx * sz,
+                              buf_sz);
+-      ffa_rx_release();
++      if (!(flags & PARTITION_INFO_GET_RETURN_COUNT_ONLY))
++              ffa_rx_release();
+       mutex_unlock(&drv_info->rx_lock);
+-- 
+2.39.5
+
diff --git a/queue-6.14/firmware-arm_scmi-balance-device-refcount-when-destr.patch b/queue-6.14/firmware-arm_scmi-balance-device-refcount-when-destr.patch
new file mode 100644 (file)
index 0000000..f2e73c1
--- /dev/null
@@ -0,0 +1,86 @@
+From 1e87098005a55f800c76e1da4ea080b81cc126c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 18:54:47 +0000
+Subject: firmware: arm_scmi: Balance device refcount when destroying devices
+
+From: Cristian Marussi <cristian.marussi@arm.com>
+
+[ Upstream commit 9ca67840c0ddf3f39407339624cef824a4f27599 ]
+
+Using device_find_child() to lookup the proper SCMI device to destroy
+causes an unbalance in device refcount, since device_find_child() calls an
+implicit get_device(): this, in turns, inhibits the call of the provided
+release methods upon devices destruction.
+
+As a consequence, one of the structures that is not freed properly upon
+destruction is the internal struct device_private dev->p populated by the
+drivers subsystem core.
+
+KMemleak detects this situation since loading/unloding some SCMI driver
+causes related devices to be created/destroyed without calling any
+device_release method.
+
+unreferenced object 0xffff00000f583800 (size 512):
+  comm "insmod", pid 227, jiffies 4294912190
+  hex dump (first 32 bytes):
+    00 00 00 00 ad 4e ad de ff ff ff ff 00 00 00 00  .....N..........
+    ff ff ff ff ff ff ff ff 60 36 1d 8a 00 80 ff ff  ........`6......
+  backtrace (crc 114e2eed):
+    kmemleak_alloc+0xbc/0xd8
+    __kmalloc_cache_noprof+0x2dc/0x398
+    device_add+0x954/0x12d0
+    device_register+0x28/0x40
+    __scmi_device_create.part.0+0x1bc/0x380
+    scmi_device_create+0x2d0/0x390
+    scmi_create_protocol_devices+0x74/0xf8
+    scmi_device_request_notifier+0x1f8/0x2a8
+    notifier_call_chain+0x110/0x3b0
+    blocking_notifier_call_chain+0x70/0xb0
+    scmi_driver_register+0x350/0x7f0
+    0xffff80000a3b3038
+    do_one_initcall+0x12c/0x730
+    do_init_module+0x1dc/0x640
+    load_module+0x4b20/0x5b70
+    init_module_from_file+0xec/0x158
+
+$ ./scripts/faddr2line ./vmlinux device_add+0x954/0x12d0
+device_add+0x954/0x12d0:
+kmalloc_noprof at include/linux/slab.h:901
+(inlined by) kzalloc_noprof at include/linux/slab.h:1037
+(inlined by) device_private_init at drivers/base/core.c:3510
+(inlined by) device_add at drivers/base/core.c:3561
+
+Balance device refcount by issuing a put_device() on devices found via
+device_find_child().
+
+Reported-by: Alice Ryhl <aliceryhl@google.com>
+Closes: https://lore.kernel.org/linux-arm-kernel/Z8nK3uFkspy61yjP@arm.com/T/#mc1f73a0ea5e41014fa145147b7b839fc988ada8f
+CC: Sudeep Holla <sudeep.holla@arm.com>
+CC: Catalin Marinas <catalin.marinas@arm.com>
+Fixes: d4f9dddd21f3 ("firmware: arm_scmi: Add dynamic scmi devices creation")
+Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
+Tested-by: Alice Ryhl <aliceryhl@google.com>
+Message-Id: <20250306185447.2039336-1-cristian.marussi@arm.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/bus.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
+index a3386bf36de50..7d7af2262c013 100644
+--- a/drivers/firmware/arm_scmi/bus.c
++++ b/drivers/firmware/arm_scmi/bus.c
+@@ -260,6 +260,9 @@ static struct scmi_device *scmi_child_dev_find(struct device *parent,
+       if (!dev)
+               return NULL;
++      /* Drop the refcnt bumped implicitly by device_find_child */
++      put_device(dev);
++
+       return to_scmi_dev(dev);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/kernel-globalize-lookup_or_create_module_kobject.patch b/queue-6.14/kernel-globalize-lookup_or_create_module_kobject.patch
new file mode 100644 (file)
index 0000000..e3541a1
--- /dev/null
@@ -0,0 +1,55 @@
+From 99ddade36cad46b104dec6c09fa785bd0bc9adfe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 10:49:29 -0800
+Subject: kernel: globalize lookup_or_create_module_kobject()
+
+From: Shyam Saini <shyamsaini@linux.microsoft.com>
+
+[ Upstream commit 7c76c813cfc42a7376378a0c4b7250db2eebab81 ]
+
+lookup_or_create_module_kobject() is marked as static and __init,
+to make it global drop static keyword.
+Since this function can be called from non-init code, use __modinit
+instead of __init, __modinit marker will make it __init if
+CONFIG_MODULES is not defined.
+
+Suggested-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Signed-off-by: Shyam Saini <shyamsaini@linux.microsoft.com>
+Link: https://lore.kernel.org/r/20250227184930.34163-4-shyamsaini@linux.microsoft.com
+Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
+Stable-dep-of: f95bbfe18512 ("drivers: base: handle module_kobject creation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/module.h | 2 ++
+ kernel/params.c        | 2 +-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/module.h b/include/linux/module.h
+index 30e5b19bafa98..ba33bba3cc742 100644
+--- a/include/linux/module.h
++++ b/include/linux/module.h
+@@ -162,6 +162,8 @@ extern void cleanup_module(void);
+ #define __INITRODATA_OR_MODULE __INITRODATA
+ #endif /*CONFIG_MODULES*/
++struct module_kobject *lookup_or_create_module_kobject(const char *name);
++
+ /* Generic info of form tag = "info" */
+ #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
+diff --git a/kernel/params.c b/kernel/params.c
+index de1e64cc202b9..c417d28bc1dfb 100644
+--- a/kernel/params.c
++++ b/kernel/params.c
+@@ -763,7 +763,7 @@ void destroy_params(const struct kernel_param *params, unsigned num)
+                       params[i].ops->free(params[i].arg);
+ }
+-static struct module_kobject * __init lookup_or_create_module_kobject(const char *name)
++struct module_kobject __modinit * lookup_or_create_module_kobject(const char *name)
+ {
+       struct module_kobject *mk;
+       struct kobject *kobj;
+-- 
+2.39.5
+
diff --git a/queue-6.14/kernel-param-rename-locate_module_kobject.patch b/queue-6.14/kernel-param-rename-locate_module_kobject.patch
new file mode 100644 (file)
index 0000000..81558f0
--- /dev/null
@@ -0,0 +1,62 @@
+From 6040cbcabc670fc1ddfe66e9a0e8fdf0e61f8e5e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 10:49:27 -0800
+Subject: kernel: param: rename locate_module_kobject
+
+From: Shyam Saini <shyamsaini@linux.microsoft.com>
+
+[ Upstream commit bbc9462f0cb0c8917a4908e856731708f0cee910 ]
+
+The locate_module_kobject() function looks up an existing
+module_kobject for a given module name. If it cannot find the
+corresponding module_kobject, it creates one for the given name.
+
+This commit renames locate_module_kobject() to
+lookup_or_create_module_kobject() to better describe its operations.
+
+This doesn't change anything functionality wise.
+
+Suggested-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Signed-off-by: Shyam Saini <shyamsaini@linux.microsoft.com>
+Link: https://lore.kernel.org/r/20250227184930.34163-2-shyamsaini@linux.microsoft.com
+Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
+Stable-dep-of: f95bbfe18512 ("drivers: base: handle module_kobject creation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/params.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/params.c b/kernel/params.c
+index 0074d29c9b80c..de1e64cc202b9 100644
+--- a/kernel/params.c
++++ b/kernel/params.c
+@@ -763,7 +763,7 @@ void destroy_params(const struct kernel_param *params, unsigned num)
+                       params[i].ops->free(params[i].arg);
+ }
+-static struct module_kobject * __init locate_module_kobject(const char *name)
++static struct module_kobject * __init lookup_or_create_module_kobject(const char *name)
+ {
+       struct module_kobject *mk;
+       struct kobject *kobj;
+@@ -805,7 +805,7 @@ static void __init kernel_add_sysfs_param(const char *name,
+       struct module_kobject *mk;
+       int err;
+-      mk = locate_module_kobject(name);
++      mk = lookup_or_create_module_kobject(name);
+       if (!mk)
+               return;
+@@ -876,7 +876,7 @@ static void __init version_sysfs_builtin(void)
+       int err;
+       for (vattr = __start___modver; vattr < __stop___modver; vattr++) {
+-              mk = locate_module_kobject(vattr->module_name);
++              mk = lookup_or_create_module_kobject(vattr->module_name);
+               if (mk) {
+                       err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr);
+                       WARN_ON_ONCE(err);
+-- 
+2.39.5
+
index 78450f61f49970a8e6e75498cd335b8482325f55..c26118f5455ad91ccc4f92d37495c11b2f640a4b 100644 (file)
@@ -163,3 +163,20 @@ sch_drr-make-drr_qlen_notify-idempotent.patch
 sch_hfsc-make-hfsc_qlen_notify-idempotent.patch
 sch_qfq-make-qfq_qlen_notify-idempotent.patch
 sch_ets-make-est_qlen_notify-idempotent.patch
+firmware-arm_scmi-balance-device-refcount-when-destr.patch
+firmware-arm_ffa-skip-rx-buffer-ownership-release-if.patch
+arm64-dts-imx95-correct-the-range-of-pcie-app-reg-re.patch
+arm-dts-opos6ul-add-ksz8081-phy-properties.patch
+arm64-dts-st-adjust-interrupt-controller-for-stm32mp.patch
+arm64-dts-st-use-128kb-size-for-aliased-gic400-regis.patch
+block-introduce-zone-capacity-helper.patch
+btrfs-zoned-skip-reporting-zone-for-new-block-group.patch
+kernel-param-rename-locate_module_kobject.patch
+kernel-globalize-lookup_or_create_module_kobject.patch
+drivers-base-handle-module_kobject-creation.patch
+btrfs-expose-per-inode-stable-writes-flag.patch
+btrfs-pass-struct-btrfs_inode-to-btrfs_read_locked_i.patch
+btrfs-pass-struct-btrfs_inode-to-btrfs_iget_locked.patch
+btrfs-fix-the-inode-leak-in-btrfs_iget.patch
+drm-amd-display-add-scoped-mutexes-for-amdgpu_dm_dhc.patch
+drm-amd-display-fix-slab-use-after-free-in-hdcp.patch