--- /dev/null
+From 00d774255f0968a35bffc69538ee47c3b263b8b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Nov 2024 10:36:41 -0500
+Subject: ARM: dts: imxrt1050: Fix clocks for mmc
+
+From: Jesse Taube <Mr.Bossman075@gmail.com>
+
+[ Upstream commit 5f122030061db3e5d2bddd9cf5c583deaa6c54ff ]
+
+One of the usdhc1 controller's clocks should be IMXRT1050_CLK_AHB_PODF not
+IMXRT1050_CLK_OSC.
+
+Fixes: 1c4f01be3490 ("ARM: dts: imx: Add i.MXRT1050-EVK support")
+Signed-off-by: Jesse Taube <Mr.Bossman075@gmail.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/nxp/imx/imxrt1050.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/nxp/imx/imxrt1050.dtsi b/arch/arm/boot/dts/nxp/imx/imxrt1050.dtsi
+index dd714d235d5f..b0bad0d1ba36 100644
+--- a/arch/arm/boot/dts/nxp/imx/imxrt1050.dtsi
++++ b/arch/arm/boot/dts/nxp/imx/imxrt1050.dtsi
+@@ -87,7 +87,7 @@
+ reg = <0x402c0000 0x4000>;
+ interrupts = <110>;
+ clocks = <&clks IMXRT1050_CLK_IPG_PDOF>,
+- <&clks IMXRT1050_CLK_OSC>,
++ <&clks IMXRT1050_CLK_AHB_PODF>,
+ <&clks IMXRT1050_CLK_USDHC1>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+--
+2.39.5
+
--- /dev/null
+From 7339b9770da729494327ccf73b0b9cd91b57acaf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 14 Dec 2024 22:43:39 +0000
+Subject: arm64: dts: rockchip: add hevc power domain clock to rk3328
+
+From: Peter Geis <pgwipeout@gmail.com>
+
+[ Upstream commit 3699f2c43ea9984e00d70463f8c29baaf260ea97 ]
+
+There is a race condition at startup between disabling power domains not
+used and disabling clocks not used on the rk3328. When the clocks are
+disabled first, the hevc power domain fails to shut off leading to a
+splat of failures. Add the hevc core clock to the rk3328 power domain
+node to prevent this condition.
+
+rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 3-.... }
+1087 jiffies s: 89 root: 0x8/.
+rcu: blocking rcu_node structures (internal RCU debug):
+Sending NMI from CPU 0 to CPUs 3:
+NMI backtrace for cpu 3
+CPU: 3 UID: 0 PID: 86 Comm: kworker/3:3 Not tainted 6.12.0-rc5+ #53
+Hardware name: Firefly ROC-RK3328-CC (DT)
+Workqueue: pm genpd_power_off_work_fn
+pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : regmap_unlock_spinlock+0x18/0x30
+lr : regmap_read+0x60/0x88
+sp : ffff800081123c00
+x29: ffff800081123c00 x28: ffff2fa4c62cad80 x27: 0000000000000000
+x26: ffffd74e6e660eb8 x25: ffff2fa4c62cae00 x24: 0000000000000040
+x23: ffffd74e6d2f3ab8 x22: 0000000000000001 x21: ffff800081123c74
+x20: 0000000000000000 x19: ffff2fa4c0412000 x18: 0000000000000000
+x17: 77202c31203d2065 x16: 6c6469203a72656c x15: 6c6f72746e6f632d
+x14: 7265776f703a6e6f x13: 2063766568206e69 x12: 616d6f64202c3431
+x11: 347830206f742030 x10: 3430303034783020 x9 : ffffd74e6c7369e0
+x8 : 3030316666206e69 x7 : 205d383738353733 x6 : 332e31202020205b
+x5 : ffffd74e6c73fc88 x4 : ffffd74e6c73fcd4 x3 : ffffd74e6c740b40
+x2 : ffff800080015484 x1 : 0000000000000000 x0 : ffff2fa4c0412000
+Call trace:
+regmap_unlock_spinlock+0x18/0x30
+rockchip_pmu_set_idle_request+0xac/0x2c0
+rockchip_pd_power+0x144/0x5f8
+rockchip_pd_power_off+0x1c/0x30
+_genpd_power_off+0x9c/0x180
+genpd_power_off.part.0.isra.0+0x130/0x2a8
+genpd_power_off_work_fn+0x6c/0x98
+process_one_work+0x170/0x3f0
+worker_thread+0x290/0x4a8
+kthread+0xec/0xf8
+ret_from_fork+0x10/0x20
+rockchip-pm-domain ff100000.syscon:power-controller: failed to get ack on domain 'hevc', val=0x88220
+
+Fixes: 52e02d377a72 ("arm64: dts: rockchip: add core dtsi file for RK3328 SoCs")
+Signed-off-by: Peter Geis <pgwipeout@gmail.com>
+Reviewed-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/20241214224339.24674-1-pgwipeout@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3328.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+index 5d47acbf4a24..82eb7c49e825 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+@@ -304,6 +304,7 @@
+
+ power-domain@RK3328_PD_HEVC {
+ reg = <RK3328_PD_HEVC>;
++ clocks = <&cru SCLK_VENC_CORE>;
+ #power-domain-cells = <0>;
+ };
+ power-domain@RK3328_PD_VIDEO {
+--
+2.39.5
+
--- /dev/null
+From d58c17f4eed498e0e867147029b36b4bd8cd59c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jan 2025 16:41:48 +0800
+Subject: block, bfq: fix waker_bfqq UAF after bfq_split_bfqq()
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit fcede1f0a043ccefe9bc6ad57f12718e42f63f1d ]
+
+Our syzkaller report a following UAF for v6.6:
+
+BUG: KASAN: slab-use-after-free in bfq_init_rq+0x175d/0x17a0 block/bfq-iosched.c:6958
+Read of size 8 at addr ffff8881b57147d8 by task fsstress/232726
+
+CPU: 2 PID: 232726 Comm: fsstress Not tainted 6.6.0-g3629d1885222 #39
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0x91/0xf0 lib/dump_stack.c:106
+ print_address_description.constprop.0+0x66/0x300 mm/kasan/report.c:364
+ print_report+0x3e/0x70 mm/kasan/report.c:475
+ kasan_report+0xb8/0xf0 mm/kasan/report.c:588
+ hlist_add_head include/linux/list.h:1023 [inline]
+ bfq_init_rq+0x175d/0x17a0 block/bfq-iosched.c:6958
+ bfq_insert_request.isra.0+0xe8/0xa20 block/bfq-iosched.c:6271
+ bfq_insert_requests+0x27f/0x390 block/bfq-iosched.c:6323
+ blk_mq_insert_request+0x290/0x8f0 block/blk-mq.c:2660
+ blk_mq_submit_bio+0x1021/0x15e0 block/blk-mq.c:3143
+ __submit_bio+0xa0/0x6b0 block/blk-core.c:639
+ __submit_bio_noacct_mq block/blk-core.c:718 [inline]
+ submit_bio_noacct_nocheck+0x5b7/0x810 block/blk-core.c:747
+ submit_bio_noacct+0xca0/0x1990 block/blk-core.c:847
+ __ext4_read_bh fs/ext4/super.c:205 [inline]
+ ext4_read_bh+0x15e/0x2e0 fs/ext4/super.c:230
+ __read_extent_tree_block+0x304/0x6f0 fs/ext4/extents.c:567
+ ext4_find_extent+0x479/0xd20 fs/ext4/extents.c:947
+ ext4_ext_map_blocks+0x1a3/0x2680 fs/ext4/extents.c:4182
+ ext4_map_blocks+0x929/0x15a0 fs/ext4/inode.c:660
+ ext4_iomap_begin_report+0x298/0x480 fs/ext4/inode.c:3569
+ iomap_iter+0x3dd/0x1010 fs/iomap/iter.c:91
+ iomap_fiemap+0x1f4/0x360 fs/iomap/fiemap.c:80
+ ext4_fiemap+0x181/0x210 fs/ext4/extents.c:5051
+ ioctl_fiemap.isra.0+0x1b4/0x290 fs/ioctl.c:220
+ do_vfs_ioctl+0x31c/0x11a0 fs/ioctl.c:811
+ __do_sys_ioctl fs/ioctl.c:869 [inline]
+ __se_sys_ioctl+0xae/0x190 fs/ioctl.c:857
+ do_syscall_x64 arch/x86/entry/common.c:51 [inline]
+ do_syscall_64+0x70/0x120 arch/x86/entry/common.c:81
+ entry_SYSCALL_64_after_hwframe+0x78/0xe2
+
+Allocated by task 232719:
+ kasan_save_stack+0x22/0x50 mm/kasan/common.c:45
+ kasan_set_track+0x25/0x30 mm/kasan/common.c:52
+ __kasan_slab_alloc+0x87/0x90 mm/kasan/common.c:328
+ kasan_slab_alloc include/linux/kasan.h:188 [inline]
+ slab_post_alloc_hook mm/slab.h:768 [inline]
+ slab_alloc_node mm/slub.c:3492 [inline]
+ kmem_cache_alloc_node+0x1b8/0x6f0 mm/slub.c:3537
+ bfq_get_queue+0x215/0x1f00 block/bfq-iosched.c:5869
+ bfq_get_bfqq_handle_split+0x167/0x5f0 block/bfq-iosched.c:6776
+ bfq_init_rq+0x13a4/0x17a0 block/bfq-iosched.c:6938
+ bfq_insert_request.isra.0+0xe8/0xa20 block/bfq-iosched.c:6271
+ bfq_insert_requests+0x27f/0x390 block/bfq-iosched.c:6323
+ blk_mq_insert_request+0x290/0x8f0 block/blk-mq.c:2660
+ blk_mq_submit_bio+0x1021/0x15e0 block/blk-mq.c:3143
+ __submit_bio+0xa0/0x6b0 block/blk-core.c:639
+ __submit_bio_noacct_mq block/blk-core.c:718 [inline]
+ submit_bio_noacct_nocheck+0x5b7/0x810 block/blk-core.c:747
+ submit_bio_noacct+0xca0/0x1990 block/blk-core.c:847
+ __ext4_read_bh fs/ext4/super.c:205 [inline]
+ ext4_read_bh_nowait+0x15a/0x240 fs/ext4/super.c:217
+ ext4_read_bh_lock+0xac/0xd0 fs/ext4/super.c:242
+ ext4_bread_batch+0x268/0x500 fs/ext4/inode.c:958
+ __ext4_find_entry+0x448/0x10f0 fs/ext4/namei.c:1671
+ ext4_lookup_entry fs/ext4/namei.c:1774 [inline]
+ ext4_lookup.part.0+0x359/0x6f0 fs/ext4/namei.c:1842
+ ext4_lookup+0x72/0x90 fs/ext4/namei.c:1839
+ __lookup_slow+0x257/0x480 fs/namei.c:1696
+ lookup_slow fs/namei.c:1713 [inline]
+ walk_component+0x454/0x5c0 fs/namei.c:2004
+ link_path_walk.part.0+0x773/0xda0 fs/namei.c:2331
+ link_path_walk fs/namei.c:3826 [inline]
+ path_openat+0x1b9/0x520 fs/namei.c:3826
+ do_filp_open+0x1b7/0x400 fs/namei.c:3857
+ do_sys_openat2+0x5dc/0x6e0 fs/open.c:1428
+ do_sys_open fs/open.c:1443 [inline]
+ __do_sys_openat fs/open.c:1459 [inline]
+ __se_sys_openat fs/open.c:1454 [inline]
+ __x64_sys_openat+0x148/0x200 fs/open.c:1454
+ do_syscall_x64 arch/x86/entry/common.c:51 [inline]
+ do_syscall_64+0x70/0x120 arch/x86/entry/common.c:81
+ entry_SYSCALL_64_after_hwframe+0x78/0xe2
+
+Freed by task 232726:
+ kasan_save_stack+0x22/0x50 mm/kasan/common.c:45
+ kasan_set_track+0x25/0x30 mm/kasan/common.c:52
+ kasan_save_free_info+0x2b/0x50 mm/kasan/generic.c:522
+ ____kasan_slab_free mm/kasan/common.c:236 [inline]
+ __kasan_slab_free+0x12a/0x1b0 mm/kasan/common.c:244
+ kasan_slab_free include/linux/kasan.h:164 [inline]
+ slab_free_hook mm/slub.c:1827 [inline]
+ slab_free_freelist_hook mm/slub.c:1853 [inline]
+ slab_free mm/slub.c:3820 [inline]
+ kmem_cache_free+0x110/0x760 mm/slub.c:3842
+ bfq_put_queue+0x6a7/0xfb0 block/bfq-iosched.c:5428
+ bfq_forget_entity block/bfq-wf2q.c:634 [inline]
+ bfq_put_idle_entity+0x142/0x240 block/bfq-wf2q.c:645
+ bfq_forget_idle+0x189/0x1e0 block/bfq-wf2q.c:671
+ bfq_update_vtime block/bfq-wf2q.c:1280 [inline]
+ __bfq_lookup_next_entity block/bfq-wf2q.c:1374 [inline]
+ bfq_lookup_next_entity+0x350/0x480 block/bfq-wf2q.c:1433
+ bfq_update_next_in_service+0x1c0/0x4f0 block/bfq-wf2q.c:128
+ bfq_deactivate_entity+0x10a/0x240 block/bfq-wf2q.c:1188
+ bfq_deactivate_bfqq block/bfq-wf2q.c:1592 [inline]
+ bfq_del_bfqq_busy+0x2e8/0xad0 block/bfq-wf2q.c:1659
+ bfq_release_process_ref+0x1cc/0x220 block/bfq-iosched.c:3139
+ bfq_split_bfqq+0x481/0xdf0 block/bfq-iosched.c:6754
+ bfq_init_rq+0xf29/0x17a0 block/bfq-iosched.c:6934
+ bfq_insert_request.isra.0+0xe8/0xa20 block/bfq-iosched.c:6271
+ bfq_insert_requests+0x27f/0x390 block/bfq-iosched.c:6323
+ blk_mq_insert_request+0x290/0x8f0 block/blk-mq.c:2660
+ blk_mq_submit_bio+0x1021/0x15e0 block/blk-mq.c:3143
+ __submit_bio+0xa0/0x6b0 block/blk-core.c:639
+ __submit_bio_noacct_mq block/blk-core.c:718 [inline]
+ submit_bio_noacct_nocheck+0x5b7/0x810 block/blk-core.c:747
+ submit_bio_noacct+0xca0/0x1990 block/blk-core.c:847
+ __ext4_read_bh fs/ext4/super.c:205 [inline]
+ ext4_read_bh+0x15e/0x2e0 fs/ext4/super.c:230
+ __read_extent_tree_block+0x304/0x6f0 fs/ext4/extents.c:567
+ ext4_find_extent+0x479/0xd20 fs/ext4/extents.c:947
+ ext4_ext_map_blocks+0x1a3/0x2680 fs/ext4/extents.c:4182
+ ext4_map_blocks+0x929/0x15a0 fs/ext4/inode.c:660
+ ext4_iomap_begin_report+0x298/0x480 fs/ext4/inode.c:3569
+ iomap_iter+0x3dd/0x1010 fs/iomap/iter.c:91
+ iomap_fiemap+0x1f4/0x360 fs/iomap/fiemap.c:80
+ ext4_fiemap+0x181/0x210 fs/ext4/extents.c:5051
+ ioctl_fiemap.isra.0+0x1b4/0x290 fs/ioctl.c:220
+ do_vfs_ioctl+0x31c/0x11a0 fs/ioctl.c:811
+ __do_sys_ioctl fs/ioctl.c:869 [inline]
+ __se_sys_ioctl+0xae/0x190 fs/ioctl.c:857
+ do_syscall_x64 arch/x86/entry/common.c:51 [inline]
+ do_syscall_64+0x70/0x120 arch/x86/entry/common.c:81
+ entry_SYSCALL_64_after_hwframe+0x78/0xe2
+
+commit 1ba0403ac644 ("block, bfq: fix uaf for accessing waker_bfqq after
+splitting") fix the problem that if waker_bfqq is in the merge chain,
+and current is the only procress, waker_bfqq can be freed from
+bfq_split_bfqq(). However, the case that waker_bfqq is not in the merge
+chain is missed, and if the procress reference of waker_bfqq is 0,
+waker_bfqq can be freed as well.
+
+Fix the problem by checking procress reference if waker_bfqq is not in
+the merge_chain.
+
+Fixes: 1ba0403ac644 ("block, bfq: fix uaf for accessing waker_bfqq after splitting")
+Signed-off-by: Hou Tao <houtao1@huawei.com>
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20250108084148.1549973-1-yukuai1@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bfq-iosched.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index dd8ca3f7ba60..617d6802b8a0 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -6843,16 +6843,24 @@ static struct bfq_queue *bfq_waker_bfqq(struct bfq_queue *bfqq)
+ if (new_bfqq == waker_bfqq) {
+ /*
+ * If waker_bfqq is in the merge chain, and current
+- * is the only procress.
++ * is the only process, waker_bfqq can be freed.
+ */
+ if (bfqq_process_refs(waker_bfqq) == 1)
+ return NULL;
+- break;
++
++ return waker_bfqq;
+ }
+
+ new_bfqq = new_bfqq->new_bfqq;
+ }
+
++ /*
++ * If waker_bfqq is not in the merge chain, and it's procress reference
++ * is 0, waker_bfqq can be freed.
++ */
++ if (bfqq_process_refs(waker_bfqq) == 0)
++ return NULL;
++
+ return waker_bfqq;
+ }
+
+--
+2.39.5
+
--- /dev/null
+From 78d03682615cae6825c520bb51887a2e011e13ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Dec 2024 01:18:01 +0000
+Subject: drm/mediatek: Only touch DISP_REG_OVL_PITCH_MSB if AFBC is supported
+
+From: Daniel Golle <daniel@makrotopia.org>
+
+[ Upstream commit f8d9b91739e1fb436447c437a346a36deb676a36 ]
+
+Touching DISP_REG_OVL_PITCH_MSB leads to video overlay on MT2701, MT7623N
+and probably other older SoCs being broken.
+
+Move setting up AFBC layer configuration into a separate function only
+being called on hardware which actually supports AFBC which restores the
+behavior as it was before commit c410fa9b07c3 ("drm/mediatek: Add AFBC
+support to Mediatek DRM driver") on non-AFBC hardware.
+
+Fixes: c410fa9b07c3 ("drm/mediatek: Add AFBC support to Mediatek DRM driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/c7fbd3c3e633c0b7dd6d1cd78ccbdded31e1ca0f.1734397800.git.daniel@makrotopia.org/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 57 +++++++++++++------------
+ 1 file changed, 29 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+index 6f15069da8b0..ce0f441e3f13 100644
+--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
++++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+@@ -403,6 +403,29 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
+ }
+ }
+
++static void mtk_ovl_afbc_layer_config(struct mtk_disp_ovl *ovl,
++ unsigned int idx,
++ struct mtk_plane_pending_state *pending,
++ struct cmdq_pkt *cmdq_pkt)
++{
++ unsigned int pitch_msb = pending->pitch >> 16;
++ unsigned int hdr_pitch = pending->hdr_pitch;
++ unsigned int hdr_addr = pending->hdr_addr;
++
++ if (pending->modifier != DRM_FORMAT_MOD_LINEAR) {
++ mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs,
++ DISP_REG_OVL_HDR_ADDR(ovl, idx));
++ mtk_ddp_write_relaxed(cmdq_pkt,
++ OVL_PITCH_MSB_2ND_SUBBUF | pitch_msb,
++ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
++ mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs,
++ DISP_REG_OVL_HDR_PITCH(ovl, idx));
++ } else {
++ mtk_ddp_write_relaxed(cmdq_pkt, pitch_msb,
++ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
++ }
++}
++
+ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
+ struct mtk_plane_state *state,
+ struct cmdq_pkt *cmdq_pkt)
+@@ -410,24 +433,12 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+ struct mtk_plane_pending_state *pending = &state->pending;
+ unsigned int addr = pending->addr;
+- unsigned int hdr_addr = pending->hdr_addr;
+- unsigned int pitch = pending->pitch;
+- unsigned int hdr_pitch = pending->hdr_pitch;
++ unsigned int pitch_lsb = pending->pitch & GENMASK(15, 0);
+ unsigned int fmt = pending->format;
+ unsigned int offset = (pending->y << 16) | pending->x;
+ unsigned int src_size = (pending->height << 16) | pending->width;
+ unsigned int ignore_pixel_alpha = 0;
+ unsigned int con;
+- bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR;
+- union overlay_pitch {
+- struct split_pitch {
+- u16 lsb;
+- u16 msb;
+- } split_pitch;
+- u32 pitch;
+- } overlay_pitch;
+-
+- overlay_pitch.pitch = pitch;
+
+ if (!pending->enable) {
+ mtk_ovl_layer_off(dev, idx, cmdq_pkt);
+@@ -457,11 +468,12 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
+ }
+
+ if (ovl->data->supports_afbc)
+- mtk_ovl_set_afbc(ovl, cmdq_pkt, idx, is_afbc);
++ mtk_ovl_set_afbc(ovl, cmdq_pkt, idx,
++ pending->modifier != DRM_FORMAT_MOD_LINEAR);
+
+ mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs,
+ DISP_REG_OVL_CON(idx));
+- mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb | ignore_pixel_alpha,
++ mtk_ddp_write_relaxed(cmdq_pkt, pitch_lsb | ignore_pixel_alpha,
+ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH(idx));
+ mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs,
+ DISP_REG_OVL_SRC_SIZE(idx));
+@@ -470,19 +482,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
+ mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl->regs,
+ DISP_REG_OVL_ADDR(ovl, idx));
+
+- if (is_afbc) {
+- mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs,
+- DISP_REG_OVL_HDR_ADDR(ovl, idx));
+- mtk_ddp_write_relaxed(cmdq_pkt,
+- OVL_PITCH_MSB_2ND_SUBBUF | overlay_pitch.split_pitch.msb,
+- &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
+- mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs,
+- DISP_REG_OVL_HDR_PITCH(ovl, idx));
+- } else {
+- mtk_ddp_write_relaxed(cmdq_pkt,
+- overlay_pitch.split_pitch.msb,
+- &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
+- }
++ if (ovl->data->supports_afbc)
++ mtk_ovl_afbc_layer_config(ovl, idx, pending, cmdq_pkt);
+
+ mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt);
+ mtk_ovl_layer_on(dev, idx, cmdq_pkt);
+--
+2.39.5
+
--- /dev/null
+From dccc8cbea0c13d2b0befc4569f7482477b270017 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Nov 2023 10:19:02 -0500
+Subject: fs/Kconfig: make hugetlbfs a menuconfig
+
+From: Peter Xu <peterx@redhat.com>
+
+[ Upstream commit cddba0af0b7919e93134469f6fdf29a7d362768a ]
+
+Hugetlb vmemmap default option (HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON)
+is a sub-option to hugetlbfs, but it shows in the same level as hugetlbfs
+itself, under "Pesudo filesystems".
+
+Make the vmemmap option a sub-option to hugetlbfs, by changing hugetlbfs
+into a menuconfig. When moving it, fix a typo 'v' spot by Randy.
+
+Link: https://lkml.kernel.org/r/20231124151902.1075697-1-peterx@redhat.com
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Reviewed-by: Muchun Song <songmuchun@bytedance.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 59d9094df3d7 ("mm: hugetlb: independent PMD page table shared count")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/Kconfig | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/fs/Kconfig b/fs/Kconfig
+index aa7e03cc1941..0ad3c7c7e984 100644
+--- a/fs/Kconfig
++++ b/fs/Kconfig
+@@ -253,7 +253,7 @@ config TMPFS_QUOTA
+ config ARCH_SUPPORTS_HUGETLBFS
+ def_bool n
+
+-config HUGETLBFS
++menuconfig HUGETLBFS
+ bool "HugeTLB file system support"
+ depends on X86 || IA64 || SPARC64 || ARCH_SUPPORTS_HUGETLBFS || BROKEN
+ depends on (SYSFS || SYSCTL)
+@@ -265,22 +265,24 @@ config HUGETLBFS
+
+ If unsure, say N.
+
+-config HUGETLB_PAGE
+- def_bool HUGETLBFS
+-
+-config HUGETLB_PAGE_OPTIMIZE_VMEMMAP
+- def_bool HUGETLB_PAGE
+- depends on ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP
+- depends on SPARSEMEM_VMEMMAP
+-
++if HUGETLBFS
+ config HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON
+ bool "HugeTLB Vmemmap Optimization (HVO) defaults to on"
+ default n
+ depends on HUGETLB_PAGE_OPTIMIZE_VMEMMAP
+ help
+- The HugeTLB VmemmapvOptimization (HVO) defaults to off. Say Y here to
++ The HugeTLB Vmemmap Optimization (HVO) defaults to off. Say Y here to
+ enable HVO by default. It can be disabled via hugetlb_free_vmemmap=off
+ (boot command line) or hugetlb_optimize_vmemmap (sysctl).
++endif # HUGETLBFS
++
++config HUGETLB_PAGE
++ def_bool HUGETLBFS
++
++config HUGETLB_PAGE_OPTIMIZE_VMEMMAP
++ def_bool HUGETLB_PAGE
++ depends on ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP
++ depends on SPARSEMEM_VMEMMAP
+
+ config ARCH_HAS_GIGANTIC_PAGE
+ bool
+--
+2.39.5
+
--- /dev/null
+From 7bc6649b366d33621fe09abda5ba89caef84248b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jan 2025 21:36:18 +0000
+Subject: hwmon: (drivetemp) Fix driver producing garbage data when SCSI errors
+ occur
+
+From: Daniil Stas <daniil.stas@posteo.net>
+
+[ Upstream commit 82163d63ae7a4c36142cd252388737205bb7e4b9 ]
+
+scsi_execute_cmd() function can return both negative (linux codes) and
+positive (scsi_cmnd result field) error codes.
+
+Currently the driver just passes error codes of scsi_execute_cmd() to
+hwmon core, which is incorrect because hwmon only checks for negative
+error codes. This leads to hwmon reporting uninitialized data to
+userspace in case of SCSI errors (for example if the disk drive was
+disconnected).
+
+This patch checks scsi_execute_cmd() output and returns -EIO if it's
+error code is positive.
+
+Fixes: 5b46903d8bf37 ("hwmon: Driver for disk and solid state drives with temperature sensors")
+Signed-off-by: Daniil Stas <daniil.stas@posteo.net>
+Cc: Guenter Roeck <linux@roeck-us.net>
+Cc: Chris Healy <cphealy@gmail.com>
+Cc: Linus Walleij <linus.walleij@linaro.org>
+Cc: Martin K. Petersen <martin.petersen@oracle.com>
+Cc: Bart Van Assche <bvanassche@acm.org>
+Cc: linux-kernel@vger.kernel.org
+Cc: linux-scsi@vger.kernel.org
+Cc: linux-ide@vger.kernel.org
+Cc: linux-hwmon@vger.kernel.org
+Link: https://lore.kernel.org/r/20250105213618.531691-1-daniil.stas@posteo.net
+[groeck: Avoid inline variable declaration for portability]
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/drivetemp.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hwmon/drivetemp.c b/drivers/hwmon/drivetemp.c
+index 6bdd21aa005a..2a4ec55ddb47 100644
+--- a/drivers/hwmon/drivetemp.c
++++ b/drivers/hwmon/drivetemp.c
+@@ -165,6 +165,7 @@ static int drivetemp_scsi_command(struct drivetemp_data *st,
+ {
+ u8 scsi_cmd[MAX_COMMAND_SIZE];
+ enum req_op op;
++ int err;
+
+ memset(scsi_cmd, 0, sizeof(scsi_cmd));
+ scsi_cmd[0] = ATA_16;
+@@ -192,8 +193,11 @@ static int drivetemp_scsi_command(struct drivetemp_data *st,
+ scsi_cmd[12] = lba_high;
+ scsi_cmd[14] = ata_command;
+
+- return scsi_execute_cmd(st->sdev, scsi_cmd, op, st->smartdata,
+- ATA_SECT_SIZE, HZ, 5, NULL);
++ err = scsi_execute_cmd(st->sdev, scsi_cmd, op, st->smartdata,
++ ATA_SECT_SIZE, HZ, 5, NULL);
++ if (err > 0)
++ err = -EIO;
++ return err;
+ }
+
+ static int drivetemp_ata_command(struct drivetemp_data *st, u8 feature,
+--
+2.39.5
+
--- /dev/null
+From 3433b20607ba1bb4b7386cf1bd3372975f9346e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jul 2024 17:07:27 +0200
+Subject: mm/hugetlb: enforce that PMD PT sharing has split PMD PT locks
+
+From: David Hildenbrand <david@redhat.com>
+
+[ Upstream commit 188cac58a8bcdf82c7f63275b68f7a46871e45d6 ]
+
+Sharing page tables between processes but falling back to per-MM page
+table locks cannot possibly work.
+
+So, let's make sure that we do have split PMD locks by adding a new
+Kconfig option and letting that depend on CONFIG_SPLIT_PMD_PTLOCKS.
+
+Link: https://lkml.kernel.org/r/20240726150728.3159964-3-david@redhat.com
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
+Cc: Alexander Viro <viro@zeniv.linux.org.uk>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Juergen Gross <jgross@suse.com>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Muchun Song <muchun.song@linux.dev>
+Cc: "Naveen N. Rao" <naveen.n.rao@linux.ibm.com>
+Cc: Nicholas Piggin <npiggin@gmail.com>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Russell King <linux@armlinux.org.uk>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 59d9094df3d7 ("mm: hugetlb: independent PMD page table shared count")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/Kconfig | 4 ++++
+ include/linux/hugetlb.h | 5 ++---
+ mm/hugetlb.c | 8 ++++----
+ 3 files changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/fs/Kconfig b/fs/Kconfig
+index 0ad3c7c7e984..02a9237807a7 100644
+--- a/fs/Kconfig
++++ b/fs/Kconfig
+@@ -284,6 +284,10 @@ config HUGETLB_PAGE_OPTIMIZE_VMEMMAP
+ depends on ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP
+ depends on SPARSEMEM_VMEMMAP
+
++config HUGETLB_PMD_PAGE_TABLE_SHARING
++ def_bool HUGETLB_PAGE
++ depends on ARCH_WANT_HUGE_PMD_SHARE && SPLIT_PMD_PTLOCKS
++
+ config ARCH_HAS_GIGANTIC_PAGE
+ bool
+
+diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
+index 0c50c4fceb95..0ca93c7574ad 100644
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -1239,7 +1239,7 @@ static inline __init void hugetlb_cma_reserve(int order)
+ }
+ #endif
+
+-#ifdef CONFIG_ARCH_WANT_HUGE_PMD_SHARE
++#ifdef CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING
+ static inline bool hugetlb_pmd_shared(pte_t *pte)
+ {
+ return page_count(virt_to_page(pte)) > 1;
+@@ -1275,8 +1275,7 @@ bool __vma_private_lock(struct vm_area_struct *vma);
+ static inline pte_t *
+ hugetlb_walk(struct vm_area_struct *vma, unsigned long addr, unsigned long sz)
+ {
+-#if defined(CONFIG_HUGETLB_PAGE) && \
+- defined(CONFIG_ARCH_WANT_HUGE_PMD_SHARE) && defined(CONFIG_LOCKDEP)
++#if defined(CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING) && defined(CONFIG_LOCKDEP)
+ struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;
+
+ /*
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 92b955cc5a41..5b8cc558ab6e 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -6907,7 +6907,7 @@ long hugetlb_unreserve_pages(struct inode *inode, long start, long end,
+ return 0;
+ }
+
+-#ifdef CONFIG_ARCH_WANT_HUGE_PMD_SHARE
++#ifdef CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING
+ static unsigned long page_table_shareable(struct vm_area_struct *svma,
+ struct vm_area_struct *vma,
+ unsigned long addr, pgoff_t idx)
+@@ -7069,7 +7069,7 @@ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma,
+ return 1;
+ }
+
+-#else /* !CONFIG_ARCH_WANT_HUGE_PMD_SHARE */
++#else /* !CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING */
+
+ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long addr, pud_t *pud)
+@@ -7092,7 +7092,7 @@ bool want_pmd_share(struct vm_area_struct *vma, unsigned long addr)
+ {
+ return false;
+ }
+-#endif /* CONFIG_ARCH_WANT_HUGE_PMD_SHARE */
++#endif /* CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING */
+
+ #ifdef CONFIG_ARCH_WANT_GENERAL_HUGETLB
+ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -7190,7 +7190,7 @@ unsigned long hugetlb_mask_last_page(struct hstate *h)
+ /* See description above. Architectures can provide their own version. */
+ __weak unsigned long hugetlb_mask_last_page(struct hstate *h)
+ {
+-#ifdef CONFIG_ARCH_WANT_HUGE_PMD_SHARE
++#ifdef CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING
+ if (huge_page_size(h) == PMD_SIZE)
+ return PUD_SIZE - PMD_SIZE;
+ #endif
+--
+2.39.5
+
--- /dev/null
+From f7eb229fcc93826ed4782e0f16540efd3e9ae689 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Dec 2024 15:11:47 +0800
+Subject: mm: hugetlb: independent PMD page table shared count
+
+From: Liu Shixin <liushixin2@huawei.com>
+
+[ Upstream commit 59d9094df3d79443937add8700b2ef1a866b1081 ]
+
+The folio refcount may be increased unexpectly through try_get_folio() by
+caller such as split_huge_pages. In huge_pmd_unshare(), we use refcount
+to check whether a pmd page table is shared. The check is incorrect if
+the refcount is increased by the above caller, and this can cause the page
+table leaked:
+
+ BUG: Bad page state in process sh pfn:109324
+ page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x66 pfn:0x109324
+ flags: 0x17ffff800000000(node=0|zone=2|lastcpupid=0xfffff)
+ page_type: f2(table)
+ raw: 017ffff800000000 0000000000000000 0000000000000000 0000000000000000
+ raw: 0000000000000066 0000000000000000 00000000f2000000 0000000000000000
+ page dumped because: nonzero mapcount
+ ...
+ CPU: 31 UID: 0 PID: 7515 Comm: sh Kdump: loaded Tainted: G B 6.13.0-rc2master+ #7
+ Tainted: [B]=BAD_PAGE
+ Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015
+ Call trace:
+ show_stack+0x20/0x38 (C)
+ dump_stack_lvl+0x80/0xf8
+ dump_stack+0x18/0x28
+ bad_page+0x8c/0x130
+ free_page_is_bad_report+0xa4/0xb0
+ free_unref_page+0x3cc/0x620
+ __folio_put+0xf4/0x158
+ split_huge_pages_all+0x1e0/0x3e8
+ split_huge_pages_write+0x25c/0x2d8
+ full_proxy_write+0x64/0xd8
+ vfs_write+0xcc/0x280
+ ksys_write+0x70/0x110
+ __arm64_sys_write+0x24/0x38
+ invoke_syscall+0x50/0x120
+ el0_svc_common.constprop.0+0xc8/0xf0
+ do_el0_svc+0x24/0x38
+ el0_svc+0x34/0x128
+ el0t_64_sync_handler+0xc8/0xd0
+ el0t_64_sync+0x190/0x198
+
+The issue may be triggered by damon, offline_page, page_idle, etc, which
+will increase the refcount of page table.
+
+1. The page table itself will be discarded after reporting the
+ "nonzero mapcount".
+
+2. The HugeTLB page mapped by the page table miss freeing since we
+ treat the page table as shared and a shared page table will not be
+ unmapped.
+
+Fix it by introducing independent PMD page table shared count. As
+described by comment, pt_index/pt_mm/pt_frag_refcount are used for s390
+gmap, x86 pgds and powerpc, pt_share_count is used for x86/arm64/riscv
+pmds, so we can reuse the field as pt_share_count.
+
+Link: https://lkml.kernel.org/r/20241216071147.3984217-1-liushixin2@huawei.com
+Fixes: 39dde65c9940 ("[PATCH] shared page table for hugetlb page")
+Signed-off-by: Liu Shixin <liushixin2@huawei.com>
+Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
+Cc: Ken Chen <kenneth.w.chen@intel.com>
+Cc: Muchun Song <muchun.song@linux.dev>
+Cc: Nanyong Sun <sunnanyong@huawei.com>
+Cc: Jane Chu <jane.chu@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mm.h | 1 +
+ include/linux/mm_types.h | 30 ++++++++++++++++++++++++++++++
+ mm/hugetlb.c | 16 +++++++---------
+ 3 files changed, 38 insertions(+), 9 deletions(-)
+
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index b6a4d6471b4a..209370f64436 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -3031,6 +3031,7 @@ static inline bool pagetable_pmd_ctor(struct ptdesc *ptdesc)
+ if (!pmd_ptlock_init(ptdesc))
+ return false;
+ __folio_set_pgtable(folio);
++ ptdesc_pmd_pts_init(ptdesc);
+ lruvec_stat_add_folio(folio, NR_PAGETABLE);
+ return true;
+ }
+diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
+index 1f224c55fb58..e77d4a5c0bac 100644
+--- a/include/linux/mm_types.h
++++ b/include/linux/mm_types.h
+@@ -399,6 +399,7 @@ FOLIO_MATCH(compound_head, _head_2a);
+ * @__page_mapping: Aliases with page->mapping. Unused for page tables.
+ * @pt_mm: Used for x86 pgds.
+ * @pt_frag_refcount: For fragmented page table tracking. Powerpc only.
++ * @pt_share_count: Used for HugeTLB PMD page table share count.
+ * @_pt_pad_2: Padding to ensure proper alignment.
+ * @ptl: Lock for the page table.
+ * @__page_type: Same as page->page_type. Unused for page tables.
+@@ -424,6 +425,9 @@ struct ptdesc {
+ union {
+ struct mm_struct *pt_mm;
+ atomic_t pt_frag_refcount;
++#ifdef CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING
++ atomic_t pt_share_count;
++#endif
+ };
+
+ union {
+@@ -468,6 +472,32 @@ static_assert(sizeof(struct ptdesc) <= sizeof(struct page));
+ const struct page *: (const struct ptdesc *)(p), \
+ struct page *: (struct ptdesc *)(p)))
+
++#ifdef CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING
++static inline void ptdesc_pmd_pts_init(struct ptdesc *ptdesc)
++{
++ atomic_set(&ptdesc->pt_share_count, 0);
++}
++
++static inline void ptdesc_pmd_pts_inc(struct ptdesc *ptdesc)
++{
++ atomic_inc(&ptdesc->pt_share_count);
++}
++
++static inline void ptdesc_pmd_pts_dec(struct ptdesc *ptdesc)
++{
++ atomic_dec(&ptdesc->pt_share_count);
++}
++
++static inline int ptdesc_pmd_pts_count(struct ptdesc *ptdesc)
++{
++ return atomic_read(&ptdesc->pt_share_count);
++}
++#else
++static inline void ptdesc_pmd_pts_init(struct ptdesc *ptdesc)
++{
++}
++#endif
++
+ /*
+ * Used for sizing the vmemmap region on some architectures
+ */
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 5b8cc558ab6e..21c12519a7ef 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -7014,7 +7014,7 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,
+ spte = hugetlb_walk(svma, saddr,
+ vma_mmu_pagesize(svma));
+ if (spte) {
+- get_page(virt_to_page(spte));
++ ptdesc_pmd_pts_inc(virt_to_ptdesc(spte));
+ break;
+ }
+ }
+@@ -7029,7 +7029,7 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,
+ (pmd_t *)((unsigned long)spte & PAGE_MASK));
+ mm_inc_nr_pmds(mm);
+ } else {
+- put_page(virt_to_page(spte));
++ ptdesc_pmd_pts_dec(virt_to_ptdesc(spte));
+ }
+ spin_unlock(&mm->page_table_lock);
+ out:
+@@ -7041,10 +7041,6 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,
+ /*
+ * unmap huge page backed by shared pte.
+ *
+- * Hugetlb pte page is ref counted at the time of mapping. If pte is shared
+- * indicated by page_count > 1, unmap is achieved by clearing pud and
+- * decrementing the ref count. If count == 1, the pte page is not shared.
+- *
+ * Called with page table lock held.
+ *
+ * returns: 1 successfully unmapped a shared pte page
+@@ -7053,18 +7049,20 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,
+ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+ {
++ unsigned long sz = huge_page_size(hstate_vma(vma));
+ pgd_t *pgd = pgd_offset(mm, addr);
+ p4d_t *p4d = p4d_offset(pgd, addr);
+ pud_t *pud = pud_offset(p4d, addr);
+
+ i_mmap_assert_write_locked(vma->vm_file->f_mapping);
+ hugetlb_vma_assert_locked(vma);
+- BUG_ON(page_count(virt_to_page(ptep)) == 0);
+- if (page_count(virt_to_page(ptep)) == 1)
++ if (sz != PMD_SIZE)
++ return 0;
++ if (!ptdesc_pmd_pts_count(virt_to_ptdesc(ptep)))
+ return 0;
+
+ pud_clear(pud);
+- put_page(virt_to_page(ptep));
++ ptdesc_pmd_pts_dec(virt_to_ptdesc(ptep));
+ mm_dec_nr_pmds(mm);
+ return 1;
+ }
+--
+2.39.5
+
--- /dev/null
+From f93562157e55623c398010b4132ed0d645bd94f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Nov 2023 20:43:49 +0100
+Subject: pgtable: fix s390 ptdesc field comments
+
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+
+[ Upstream commit 38ca8a185389716e9f7566bce4bb0085f71da61d ]
+
+Patch series "minor ptdesc updates", v3.
+
+This patch (of 2):
+
+Since commit d08d4e7cd6bf ("s390/mm: use full 4KB page for 2KB PTE") there
+is no fragmented page tracking on s390. Fix the corresponding comments.
+
+Link: https://lkml.kernel.org/r/cover.1700594815.git.agordeev@linux.ibm.com
+Link: https://lkml.kernel.org/r/2eead241f3a45bed26c7911cf66bded1e35670b8.1700594815.git.agordeev@linux.ibm.com
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Suggested-by: Heiko Carstens <hca@linux.ibm.com>
+Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
+Cc: Vishal Moola (Oracle) <vishal.moola@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 59d9094df3d7 ("mm: hugetlb: independent PMD page table shared count")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mm_types.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
+index 20c96ce98751..1f224c55fb58 100644
+--- a/include/linux/mm_types.h
++++ b/include/linux/mm_types.h
+@@ -398,11 +398,11 @@ FOLIO_MATCH(compound_head, _head_2a);
+ * @pmd_huge_pte: Protected by ptdesc->ptl, used for THPs.
+ * @__page_mapping: Aliases with page->mapping. Unused for page tables.
+ * @pt_mm: Used for x86 pgds.
+- * @pt_frag_refcount: For fragmented page table tracking. Powerpc and s390 only.
++ * @pt_frag_refcount: For fragmented page table tracking. Powerpc only.
+ * @_pt_pad_2: Padding to ensure proper alignment.
+ * @ptl: Lock for the page table.
+ * @__page_type: Same as page->page_type. Unused for page tables.
+- * @_refcount: Same as page refcount. Used for s390 page tables.
++ * @_refcount: Same as page refcount.
+ * @pt_memcg_data: Memcg data. Tracked for page tables here.
+ *
+ * This struct overlays struct page for now. Do not modify without a good
+--
+2.39.5
+
--- /dev/null
+From d9d195cfa7d24b24136ff740018acb5bfda88a76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Dec 2024 12:01:59 +0900
+Subject: pmdomain: imx: gpcv2: fix an OF node reference leak in
+ imx_gpcv2_probe()
+
+From: Joe Hattori <joe@pf.is.s.u-tokyo.ac.jp>
+
+[ Upstream commit 469c0682e03d67d8dc970ecaa70c2d753057c7c0 ]
+
+imx_gpcv2_probe() leaks an OF node reference obtained by
+of_get_child_by_name(). Fix it by declaring the device node with the
+__free(device_node) cleanup construct.
+
+This bug was found by an experimental static analysis tool that I am
+developing.
+
+Fixes: 03aa12629fc4 ("soc: imx: Add GPCv2 power gating driver")
+Signed-off-by: Joe Hattori <joe@pf.is.s.u-tokyo.ac.jp>
+Cc: stable@vger.kernel.org
+Message-ID: <20241215030159.1526624-1-joe@pf.is.s.u-tokyo.ac.jp>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pmdomain/imx/gpcv2.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pmdomain/imx/gpcv2.c b/drivers/pmdomain/imx/gpcv2.c
+index ec789bf92274..13fce2b134f6 100644
+--- a/drivers/pmdomain/imx/gpcv2.c
++++ b/drivers/pmdomain/imx/gpcv2.c
+@@ -1449,12 +1449,12 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
+ .max_register = SZ_4K,
+ };
+ struct device *dev = &pdev->dev;
+- struct device_node *pgc_np;
++ struct device_node *pgc_np __free(device_node) =
++ of_get_child_by_name(dev->of_node, "pgc");
+ struct regmap *regmap;
+ void __iomem *base;
+ int ret;
+
+- pgc_np = of_get_child_by_name(dev->of_node, "pgc");
+ if (!pgc_np) {
+ dev_err(dev, "No power domains specified in DT\n");
+ return -EINVAL;
+--
+2.39.5
+
--- /dev/null
+From e32600438e4a014b04d003c86e4a638bca5378ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Aug 2024 14:51:08 +0200
+Subject: pmdomain: imx: gpcv2: Simplify with scoped for each OF child loop
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 13bd778c900537f3fff7cfb671ff2eb0e92feee6 ]
+
+Use scoped for_each_child_of_node_scoped() when iterating over device
+nodes to make code a bit simpler.
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20240823-cleanup-h-guard-pm-domain-v1-4-8320722eaf39@linaro.org
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Stable-dep-of: 469c0682e03d ("pmdomain: imx: gpcv2: fix an OF node reference leak in imx_gpcv2_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pmdomain/imx/gpcv2.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/pmdomain/imx/gpcv2.c b/drivers/pmdomain/imx/gpcv2.c
+index fbd3d92f8cd8..ec789bf92274 100644
+--- a/drivers/pmdomain/imx/gpcv2.c
++++ b/drivers/pmdomain/imx/gpcv2.c
+@@ -1449,7 +1449,7 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
+ .max_register = SZ_4K,
+ };
+ struct device *dev = &pdev->dev;
+- struct device_node *pgc_np, *np;
++ struct device_node *pgc_np;
+ struct regmap *regmap;
+ void __iomem *base;
+ int ret;
+@@ -1471,7 +1471,7 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+- for_each_child_of_node(pgc_np, np) {
++ for_each_child_of_node_scoped(pgc_np, np) {
+ struct platform_device *pd_pdev;
+ struct imx_pgc_domain *domain;
+ u32 domain_index;
+@@ -1482,7 +1482,6 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
+ ret = of_property_read_u32(np, "reg", &domain_index);
+ if (ret) {
+ dev_err(dev, "Failed to read 'reg' property\n");
+- of_node_put(np);
+ return ret;
+ }
+
+@@ -1497,7 +1496,6 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
+ domain_index);
+ if (!pd_pdev) {
+ dev_err(dev, "Failed to allocate platform device\n");
+- of_node_put(np);
+ return -ENOMEM;
+ }
+
+@@ -1506,7 +1504,6 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
+ sizeof(domain_data->domains[domain_index]));
+ if (ret) {
+ platform_device_put(pd_pdev);
+- of_node_put(np);
+ return ret;
+ }
+
+@@ -1523,7 +1520,6 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
+ ret = platform_device_add(pd_pdev);
+ if (ret) {
+ platform_device_put(pd_pdev);
+- of_node_put(np);
+ return ret;
+ }
+ }
+--
+2.39.5
+
--- /dev/null
+From 941481db4a1d865e2a28886ec9ef36d52a878989 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 13:10:56 +0100
+Subject: riscv: Fix text patching when IPI are used
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alexandre Ghiti <alexghiti@rivosinc.com>
+
+[ Upstream commit c97bf629963e52b205ed5fbaf151e5bd342f9c63 ]
+
+For now, we use stop_machine() to patch the text and when we use IPIs for
+remote icache flushes (which is emitted in patch_text_nosync()), the system
+hangs.
+
+So instead, make sure every CPU executes the stop_machine() patching
+function and emit a local icache flush there.
+
+Co-developed-by: Björn Töpel <bjorn@rivosinc.com>
+Signed-off-by: Björn Töpel <bjorn@rivosinc.com>
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Reviewed-by: Andrea Parri <parri.andrea@gmail.com>
+Link: https://lore.kernel.org/r/20240229121056.203419-3-alexghiti@rivosinc.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Stable-dep-of: 13134cc94914 ("riscv: kprobes: Fix incorrect address calculation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/include/asm/patch.h | 1 +
+ arch/riscv/kernel/ftrace.c | 44 ++++++++++++++++++++++++++++++----
+ arch/riscv/kernel/patch.c | 16 +++++++++----
+ 3 files changed, 53 insertions(+), 8 deletions(-)
+
+diff --git a/arch/riscv/include/asm/patch.h b/arch/riscv/include/asm/patch.h
+index e88b52d39eac..9f5d6e14c405 100644
+--- a/arch/riscv/include/asm/patch.h
++++ b/arch/riscv/include/asm/patch.h
+@@ -6,6 +6,7 @@
+ #ifndef _ASM_RISCV_PATCH_H
+ #define _ASM_RISCV_PATCH_H
+
++int patch_insn_write(void *addr, const void *insn, size_t len);
+ int patch_text_nosync(void *addr, const void *insns, size_t len);
+ int patch_text_set_nosync(void *addr, u8 c, size_t len);
+ int patch_text(void *addr, u32 *insns, int ninsns);
+diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c
+index 03a6434a8cdd..6ede2bcce238 100644
+--- a/arch/riscv/kernel/ftrace.c
++++ b/arch/riscv/kernel/ftrace.c
+@@ -8,6 +8,7 @@
+ #include <linux/ftrace.h>
+ #include <linux/uaccess.h>
+ #include <linux/memory.h>
++#include <linux/stop_machine.h>
+ #include <asm/cacheflush.h>
+ #include <asm/patch.h>
+
+@@ -75,8 +76,7 @@ static int __ftrace_modify_call(unsigned long hook_pos, unsigned long target,
+ make_call_t0(hook_pos, target, call);
+
+ /* Replace the auipc-jalr pair at once. Return -EPERM on write error. */
+- if (patch_text_nosync
+- ((void *)hook_pos, enable ? call : nops, MCOUNT_INSN_SIZE))
++ if (patch_insn_write((void *)hook_pos, enable ? call : nops, MCOUNT_INSN_SIZE))
+ return -EPERM;
+
+ return 0;
+@@ -88,7 +88,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+
+ make_call_t0(rec->ip, addr, call);
+
+- if (patch_text_nosync((void *)rec->ip, call, MCOUNT_INSN_SIZE))
++ if (patch_insn_write((void *)rec->ip, call, MCOUNT_INSN_SIZE))
+ return -EPERM;
+
+ return 0;
+@@ -99,7 +99,7 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
+ {
+ unsigned int nops[2] = {NOP4, NOP4};
+
+- if (patch_text_nosync((void *)rec->ip, nops, MCOUNT_INSN_SIZE))
++ if (patch_insn_write((void *)rec->ip, nops, MCOUNT_INSN_SIZE))
+ return -EPERM;
+
+ return 0;
+@@ -134,6 +134,42 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
+
+ return ret;
+ }
++
++struct ftrace_modify_param {
++ int command;
++ atomic_t cpu_count;
++};
++
++static int __ftrace_modify_code(void *data)
++{
++ struct ftrace_modify_param *param = data;
++
++ if (atomic_inc_return(¶m->cpu_count) == num_online_cpus()) {
++ ftrace_modify_all_code(param->command);
++ /*
++ * Make sure the patching store is effective *before* we
++ * increment the counter which releases all waiting CPUs
++ * by using the release variant of atomic increment. The
++ * release pairs with the call to local_flush_icache_all()
++ * on the waiting CPU.
++ */
++ atomic_inc_return_release(¶m->cpu_count);
++ } else {
++ while (atomic_read(¶m->cpu_count) <= num_online_cpus())
++ cpu_relax();
++ }
++
++ local_flush_icache_all();
++
++ return 0;
++}
++
++void arch_ftrace_update_code(int command)
++{
++ struct ftrace_modify_param param = { command, ATOMIC_INIT(0) };
++
++ stop_machine(__ftrace_modify_code, ¶m, cpu_online_mask);
++}
+ #endif
+
+ #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
+diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c
+index 30e12b310cab..78387d843aa5 100644
+--- a/arch/riscv/kernel/patch.c
++++ b/arch/riscv/kernel/patch.c
+@@ -196,7 +196,7 @@ int patch_text_set_nosync(void *addr, u8 c, size_t len)
+ }
+ NOKPROBE_SYMBOL(patch_text_set_nosync);
+
+-static int patch_insn_write(void *addr, const void *insn, size_t len)
++int patch_insn_write(void *addr, const void *insn, size_t len)
+ {
+ size_t patched = 0;
+ size_t size;
+@@ -240,16 +240,24 @@ static int patch_text_cb(void *data)
+ if (atomic_inc_return(&patch->cpu_count) == num_online_cpus()) {
+ for (i = 0; ret == 0 && i < patch->ninsns; i++) {
+ len = GET_INSN_LENGTH(patch->insns[i]);
+- ret = patch_text_nosync(patch->addr + i * len,
+- &patch->insns[i], len);
++ ret = patch_insn_write(patch->addr + i * len, &patch->insns[i], len);
+ }
+- atomic_inc(&patch->cpu_count);
++ /*
++ * Make sure the patching store is effective *before* we
++ * increment the counter which releases all waiting CPUs
++ * by using the release variant of atomic increment. The
++ * release pairs with the call to local_flush_icache_all()
++ * on the waiting CPU.
++ */
++ atomic_inc_return_release(&patch->cpu_count);
+ } else {
+ while (atomic_read(&patch->cpu_count) <= num_online_cpus())
+ cpu_relax();
+ smp_mb();
+ }
+
++ local_flush_icache_all();
++
+ return ret;
+ }
+ NOKPROBE_SYMBOL(patch_text_cb);
+--
+2.39.5
+
iio-adc-ad7124-disable-all-channels-at-probe-time.patch
riscv-kprobes-fix-incorrect-address-calculation.patch
io_uring-eventfd-ensure-io_eventfd_signal-defers-another-rcu-period.patch
+arm-dts-imxrt1050-fix-clocks-for-mmc.patch
+hwmon-drivetemp-fix-driver-producing-garbage-data-wh.patch
+block-bfq-fix-waker_bfqq-uaf-after-bfq_split_bfqq.patch
+arm64-dts-rockchip-add-hevc-power-domain-clock-to-rk.patch
+pmdomain-imx-gpcv2-simplify-with-scoped-for-each-of-.patch
+pmdomain-imx-gpcv2-fix-an-of-node-reference-leak-in-.patch
+workqueue-add-rcu-lock-check-at-the-end-of-work-item.patch
+workqueue-update-lock-debugging-code.patch
+workqueue-do-not-warn-when-cancelling-wq_mem_reclaim.patch
+pgtable-fix-s390-ptdesc-field-comments.patch
+fs-kconfig-make-hugetlbfs-a-menuconfig.patch
+mm-hugetlb-enforce-that-pmd-pt-sharing-has-split-pmd.patch
+mm-hugetlb-independent-pmd-page-table-shared-count.patch
+riscv-fix-text-patching-when-ipi-are-used.patch
+drm-mediatek-only-touch-disp_reg_ovl_pitch_msb-if-af.patch
--- /dev/null
+From a2edf6676650ed3f2e0a747da328bb0355bc225d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 11:27:24 +0800
+Subject: workqueue: Add rcu lock check at the end of work item execution
+
+From: Xuewen Yan <xuewen.yan@unisoc.com>
+
+[ Upstream commit 1a65a6d17cbc58e1aeffb2be962acce49efbef9c ]
+
+Currently the workqueue just checks the atomic and locking states after work
+execution ends. However, sometimes, a work item may not unlock rcu after
+acquiring rcu_read_lock(). And as a result, it would cause rcu stall, but
+the rcu stall warning can not dump the work func, because the work has
+finished.
+
+In order to quickly discover those works that do not call rcu_read_unlock()
+after rcu_read_lock(), add the rcu lock check.
+
+Use rcu_preempt_depth() to check the work's rcu status. Normally, this value
+is 0. If this value is bigger than 0, it means the work are still holding
+rcu lock. If so, print err info and the work func.
+
+tj: Reworded the description for clarity. Minor formatting tweak.
+
+Signed-off-by: Xuewen Yan <xuewen.yan@unisoc.com>
+Reviewed-by: Lai Jiangshan <jiangshanlai@gmail.com>
+Reviewed-by: Waiman Long <longman@redhat.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Stable-dep-of: de35994ecd2d ("workqueue: Do not warn when cancelling WQ_MEM_RECLAIM work from !WQ_MEM_RECLAIM worker")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/workqueue.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/kernel/workqueue.c b/kernel/workqueue.c
+index 7fa1c7c9151a..2d85f232c675 100644
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -2638,11 +2638,12 @@ __acquires(&pool->lock)
+ lock_map_release(&lockdep_map);
+ lock_map_release(&pwq->wq->lockdep_map);
+
+- if (unlikely(in_atomic() || lockdep_depth(current) > 0)) {
+- pr_err("BUG: workqueue leaked lock or atomic: %s/0x%08x/%d\n"
++ if (unlikely(in_atomic() || lockdep_depth(current) > 0 ||
++ rcu_preempt_depth() > 0)) {
++ pr_err("BUG: workqueue leaked lock or atomic: %s/0x%08x/%d/%d\n"
+ " last function: %ps\n",
+- current->comm, preempt_count(), task_pid_nr(current),
+- worker->current_func);
++ current->comm, preempt_count(), rcu_preempt_depth(),
++ task_pid_nr(current), worker->current_func);
+ debug_show_held_locks(current);
+ dump_stack();
+ }
+--
+2.39.5
+
--- /dev/null
+From 7ccf278afad0f56ad044b774e2de183520108092 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Dec 2024 09:30:30 +0000
+Subject: workqueue: Do not warn when cancelling WQ_MEM_RECLAIM work from
+ !WQ_MEM_RECLAIM worker
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
+
+[ Upstream commit de35994ecd2dd6148ab5a6c5050a1670a04dec77 ]
+
+After commit
+746ae46c1113 ("drm/sched: Mark scheduler work queues with WQ_MEM_RECLAIM")
+amdgpu started seeing the following warning:
+
+ [ ] workqueue: WQ_MEM_RECLAIM sdma0:drm_sched_run_job_work [gpu_sched] is flushing !WQ_MEM_RECLAIM events:amdgpu_device_delay_enable_gfx_off [amdgpu]
+...
+ [ ] Workqueue: sdma0 drm_sched_run_job_work [gpu_sched]
+...
+ [ ] Call Trace:
+ [ ] <TASK>
+...
+ [ ] ? check_flush_dependency+0xf5/0x110
+...
+ [ ] cancel_delayed_work_sync+0x6e/0x80
+ [ ] amdgpu_gfx_off_ctrl+0xab/0x140 [amdgpu]
+ [ ] amdgpu_ring_alloc+0x40/0x50 [amdgpu]
+ [ ] amdgpu_ib_schedule+0xf4/0x810 [amdgpu]
+ [ ] ? drm_sched_run_job_work+0x22c/0x430 [gpu_sched]
+ [ ] amdgpu_job_run+0xaa/0x1f0 [amdgpu]
+ [ ] drm_sched_run_job_work+0x257/0x430 [gpu_sched]
+ [ ] process_one_work+0x217/0x720
+...
+ [ ] </TASK>
+
+The intent of the verifcation done in check_flush_depedency is to ensure
+forward progress during memory reclaim, by flagging cases when either a
+memory reclaim process, or a memory reclaim work item is flushed from a
+context not marked as memory reclaim safe.
+
+This is correct when flushing, but when called from the
+cancel(_delayed)_work_sync() paths it is a false positive because work is
+either already running, or will not be running at all. Therefore
+cancelling it is safe and we can relax the warning criteria by letting the
+helper know of the calling context.
+
+Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
+Fixes: fca839c00a12 ("workqueue: warn if memory reclaim tries to flush !WQ_MEM_RECLAIM workqueue")
+References: 746ae46c1113 ("drm/sched: Mark scheduler work queues with WQ_MEM_RECLAIM")
+Cc: Tejun Heo <tj@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Lai Jiangshan <jiangshanlai@gmail.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: Christian König <christian.koenig@amd.com
+Cc: Matthew Brost <matthew.brost@intel.com>
+Cc: <stable@vger.kernel.org> # v4.5+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/workqueue.c | 22 +++++++++++++---------
+ 1 file changed, 13 insertions(+), 9 deletions(-)
+
+diff --git a/kernel/workqueue.c b/kernel/workqueue.c
+index da5750246a92..59b6efb2a11c 100644
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -2947,23 +2947,27 @@ static int rescuer_thread(void *__rescuer)
+ * check_flush_dependency - check for flush dependency sanity
+ * @target_wq: workqueue being flushed
+ * @target_work: work item being flushed (NULL for workqueue flushes)
++ * @from_cancel: are we called from the work cancel path
+ *
+ * %current is trying to flush the whole @target_wq or @target_work on it.
+- * If @target_wq doesn't have %WQ_MEM_RECLAIM, verify that %current is not
+- * reclaiming memory or running on a workqueue which doesn't have
+- * %WQ_MEM_RECLAIM as that can break forward-progress guarantee leading to
+- * a deadlock.
++ * If this is not the cancel path (which implies work being flushed is either
++ * already running, or will not be at all), check if @target_wq doesn't have
++ * %WQ_MEM_RECLAIM and verify that %current is not reclaiming memory or running
++ * on a workqueue which doesn't have %WQ_MEM_RECLAIM as that can break forward-
++ * progress guarantee leading to a deadlock.
+ */
+ static void check_flush_dependency(struct workqueue_struct *target_wq,
+- struct work_struct *target_work)
++ struct work_struct *target_work,
++ bool from_cancel)
+ {
+- work_func_t target_func = target_work ? target_work->func : NULL;
++ work_func_t target_func;
+ struct worker *worker;
+
+- if (target_wq->flags & WQ_MEM_RECLAIM)
++ if (from_cancel || target_wq->flags & WQ_MEM_RECLAIM)
+ return;
+
+ worker = current_wq_worker();
++ target_func = target_work ? target_work->func : NULL;
+
+ WARN_ONCE(current->flags & PF_MEMALLOC,
+ "workqueue: PF_MEMALLOC task %d(%s) is flushing !WQ_MEM_RECLAIM %s:%ps",
+@@ -3208,7 +3212,7 @@ void __flush_workqueue(struct workqueue_struct *wq)
+ list_add_tail(&this_flusher.list, &wq->flusher_overflow);
+ }
+
+- check_flush_dependency(wq, NULL);
++ check_flush_dependency(wq, NULL, false);
+
+ mutex_unlock(&wq->mutex);
+
+@@ -3385,7 +3389,7 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr,
+ }
+
+ wq = pwq->wq;
+- check_flush_dependency(wq, work);
++ check_flush_dependency(wq, work, from_cancel);
+
+ insert_wq_barrier(pwq, barr, work, worker);
+ raw_spin_unlock_irq(&pool->lock);
+--
+2.39.5
+
--- /dev/null
+From 125f6c2f1b7408d78fc4568e7c6a951b85184a6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 Feb 2024 11:28:06 -1000
+Subject: workqueue: Update lock debugging code
+
+From: Tejun Heo <tj@kernel.org>
+
+[ Upstream commit c35aea39d1e106f61fd2130f0d32a3bac8bd4570 ]
+
+These changes are in preparation of BH workqueue which will execute work
+items from BH context.
+
+- Update lock and RCU depth checks in process_one_work() so that it
+ remembers and checks against the starting depths and prints out the depth
+ changes.
+
+- Factor out lockdep annotations in the flush paths into
+ touch_{wq|work}_lockdep_map(). The work->lockdep_map touching is moved
+ from __flush_work() to its callee - start_flush_work(). This brings it
+ closer to the wq counterpart and will allow testing the associated wq's
+ flags which will be needed to support BH workqueues. This is not expected
+ to cause any functional changes.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Tested-by: Allen Pais <allen.lkml@gmail.com>
+Stable-dep-of: de35994ecd2d ("workqueue: Do not warn when cancelling WQ_MEM_RECLAIM work from !WQ_MEM_RECLAIM worker")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/workqueue.c | 51 ++++++++++++++++++++++++++++++----------------
+ 1 file changed, 34 insertions(+), 17 deletions(-)
+
+diff --git a/kernel/workqueue.c b/kernel/workqueue.c
+index 2d85f232c675..da5750246a92 100644
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -2541,6 +2541,7 @@ __acquires(&pool->lock)
+ struct pool_workqueue *pwq = get_work_pwq(work);
+ struct worker_pool *pool = worker->pool;
+ unsigned long work_data;
++ int lockdep_start_depth, rcu_start_depth;
+ #ifdef CONFIG_LOCKDEP
+ /*
+ * It is permissible to free the struct work_struct from
+@@ -2603,6 +2604,8 @@ __acquires(&pool->lock)
+ pwq->stats[PWQ_STAT_STARTED]++;
+ raw_spin_unlock_irq(&pool->lock);
+
++ rcu_start_depth = rcu_preempt_depth();
++ lockdep_start_depth = lockdep_depth(current);
+ lock_map_acquire(&pwq->wq->lockdep_map);
+ lock_map_acquire(&lockdep_map);
+ /*
+@@ -2638,12 +2641,15 @@ __acquires(&pool->lock)
+ lock_map_release(&lockdep_map);
+ lock_map_release(&pwq->wq->lockdep_map);
+
+- if (unlikely(in_atomic() || lockdep_depth(current) > 0 ||
+- rcu_preempt_depth() > 0)) {
+- pr_err("BUG: workqueue leaked lock or atomic: %s/0x%08x/%d/%d\n"
+- " last function: %ps\n",
+- current->comm, preempt_count(), rcu_preempt_depth(),
+- task_pid_nr(current), worker->current_func);
++ if (unlikely((worker->task && in_atomic()) ||
++ lockdep_depth(current) != lockdep_start_depth ||
++ rcu_preempt_depth() != rcu_start_depth)) {
++ pr_err("BUG: workqueue leaked atomic, lock or RCU: %s[%d]\n"
++ " preempt=0x%08x lock=%d->%d RCU=%d->%d workfn=%ps\n",
++ current->comm, task_pid_nr(current), preempt_count(),
++ lockdep_start_depth, lockdep_depth(current),
++ rcu_start_depth, rcu_preempt_depth(),
++ worker->current_func);
+ debug_show_held_locks(current);
+ dump_stack();
+ }
+@@ -3123,6 +3129,19 @@ static bool flush_workqueue_prep_pwqs(struct workqueue_struct *wq,
+ return wait;
+ }
+
++static void touch_wq_lockdep_map(struct workqueue_struct *wq)
++{
++ lock_map_acquire(&wq->lockdep_map);
++ lock_map_release(&wq->lockdep_map);
++}
++
++static void touch_work_lockdep_map(struct work_struct *work,
++ struct workqueue_struct *wq)
++{
++ lock_map_acquire(&work->lockdep_map);
++ lock_map_release(&work->lockdep_map);
++}
++
+ /**
+ * __flush_workqueue - ensure that any scheduled work has run to completion.
+ * @wq: workqueue to flush
+@@ -3142,8 +3161,7 @@ void __flush_workqueue(struct workqueue_struct *wq)
+ if (WARN_ON(!wq_online))
+ return;
+
+- lock_map_acquire(&wq->lockdep_map);
+- lock_map_release(&wq->lockdep_map);
++ touch_wq_lockdep_map(wq);
+
+ mutex_lock(&wq->mutex);
+
+@@ -3342,6 +3360,7 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr,
+ struct worker *worker = NULL;
+ struct worker_pool *pool;
+ struct pool_workqueue *pwq;
++ struct workqueue_struct *wq;
+
+ might_sleep();
+
+@@ -3365,11 +3384,14 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr,
+ pwq = worker->current_pwq;
+ }
+
+- check_flush_dependency(pwq->wq, work);
++ wq = pwq->wq;
++ check_flush_dependency(wq, work);
+
+ insert_wq_barrier(pwq, barr, work, worker);
+ raw_spin_unlock_irq(&pool->lock);
+
++ touch_work_lockdep_map(work, wq);
++
+ /*
+ * Force a lock recursion deadlock when using flush_work() inside a
+ * single-threaded or rescuer equipped workqueue.
+@@ -3379,11 +3401,9 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr,
+ * workqueues the deadlock happens when the rescuer stalls, blocking
+ * forward progress.
+ */
+- if (!from_cancel &&
+- (pwq->wq->saved_max_active == 1 || pwq->wq->rescuer)) {
+- lock_map_acquire(&pwq->wq->lockdep_map);
+- lock_map_release(&pwq->wq->lockdep_map);
+- }
++ if (!from_cancel && (wq->saved_max_active == 1 || wq->rescuer))
++ touch_wq_lockdep_map(wq);
++
+ rcu_read_unlock();
+ return true;
+ already_gone:
+@@ -3402,9 +3422,6 @@ static bool __flush_work(struct work_struct *work, bool from_cancel)
+ if (WARN_ON(!work->func))
+ return false;
+
+- lock_map_acquire(&work->lockdep_map);
+- lock_map_release(&work->lockdep_map);
+-
+ if (start_flush_work(work, &barr, from_cancel)) {
+ wait_for_completion(&barr.done);
+ destroy_work_on_stack(&barr.work);
+--
+2.39.5
+