]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.6
authorSasha Levin <sashal@kernel.org>
Mon, 13 Jan 2025 14:02:56 +0000 (09:02 -0500)
committerSasha Levin <sashal@kernel.org>
Mon, 13 Jan 2025 14:02:56 +0000 (09:02 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
16 files changed:
queue-6.6/arm-dts-imxrt1050-fix-clocks-for-mmc.patch [new file with mode: 0644]
queue-6.6/arm64-dts-rockchip-add-hevc-power-domain-clock-to-rk.patch [new file with mode: 0644]
queue-6.6/block-bfq-fix-waker_bfqq-uaf-after-bfq_split_bfqq.patch [new file with mode: 0644]
queue-6.6/drm-mediatek-only-touch-disp_reg_ovl_pitch_msb-if-af.patch [new file with mode: 0644]
queue-6.6/fs-kconfig-make-hugetlbfs-a-menuconfig.patch [new file with mode: 0644]
queue-6.6/hwmon-drivetemp-fix-driver-producing-garbage-data-wh.patch [new file with mode: 0644]
queue-6.6/mm-hugetlb-enforce-that-pmd-pt-sharing-has-split-pmd.patch [new file with mode: 0644]
queue-6.6/mm-hugetlb-independent-pmd-page-table-shared-count.patch [new file with mode: 0644]
queue-6.6/pgtable-fix-s390-ptdesc-field-comments.patch [new file with mode: 0644]
queue-6.6/pmdomain-imx-gpcv2-fix-an-of-node-reference-leak-in-.patch [new file with mode: 0644]
queue-6.6/pmdomain-imx-gpcv2-simplify-with-scoped-for-each-of-.patch [new file with mode: 0644]
queue-6.6/riscv-fix-text-patching-when-ipi-are-used.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/workqueue-add-rcu-lock-check-at-the-end-of-work-item.patch [new file with mode: 0644]
queue-6.6/workqueue-do-not-warn-when-cancelling-wq_mem_reclaim.patch [new file with mode: 0644]
queue-6.6/workqueue-update-lock-debugging-code.patch [new file with mode: 0644]

diff --git a/queue-6.6/arm-dts-imxrt1050-fix-clocks-for-mmc.patch b/queue-6.6/arm-dts-imxrt1050-fix-clocks-for-mmc.patch
new file mode 100644 (file)
index 0000000..8329d1c
--- /dev/null
@@ -0,0 +1,36 @@
+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
+
diff --git a/queue-6.6/arm64-dts-rockchip-add-hevc-power-domain-clock-to-rk.patch b/queue-6.6/arm64-dts-rockchip-add-hevc-power-domain-clock-to-rk.patch
new file mode 100644 (file)
index 0000000..517bd0d
--- /dev/null
@@ -0,0 +1,76 @@
+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
+
diff --git a/queue-6.6/block-bfq-fix-waker_bfqq-uaf-after-bfq_split_bfqq.patch b/queue-6.6/block-bfq-fix-waker_bfqq-uaf-after-bfq_split_bfqq.patch
new file mode 100644 (file)
index 0000000..cb43878
--- /dev/null
@@ -0,0 +1,199 @@
+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
+
diff --git a/queue-6.6/drm-mediatek-only-touch-disp_reg_ovl_pitch_msb-if-af.patch b/queue-6.6/drm-mediatek-only-touch-disp_reg_ovl_pitch_msb-if-af.patch
new file mode 100644 (file)
index 0000000..9cb9246
--- /dev/null
@@ -0,0 +1,128 @@
+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
+
diff --git a/queue-6.6/fs-kconfig-make-hugetlbfs-a-menuconfig.patch b/queue-6.6/fs-kconfig-make-hugetlbfs-a-menuconfig.patch
new file mode 100644 (file)
index 0000000..2d0ab92
--- /dev/null
@@ -0,0 +1,78 @@
+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
+
diff --git a/queue-6.6/hwmon-drivetemp-fix-driver-producing-garbage-data-wh.patch b/queue-6.6/hwmon-drivetemp-fix-driver-producing-garbage-data-wh.patch
new file mode 100644 (file)
index 0000000..275c2e2
--- /dev/null
@@ -0,0 +1,70 @@
+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
+
diff --git a/queue-6.6/mm-hugetlb-enforce-that-pmd-pt-sharing-has-split-pmd.patch b/queue-6.6/mm-hugetlb-enforce-that-pmd-pt-sharing-has-split-pmd.patch
new file mode 100644 (file)
index 0000000..318d271
--- /dev/null
@@ -0,0 +1,125 @@
+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
+
diff --git a/queue-6.6/mm-hugetlb-independent-pmd-page-table-shared-count.patch b/queue-6.6/mm-hugetlb-independent-pmd-page-table-shared-count.patch
new file mode 100644 (file)
index 0000000..a81748d
--- /dev/null
@@ -0,0 +1,206 @@
+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
+
diff --git a/queue-6.6/pgtable-fix-s390-ptdesc-field-comments.patch b/queue-6.6/pgtable-fix-s390-ptdesc-field-comments.patch
new file mode 100644 (file)
index 0000000..ade1122
--- /dev/null
@@ -0,0 +1,50 @@
+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
+
diff --git a/queue-6.6/pmdomain-imx-gpcv2-fix-an-of-node-reference-leak-in-.patch b/queue-6.6/pmdomain-imx-gpcv2-fix-an-of-node-reference-leak-in-.patch
new file mode 100644 (file)
index 0000000..226ca09
--- /dev/null
@@ -0,0 +1,49 @@
+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
+
diff --git a/queue-6.6/pmdomain-imx-gpcv2-simplify-with-scoped-for-each-of-.patch b/queue-6.6/pmdomain-imx-gpcv2-simplify-with-scoped-for-each-of-.patch
new file mode 100644 (file)
index 0000000..2ebb276
--- /dev/null
@@ -0,0 +1,78 @@
+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
+
diff --git a/queue-6.6/riscv-fix-text-patching-when-ipi-are-used.patch b/queue-6.6/riscv-fix-text-patching-when-ipi-are-used.patch
new file mode 100644 (file)
index 0000000..290443b
--- /dev/null
@@ -0,0 +1,172 @@
+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(&param->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(&param->cpu_count);
++      } else {
++              while (atomic_read(&param->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, &param, 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
+
index d6712b0cc5ca9327c735321920191d67a11f4961..38e47c43d18b9723d330adf1715d7ff763de7211 100644 (file)
@@ -114,3 +114,18 @@ iio-inkern-call-iio_device_put-only-on-mapped-devices.patch
 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
diff --git a/queue-6.6/workqueue-add-rcu-lock-check-at-the-end-of-work-item.patch b/queue-6.6/workqueue-add-rcu-lock-check-at-the-end-of-work-item.patch
new file mode 100644 (file)
index 0000000..8ce9559
--- /dev/null
@@ -0,0 +1,58 @@
+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
+
diff --git a/queue-6.6/workqueue-do-not-warn-when-cancelling-wq_mem_reclaim.patch b/queue-6.6/workqueue-do-not-warn-when-cancelling-wq_mem_reclaim.patch
new file mode 100644 (file)
index 0000000..4b95dcf
--- /dev/null
@@ -0,0 +1,124 @@
+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
+
diff --git a/queue-6.6/workqueue-update-lock-debugging-code.patch b/queue-6.6/workqueue-update-lock-debugging-code.patch
new file mode 100644 (file)
index 0000000..0909bc3
--- /dev/null
@@ -0,0 +1,156 @@
+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
+