From 5bcfcb7e3fc8506f11ea751b5cab31ed6753ccb1 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Wed, 7 May 2025 11:36:14 -0400 Subject: [PATCH] Fixes for 6.14 Signed-off-by: Sasha Levin --- ...s-opos6ul-add-ksz8081-phy-properties.patch | 44 +++ ...correct-the-range-of-pcie-app-reg-re.patch | 64 ++++ ...ust-interrupt-controller-for-stm32mp.patch | 39 +++ ...-128kb-size-for-aliased-gic400-regis.patch | 48 +++ ...block-introduce-zone-capacity-helper.patch | 121 ++++++++ ...-expose-per-inode-stable-writes-flag.patch | 114 +++++++ ...rfs-fix-the-inode-leak-in-btrfs_iget.patch | 86 ++++++ ...uct-btrfs_inode-to-btrfs_iget_locked.patch | 111 +++++++ ...t-btrfs_inode-to-btrfs_read_locked_i.patch | 274 +++++++++++++++++ ...p-reporting-zone-for-new-block-group.patch | 286 ++++++++++++++++++ ...-base-handle-module_kobject-creation.patch | 65 ++++ ...add-scoped-mutexes-for-amdgpu_dm_dhc.patch | 205 +++++++++++++ ...play-fix-slab-use-after-free-in-hdcp.patch | 177 +++++++++++ ...-skip-rx-buffer-ownership-release-if.patch | 52 ++++ ...i-balance-device-refcount-when-destr.patch | 86 ++++++ ...lize-lookup_or_create_module_kobject.patch | 55 ++++ ...l-param-rename-locate_module_kobject.patch | 62 ++++ queue-6.14/series | 17 ++ 18 files changed, 1906 insertions(+) create mode 100644 queue-6.14/arm-dts-opos6ul-add-ksz8081-phy-properties.patch create mode 100644 queue-6.14/arm64-dts-imx95-correct-the-range-of-pcie-app-reg-re.patch create mode 100644 queue-6.14/arm64-dts-st-adjust-interrupt-controller-for-stm32mp.patch create mode 100644 queue-6.14/arm64-dts-st-use-128kb-size-for-aliased-gic400-regis.patch create mode 100644 queue-6.14/block-introduce-zone-capacity-helper.patch create mode 100644 queue-6.14/btrfs-expose-per-inode-stable-writes-flag.patch create mode 100644 queue-6.14/btrfs-fix-the-inode-leak-in-btrfs_iget.patch create mode 100644 queue-6.14/btrfs-pass-struct-btrfs_inode-to-btrfs_iget_locked.patch create mode 100644 queue-6.14/btrfs-pass-struct-btrfs_inode-to-btrfs_read_locked_i.patch create mode 100644 queue-6.14/btrfs-zoned-skip-reporting-zone-for-new-block-group.patch create mode 100644 queue-6.14/drivers-base-handle-module_kobject-creation.patch create mode 100644 queue-6.14/drm-amd-display-add-scoped-mutexes-for-amdgpu_dm_dhc.patch create mode 100644 queue-6.14/drm-amd-display-fix-slab-use-after-free-in-hdcp.patch create mode 100644 queue-6.14/firmware-arm_ffa-skip-rx-buffer-ownership-release-if.patch create mode 100644 queue-6.14/firmware-arm_scmi-balance-device-refcount-when-destr.patch create mode 100644 queue-6.14/kernel-globalize-lookup_or_create_module_kobject.patch create mode 100644 queue-6.14/kernel-param-rename-locate_module_kobject.patch 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 index 0000000000..9ff8792e66 --- /dev/null +++ b/queue-6.14/arm-dts-opos6ul-add-ksz8081-phy-properties.patch @@ -0,0 +1,44 @@ +From f4464e5f3e0d79713175050d62ee2c431234cad2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Oleksij Rempel +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..8f7313476d --- /dev/null +++ b/queue-6.14/arm64-dts-imx95-correct-the-range-of-pcie-app-reg-re.patch @@ -0,0 +1,64 @@ +From d3e4f6b078703c08c5ac9d5966b50de6fbf1d2b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Mar 2025 14:01:04 +0800 +Subject: arm64: dts: imx95: Correct the range of PCIe app-reg region + +From: Richard Zhu + +[ 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 +Reviewed-by: Frank Li +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..3602eca7a0 --- /dev/null +++ b/queue-6.14/arm64-dts-st-adjust-interrupt-controller-for-stm32mp.patch @@ -0,0 +1,39 @@ +From 4a45c9da5b544275cebdb94dbe5e54de2c1c01ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Apr 2025 14:06:58 +0200 +Subject: arm64: dts: st: Adjust interrupt-controller for stm32mp25 SoCs + +From: Christian Bruel + +[ 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 +Link: https://lore.kernel.org/r/20250415111654.2103767-2-christian.bruel@foss.st.com +Signed-off-by: Alexandre Torgue +Signed-off-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..c3ac755e33 --- /dev/null +++ b/queue-6.14/arm64-dts-st-use-128kb-size-for-aliased-gic400-regis.patch @@ -0,0 +1,48 @@ +From 601e9de9e5078b6823a4ce554116a482680f92f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Christian Bruel +Acked-by: Marc Zyngier +Link: https://lore.kernel.org/r/20250415111654.2103767-3-christian.bruel@foss.st.com +Signed-off-by: Alexandre Torgue +Signed-off-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..d17a7081b0 --- /dev/null +++ b/queue-6.14/block-introduce-zone-capacity-helper.patch @@ -0,0 +1,121 @@ +From f8b08d67d9cf4f4bdef0e3e71b16f8418ad5a794 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Mar 2025 10:49:16 +0900 +Subject: block: introduce zone capacity helper + +From: Naohiro Aota + +[ 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 +Reviewed-by: Damien Le Moal +Reviewed-by: Johannes Thumshirn +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: David Sterba +Stable-dep-of: 866bafae59ec ("btrfs: zoned: skip reporting zone for new block group") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..15a5953385 --- /dev/null +++ b/queue-6.14/btrfs-expose-per-inode-stable-writes-flag.patch @@ -0,0 +1,114 @@ +From e794eaca7ec6f8d9187a23be8676bb438752639e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Jan 2025 09:48:18 +1030 +Subject: btrfs: expose per-inode stable writes flag + +From: Qu Wenruo + +[ 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 +Signed-off-by: David Sterba +Stable-dep-of: 48c1d1bb525b ("btrfs: fix the inode leak in btrfs_iget()") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..3cdcc15edb --- /dev/null +++ b/queue-6.14/btrfs-fix-the-inode-leak-in-btrfs_iget.patch @@ -0,0 +1,86 @@ +From dd9d62bff68983147c4b1554f5cda5a12af4b852 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Apr 2025 08:40:29 -0700 +Subject: btrfs: fix the inode leak in btrfs_iget() + +From: Penglei Jiang + +[ 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: + + 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 + + +[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 +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 +Signed-off-by: Penglei Jiang +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..6ac2aeee03 --- /dev/null +++ b/queue-6.14/btrfs-pass-struct-btrfs_inode-to-btrfs_iget_locked.patch @@ -0,0 +1,111 @@ +From f9103454ef09f4e95ec1f0667dc7c77f4f4283ee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 22:36:17 +0100 +Subject: btrfs: pass struct btrfs_inode to btrfs_iget_locked() + +From: David Sterba + +[ 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 +Signed-off-by: David Sterba +Stable-dep-of: 48c1d1bb525b ("btrfs: fix the inode leak in btrfs_iget()") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..a27cda5243 --- /dev/null +++ b/queue-6.14/btrfs-pass-struct-btrfs_inode-to-btrfs_read_locked_i.patch @@ -0,0 +1,274 @@ +From a061f07d7d2d1d29f10360ae9632f18e34456733 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 22:29:45 +0100 +Subject: btrfs: pass struct btrfs_inode to btrfs_read_locked_inode() + +From: David Sterba + +[ 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 +Signed-off-by: David Sterba +Stable-dep-of: 48c1d1bb525b ("btrfs: fix the inode leak in btrfs_iget()") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..b2fa96ea2e --- /dev/null +++ b/queue-6.14/btrfs-zoned-skip-reporting-zone-for-new-block-group.patch @@ -0,0 +1,286 @@ +From ec6609f1b26edeede768fd8db6a3b42150778f39 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Mar 2025 10:49:17 +0900 +Subject: btrfs: zoned: skip reporting zone for new block group + +From: Naohiro Aota + +[ 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: + + 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 + + +Reported-by: Shin'ichiro Kawasaki +CC: # 6.13+ +Tested-by: Shin'ichiro Kawasaki +Reviewed-by: Damien Le Moal +Reviewed-by: Johannes Thumshirn +Signed-off-by: Naohiro Aota +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..e6271390a8 --- /dev/null +++ b/queue-6.14/drivers-base-handle-module_kobject-creation.patch @@ -0,0 +1,65 @@ +From 06c4fc04277b0bffed5b44f4477324749e1a8da2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Feb 2025 10:49:30 -0800 +Subject: drivers: base: handle module_kobject creation + +From: Shyam Saini + +[ Upstream commit f95bbfe18512c5c018720468959edac056a17196 ] + +module_add_driver() relies on module_kset list for +/sys/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//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 +Signed-off-by: Shyam Saini +Acked-by: Greg Kroah-Hartman +Link: https://lore.kernel.org/r/20250227184930.34163-5-shyamsaini@linux.microsoft.com +Signed-off-by: Petr Pavlu +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..2746f7ef56 --- /dev/null +++ b/queue-6.14/drm-amd-display-add-scoped-mutexes-for-amdgpu_dm_dhc.patch @@ -0,0 +1,205 @@ +From b25444923cd506525a2fa062ee2d7221e5792660 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Feb 2025 13:30:01 -0600 +Subject: drm/amd/display: Add scoped mutexes for amdgpu_dm_dhcp + +From: Mario Limonciello + +[ 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 +Signed-off-by: Mario Limonciello +Signed-off-by: Tom Chung +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Stable-dep-of: be593d9d91c5 ("drm/amd/display: Fix slab-use-after-free in hdcp") +Signed-off-by: Sasha Levin +--- + .../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 index 0000000000..ff50d0b2b4 --- /dev/null +++ b/queue-6.14/drm-amd-display-fix-slab-use-after-free-in-hdcp.patch @@ -0,0 +1,177 @@ +From 8da95b8d0da1069c285f541e9ea6e269075392ee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Apr 2025 16:50:05 -0500 +Subject: drm/amd/display: Fix slab-use-after-free in hdcp + +From: Chris Bainbridge + +[ 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] +[ 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] + +[ 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 +Fixes: da3fd7ac0bcf3 ("drm/amd/display: Update CP property based on HW query") +Reviewed-by: Alex Hung +Link: https://lore.kernel.org/r/20250417215005.37964-1-mario.limonciello@amd.com +Signed-off-by: Mario Limonciello +Signed-off-by: Alex Deucher +(cherry picked from commit d4673f3c3b3dcb74e36e53cdfc880baa7a87b330) +Cc: stable@vger.kernel.org +Signed-off-by: Sasha Levin +--- + .../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 index 0000000000..f2b1703111 --- /dev/null +++ b/queue-6.14/firmware-arm_ffa-skip-rx-buffer-ownership-release-if.patch @@ -0,0 +1,52 @@ +From 5e6b209e901e4402cc3f51761d0853fb73bce662 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..f2e73c124f --- /dev/null +++ b/queue-6.14/firmware-arm_scmi-balance-device-refcount-when-destr.patch @@ -0,0 +1,86 @@ +From 1e87098005a55f800c76e1da4ea080b81cc126c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Mar 2025 18:54:47 +0000 +Subject: firmware: arm_scmi: Balance device refcount when destroying devices + +From: Cristian Marussi + +[ 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 +Closes: https://lore.kernel.org/linux-arm-kernel/Z8nK3uFkspy61yjP@arm.com/T/#mc1f73a0ea5e41014fa145147b7b839fc988ada8f +CC: Sudeep Holla +CC: Catalin Marinas +Fixes: d4f9dddd21f3 ("firmware: arm_scmi: Add dynamic scmi devices creation") +Signed-off-by: Cristian Marussi +Tested-by: Alice Ryhl +Message-Id: <20250306185447.2039336-1-cristian.marussi@arm.com> +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..e3541a1341 --- /dev/null +++ b/queue-6.14/kernel-globalize-lookup_or_create_module_kobject.patch @@ -0,0 +1,55 @@ +From 99ddade36cad46b104dec6c09fa785bd0bc9adfe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Feb 2025 10:49:29 -0800 +Subject: kernel: globalize lookup_or_create_module_kobject() + +From: Shyam Saini + +[ 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 +Signed-off-by: Shyam Saini +Link: https://lore.kernel.org/r/20250227184930.34163-4-shyamsaini@linux.microsoft.com +Signed-off-by: Petr Pavlu +Stable-dep-of: f95bbfe18512 ("drivers: base: handle module_kobject creation") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..81558f0be9 --- /dev/null +++ b/queue-6.14/kernel-param-rename-locate_module_kobject.patch @@ -0,0 +1,62 @@ +From 6040cbcabc670fc1ddfe66e9a0e8fdf0e61f8e5e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Feb 2025 10:49:27 -0800 +Subject: kernel: param: rename locate_module_kobject + +From: Shyam Saini + +[ 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 +Signed-off-by: Shyam Saini +Link: https://lore.kernel.org/r/20250227184930.34163-2-shyamsaini@linux.microsoft.com +Signed-off-by: Petr Pavlu +Stable-dep-of: f95bbfe18512 ("drivers: base: handle module_kobject creation") +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/series b/queue-6.14/series index 78450f61f4..c26118f545 100644 --- a/queue-6.14/series +++ b/queue-6.14/series @@ -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 -- 2.47.3