]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.17-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 9 Nov 2025 03:20:50 +0000 (12:20 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 9 Nov 2025 03:20:50 +0000 (12:20 +0900)
added patches:
bluetooth-mgmt-fix-oob-access-in-parse_adv_monitor_pattern.patch
drm-amd-display-enable-mst-when-it-s-detected-but-yet-to-be-initialized.patch
drm-amd-display-fix-null-deref-in-debugfs-odm_combine_segments.patch
drm-amdgpu-smu-handle-s0ix-for-vangogh.patch
drm-amdkfd-don-t-clear-pt-after-process-killed.patch
drm-define-nvidia-drm-format-modifiers-for-gb20x.patch
drm-nouveau-advertise-correct-modifiers-on-gb20x.patch
drm-sched-fix-deadlock-in-drm_sched_entity_kill_jobs_cb.patch
fscrypt-fix-left-shift-underflow-when-inode-i_blkbits-page_shift.patch
io_uring-fix-regbuf-vector-size-truncation.patch
iommufd-don-t-overflow-during-division-for-dirty-tracking.patch
lib-crypto-curve25519-hacl64-fix-older-clang-kasan-workaround-for-gcc.patch
parisc-avoid-crash-due-to-unaligned-access-in-unwinder.patch
perf-core-fix-system-hang-caused-by-cpu-clock-usage.patch
platform-x86-int3472-fix-double-free-of-gpio-device-during-unregister.patch
riscv-fix-memory-leak-in-module_frob_arch_sections.patch
rtc-rx8025-fix-incorrect-register-reference.patch
scsi-ufs-core-add-a-quirk-to-suppress-link_startup_again.patch
scsi-ufs-core-fix-invalid-probe-error-return-value.patch
scsi-ufs-ufs-pci-fix-s0ix-s3-for-intel-controllers.patch
scsi-ufs-ufs-pci-set-ufshcd_quirk_perform_link_startup_once-for-intel-adl.patch
smb-client-fix-potential-uaf-in-smb2_close_cached_fid.patch
smb-client-validate-change-notify-buffer-before-copy.patch
virtio-net-fix-received-length-check-in-big-packets.patch
virtio_net-fix-alignment-for-virtio_net_hdr_v1_hash.patch
wifi-cfg80211-add-an-hrtimer-based-delayed-work-item.patch
wifi-mac80211-use-wiphy_hrtimer_work-for-csa.switch_work.patch
wifi-mac80211-use-wiphy_hrtimer_work-for-ml_reconf_work.patch
wifi-mac80211-use-wiphy_hrtimer_work-for-ttlm_work.patch
x86-amd_node-fix-amd-root-device-caching.patch
x86-cpu-amd-add-missing-terminator-for-zen5_rdseed_microcode.patch
x86-microcode-amd-add-more-known-models-to-entry-sign-checking.patch
xfs-fix-delalloc-write-failures-in-software-provided-atomic-writes.patch
xfs-fix-various-problems-in-xfs_atomic_write_cow_iomap_begin.patch

35 files changed:
queue-6.17/bluetooth-mgmt-fix-oob-access-in-parse_adv_monitor_pattern.patch [new file with mode: 0644]
queue-6.17/drm-amd-display-enable-mst-when-it-s-detected-but-yet-to-be-initialized.patch [new file with mode: 0644]
queue-6.17/drm-amd-display-fix-null-deref-in-debugfs-odm_combine_segments.patch [new file with mode: 0644]
queue-6.17/drm-amdgpu-smu-handle-s0ix-for-vangogh.patch [new file with mode: 0644]
queue-6.17/drm-amdkfd-don-t-clear-pt-after-process-killed.patch [new file with mode: 0644]
queue-6.17/drm-define-nvidia-drm-format-modifiers-for-gb20x.patch [new file with mode: 0644]
queue-6.17/drm-nouveau-advertise-correct-modifiers-on-gb20x.patch [new file with mode: 0644]
queue-6.17/drm-sched-fix-deadlock-in-drm_sched_entity_kill_jobs_cb.patch [new file with mode: 0644]
queue-6.17/fscrypt-fix-left-shift-underflow-when-inode-i_blkbits-page_shift.patch [new file with mode: 0644]
queue-6.17/io_uring-fix-regbuf-vector-size-truncation.patch [new file with mode: 0644]
queue-6.17/iommufd-don-t-overflow-during-division-for-dirty-tracking.patch [new file with mode: 0644]
queue-6.17/lib-crypto-curve25519-hacl64-fix-older-clang-kasan-workaround-for-gcc.patch [new file with mode: 0644]
queue-6.17/parisc-avoid-crash-due-to-unaligned-access-in-unwinder.patch [new file with mode: 0644]
queue-6.17/perf-core-fix-system-hang-caused-by-cpu-clock-usage.patch [new file with mode: 0644]
queue-6.17/platform-x86-int3472-fix-double-free-of-gpio-device-during-unregister.patch [new file with mode: 0644]
queue-6.17/riscv-fix-memory-leak-in-module_frob_arch_sections.patch [new file with mode: 0644]
queue-6.17/rtc-rx8025-fix-incorrect-register-reference.patch [new file with mode: 0644]
queue-6.17/scsi-ufs-core-add-a-quirk-to-suppress-link_startup_again.patch [new file with mode: 0644]
queue-6.17/scsi-ufs-core-fix-invalid-probe-error-return-value.patch [new file with mode: 0644]
queue-6.17/scsi-ufs-ufs-pci-fix-s0ix-s3-for-intel-controllers.patch [new file with mode: 0644]
queue-6.17/scsi-ufs-ufs-pci-set-ufshcd_quirk_perform_link_startup_once-for-intel-adl.patch [new file with mode: 0644]
queue-6.17/series
queue-6.17/smb-client-fix-potential-uaf-in-smb2_close_cached_fid.patch [new file with mode: 0644]
queue-6.17/smb-client-validate-change-notify-buffer-before-copy.patch [new file with mode: 0644]
queue-6.17/virtio-net-fix-received-length-check-in-big-packets.patch [new file with mode: 0644]
queue-6.17/virtio_net-fix-alignment-for-virtio_net_hdr_v1_hash.patch [new file with mode: 0644]
queue-6.17/wifi-cfg80211-add-an-hrtimer-based-delayed-work-item.patch [new file with mode: 0644]
queue-6.17/wifi-mac80211-use-wiphy_hrtimer_work-for-csa.switch_work.patch [new file with mode: 0644]
queue-6.17/wifi-mac80211-use-wiphy_hrtimer_work-for-ml_reconf_work.patch [new file with mode: 0644]
queue-6.17/wifi-mac80211-use-wiphy_hrtimer_work-for-ttlm_work.patch [new file with mode: 0644]
queue-6.17/x86-amd_node-fix-amd-root-device-caching.patch [new file with mode: 0644]
queue-6.17/x86-cpu-amd-add-missing-terminator-for-zen5_rdseed_microcode.patch [new file with mode: 0644]
queue-6.17/x86-microcode-amd-add-more-known-models-to-entry-sign-checking.patch [new file with mode: 0644]
queue-6.17/xfs-fix-delalloc-write-failures-in-software-provided-atomic-writes.patch [new file with mode: 0644]
queue-6.17/xfs-fix-various-problems-in-xfs_atomic_write_cow_iomap_begin.patch [new file with mode: 0644]

diff --git a/queue-6.17/bluetooth-mgmt-fix-oob-access-in-parse_adv_monitor_pattern.patch b/queue-6.17/bluetooth-mgmt-fix-oob-access-in-parse_adv_monitor_pattern.patch
new file mode 100644 (file)
index 0000000..6d27999
--- /dev/null
@@ -0,0 +1,60 @@
+From 8d59fba49362c65332395789fd82771f1028d87e Mon Sep 17 00:00:00 2001
+From: Ilia Gavrilov <Ilia.Gavrilov@infotecs.ru>
+Date: Mon, 20 Oct 2025 15:12:55 +0000
+Subject: Bluetooth: MGMT: Fix OOB access in parse_adv_monitor_pattern()
+
+From: Ilia Gavrilov <Ilia.Gavrilov@infotecs.ru>
+
+commit 8d59fba49362c65332395789fd82771f1028d87e upstream.
+
+In the parse_adv_monitor_pattern() function, the value of
+the 'length' variable is currently limited to HCI_MAX_EXT_AD_LENGTH(251).
+The size of the 'value' array in the mgmt_adv_pattern structure is 31.
+If the value of 'pattern[i].length' is set in the user space
+and exceeds 31, the 'patterns[i].value' array can be accessed
+out of bound when copied.
+
+Increasing the size of the 'value' array in
+the 'mgmt_adv_pattern' structure will break the userspace.
+Considering this, and to avoid OOB access revert the limits for 'offset'
+and 'length' back to the value of HCI_MAX_AD_LENGTH.
+
+Found by InfoTeCS on behalf of Linux Verification Center
+(linuxtesting.org) with SVACE.
+
+Fixes: db08722fc7d4 ("Bluetooth: hci_core: Fix missing instances using HCI_MAX_AD_LENGTH")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ilia Gavrilov <Ilia.Gavrilov@infotecs.ru>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/bluetooth/mgmt.h |    2 +-
+ net/bluetooth/mgmt.c         |    6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/include/net/bluetooth/mgmt.h
++++ b/include/net/bluetooth/mgmt.h
+@@ -775,7 +775,7 @@ struct mgmt_adv_pattern {
+       __u8 ad_type;
+       __u8 offset;
+       __u8 length;
+-      __u8 value[31];
++      __u8 value[HCI_MAX_AD_LENGTH];
+ } __packed;
+ #define MGMT_OP_ADD_ADV_PATTERNS_MONITOR      0x0052
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -5395,9 +5395,9 @@ static u8 parse_adv_monitor_pattern(stru
+       for (i = 0; i < pattern_count; i++) {
+               offset = patterns[i].offset;
+               length = patterns[i].length;
+-              if (offset >= HCI_MAX_EXT_AD_LENGTH ||
+-                  length > HCI_MAX_EXT_AD_LENGTH ||
+-                  (offset + length) > HCI_MAX_EXT_AD_LENGTH)
++              if (offset >= HCI_MAX_AD_LENGTH ||
++                  length > HCI_MAX_AD_LENGTH ||
++                  (offset + length) > HCI_MAX_AD_LENGTH)
+                       return MGMT_STATUS_INVALID_PARAMS;
+               p = kmalloc(sizeof(*p), GFP_KERNEL);
diff --git a/queue-6.17/drm-amd-display-enable-mst-when-it-s-detected-but-yet-to-be-initialized.patch b/queue-6.17/drm-amd-display-enable-mst-when-it-s-detected-but-yet-to-be-initialized.patch
new file mode 100644 (file)
index 0000000..5332e52
--- /dev/null
@@ -0,0 +1,63 @@
+From 3c6a743c6961cc2cab453b343bb157d6bbbf8120 Mon Sep 17 00:00:00 2001
+From: Wayne Lin <Wayne.Lin@amd.com>
+Date: Wed, 5 Nov 2025 10:36:31 +0800
+Subject: drm/amd/display: Enable mst when it's detected but yet to be initialized
+
+From: Wayne Lin <Wayne.Lin@amd.com>
+
+commit 3c6a743c6961cc2cab453b343bb157d6bbbf8120 upstream.
+
+[Why]
+drm_dp_mst_topology_queue_probe() is used under the assumption that
+mst is already initialized. If we connect system with SST first
+then switch to the mst branch during suspend, we will fail probing
+topology by calling the wrong API since the mst manager is yet to
+be initialized.
+
+[How]
+At dm_resume(), once it's detected as mst branc connected, check if
+the mst is initialized already. If not, call
+dm_helpers_dp_mst_start_top_mgr() instead to initialize mst
+
+V2: Adjust the commit msg a bit
+
+Fixes: bc068194f548 ("drm/amd/display: Don't write DP_MSTM_CTRL after LT")
+Cc: Fangzhi Zuo <jerry.zuo@amd.com>
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Tom Chung <chiahsuan.chung@amd.com>
+Signed-off-by: Wayne Lin <Wayne.Lin@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 62320fb8d91a0bddc44a228203cfa9bfbb5395bd)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -3574,6 +3574,7 @@ static int dm_resume(struct amdgpu_ip_bl
+       /* Do mst topology probing after resuming cached state*/
+       drm_connector_list_iter_begin(ddev, &iter);
+       drm_for_each_connector_iter(connector, &iter) {
++              bool init = false;
+               if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+                       continue;
+@@ -3583,7 +3584,14 @@ static int dm_resume(struct amdgpu_ip_bl
+                   aconnector->mst_root)
+                       continue;
+-              drm_dp_mst_topology_queue_probe(&aconnector->mst_mgr);
++              scoped_guard(mutex, &aconnector->mst_mgr.lock) {
++                      init = !aconnector->mst_mgr.mst_primary;
++              }
++              if (init)
++                      dm_helpers_dp_mst_start_top_mgr(aconnector->dc_link->ctx,
++                              aconnector->dc_link, false);
++              else
++                      drm_dp_mst_topology_queue_probe(&aconnector->mst_mgr);
+       }
+       drm_connector_list_iter_end(&iter);
diff --git a/queue-6.17/drm-amd-display-fix-null-deref-in-debugfs-odm_combine_segments.patch b/queue-6.17/drm-amd-display-fix-null-deref-in-debugfs-odm_combine_segments.patch
new file mode 100644 (file)
index 0000000..dc0d90d
--- /dev/null
@@ -0,0 +1,101 @@
+From 6dd97ceb645c08aca9fc871a3006e47fe699f0ac Mon Sep 17 00:00:00 2001
+From: Rong Zhang <i@rong.moe>
+Date: Tue, 14 Oct 2025 00:47:35 +0800
+Subject: drm/amd/display: Fix NULL deref in debugfs odm_combine_segments
+
+From: Rong Zhang <i@rong.moe>
+
+commit 6dd97ceb645c08aca9fc871a3006e47fe699f0ac upstream.
+
+When a connector is connected but inactive (e.g., disabled by desktop
+environments), pipe_ctx->stream_res.tg will be destroyed. Then, reading
+odm_combine_segments causes kernel NULL pointer dereference.
+
+ BUG: kernel NULL pointer dereference, address: 0000000000000000
+ #PF: supervisor read access in kernel mode
+ #PF: error_code(0x0000) - not-present page
+ PGD 0 P4D 0
+ Oops: Oops: 0000 [#1] SMP NOPTI
+ CPU: 16 UID: 0 PID: 26474 Comm: cat Not tainted 6.17.0+ #2 PREEMPT(lazy)  e6a17af9ee6db7c63e9d90dbe5b28ccab67520c6
+ Hardware name: LENOVO 21Q4/LNVNB161216, BIOS PXCN25WW 03/27/2025
+ RIP: 0010:odm_combine_segments_show+0x93/0xf0 [amdgpu]
+ Code: 41 83 b8 b0 00 00 00 01 75 6e 48 98 ba a1 ff ff ff 48 c1 e0 0c 48 8d 8c 07 d8 02 00 00 48 85 c9 74 2d 48 8b bc 07 f0 08 00 00 <48> 8b 07 48 8b 80 08 02 00>
+ RSP: 0018:ffffd1bf4b953c58 EFLAGS: 00010286
+ RAX: 0000000000005000 RBX: ffff8e35976b02d0 RCX: ffff8e3aeed052d8
+ RDX: 00000000ffffffa1 RSI: ffff8e35a3120800 RDI: 0000000000000000
+ RBP: 0000000000000000 R08: ffff8e3580eb0000 R09: ffff8e35976b02d0
+ R10: ffffd1bf4b953c78 R11: 0000000000000000 R12: ffffd1bf4b953d08
+ R13: 0000000000040000 R14: 0000000000000001 R15: 0000000000000001
+ FS:  00007f44d3f9f740(0000) GS:ffff8e3caa47f000(0000) knlGS:0000000000000000
+ CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 0000000000000000 CR3: 00000006485c2000 CR4: 0000000000f50ef0
+ PKRU: 55555554
+ Call Trace:
+  <TASK>
+  seq_read_iter+0x125/0x490
+  ? __alloc_frozen_pages_noprof+0x18f/0x350
+  seq_read+0x12c/0x170
+  full_proxy_read+0x51/0x80
+  vfs_read+0xbc/0x390
+  ? __handle_mm_fault+0xa46/0xef0
+  ? do_syscall_64+0x71/0x900
+  ksys_read+0x73/0xf0
+  do_syscall_64+0x71/0x900
+  ? count_memcg_events+0xc2/0x190
+  ? handle_mm_fault+0x1d7/0x2d0
+  ? do_user_addr_fault+0x21a/0x690
+  ? exc_page_fault+0x7e/0x1a0
+  entry_SYSCALL_64_after_hwframe+0x6c/0x74
+ RIP: 0033:0x7f44d4031687
+ Code: 48 89 fa 4c 89 df e8 58 b3 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00>
+ RSP: 002b:00007ffdb4b5f0b0 EFLAGS: 00000202 ORIG_RAX: 0000000000000000
+ RAX: ffffffffffffffda RBX: 00007f44d3f9f740 RCX: 00007f44d4031687
+ RDX: 0000000000040000 RSI: 00007f44d3f5e000 RDI: 0000000000000003
+ RBP: 0000000000040000 R08: 0000000000000000 R09: 0000000000000000
+ R10: 0000000000000000 R11: 0000000000000202 R12: 00007f44d3f5e000
+ R13: 0000000000000003 R14: 0000000000000000 R15: 0000000000040000
+  </TASK>
+ Modules linked in: tls tcp_diag inet_diag xt_mark ccm snd_hrtimer snd_seq_dummy snd_seq_midi snd_seq_oss snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device x>
+  snd_hda_codec_atihdmi snd_hda_codec_realtek_lib lenovo_wmi_helpers think_lmi snd_hda_codec_generic snd_hda_codec_hdmi snd_soc_core kvm snd_compress uvcvideo sn>
+  platform_profile joydev amd_pmc mousedev mac_hid sch_fq_codel uinput i2c_dev parport_pc ppdev lp parport nvme_fabrics loop nfnetlink ip_tables x_tables dm_cryp>
+ CR2: 0000000000000000
+ ---[ end trace 0000000000000000 ]---
+ RIP: 0010:odm_combine_segments_show+0x93/0xf0 [amdgpu]
+ Code: 41 83 b8 b0 00 00 00 01 75 6e 48 98 ba a1 ff ff ff 48 c1 e0 0c 48 8d 8c 07 d8 02 00 00 48 85 c9 74 2d 48 8b bc 07 f0 08 00 00 <48> 8b 07 48 8b 80 08 02 00>
+ RSP: 0018:ffffd1bf4b953c58 EFLAGS: 00010286
+ RAX: 0000000000005000 RBX: ffff8e35976b02d0 RCX: ffff8e3aeed052d8
+ RDX: 00000000ffffffa1 RSI: ffff8e35a3120800 RDI: 0000000000000000
+ RBP: 0000000000000000 R08: ffff8e3580eb0000 R09: ffff8e35976b02d0
+ R10: ffffd1bf4b953c78 R11: 0000000000000000 R12: ffffd1bf4b953d08
+ R13: 0000000000040000 R14: 0000000000000001 R15: 0000000000000001
+ FS:  00007f44d3f9f740(0000) GS:ffff8e3caa47f000(0000) knlGS:0000000000000000
+ CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 0000000000000000 CR3: 00000006485c2000 CR4: 0000000000f50ef0
+ PKRU: 55555554
+
+Fix this by checking pipe_ctx->stream_res.tg before dereferencing.
+
+Fixes: 07926ba8a44f ("drm/amd/display: Add debugfs interface for ODM combine info")
+Signed-off-by: Rong Zhang <i@rong.moe>
+Reviewed-by: Mario Limoncello <mario.limonciello@amd.com>
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit f19bbecd34e3c15eed7e5e593db2ac0fc7a0e6d8)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+@@ -1301,7 +1301,8 @@ static int odm_combine_segments_show(str
+       if (connector->status != connector_status_connected)
+               return -ENODEV;
+-      if (pipe_ctx != NULL && pipe_ctx->stream_res.tg->funcs->get_odm_combine_segments)
++      if (pipe_ctx && pipe_ctx->stream_res.tg &&
++          pipe_ctx->stream_res.tg->funcs->get_odm_combine_segments)
+               pipe_ctx->stream_res.tg->funcs->get_odm_combine_segments(pipe_ctx->stream_res.tg, &segments);
+       seq_printf(m, "%d\n", segments);
diff --git a/queue-6.17/drm-amdgpu-smu-handle-s0ix-for-vangogh.patch b/queue-6.17/drm-amdgpu-smu-handle-s0ix-for-vangogh.patch
new file mode 100644 (file)
index 0000000..e4784f1
--- /dev/null
@@ -0,0 +1,53 @@
+From 7c5609b72bfe57d8c601d9561e0d2551b605c017 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Fri, 24 Oct 2025 13:08:11 -0400
+Subject: drm/amdgpu/smu: Handle S0ix for vangogh
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 7c5609b72bfe57d8c601d9561e0d2551b605c017 upstream.
+
+Fix the flows for S0ix.  There is no need to stop
+rlc or reintialize PMFW in S0ix.
+
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4659
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Reported-by: Antheas Kapenekakis <lkml@antheas.dev>
+Tested-by: Antheas Kapenekakis <lkml@antheas.dev>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit fd39b5a5830d8f2553e0c09d4d50bdff28b10080)
+Cc: <stable@vger.kernel.org> # c81f5cebe849: drm/amdgpu: Drop PMFW RLC notifier from amdgpu_device_suspend()
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c        |    6 ++++++
+ drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c |    3 +++
+ 2 files changed, 9 insertions(+)
+
+--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+@@ -2012,6 +2012,12 @@ static int smu_disable_dpms(struct smu_c
+           smu->is_apu && (amdgpu_in_reset(adev) || adev->in_s0ix))
+               return 0;
++      /* vangogh s0ix */
++      if ((amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 5, 0) ||
++           amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 5, 2)) &&
++          adev->in_s0ix)
++              return 0;
++
+       /*
+        * For gpu reset, runpm and hibernation through BACO,
+        * BACO feature has to be kept enabled.
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
+@@ -2217,6 +2217,9 @@ static int vangogh_post_smu_init(struct
+       uint32_t total_cu = adev->gfx.config.max_cu_per_sh *
+               adev->gfx.config.max_sh_per_se * adev->gfx.config.max_shader_engines;
++      if (adev->in_s0ix)
++              return 0;
++
+       /* allow message will be sent after enable message on Vangogh*/
+       if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT) &&
+                       (adev->pg_flags & AMD_PG_SUPPORT_GFX_PG)) {
diff --git a/queue-6.17/drm-amdkfd-don-t-clear-pt-after-process-killed.patch b/queue-6.17/drm-amdkfd-don-t-clear-pt-after-process-killed.patch
new file mode 100644 (file)
index 0000000..e26659d
--- /dev/null
@@ -0,0 +1,40 @@
+From 597eb70f7ff7551ff795cd51754b81aabedab67b Mon Sep 17 00:00:00 2001
+From: Philip Yang <Philip.Yang@amd.com>
+Date: Fri, 31 Oct 2025 10:50:02 -0400
+Subject: drm/amdkfd: Don't clear PT after process killed
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Philip Yang <Philip.Yang@amd.com>
+
+commit 597eb70f7ff7551ff795cd51754b81aabedab67b upstream.
+
+If process is killed. the vm entity is stopped, submit pt update job
+will trigger the error message "*ERROR* Trying to push to a killed
+entity", job will not execute.
+
+Suggested-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Philip Yang <Philip.Yang@amd.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 10c382ec6c6d1e11975a11962bec21cba6360391)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -1263,6 +1263,10 @@ static int unmap_bo_from_gpuvm(struct kg
+       (void)amdgpu_vm_bo_unmap(adev, bo_va, entry->va);
++      /* VM entity stopped if process killed, don't clear freed pt bo */
++      if (!amdgpu_vm_ready(vm))
++              return 0;
++
+       (void)amdgpu_vm_clear_freed(adev, vm, &bo_va->last_pt_update);
+       (void)amdgpu_sync_fence(sync, bo_va->last_pt_update, GFP_KERNEL);
diff --git a/queue-6.17/drm-define-nvidia-drm-format-modifiers-for-gb20x.patch b/queue-6.17/drm-define-nvidia-drm-format-modifiers-for-gb20x.patch
new file mode 100644 (file)
index 0000000..c3fb1b0
--- /dev/null
@@ -0,0 +1,97 @@
+From 1cf52a0d4ba079fb354fa1339f5fb34142228dae Mon Sep 17 00:00:00 2001
+From: James Jones <jajones@nvidia.com>
+Date: Thu, 30 Oct 2025 11:11:52 -0700
+Subject: drm: define NVIDIA DRM format modifiers for GB20x
+
+From: James Jones <jajones@nvidia.com>
+
+commit 1cf52a0d4ba079fb354fa1339f5fb34142228dae upstream.
+
+The layout of bits within the individual tiles
+(referred to as sectors in the
+DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D() macro)
+changed for 8 and 16-bit surfaces starting in
+Blackwell 2 GPUs (With the exception of GB10).
+To denote the difference, extend the sector field
+in the parametric format modifier definition used
+to generate modifier values for NVIDIA hardware.
+
+Without this change, it would be impossible to
+differentiate the two layouts based on modifiers,
+and as a result software could attempt to share
+surfaces directly between pre-GB20x and GB20x
+cards, resulting in corruption when the surface
+was accessed on one of the GPUs after being
+populated with content by the other.
+
+Of note: This change causes the
+DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D() macro to
+evaluate its "s" parameter twice, with the side
+effects that entails. I surveyed all usage of the
+modifier in the kernel and Mesa code, and that
+does not appear to be problematic in any current
+usage, but I thought it was worth calling out.
+
+Fixes: 6cc6e08d4542 ("drm/nouveau/kms: add support for GB20x")
+Signed-off-by: James Jones <jajones@nvidia.com>
+Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20251030181153.1208-2-jajones@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/uapi/drm/drm_fourcc.h | 23 +++++++++++++++--------
+ 1 file changed, 15 insertions(+), 8 deletions(-)
+
+diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
+index ea91aa8afde9..e527b24bd824 100644
+--- a/include/uapi/drm/drm_fourcc.h
++++ b/include/uapi/drm/drm_fourcc.h
+@@ -979,14 +979,20 @@ extern "C" {
+  *               2 = Gob Height 8, Turing+ Page Kind mapping
+  *               3 = Reserved for future use.
+  *
+- * 22:22 s     Sector layout.  On Tegra GPUs prior to Xavier, there is a further
+- *             bit remapping step that occurs at an even lower level than the
+- *             page kind and block linear swizzles.  This causes the layout of
+- *             surfaces mapped in those SOC's GPUs to be incompatible with the
+- *             equivalent mapping on other GPUs in the same system.
++ * 22:22 s     Sector layout.  There is a further bit remapping step that occurs
++ * 26:27       at an even lower level than the page kind and block linear
++ *             swizzles.  This causes the bit arrangement of surfaces in memory
++ *             to differ subtly, and prevents direct sharing of surfaces between
++ *             GPUs with different layouts.
+  *
+- *               0 = Tegra K1 - Tegra Parker/TX2 Layout.
+- *               1 = Desktop GPU and Tegra Xavier+ Layout
++ *               0 = Tegra K1 - Tegra Parker/TX2 Layout
++ *               1 = Pre-GB20x, GB20x 32+ bpp, GB10, Tegra Xavier-Orin Layout
++ *               2 = GB20x(Blackwell 2)+ 8 bpp surface layout
++ *               3 = GB20x(Blackwell 2)+ 16 bpp surface layout
++ *               4 = Reserved for future use.
++ *               5 = Reserved for future use.
++ *               6 = Reserved for future use.
++ *               7 = Reserved for future use.
+  *
+  * 25:23 c     Lossless Framebuffer Compression type.
+  *
+@@ -1001,7 +1007,7 @@ extern "C" {
+  *               6 = Reserved for future use
+  *               7 = Reserved for future use
+  *
+- * 55:25 -     Reserved for future use.  Must be zero.
++ * 55:28 -     Reserved for future use.  Must be zero.
+  */
+ #define DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(c, s, g, k, h) \
+       fourcc_mod_code(NVIDIA, (0x10 | \
+@@ -1009,6 +1015,7 @@ extern "C" {
+                                (((k) & 0xff) << 12) | \
+                                (((g) & 0x3) << 20) | \
+                                (((s) & 0x1) << 22) | \
++                               (((s) & 0x6) << 25) | \
+                                (((c) & 0x7) << 23)))
+ /* To grandfather in prior block linear format modifiers to the above layout,
+-- 
+2.51.2
+
diff --git a/queue-6.17/drm-nouveau-advertise-correct-modifiers-on-gb20x.patch b/queue-6.17/drm-nouveau-advertise-correct-modifiers-on-gb20x.patch
new file mode 100644 (file)
index 0000000..c7365b0
--- /dev/null
@@ -0,0 +1,150 @@
+From 664ce10246ba00746af94a08b7fbda8ccaacd930 Mon Sep 17 00:00:00 2001
+From: James Jones <jajones@nvidia.com>
+Date: Thu, 30 Oct 2025 11:11:53 -0700
+Subject: drm/nouveau: Advertise correct modifiers on GB20x
+
+From: James Jones <jajones@nvidia.com>
+
+commit 664ce10246ba00746af94a08b7fbda8ccaacd930 upstream.
+
+8 and 16 bit formats use a different layout on
+GB20x than they did on prior chips. Add the
+corresponding DRM format modifiers to the list of
+modifiers supported by the display engine on such
+chips, and filter the supported modifiers for each
+format based on its bytes per pixel in
+nv50_plane_format_mod_supported().
+
+Note this logic will need to be updated when GB10
+support is added, since it is a GB20x chip that
+uses the pre-GB20x sector layout for all formats.
+
+Fixes: 6cc6e08d4542 ("drm/nouveau/kms: add support for GB20x")
+Signed-off-by: James Jones <jajones@nvidia.com>
+Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20251030181153.1208-3-jajones@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/nouveau/dispnv50/disp.c     |    4 ++-
+ drivers/gpu/drm/nouveau/dispnv50/disp.h     |    1 
+ drivers/gpu/drm/nouveau/dispnv50/wndw.c     |   24 ++++++++++++++++++--
+ drivers/gpu/drm/nouveau/dispnv50/wndwca7e.c |   33 ++++++++++++++++++++++++++++
+ 4 files changed, 59 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
++++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
+@@ -2867,7 +2867,9 @@ nv50_display_create(struct drm_device *d
+       }
+       /* Assign the correct format modifiers */
+-      if (disp->disp->object.oclass >= TU102_DISP)
++      if (disp->disp->object.oclass >= GB202_DISP)
++              nouveau_display(dev)->format_modifiers = wndwca7e_modifiers;
++      else if (disp->disp->object.oclass >= TU102_DISP)
+               nouveau_display(dev)->format_modifiers = wndwc57e_modifiers;
+       else
+       if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_FERMI)
+--- a/drivers/gpu/drm/nouveau/dispnv50/disp.h
++++ b/drivers/gpu/drm/nouveau/dispnv50/disp.h
+@@ -104,4 +104,5 @@ struct nouveau_encoder *nv50_real_outp(s
+ extern const u64 disp50xx_modifiers[];
+ extern const u64 disp90xx_modifiers[];
+ extern const u64 wndwc57e_modifiers[];
++extern const u64 wndwca7e_modifiers[];
+ #endif
+--- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c
++++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
+@@ -786,13 +786,14 @@ nv50_wndw_destroy(struct drm_plane *plan
+ }
+ /* This function assumes the format has already been validated against the plane
+- * and the modifier was validated against the device-wides modifier list at FB
++ * and the modifier was validated against the device-wide modifier list at FB
+  * creation time.
+  */
+ static bool nv50_plane_format_mod_supported(struct drm_plane *plane,
+                                           u32 format, u64 modifier)
+ {
+       struct nouveau_drm *drm = nouveau_drm(plane->dev);
++      const struct drm_format_info *info = drm_format_info(format);
+       uint8_t i;
+       /* All chipsets can display all formats in linear layout */
+@@ -800,13 +801,32 @@ static bool nv50_plane_format_mod_suppor
+               return true;
+       if (drm->client.device.info.chipset < 0xc0) {
+-              const struct drm_format_info *info = drm_format_info(format);
+               const uint8_t kind = (modifier >> 12) & 0xff;
+               if (!format) return false;
+               for (i = 0; i < info->num_planes; i++)
+                       if ((info->cpp[i] != 4) && kind != 0x70) return false;
++      } else if (drm->client.device.info.chipset >= 0x1b2) {
++              const uint8_t slayout = ((modifier >> 22) & 0x1) |
++                      ((modifier >> 25) & 0x6);
++
++              if (!format)
++                      return false;
++
++              /*
++               * Note in practice this implies only formats where cpp is equal
++               * for each plane, or >= 4 for all planes, are supported.
++               */
++              for (i = 0; i < info->num_planes; i++) {
++                      if (((info->cpp[i] == 2) && slayout != 3) ||
++                          ((info->cpp[i] == 1) && slayout != 2) ||
++                          ((info->cpp[i] >= 4) && slayout != 1))
++                              return false;
++
++                      /* 24-bit not supported. It has yet another layout */
++                      WARN_ON(info->cpp[i] == 3);
++              }
+       }
+       return true;
+--- a/drivers/gpu/drm/nouveau/dispnv50/wndwca7e.c
++++ b/drivers/gpu/drm/nouveau/dispnv50/wndwca7e.c
+@@ -179,6 +179,39 @@ wndwca7e_ntfy_set(struct nv50_wndw *wndw
+       return 0;
+ }
++/****************************************************************
++ *            Log2(block height) ----------------------------+  *
++ *            Page Kind ----------------------------------+  |  *
++ *            Gob Height/Page Kind Generation ------+     |  |  *
++ *                          Sector layout -------+  |     |  |  *
++ *                          Compression ------+  |  |     |  |  */
++const u64 wndwca7e_modifiers[] = { /*         |  |  |     |  |  */
++      /* 4cpp+ modifiers */
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 0),
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 1),
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 2),
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 3),
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 4),
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 5),
++      /* 1cpp/8bpp modifiers */
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 0),
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 1),
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 2),
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 3),
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 4),
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 5),
++      /* 2cpp/16bpp modifiers */
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 0),
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 1),
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 2),
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 3),
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 4),
++      DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 5),
++      /* All formats support linear */
++      DRM_FORMAT_MOD_LINEAR,
++      DRM_FORMAT_MOD_INVALID
++};
++
+ static const struct nv50_wndw_func
+ wndwca7e = {
+       .acquire = wndwc37e_acquire,
diff --git a/queue-6.17/drm-sched-fix-deadlock-in-drm_sched_entity_kill_jobs_cb.patch b/queue-6.17/drm-sched-fix-deadlock-in-drm_sched_entity_kill_jobs_cb.patch
new file mode 100644 (file)
index 0000000..12657a0
--- /dev/null
@@ -0,0 +1,119 @@
+From 487df8b698345dd5a91346335f05170ed5f29d4e Mon Sep 17 00:00:00 2001
+From: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
+Date: Tue, 4 Nov 2025 10:53:57 +0100
+Subject: drm/sched: Fix deadlock in drm_sched_entity_kill_jobs_cb
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
+
+commit 487df8b698345dd5a91346335f05170ed5f29d4e upstream.
+
+The Mesa issue referenced below pointed out a possible deadlock:
+
+[ 1231.611031]  Possible interrupt unsafe locking scenario:
+
+[ 1231.611033]        CPU0                    CPU1
+[ 1231.611034]        ----                    ----
+[ 1231.611035]   lock(&xa->xa_lock#17);
+[ 1231.611038]                                local_irq_disable();
+[ 1231.611039]                                lock(&fence->lock);
+[ 1231.611041]                                lock(&xa->xa_lock#17);
+[ 1231.611044]   <Interrupt>
+[ 1231.611045]     lock(&fence->lock);
+[ 1231.611047]
+                *** DEADLOCK ***
+
+In this example, CPU0 would be any function accessing job->dependencies
+through the xa_* functions that don't disable interrupts (eg:
+drm_sched_job_add_dependency(), drm_sched_entity_kill_jobs_cb()).
+
+CPU1 is executing drm_sched_entity_kill_jobs_cb() as a fence signalling
+callback so in an interrupt context. It will deadlock when trying to
+grab the xa_lock which is already held by CPU0.
+
+Replacing all xa_* usage by their xa_*_irq counterparts would fix
+this issue, but Christian pointed out another issue: dma_fence_signal
+takes fence.lock and so does dma_fence_add_callback.
+
+  dma_fence_signal() // locks f1.lock
+  -> drm_sched_entity_kill_jobs_cb()
+  -> foreach dependencies
+     -> dma_fence_add_callback() // locks f2.lock
+
+This will deadlock if f1 and f2 share the same spinlock.
+
+To fix both issues, the code iterating on dependencies and re-arming them
+is moved out to drm_sched_entity_kill_jobs_work().
+
+Cc: stable@vger.kernel.org # v6.2+
+Fixes: 2fdb8a8f07c2 ("drm/scheduler: rework entity flush, kill and fini")
+Link: https://gitlab.freedesktop.org/mesa/mesa/-/issues/13908
+Reported-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
+Suggested-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
+[phasta: commit message nits]
+Signed-off-by: Philipp Stanner <phasta@kernel.org>
+Link: https://patch.msgid.link/20251104095358.15092-1-pierre-eric.pelloux-prayer@amd.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/scheduler/sched_entity.c |   34 +++++++++++++++++--------------
+ 1 file changed, 19 insertions(+), 15 deletions(-)
+
+--- a/drivers/gpu/drm/scheduler/sched_entity.c
++++ b/drivers/gpu/drm/scheduler/sched_entity.c
+@@ -173,26 +173,15 @@ int drm_sched_entity_error(struct drm_sc
+ }
+ EXPORT_SYMBOL(drm_sched_entity_error);
++static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
++                                        struct dma_fence_cb *cb);
++
+ static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk)
+ {
+       struct drm_sched_job *job = container_of(wrk, typeof(*job), work);
+-
+-      drm_sched_fence_scheduled(job->s_fence, NULL);
+-      drm_sched_fence_finished(job->s_fence, -ESRCH);
+-      WARN_ON(job->s_fence->parent);
+-      job->sched->ops->free_job(job);
+-}
+-
+-/* Signal the scheduler finished fence when the entity in question is killed. */
+-static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
+-                                        struct dma_fence_cb *cb)
+-{
+-      struct drm_sched_job *job = container_of(cb, struct drm_sched_job,
+-                                               finish_cb);
++      struct dma_fence *f;
+       unsigned long index;
+-      dma_fence_put(f);
+-
+       /* Wait for all dependencies to avoid data corruptions */
+       xa_for_each(&job->dependencies, index, f) {
+               struct drm_sched_fence *s_fence = to_drm_sched_fence(f);
+@@ -220,6 +209,21 @@ static void drm_sched_entity_kill_jobs_c
+               dma_fence_put(f);
+       }
++      drm_sched_fence_scheduled(job->s_fence, NULL);
++      drm_sched_fence_finished(job->s_fence, -ESRCH);
++      WARN_ON(job->s_fence->parent);
++      job->sched->ops->free_job(job);
++}
++
++/* Signal the scheduler finished fence when the entity in question is killed. */
++static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
++                                        struct dma_fence_cb *cb)
++{
++      struct drm_sched_job *job = container_of(cb, struct drm_sched_job,
++                                               finish_cb);
++
++      dma_fence_put(f);
++
+       INIT_WORK(&job->work, drm_sched_entity_kill_jobs_work);
+       schedule_work(&job->work);
+ }
diff --git a/queue-6.17/fscrypt-fix-left-shift-underflow-when-inode-i_blkbits-page_shift.patch b/queue-6.17/fscrypt-fix-left-shift-underflow-when-inode-i_blkbits-page_shift.patch
new file mode 100644 (file)
index 0000000..b25d779
--- /dev/null
@@ -0,0 +1,101 @@
+From 1e39da974ce621ed874c6d3aaf65ad14848c9f0d Mon Sep 17 00:00:00 2001
+From: Yongpeng Yang <yangyongpeng@xiaomi.com>
+Date: Tue, 4 Nov 2025 16:36:42 -0800
+Subject: fscrypt: fix left shift underflow when inode->i_blkbits > PAGE_SHIFT
+
+From: Yongpeng Yang <yangyongpeng@xiaomi.com>
+
+commit 1e39da974ce621ed874c6d3aaf65ad14848c9f0d upstream.
+
+When simulating an nvme device on qemu with both logical_block_size and
+physical_block_size set to 8 KiB, an error trace appears during
+partition table reading at boot time. The issue is caused by
+inode->i_blkbits being larger than PAGE_SHIFT, which leads to a left
+shift of -1 and triggering a UBSAN warning.
+
+[    2.697306] ------------[ cut here ]------------
+[    2.697309] UBSAN: shift-out-of-bounds in fs/crypto/inline_crypt.c:336:37
+[    2.697311] shift exponent -1 is negative
+[    2.697315] CPU: 3 UID: 0 PID: 274 Comm: (udev-worker) Not tainted 6.18.0-rc2+ #34 PREEMPT(voluntary)
+[    2.697317] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
+[    2.697320] Call Trace:
+[    2.697324]  <TASK>
+[    2.697325]  dump_stack_lvl+0x76/0xa0
+[    2.697340]  dump_stack+0x10/0x20
+[    2.697342]  __ubsan_handle_shift_out_of_bounds+0x1e3/0x390
+[    2.697351]  bh_get_inode_and_lblk_num.cold+0x12/0x94
+[    2.697359]  fscrypt_set_bio_crypt_ctx_bh+0x44/0x90
+[    2.697365]  submit_bh_wbc+0xb6/0x190
+[    2.697370]  block_read_full_folio+0x194/0x270
+[    2.697371]  ? __pfx_blkdev_get_block+0x10/0x10
+[    2.697375]  ? __pfx_blkdev_read_folio+0x10/0x10
+[    2.697377]  blkdev_read_folio+0x18/0x30
+[    2.697379]  filemap_read_folio+0x40/0xe0
+[    2.697382]  filemap_get_pages+0x5ef/0x7a0
+[    2.697385]  ? mmap_region+0x63/0xd0
+[    2.697389]  filemap_read+0x11d/0x520
+[    2.697392]  blkdev_read_iter+0x7c/0x180
+[    2.697393]  vfs_read+0x261/0x390
+[    2.697397]  ksys_read+0x71/0xf0
+[    2.697398]  __x64_sys_read+0x19/0x30
+[    2.697399]  x64_sys_call+0x1e88/0x26a0
+[    2.697405]  do_syscall_64+0x80/0x670
+[    2.697410]  ? __x64_sys_newfstat+0x15/0x20
+[    2.697414]  ? x64_sys_call+0x204a/0x26a0
+[    2.697415]  ? do_syscall_64+0xb8/0x670
+[    2.697417]  ? irqentry_exit_to_user_mode+0x2e/0x2a0
+[    2.697420]  ? irqentry_exit+0x43/0x50
+[    2.697421]  ? exc_page_fault+0x90/0x1b0
+[    2.697422]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
+[    2.697425] RIP: 0033:0x75054cba4a06
+[    2.697426] Code: 5d e8 41 8b 93 08 03 00 00 59 5e 48 83 f8 fc 75 19 83 e2 39 83 fa 08 75 11 e8 26 ff ff ff 66 0f 1f 44 00 00 48 8b 45 10 0f 05 <48> 8b 5d f8 c9 c3 0f 1f 40 00 f3 0f 1e fa 55 48 89 e5 48 83 ec 08
+[    2.697427] RSP: 002b:00007fff973723a0 EFLAGS: 00000202 ORIG_RAX: 0000000000000000
+[    2.697430] RAX: ffffffffffffffda RBX: 00005ea9a2c02760 RCX: 000075054cba4a06
+[    2.697432] RDX: 0000000000002000 RSI: 000075054c190000 RDI: 000000000000001b
+[    2.697433] RBP: 00007fff973723c0 R08: 0000000000000000 R09: 0000000000000000
+[    2.697434] R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000000
+[    2.697434] R13: 00005ea9a2c027c0 R14: 00005ea9a2be5608 R15: 00005ea9a2be55f0
+[    2.697436]  </TASK>
+[    2.697436] ---[ end trace ]---
+
+This situation can happen for block devices because when
+CONFIG_TRANSPARENT_HUGEPAGE is enabled, the maximum logical_block_size
+is 64 KiB. set_init_blocksize() then sets the block device
+inode->i_blkbits to 13, which is within this limit.
+
+File I/O does not trigger this problem because for filesystems that do
+not support the FS_LBS feature, sb_set_blocksize() prevents
+sb->s_blocksize_bits from being larger than PAGE_SHIFT. During inode
+allocation, alloc_inode()->inode_init_always() assigns inode->i_blkbits
+from sb->s_blocksize_bits. Currently, only xfs_fs_type has the FS_LBS
+flag, and since xfs I/O paths do not reach submit_bh_wbc(), it does not
+hit the left-shift underflow issue.
+
+Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
+Fixes: 47dd67532303 ("block/bdev: lift block size restrictions to 64k")
+Cc: stable@vger.kernel.org
+[EB: use folio_pos() and consolidate the two shifts by i_blkbits]
+Link: https://lore.kernel.org/r/20251105003642.42796-1-ebiggers@kernel.org
+Signed-off-by: Eric Biggers <ebiggers@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/crypto/inline_crypt.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c
+index 5dee7c498bc8..ed6e926226b5 100644
+--- a/fs/crypto/inline_crypt.c
++++ b/fs/crypto/inline_crypt.c
+@@ -333,8 +333,7 @@ static bool bh_get_inode_and_lblk_num(const struct buffer_head *bh,
+       inode = mapping->host;
+       *inode_ret = inode;
+-      *lblk_num_ret = ((u64)folio->index << (PAGE_SHIFT - inode->i_blkbits)) +
+-                      (bh_offset(bh) >> inode->i_blkbits);
++      *lblk_num_ret = (folio_pos(folio) + bh_offset(bh)) >> inode->i_blkbits;
+       return true;
+ }
+-- 
+2.51.2
+
diff --git a/queue-6.17/io_uring-fix-regbuf-vector-size-truncation.patch b/queue-6.17/io_uring-fix-regbuf-vector-size-truncation.patch
new file mode 100644 (file)
index 0000000..7b9cc4b
--- /dev/null
@@ -0,0 +1,56 @@
+From 146eb58629f45f8297e83d69e64d4eea4b28d972 Mon Sep 17 00:00:00 2001
+From: Pavel Begunkov <asml.silence@gmail.com>
+Date: Fri, 7 Nov 2025 18:41:26 +0000
+Subject: io_uring: fix regbuf vector size truncation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+commit 146eb58629f45f8297e83d69e64d4eea4b28d972 upstream.
+
+There is a report of io_estimate_bvec_size() truncating the calculated
+number of segments that leads to corruption issues. Check it doesn't
+overflow "int"s used later. Rough but simple, can be improved on top.
+
+Cc: stable@vger.kernel.org
+Fixes: 9ef4cbbcb4ac3 ("io_uring: add infra for importing vectored reg buffers")
+Reported-by: Google Big Sleep <big-sleep-vuln-reports+bigsleep-458654612@google.com>
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Reviewed-by: Günther Noack <gnoack@google.com>
+Tested-by: Günther Noack <gnoack@google.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ io_uring/rsrc.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/io_uring/rsrc.c
++++ b/io_uring/rsrc.c
+@@ -1402,8 +1402,11 @@ static int io_estimate_bvec_size(struct
+       size_t max_segs = 0;
+       unsigned i;
+-      for (i = 0; i < nr_iovs; i++)
++      for (i = 0; i < nr_iovs; i++) {
+               max_segs += (iov[i].iov_len >> shift) + 2;
++              if (max_segs > INT_MAX)
++                      return -EOVERFLOW;
++      }
+       return max_segs;
+ }
+@@ -1509,7 +1512,11 @@ int io_import_reg_vec(int ddir, struct i
+               if (unlikely(ret))
+                       return ret;
+       } else {
+-              nr_segs = io_estimate_bvec_size(iov, nr_iovs, imu);
++              int ret = io_estimate_bvec_size(iov, nr_iovs, imu);
++
++              if (ret < 0)
++                      return ret;
++              nr_segs = ret;
+       }
+       if (sizeof(struct bio_vec) > sizeof(struct iovec)) {
diff --git a/queue-6.17/iommufd-don-t-overflow-during-division-for-dirty-tracking.patch b/queue-6.17/iommufd-don-t-overflow-during-division-for-dirty-tracking.patch
new file mode 100644 (file)
index 0000000..e6364c1
--- /dev/null
@@ -0,0 +1,43 @@
+From cb30dfa75d55eced379a42fd67bd5fb7ec38555e Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgg@nvidia.com>
+Date: Wed, 8 Oct 2025 15:17:18 -0300
+Subject: iommufd: Don't overflow during division for dirty tracking
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+commit cb30dfa75d55eced379a42fd67bd5fb7ec38555e upstream.
+
+If pgshift is 63 then BITS_PER_TYPE(*bitmap->bitmap) * pgsize will overflow
+to 0 and this triggers divide by 0.
+
+In this case the index should just be 0, so reorganize things to divide
+by shift and avoid hitting any overflows.
+
+Link: https://patch.msgid.link/r/0-v1-663679b57226+172-iommufd_dirty_div0_jgg@nvidia.com
+Cc: stable@vger.kernel.org
+Fixes: 58ccf0190d19 ("vfio: Add an IOVA bitmap support")
+Reviewed-by: Joao Martins <joao.m.martins@oracle.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Reported-by: syzbot+093a8a8b859472e6c257@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=093a8a8b859472e6c257
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iommu/iommufd/iova_bitmap.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/iommu/iommufd/iova_bitmap.c
++++ b/drivers/iommu/iommufd/iova_bitmap.c
+@@ -130,9 +130,8 @@ struct iova_bitmap {
+ static unsigned long iova_bitmap_offset_to_index(struct iova_bitmap *bitmap,
+                                                unsigned long iova)
+ {
+-      unsigned long pgsize = 1UL << bitmap->mapped.pgshift;
+-
+-      return iova / (BITS_PER_TYPE(*bitmap->bitmap) * pgsize);
++      return (iova >> bitmap->mapped.pgshift) /
++             BITS_PER_TYPE(*bitmap->bitmap);
+ }
+ /*
diff --git a/queue-6.17/lib-crypto-curve25519-hacl64-fix-older-clang-kasan-workaround-for-gcc.patch b/queue-6.17/lib-crypto-curve25519-hacl64-fix-older-clang-kasan-workaround-for-gcc.patch
new file mode 100644 (file)
index 0000000..f5bbc33
--- /dev/null
@@ -0,0 +1,37 @@
+From 2b81082ad37cc3f28355fb73a6a69b91ff7dbf20 Mon Sep 17 00:00:00 2001
+From: Nathan Chancellor <nathan@kernel.org>
+Date: Mon, 3 Nov 2025 12:11:24 -0700
+Subject: lib/crypto: curve25519-hacl64: Fix older clang KASAN workaround for GCC
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+commit 2b81082ad37cc3f28355fb73a6a69b91ff7dbf20 upstream.
+
+Commit 2f13daee2a72 ("lib/crypto/curve25519-hacl64: Disable KASAN with
+clang-17 and older") inadvertently disabled KASAN in curve25519-hacl64.o
+for GCC unconditionally because clang-min-version will always evaluate
+to nothing for GCC. Add a check for CONFIG_CC_IS_CLANG to avoid applying
+the workaround for GCC, which is only needed for clang-17 and older.
+
+Cc: stable@vger.kernel.org
+Fixes: 2f13daee2a72 ("lib/crypto/curve25519-hacl64: Disable KASAN with clang-17 and older")
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Acked-by: Ard Biesheuvel <ardb@kernel.org>
+Link: https://lore.kernel.org/r/20251103-curve25519-hacl64-fix-kasan-workaround-v2-1-ab581cbd8035@kernel.org
+Signed-off-by: Eric Biggers <ebiggers@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ lib/crypto/Makefile |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/lib/crypto/Makefile
++++ b/lib/crypto/Makefile
+@@ -48,7 +48,7 @@ libcurve25519-generic-y                              := curve25519
+ libcurve25519-generic-$(CONFIG_ARCH_SUPPORTS_INT128)  := curve25519-hacl64.o
+ libcurve25519-generic-y                               += curve25519-generic.o
+ # clang versions prior to 18 may blow out the stack with KASAN
+-ifeq ($(call clang-min-version, 180000),)
++ifeq ($(CONFIG_CC_IS_CLANG)_$(call clang-min-version, 180000),y_)
+ KASAN_SANITIZE_curve25519-hacl64.o := n
+ endif
diff --git a/queue-6.17/parisc-avoid-crash-due-to-unaligned-access-in-unwinder.patch b/queue-6.17/parisc-avoid-crash-due-to-unaligned-access-in-unwinder.patch
new file mode 100644 (file)
index 0000000..c4576c0
--- /dev/null
@@ -0,0 +1,89 @@
+From fd9f30d1038ee1624baa17a6ff11effe5f7617cb Mon Sep 17 00:00:00 2001
+From: Helge Deller <deller@gmx.de>
+Date: Mon, 3 Nov 2025 22:38:26 +0100
+Subject: parisc: Avoid crash due to unaligned access in unwinder
+
+From: Helge Deller <deller@gmx.de>
+
+commit fd9f30d1038ee1624baa17a6ff11effe5f7617cb upstream.
+
+Guenter Roeck reported this kernel crash on his emulated B160L machine:
+
+Starting network: udhcpc: started, v1.36.1
+ Backtrace:
+  [<104320d4>] unwind_once+0x1c/0x5c
+  [<10434a00>] walk_stackframe.isra.0+0x74/0xb8
+  [<10434a6c>] arch_stack_walk+0x28/0x38
+  [<104e5efc>] stack_trace_save+0x48/0x5c
+  [<105d1bdc>] set_track_prepare+0x44/0x6c
+  [<105d9c80>] ___slab_alloc+0xfc4/0x1024
+  [<105d9d38>] __slab_alloc.isra.0+0x58/0x90
+  [<105dc80c>] kmem_cache_alloc_noprof+0x2ac/0x4a0
+  [<105b8e54>] __anon_vma_prepare+0x60/0x280
+  [<105a823c>] __vmf_anon_prepare+0x68/0x94
+  [<105a8b34>] do_wp_page+0x8cc/0xf10
+  [<105aad88>] handle_mm_fault+0x6c0/0xf08
+  [<10425568>] do_page_fault+0x110/0x440
+  [<10427938>] handle_interruption+0x184/0x748
+  [<11178398>] schedule+0x4c/0x190
+  BUG: spinlock recursion on CPU#0, ifconfig/2420
+  lock: terminate_lock.2+0x0/0x1c, .magic: dead4ead, .owner: ifconfig/2420, .owner_cpu: 0
+
+While creating the stack trace, the unwinder uses the stack pointer to guess
+the previous frame to read the previous stack pointer from memory.  The crash
+happens, because the unwinder tries to read from unaligned memory and as such
+triggers the unalignment trap handler which then leads to the spinlock
+recursion and finally to a deadlock.
+
+Fix it by checking the alignment before accessing the memory.
+
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Cc: stable@vger.kernel.org # v6.12+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/parisc/kernel/unwind.c |   13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+--- a/arch/parisc/kernel/unwind.c
++++ b/arch/parisc/kernel/unwind.c
+@@ -35,6 +35,8 @@
+ #define KERNEL_START (KERNEL_BINARY_TEXT_START)
++#define ALIGNMENT_OK(ptr, type) (((ptr) & (sizeof(type) - 1)) == 0)
++
+ extern struct unwind_table_entry __start___unwind[];
+ extern struct unwind_table_entry __stop___unwind[];
+@@ -257,12 +259,15 @@ static int unwind_special(struct unwind_
+       if (pc_is_kernel_fn(pc, _switch_to) ||
+           pc == (unsigned long)&_switch_to_ret) {
+               info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE;
+-              info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET);
++              if (ALIGNMENT_OK(info->prev_sp, long))
++                      info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET);
++              else
++                      info->prev_ip = info->prev_sp = 0;
+               return 1;
+       }
+ #ifdef CONFIG_IRQSTACKS
+-      if (pc == (unsigned long)&_call_on_stack) {
++      if (pc == (unsigned long)&_call_on_stack && ALIGNMENT_OK(info->sp, long)) {
+               info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ);
+               info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET);
+               return 1;
+@@ -370,8 +375,10 @@ static void unwind_frame_regs(struct unw
+                       info->prev_sp = info->sp - frame_size;
+                       if (e->Millicode)
+                               info->rp = info->r31;
+-                      else if (rpoffset)
++                      else if (rpoffset && ALIGNMENT_OK(info->prev_sp, long))
+                               info->rp = *(unsigned long *)(info->prev_sp - rpoffset);
++                      else
++                              info->rp = 0;
+                       info->prev_ip = info->rp;
+                       info->rp = 0;
+               }
diff --git a/queue-6.17/perf-core-fix-system-hang-caused-by-cpu-clock-usage.patch b/queue-6.17/perf-core-fix-system-hang-caused-by-cpu-clock-usage.patch
new file mode 100644 (file)
index 0000000..e41f965
--- /dev/null
@@ -0,0 +1,112 @@
+From eb3182ef0405ff2f6668fd3e5ff9883f60ce8801 Mon Sep 17 00:00:00 2001
+From: Dapeng Mi <dapeng1.mi@linux.intel.com>
+Date: Wed, 15 Oct 2025 13:18:28 +0800
+Subject: perf/core: Fix system hang caused by cpu-clock usage
+
+From: Dapeng Mi <dapeng1.mi@linux.intel.com>
+
+commit eb3182ef0405ff2f6668fd3e5ff9883f60ce8801 upstream.
+
+cpu-clock usage by the async-profiler tool can trigger a system hang,
+which got bisected back to the following commit by Octavia Togami:
+
+  18dbcbfabfff ("perf: Fix the POLL_HUP delivery breakage") causes this issue
+
+The root cause of the hang is that cpu-clock is a special type of SW
+event which relies on hrtimers. The __perf_event_overflow() callback
+is invoked from the hrtimer handler for cpu-clock events, and
+__perf_event_overflow() tries to call cpu_clock_event_stop()
+to stop the event, which calls htimer_cancel() to cancel the hrtimer.
+
+But that's a recursion into the hrtimer code from a hrtimer handler,
+which (unsurprisingly) deadlocks.
+
+To fix this bug, use hrtimer_try_to_cancel() instead, and set
+the PERF_HES_STOPPED flag, which causes perf_swevent_hrtimer()
+to stop the event once it sees the PERF_HES_STOPPED flag.
+
+[ mingo: Fixed the comments and improved the changelog. ]
+
+Closes: https://lore.kernel.org/all/CAHPNGSQpXEopYreir+uDDEbtXTBvBvi8c6fYXJvceqtgTPao3Q@mail.gmail.com/
+Fixes: 18dbcbfabfff ("perf: Fix the POLL_HUP delivery breakage")
+Reported-by: Octavia Togami <octavia.togami@gmail.com>
+Suggested-by: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Tested-by: Octavia Togami <octavia.togami@gmail.com>
+Cc: stable@vger.kernel.org
+Link: https://github.com/lucko/spark/issues/530
+Link: https://patch.msgid.link/20251015051828.12809-1-dapeng1.mi@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/events/core.c |   20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -11757,7 +11757,8 @@ static enum hrtimer_restart perf_swevent
+       event = container_of(hrtimer, struct perf_event, hw.hrtimer);
+-      if (event->state != PERF_EVENT_STATE_ACTIVE)
++      if (event->state != PERF_EVENT_STATE_ACTIVE ||
++          event->hw.state & PERF_HES_STOPPED)
+               return HRTIMER_NORESTART;
+       event->pmu->read(event);
+@@ -11803,15 +11804,20 @@ static void perf_swevent_cancel_hrtimer(
+       struct hw_perf_event *hwc = &event->hw;
+       /*
+-       * The throttle can be triggered in the hrtimer handler.
+-       * The HRTIMER_NORESTART should be used to stop the timer,
+-       * rather than hrtimer_cancel(). See perf_swevent_hrtimer()
++       * Careful: this function can be triggered in the hrtimer handler,
++       * for cpu-clock events, so hrtimer_cancel() would cause a
++       * deadlock.
++       *
++       * So use hrtimer_try_to_cancel() to try to stop the hrtimer,
++       * and the cpu-clock handler also sets the PERF_HES_STOPPED flag,
++       * which guarantees that perf_swevent_hrtimer() will stop the
++       * hrtimer once it sees the PERF_HES_STOPPED flag.
+        */
+       if (is_sampling_event(event) && (hwc->interrupts != MAX_INTERRUPTS)) {
+               ktime_t remaining = hrtimer_get_remaining(&hwc->hrtimer);
+               local64_set(&hwc->period_left, ktime_to_ns(remaining));
+-              hrtimer_cancel(&hwc->hrtimer);
++              hrtimer_try_to_cancel(&hwc->hrtimer);
+       }
+ }
+@@ -11855,12 +11861,14 @@ static void cpu_clock_event_update(struc
+ static void cpu_clock_event_start(struct perf_event *event, int flags)
+ {
++      event->hw.state = 0;
+       local64_set(&event->hw.prev_count, local_clock());
+       perf_swevent_start_hrtimer(event);
+ }
+ static void cpu_clock_event_stop(struct perf_event *event, int flags)
+ {
++      event->hw.state = PERF_HES_STOPPED;
+       perf_swevent_cancel_hrtimer(event);
+       if (flags & PERF_EF_UPDATE)
+               cpu_clock_event_update(event);
+@@ -11934,12 +11942,14 @@ static void task_clock_event_update(stru
+ static void task_clock_event_start(struct perf_event *event, int flags)
+ {
++      event->hw.state = 0;
+       local64_set(&event->hw.prev_count, event->ctx->time);
+       perf_swevent_start_hrtimer(event);
+ }
+ static void task_clock_event_stop(struct perf_event *event, int flags)
+ {
++      event->hw.state = PERF_HES_STOPPED;
+       perf_swevent_cancel_hrtimer(event);
+       if (flags & PERF_EF_UPDATE)
+               task_clock_event_update(event, event->ctx->time);
diff --git a/queue-6.17/platform-x86-int3472-fix-double-free-of-gpio-device-during-unregister.patch b/queue-6.17/platform-x86-int3472-fix-double-free-of-gpio-device-during-unregister.patch
new file mode 100644 (file)
index 0000000..9293a92
--- /dev/null
@@ -0,0 +1,75 @@
+From f0f7a3f542c1698edb69075f25a3f846207facba Mon Sep 17 00:00:00 2001
+From: Qiu Wenbo <qiuwenbo@kylinsec.com.cn>
+Date: Tue, 28 Oct 2025 14:30:09 +0800
+Subject: platform/x86: int3472: Fix double free of GPIO device during unregister
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Qiu Wenbo <qiuwenbo@kylinsec.com.cn>
+
+commit f0f7a3f542c1698edb69075f25a3f846207facba upstream.
+
+regulator_unregister() already frees the associated GPIO device. On
+ThinkPad X9 (Lunar Lake), this causes a double free issue that leads to
+random failures when other drivers (typically Intel THC) attempt to
+allocate interrupts. The root cause is that the reference count of the
+pinctrl_intel_platform module unexpectedly drops to zero when this
+driver defers its probe.
+
+This behavior can also be reproduced by unloading the module directly.
+
+Fix the issue by removing the redundant release of the GPIO device
+during regulator unregistration.
+
+Cc: stable@vger.kernel.org
+Fixes: 1e5d088a52c2 ("platform/x86: int3472: Stop using devm_gpiod_get()")
+Signed-off-by: Qiu Wenbo <qiuwenbo@kylinsec.com.cn>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Reviewed-by: Hans de Goede <hansg@kernel.org>
+Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
+Link: https://patch.msgid.link/20251028063009.289414-1-qiuwenbo@gnome.org
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/platform/x86/intel/int3472/clk_and_regulator.c | 5 +----
+ include/linux/platform_data/x86/int3472.h              | 1 -
+ 2 files changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/drivers/platform/x86/intel/int3472/clk_and_regulator.c b/drivers/platform/x86/intel/int3472/clk_and_regulator.c
+index 476ec24d3702..9e052b164a1a 100644
+--- a/drivers/platform/x86/intel/int3472/clk_and_regulator.c
++++ b/drivers/platform/x86/intel/int3472/clk_and_regulator.c
+@@ -245,15 +245,12 @@ int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
+       if (IS_ERR(regulator->rdev))
+               return PTR_ERR(regulator->rdev);
+-      int3472->regulators[int3472->n_regulator_gpios].ena_gpio = gpio;
+       int3472->n_regulator_gpios++;
+       return 0;
+ }
+ void skl_int3472_unregister_regulator(struct int3472_discrete_device *int3472)
+ {
+-      for (int i = 0; i < int3472->n_regulator_gpios; i++) {
++      for (int i = 0; i < int3472->n_regulator_gpios; i++)
+               regulator_unregister(int3472->regulators[i].rdev);
+-              gpiod_put(int3472->regulators[i].ena_gpio);
+-      }
+ }
+diff --git a/include/linux/platform_data/x86/int3472.h b/include/linux/platform_data/x86/int3472.h
+index 1571e9157fa5..b1b837583d54 100644
+--- a/include/linux/platform_data/x86/int3472.h
++++ b/include/linux/platform_data/x86/int3472.h
+@@ -100,7 +100,6 @@ struct int3472_gpio_regulator {
+       struct regulator_consumer_supply supply_map[GPIO_REGULATOR_SUPPLY_MAP_COUNT * 2];
+       char supply_name_upper[GPIO_SUPPLY_NAME_LENGTH];
+       char regulator_name[GPIO_REGULATOR_NAME_LENGTH];
+-      struct gpio_desc *ena_gpio;
+       struct regulator_dev *rdev;
+       struct regulator_desc rdesc;
+ };
+-- 
+2.51.2
+
diff --git a/queue-6.17/riscv-fix-memory-leak-in-module_frob_arch_sections.patch b/queue-6.17/riscv-fix-memory-leak-in-module_frob_arch_sections.patch
new file mode 100644 (file)
index 0000000..c34a6d1
--- /dev/null
@@ -0,0 +1,59 @@
+From c42458fcf54b3d0bc2ac06667c98dceb43831889 Mon Sep 17 00:00:00 2001
+From: Miaoqian Lin <linmq006@gmail.com>
+Date: Mon, 27 Oct 2025 11:40:44 -0600
+Subject: riscv: Fix memory leak in module_frob_arch_sections()
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+commit c42458fcf54b3d0bc2ac06667c98dceb43831889 upstream.
+
+The current code directly overwrites the scratch pointer with the
+return value of kvrealloc(). If kvrealloc() fails and returns NULL,
+the original buffer becomes unreachable, causing a memory leak.
+
+Fix this by using a temporary variable to store kvrealloc()'s return
+value and only update the scratch pointer on success.
+
+Found via static anlaysis and this is similar to commit 42378a9ca553
+("bpf, verifier: Fix memory leak in array reallocation for stack state")
+
+Fixes: be17c0df6795 ("riscv: module: Optimize PLT/GOT entry counting")
+Cc: stable@vger.kernel.org
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20251026091912.39727-1-linmq006@gmail.com
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/riscv/kernel/module-sections.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/arch/riscv/kernel/module-sections.c b/arch/riscv/kernel/module-sections.c
+index 75551ac6504c..1675cbad8619 100644
+--- a/arch/riscv/kernel/module-sections.c
++++ b/arch/riscv/kernel/module-sections.c
+@@ -119,6 +119,7 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
+       unsigned int num_plts = 0;
+       unsigned int num_gots = 0;
+       Elf_Rela *scratch = NULL;
++      Elf_Rela *new_scratch;
+       size_t scratch_size = 0;
+       int i;
+@@ -168,9 +169,12 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
+               scratch_size_needed = (num_scratch_relas + num_relas) * sizeof(*scratch);
+               if (scratch_size_needed > scratch_size) {
+                       scratch_size = scratch_size_needed;
+-                      scratch = kvrealloc(scratch, scratch_size, GFP_KERNEL);
+-                      if (!scratch)
++                      new_scratch = kvrealloc(scratch, scratch_size, GFP_KERNEL);
++                      if (!new_scratch) {
++                              kvfree(scratch);
+                               return -ENOMEM;
++                      }
++                      scratch = new_scratch;
+               }
+               for (size_t j = 0; j < num_relas; j++)
+-- 
+2.51.2
+
diff --git a/queue-6.17/rtc-rx8025-fix-incorrect-register-reference.patch b/queue-6.17/rtc-rx8025-fix-incorrect-register-reference.patch
new file mode 100644 (file)
index 0000000..f42165f
--- /dev/null
@@ -0,0 +1,33 @@
+From 162f24cbb0f6ec596e7e9f3e91610d79dc805229 Mon Sep 17 00:00:00 2001
+From: Yuta Hayama <hayama@lineo.co.jp>
+Date: Wed, 15 Oct 2025 12:07:05 +0900
+Subject: rtc: rx8025: fix incorrect register reference
+
+From: Yuta Hayama <hayama@lineo.co.jp>
+
+commit 162f24cbb0f6ec596e7e9f3e91610d79dc805229 upstream.
+
+This code is intended to operate on the CTRL1 register, but ctrl[1] is
+actually CTRL2. Correctly, ctrl[0] is CTRL1.
+
+Signed-off-by: Yuta Hayama <hayama@lineo.co.jp>
+Fixes: 71af91565052 ("rtc: rx8025: fix 12/24 hour mode detection on RX-8035")
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/eae5f479-5d28-4a37-859d-d54794e7628c@lineo.co.jp
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/rtc/rtc-rx8025.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/rtc/rtc-rx8025.c
++++ b/drivers/rtc/rtc-rx8025.c
+@@ -316,7 +316,7 @@ static int rx8025_init_client(struct i2c
+                       return hour_reg;
+               rx8025->is_24 = (hour_reg & RX8035_BIT_HOUR_1224);
+       } else {
+-              rx8025->is_24 = (ctrl[1] & RX8025_BIT_CTRL1_1224);
++              rx8025->is_24 = (ctrl[0] & RX8025_BIT_CTRL1_1224);
+       }
+ out:
+       return err;
diff --git a/queue-6.17/scsi-ufs-core-add-a-quirk-to-suppress-link_startup_again.patch b/queue-6.17/scsi-ufs-core-add-a-quirk-to-suppress-link_startup_again.patch
new file mode 100644 (file)
index 0000000..785198a
--- /dev/null
@@ -0,0 +1,60 @@
+From d34caa89a132cd69efc48361d4772251546fdb88 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Fri, 24 Oct 2025 11:59:16 +0300
+Subject: scsi: ufs: core: Add a quirk to suppress link_startup_again
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit d34caa89a132cd69efc48361d4772251546fdb88 upstream.
+
+ufshcd_link_startup() has a facility (link_startup_again) to issue
+DME_LINKSTARTUP a 2nd time even though the 1st time was successful.
+
+Some older hardware benefits from that, however the behaviour is
+non-standard, and has been found to cause link startup to be unreliable
+for some Intel Alder Lake based host controllers.
+
+Add UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE to suppress
+link_startup_again, in preparation for setting the quirk for affected
+controllers.
+
+Fixes: 7dc9fb47bc9a ("scsi: ufs: ufs-pci: Add support for Intel ADL")
+Cc: stable@vger.kernel.org
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://patch.msgid.link/20251024085918.31825-3-adrian.hunter@intel.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ufs/core/ufshcd.c |    3 ++-
+ include/ufs/ufshcd.h      |    7 +++++++
+ 2 files changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -5060,7 +5060,8 @@ static int ufshcd_link_startup(struct uf
+        * If UFS device isn't active then we will have to issue link startup
+        * 2 times to make sure the device state move to active.
+        */
+-      if (!ufshcd_is_ufs_dev_active(hba))
++      if (!(hba->quirks & UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE) &&
++          !ufshcd_is_ufs_dev_active(hba))
+               link_startup_again = true;
+ link_startup:
+--- a/include/ufs/ufshcd.h
++++ b/include/ufs/ufshcd.h
+@@ -689,6 +689,13 @@ enum ufshcd_quirks {
+        * single doorbell mode.
+        */
+       UFSHCD_QUIRK_BROKEN_LSDBS_CAP                   = 1 << 25,
++
++      /*
++       * This quirk indicates that DME_LINKSTARTUP should not be issued a 2nd
++       * time (refer link_startup_again) after the 1st time was successful,
++       * because it causes link startup to become unreliable.
++       */
++      UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE          = 1 << 26,
+ };
+ enum ufshcd_caps {
diff --git a/queue-6.17/scsi-ufs-core-fix-invalid-probe-error-return-value.patch b/queue-6.17/scsi-ufs-core-fix-invalid-probe-error-return-value.patch
new file mode 100644 (file)
index 0000000..1621cfc
--- /dev/null
@@ -0,0 +1,53 @@
+From a2b32bc1d9e359a9f90d0de6af16699facb10935 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Fri, 24 Oct 2025 11:59:18 +0300
+Subject: scsi: ufs: core: Fix invalid probe error return value
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit a2b32bc1d9e359a9f90d0de6af16699facb10935 upstream.
+
+After DME Link Startup, the error return value is set to the MIPI UniPro
+GenericErrorCode which can be 0 (SUCCESS) or 1 (FAILURE).  Upon failure
+during driver probe, the error code 1 is propagated back to the driver
+probe function which must return a negative value to indicate an error,
+but 1 is not negative, so the probe is considered to be successful even
+though it failed.  Subsequently, removing the driver results in an oops
+because it is not in a valid state.
+
+This happens because none of the callers of ufshcd_init() expect a
+non-negative error code.
+
+Fix the return value and documentation to match actual usage.
+
+Fixes: 69f5eb78d4b0 ("scsi: ufs: core: Move the ufshcd_device_init(hba, true) call")
+Cc: stable@vger.kernel.org
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://patch.msgid.link/20251024085918.31825-5-adrian.hunter@intel.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ufs/core/ufshcd.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -10638,7 +10638,7 @@ remove_scsi_host:
+  * @mmio_base: base register address
+  * @irq: Interrupt line of device
+  *
+- * Return: 0 on success, non-zero value on failure.
++ * Return: 0 on success; < 0 on failure.
+  */
+ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
+ {
+@@ -10879,7 +10879,7 @@ out_disable:
+       hba->is_irq_enabled = false;
+       ufshcd_hba_exit(hba);
+ out_error:
+-      return err;
++      return err > 0 ? -EIO : err;
+ }
+ EXPORT_SYMBOL_GPL(ufshcd_init);
diff --git a/queue-6.17/scsi-ufs-ufs-pci-fix-s0ix-s3-for-intel-controllers.patch b/queue-6.17/scsi-ufs-ufs-pci-fix-s0ix-s3-for-intel-controllers.patch
new file mode 100644 (file)
index 0000000..16b9526
--- /dev/null
@@ -0,0 +1,138 @@
+From bb44826c3bdbf1fa3957008a04908f45e5666463 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Fri, 24 Oct 2025 11:59:15 +0300
+Subject: scsi: ufs: ufs-pci: Fix S0ix/S3 for Intel controllers
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit bb44826c3bdbf1fa3957008a04908f45e5666463 upstream.
+
+Intel platforms with UFS, can support Suspend-to-Idle (S0ix) and
+Suspend-to-RAM (S3).  For S0ix the link state should be HIBERNATE.  For
+S3, state is lost, so the link state must be OFF.  Driver policy,
+expressed by spm_lvl, can be 3 (link HIBERNATE, device SLEEP) for S0ix
+but must be changed to 5 (link OFF, device POWEROFF) for S3.
+
+Fix support for S0ix/S3 by switching spm_lvl as needed.  During suspend
+->prepare(), if the suspend target state is not Suspend-to-Idle, ensure
+the spm_lvl is at least 5 to ensure that resume will be possible from
+deep sleep states.  During suspend ->complete(), restore the spm_lvl to
+its original value that is suitable for S0ix.
+
+This fix is first needed in Intel Alder Lake based controllers.
+
+Fixes: 7dc9fb47bc9a ("scsi: ufs: ufs-pci: Add support for Intel ADL")
+Cc: stable@vger.kernel.org
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://patch.msgid.link/20251024085918.31825-2-adrian.hunter@intel.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ufs/host/ufshcd-pci.c |   67 ++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 65 insertions(+), 2 deletions(-)
+
+--- a/drivers/ufs/host/ufshcd-pci.c
++++ b/drivers/ufs/host/ufshcd-pci.c
+@@ -15,6 +15,7 @@
+ #include <linux/pci.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/pm_qos.h>
++#include <linux/suspend.h>
+ #include <linux/debugfs.h>
+ #include <linux/uuid.h>
+ #include <linux/acpi.h>
+@@ -31,6 +32,7 @@ struct intel_host {
+       u32             dsm_fns;
+       u32             active_ltr;
+       u32             idle_ltr;
++      int             saved_spm_lvl;
+       struct dentry   *debugfs_root;
+       struct gpio_desc *reset_gpio;
+ };
+@@ -347,6 +349,7 @@ static int ufs_intel_common_init(struct
+       host = devm_kzalloc(hba->dev, sizeof(*host), GFP_KERNEL);
+       if (!host)
+               return -ENOMEM;
++      host->saved_spm_lvl = -1;
+       ufshcd_set_variant(hba, host);
+       intel_dsm_init(host, hba->dev);
+       if (INTEL_DSM_SUPPORTED(host, RESET)) {
+@@ -538,6 +541,66 @@ static int ufshcd_pci_restore(struct dev
+       return ufshcd_system_resume(dev);
+ }
++
++static int ufs_intel_suspend_prepare(struct device *dev)
++{
++      struct ufs_hba *hba = dev_get_drvdata(dev);
++      struct intel_host *host = ufshcd_get_variant(hba);
++      int err;
++
++      /*
++       * Only s2idle (S0ix) retains link state.  Force power-off
++       * (UFS_PM_LVL_5) for any other case.
++       */
++      if (pm_suspend_target_state != PM_SUSPEND_TO_IDLE && hba->spm_lvl < UFS_PM_LVL_5) {
++              host->saved_spm_lvl = hba->spm_lvl;
++              hba->spm_lvl = UFS_PM_LVL_5;
++      }
++
++      err = ufshcd_suspend_prepare(dev);
++
++      if (err < 0 && host->saved_spm_lvl != -1) {
++              hba->spm_lvl = host->saved_spm_lvl;
++              host->saved_spm_lvl = -1;
++      }
++
++      return err;
++}
++
++static void ufs_intel_resume_complete(struct device *dev)
++{
++      struct ufs_hba *hba = dev_get_drvdata(dev);
++      struct intel_host *host = ufshcd_get_variant(hba);
++
++      ufshcd_resume_complete(dev);
++
++      if (host->saved_spm_lvl != -1) {
++              hba->spm_lvl = host->saved_spm_lvl;
++              host->saved_spm_lvl = -1;
++      }
++}
++
++static int ufshcd_pci_suspend_prepare(struct device *dev)
++{
++      struct ufs_hba *hba = dev_get_drvdata(dev);
++
++      if (!strcmp(hba->vops->name, "intel-pci"))
++              return ufs_intel_suspend_prepare(dev);
++
++      return ufshcd_suspend_prepare(dev);
++}
++
++static void ufshcd_pci_resume_complete(struct device *dev)
++{
++      struct ufs_hba *hba = dev_get_drvdata(dev);
++
++      if (!strcmp(hba->vops->name, "intel-pci")) {
++              ufs_intel_resume_complete(dev);
++              return;
++      }
++
++      ufshcd_resume_complete(dev);
++}
+ #endif
+ /**
+@@ -611,8 +674,8 @@ static const struct dev_pm_ops ufshcd_pc
+       .thaw           = ufshcd_system_resume,
+       .poweroff       = ufshcd_system_suspend,
+       .restore        = ufshcd_pci_restore,
+-      .prepare        = ufshcd_suspend_prepare,
+-      .complete       = ufshcd_resume_complete,
++      .prepare        = ufshcd_pci_suspend_prepare,
++      .complete       = ufshcd_pci_resume_complete,
+ #endif
+ };
diff --git a/queue-6.17/scsi-ufs-ufs-pci-set-ufshcd_quirk_perform_link_startup_once-for-intel-adl.patch b/queue-6.17/scsi-ufs-ufs-pci-set-ufshcd_quirk_perform_link_startup_once-for-intel-adl.patch
new file mode 100644 (file)
index 0000000..2e1f259
--- /dev/null
@@ -0,0 +1,36 @@
+From d968e99488c4b08259a324a89e4ed17bf36561a4 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Fri, 24 Oct 2025 11:59:17 +0300
+Subject: scsi: ufs: ufs-pci: Set UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE for Intel ADL
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit d968e99488c4b08259a324a89e4ed17bf36561a4 upstream.
+
+Link startup becomes unreliable for Intel Alder Lake based host
+controllers when a 2nd DME_LINKSTARTUP is issued unnecessarily.  Employ
+UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE to suppress that from happening.
+
+Fixes: 7dc9fb47bc9a ("scsi: ufs: ufs-pci: Add support for Intel ADL")
+Cc: stable@vger.kernel.org
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://patch.msgid.link/20251024085918.31825-4-adrian.hunter@intel.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ufs/host/ufshcd-pci.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/ufs/host/ufshcd-pci.c
++++ b/drivers/ufs/host/ufshcd-pci.c
+@@ -428,7 +428,8 @@ static int ufs_intel_lkf_init(struct ufs
+ static int ufs_intel_adl_init(struct ufs_hba *hba)
+ {
+       hba->nop_out_timeout = 200;
+-      hba->quirks |= UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8;
++      hba->quirks |= UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8 |
++                     UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE;
+       hba->caps |= UFSHCD_CAP_WB_EN;
+       return ufs_intel_common_init(hba);
+ }
index d50f5686a8064cf41ca7f9f7721ef86cec95eae9..314e3a8bd4d72b0cb7363ddaa2949ade820ad9b2 100644 (file)
@@ -798,3 +798,37 @@ net-bridge-fix-use-after-free-due-to-mst-port-state-.patch
 net-bridge-fix-mst-static-key-usage.patch
 selftests-vsock-avoid-false-positives-when-checking-.patch
 tracing-fix-memory-leaks-in-create_field_var.patch
+drm-amd-display-enable-mst-when-it-s-detected-but-yet-to-be-initialized.patch
+wifi-cfg80211-add-an-hrtimer-based-delayed-work-item.patch
+wifi-mac80211-use-wiphy_hrtimer_work-for-ml_reconf_work.patch
+platform-x86-int3472-fix-double-free-of-gpio-device-during-unregister.patch
+wifi-mac80211-use-wiphy_hrtimer_work-for-ttlm_work.patch
+wifi-mac80211-use-wiphy_hrtimer_work-for-csa.switch_work.patch
+fscrypt-fix-left-shift-underflow-when-inode-i_blkbits-page_shift.patch
+drm-sched-fix-deadlock-in-drm_sched_entity_kill_jobs_cb.patch
+bluetooth-mgmt-fix-oob-access-in-parse_adv_monitor_pattern.patch
+iommufd-don-t-overflow-during-division-for-dirty-tracking.patch
+riscv-fix-memory-leak-in-module_frob_arch_sections.patch
+parisc-avoid-crash-due-to-unaligned-access-in-unwinder.patch
+rtc-rx8025-fix-incorrect-register-reference.patch
+x86-microcode-amd-add-more-known-models-to-entry-sign-checking.patch
+smb-client-validate-change-notify-buffer-before-copy.patch
+io_uring-fix-regbuf-vector-size-truncation.patch
+smb-client-fix-potential-uaf-in-smb2_close_cached_fid.patch
+perf-core-fix-system-hang-caused-by-cpu-clock-usage.patch
+x86-amd_node-fix-amd-root-device-caching.patch
+xfs-fix-delalloc-write-failures-in-software-provided-atomic-writes.patch
+xfs-fix-various-problems-in-xfs_atomic_write_cow_iomap_begin.patch
+x86-cpu-amd-add-missing-terminator-for-zen5_rdseed_microcode.patch
+drm-define-nvidia-drm-format-modifiers-for-gb20x.patch
+drm-nouveau-advertise-correct-modifiers-on-gb20x.patch
+drm-amdgpu-smu-handle-s0ix-for-vangogh.patch
+drm-amd-display-fix-null-deref-in-debugfs-odm_combine_segments.patch
+drm-amdkfd-don-t-clear-pt-after-process-killed.patch
+virtio-net-fix-received-length-check-in-big-packets.patch
+virtio_net-fix-alignment-for-virtio_net_hdr_v1_hash.patch
+lib-crypto-curve25519-hacl64-fix-older-clang-kasan-workaround-for-gcc.patch
+scsi-ufs-ufs-pci-fix-s0ix-s3-for-intel-controllers.patch
+scsi-ufs-ufs-pci-set-ufshcd_quirk_perform_link_startup_once-for-intel-adl.patch
+scsi-ufs-core-add-a-quirk-to-suppress-link_startup_again.patch
+scsi-ufs-core-fix-invalid-probe-error-return-value.patch
diff --git a/queue-6.17/smb-client-fix-potential-uaf-in-smb2_close_cached_fid.patch b/queue-6.17/smb-client-fix-potential-uaf-in-smb2_close_cached_fid.patch
new file mode 100644 (file)
index 0000000..7aba14a
--- /dev/null
@@ -0,0 +1,95 @@
+From 734e99623c5b65bf2c03e35978a0b980ebc3c2f8 Mon Sep 17 00:00:00 2001
+From: Henrique Carvalho <henrique.carvalho@suse.com>
+Date: Mon, 3 Nov 2025 19:52:55 -0300
+Subject: smb: client: fix potential UAF in smb2_close_cached_fid()
+
+From: Henrique Carvalho <henrique.carvalho@suse.com>
+
+commit 734e99623c5b65bf2c03e35978a0b980ebc3c2f8 upstream.
+
+find_or_create_cached_dir() could grab a new reference after kref_put()
+had seen the refcount drop to zero but before cfid_list_lock is acquired
+in smb2_close_cached_fid(), leading to use-after-free.
+
+Switch to kref_put_lock() so cfid_release() is called with
+cfid_list_lock held, closing that gap.
+
+Fixes: ebe98f1447bb ("cifs: enable caching of directories for which a lease is held")
+Cc: stable@vger.kernel.org
+Reported-by: Jay Shin <jaeshin@redhat.com>
+Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
+Signed-off-by: Henrique Carvalho <henrique.carvalho@suse.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/cached_dir.c |   16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+--- a/fs/smb/client/cached_dir.c
++++ b/fs/smb/client/cached_dir.c
+@@ -389,11 +389,11 @@ out:
+                        * lease. Release one here, and the second below.
+                        */
+                       cfid->has_lease = false;
+-                      kref_put(&cfid->refcount, smb2_close_cached_fid);
++                      close_cached_dir(cfid);
+               }
+               spin_unlock(&cfids->cfid_list_lock);
+-              kref_put(&cfid->refcount, smb2_close_cached_fid);
++              close_cached_dir(cfid);
+       } else {
+               *ret_cfid = cfid;
+               atomic_inc(&tcon->num_remote_opens);
+@@ -434,12 +434,14 @@ int open_cached_dir_by_dentry(struct cif
+ static void
+ smb2_close_cached_fid(struct kref *ref)
++__releases(&cfid->cfids->cfid_list_lock)
+ {
+       struct cached_fid *cfid = container_of(ref, struct cached_fid,
+                                              refcount);
+       int rc;
+-      spin_lock(&cfid->cfids->cfid_list_lock);
++      lockdep_assert_held(&cfid->cfids->cfid_list_lock);
++
+       if (cfid->on_list) {
+               list_del(&cfid->entry);
+               cfid->on_list = false;
+@@ -474,7 +476,7 @@ void drop_cached_dir_by_name(const unsig
+       spin_lock(&cfid->cfids->cfid_list_lock);
+       if (cfid->has_lease) {
+               cfid->has_lease = false;
+-              kref_put(&cfid->refcount, smb2_close_cached_fid);
++              close_cached_dir(cfid);
+       }
+       spin_unlock(&cfid->cfids->cfid_list_lock);
+       close_cached_dir(cfid);
+@@ -483,7 +485,7 @@ void drop_cached_dir_by_name(const unsig
+ void close_cached_dir(struct cached_fid *cfid)
+ {
+-      kref_put(&cfid->refcount, smb2_close_cached_fid);
++      kref_put_lock(&cfid->refcount, smb2_close_cached_fid, &cfid->cfids->cfid_list_lock);
+ }
+ /*
+@@ -594,7 +596,7 @@ cached_dir_offload_close(struct work_str
+       WARN_ON(cfid->on_list);
+-      kref_put(&cfid->refcount, smb2_close_cached_fid);
++      close_cached_dir(cfid);
+       cifs_put_tcon(tcon, netfs_trace_tcon_ref_put_cached_close);
+ }
+@@ -771,7 +773,7 @@ static void cfids_laundromat_worker(stru
+                        * Drop the ref-count from above, either the lease-ref (if there
+                        * was one) or the extra one acquired.
+                        */
+-                      kref_put(&cfid->refcount, smb2_close_cached_fid);
++                      close_cached_dir(cfid);
+       }
+       queue_delayed_work(cfid_put_wq, &cfids->laundromat_work,
+                          dir_cache_timeout * HZ);
diff --git a/queue-6.17/smb-client-validate-change-notify-buffer-before-copy.patch b/queue-6.17/smb-client-validate-change-notify-buffer-before-copy.patch
new file mode 100644 (file)
index 0000000..a3252b3
--- /dev/null
@@ -0,0 +1,43 @@
+From 4012abe8a78fbb8869634130024266eaef7081fe Mon Sep 17 00:00:00 2001
+From: Joshua Rogers <linux@joshua.hu>
+Date: Fri, 7 Nov 2025 00:09:37 +0800
+Subject: smb: client: validate change notify buffer before copy
+
+From: Joshua Rogers <linux@joshua.hu>
+
+commit 4012abe8a78fbb8869634130024266eaef7081fe upstream.
+
+SMB2_change_notify called smb2_validate_iov() but ignored the return
+code, then kmemdup()ed using server provided OutputBufferOffset/Length.
+
+Check the return of smb2_validate_iov() and bail out on error.
+
+Discovered with help from the ZeroPath security tooling.
+
+Signed-off-by: Joshua Rogers <linux@joshua.hu>
+Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
+Cc: stable@vger.kernel.org
+Fixes: e3e9463414f61 ("smb3: improve SMB3 change notification support")
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/smb2pdu.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/fs/smb/client/smb2pdu.c
++++ b/fs/smb/client/smb2pdu.c
+@@ -4054,9 +4054,12 @@ replay_again:
+               smb_rsp = (struct smb2_change_notify_rsp *)rsp_iov.iov_base;
+-              smb2_validate_iov(le16_to_cpu(smb_rsp->OutputBufferOffset),
+-                              le32_to_cpu(smb_rsp->OutputBufferLength), &rsp_iov,
++              rc = smb2_validate_iov(le16_to_cpu(smb_rsp->OutputBufferOffset),
++                              le32_to_cpu(smb_rsp->OutputBufferLength),
++                              &rsp_iov,
+                               sizeof(struct file_notify_information));
++              if (rc)
++                      goto cnotify_exit;
+               *out_data = kmemdup((char *)smb_rsp + le16_to_cpu(smb_rsp->OutputBufferOffset),
+                               le32_to_cpu(smb_rsp->OutputBufferLength), GFP_KERNEL);
diff --git a/queue-6.17/virtio-net-fix-received-length-check-in-big-packets.patch b/queue-6.17/virtio-net-fix-received-length-check-in-big-packets.patch
new file mode 100644 (file)
index 0000000..a11d607
--- /dev/null
@@ -0,0 +1,79 @@
+From 0c716703965ffc5ef4311b65cb5d84a703784717 Mon Sep 17 00:00:00 2001
+From: Bui Quang Minh <minhquangbui99@gmail.com>
+Date: Thu, 30 Oct 2025 21:44:38 +0700
+Subject: virtio-net: fix received length check in big packets
+
+From: Bui Quang Minh <minhquangbui99@gmail.com>
+
+commit 0c716703965ffc5ef4311b65cb5d84a703784717 upstream.
+
+Since commit 4959aebba8c0 ("virtio-net: use mtu size as buffer length
+for big packets"), when guest gso is off, the allocated size for big
+packets is not MAX_SKB_FRAGS * PAGE_SIZE anymore but depends on
+negotiated MTU. The number of allocated frags for big packets is stored
+in vi->big_packets_num_skbfrags.
+
+Because the host announced buffer length can be malicious (e.g. the host
+vhost_net driver's get_rx_bufs is modified to announce incorrect
+length), we need a check in virtio_net receive path. Currently, the
+check is not adapted to the new change which can lead to NULL page
+pointer dereference in the below while loop when receiving length that
+is larger than the allocated one.
+
+This commit fixes the received length check corresponding to the new
+change.
+
+Fixes: 4959aebba8c0 ("virtio-net: use mtu size as buffer length for big packets")
+Cc: stable@vger.kernel.org
+Signed-off-by: Bui Quang Minh <minhquangbui99@gmail.com>
+Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
+Tested-by: Lei Yang <leiyang@redhat.com>
+Link: https://patch.msgid.link/20251030144438.7582-1-minhquangbui99@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/virtio_net.c |   25 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -910,17 +910,6 @@ static struct sk_buff *page_to_skb(struc
+               goto ok;
+       }
+-      /*
+-       * Verify that we can indeed put this data into a skb.
+-       * This is here to handle cases when the device erroneously
+-       * tries to receive more than is possible. This is usually
+-       * the case of a broken device.
+-       */
+-      if (unlikely(len > MAX_SKB_FRAGS * PAGE_SIZE)) {
+-              net_dbg_ratelimited("%s: too much data\n", skb->dev->name);
+-              dev_kfree_skb(skb);
+-              return NULL;
+-      }
+       BUG_ON(offset >= PAGE_SIZE);
+       while (len) {
+               unsigned int frag_size = min((unsigned)PAGE_SIZE - offset, len);
+@@ -2112,9 +2101,19 @@ static struct sk_buff *receive_big(struc
+                                  struct virtnet_rq_stats *stats)
+ {
+       struct page *page = buf;
+-      struct sk_buff *skb =
+-              page_to_skb(vi, rq, page, 0, len, PAGE_SIZE, 0);
++      struct sk_buff *skb;
++
++      /* Make sure that len does not exceed the size allocated in
++       * add_recvbuf_big.
++       */
++      if (unlikely(len > (vi->big_packets_num_skbfrags + 1) * PAGE_SIZE)) {
++              pr_debug("%s: rx error: len %u exceeds allocated size %lu\n",
++                       dev->name, len,
++                       (vi->big_packets_num_skbfrags + 1) * PAGE_SIZE);
++              goto err;
++      }
++      skb = page_to_skb(vi, rq, page, 0, len, PAGE_SIZE, 0);
+       u64_stats_add(&stats->bytes, len - vi->hdr_len);
+       if (unlikely(!skb))
+               goto err;
diff --git a/queue-6.17/virtio_net-fix-alignment-for-virtio_net_hdr_v1_hash.patch b/queue-6.17/virtio_net-fix-alignment-for-virtio_net_hdr_v1_hash.patch
new file mode 100644 (file)
index 0000000..465b61f
--- /dev/null
@@ -0,0 +1,102 @@
+From c3838262b824c71c145cd3668722e99a69bc9cd9 Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst@redhat.com>
+Date: Fri, 31 Oct 2025 14:05:51 +0800
+Subject: virtio_net: fix alignment for virtio_net_hdr_v1_hash
+
+From: Michael S. Tsirkin <mst@redhat.com>
+
+commit c3838262b824c71c145cd3668722e99a69bc9cd9 upstream.
+
+Changing alignment of header would mean it's no longer safe to cast a
+2 byte aligned pointer between formats. Use two 16 bit fields to make
+it 2 byte aligned as previously.
+
+This fixes the performance regression since
+commit ("virtio_net: enable gso over UDP tunnel support.") as it uses
+virtio_net_hdr_v1_hash_tunnel which embeds
+virtio_net_hdr_v1_hash. Pktgen in guest + XDP_DROP on TAP + vhost_net
+shows the TX PPS is recovered from 2.4Mpps to 4.45Mpps.
+
+Fixes: 56a06bd40fab ("virtio_net: enable gso over UDP tunnel support.")
+Cc: stable@vger.kernel.org
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Tested-by: Lei Yang <leiyang@redhat.com>
+Link: https://patch.msgid.link/20251031060551.126-1-jasowang@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/virtio_net.c        |   15 +++++++++++++--
+ include/linux/virtio_net.h      |    3 ++-
+ include/uapi/linux/virtio_net.h |    3 ++-
+ 3 files changed, 17 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -2539,6 +2539,13 @@ err_buf:
+       return NULL;
+ }
++static inline u32
++virtio_net_hash_value(const struct virtio_net_hdr_v1_hash *hdr_hash)
++{
++      return __le16_to_cpu(hdr_hash->hash_value_lo) |
++              (__le16_to_cpu(hdr_hash->hash_value_hi) << 16);
++}
++
+ static void virtio_skb_set_hash(const struct virtio_net_hdr_v1_hash *hdr_hash,
+                               struct sk_buff *skb)
+ {
+@@ -2565,7 +2572,7 @@ static void virtio_skb_set_hash(const st
+       default:
+               rss_hash_type = PKT_HASH_TYPE_NONE;
+       }
+-      skb_set_hash(skb, __le32_to_cpu(hdr_hash->hash_value), rss_hash_type);
++      skb_set_hash(skb, virtio_net_hash_value(hdr_hash), rss_hash_type);
+ }
+ static void virtnet_receive_done(struct virtnet_info *vi, struct receive_queue *rq,
+@@ -3311,6 +3318,10 @@ static int xmit_skb(struct send_queue *s
+       pr_debug("%s: xmit %p %pM\n", vi->dev->name, skb, dest);
++      /* Make sure it's safe to cast between formats */
++      BUILD_BUG_ON(__alignof__(*hdr) != __alignof__(hdr->hash_hdr));
++      BUILD_BUG_ON(__alignof__(*hdr) != __alignof__(hdr->hash_hdr.hdr));
++
+       can_push = vi->any_header_sg &&
+               !((unsigned long)skb->data & (__alignof__(*hdr) - 1)) &&
+               !skb_header_cloned(skb) && skb_headroom(skb) >= hdr_len;
+@@ -6759,7 +6770,7 @@ static int virtnet_xdp_rx_hash(const str
+               hash_report = VIRTIO_NET_HASH_REPORT_NONE;
+       *rss_type = virtnet_xdp_rss_type[hash_report];
+-      *hash = __le32_to_cpu(hdr_hash->hash_value);
++      *hash = virtio_net_hash_value(hdr_hash);
+       return 0;
+ }
+--- a/include/linux/virtio_net.h
++++ b/include/linux/virtio_net.h
+@@ -401,7 +401,8 @@ virtio_net_hdr_tnl_from_skb(const struct
+       if (!tnl_hdr_negotiated)
+               return -EINVAL;
+-        vhdr->hash_hdr.hash_value = 0;
++      vhdr->hash_hdr.hash_value_lo = 0;
++      vhdr->hash_hdr.hash_value_hi = 0;
+         vhdr->hash_hdr.hash_report = 0;
+         vhdr->hash_hdr.padding = 0;
+--- a/include/uapi/linux/virtio_net.h
++++ b/include/uapi/linux/virtio_net.h
+@@ -193,7 +193,8 @@ struct virtio_net_hdr_v1 {
+ struct virtio_net_hdr_v1_hash {
+       struct virtio_net_hdr_v1 hdr;
+-      __le32 hash_value;
++      __le16 hash_value_lo;
++      __le16 hash_value_hi;
+ #define VIRTIO_NET_HASH_REPORT_NONE            0
+ #define VIRTIO_NET_HASH_REPORT_IPv4            1
+ #define VIRTIO_NET_HASH_REPORT_TCPv4           2
diff --git a/queue-6.17/wifi-cfg80211-add-an-hrtimer-based-delayed-work-item.patch b/queue-6.17/wifi-cfg80211-add-an-hrtimer-based-delayed-work-item.patch
new file mode 100644 (file)
index 0000000..998f9cc
--- /dev/null
@@ -0,0 +1,223 @@
+From 7ceba45a6658ce637da334cd0ebf27f4ede6c0fe Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <benjamin.berg@intel.com>
+Date: Tue, 28 Oct 2025 12:58:37 +0200
+Subject: wifi: cfg80211: add an hrtimer based delayed work item
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+commit 7ceba45a6658ce637da334cd0ebf27f4ede6c0fe upstream.
+
+The normal timer mechanism assume that timeout further in the future
+need a lower accuracy. As an example, the granularity for a timer
+scheduled 4096 ms in the future on a 1000 Hz system is already 512 ms.
+This granularity is perfectly sufficient for e.g. timeouts, but there
+are other types of events that will happen at a future point in time and
+require a higher accuracy.
+
+Add a new wiphy_hrtimer_work type that uses an hrtimer internally. The
+API is almost identical to the existing wiphy_delayed_work and it can be
+used as a drop-in replacement after minor adjustments. The work will be
+scheduled relative to the current time with a slack of 1 millisecond.
+
+CC: stable@vger.kernel.org # 6.4+
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Reviewed-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20251028125710.7f13a2adc5eb.I01b5af0363869864b0580d9c2a1770bafab69566@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/cfg80211.h |   78 +++++++++++++++++++++++++++++++++++++++++++++++++
+ net/wireless/core.c    |   56 +++++++++++++++++++++++++++++++++++
+ net/wireless/trace.h   |   21 +++++++++++++
+ 3 files changed, 155 insertions(+)
+
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -6289,6 +6289,11 @@ static inline void wiphy_delayed_work_in
+  * after wiphy_lock() was called. Therefore, wiphy_cancel_work() can
+  * use just cancel_work() instead of cancel_work_sync(), it requires
+  * being in a section protected by wiphy_lock().
++ *
++ * Note that these are scheduled with a timer where the accuracy
++ * becomes less the longer in the future the scheduled timer is. Use
++ * wiphy_hrtimer_work_queue() if the timer must be not be late by more
++ * than approximately 10 percent.
+  */
+ void wiphy_delayed_work_queue(struct wiphy *wiphy,
+                             struct wiphy_delayed_work *dwork,
+@@ -6360,6 +6365,79 @@ void wiphy_delayed_work_flush(struct wip
+ bool wiphy_delayed_work_pending(struct wiphy *wiphy,
+                               struct wiphy_delayed_work *dwork);
++struct wiphy_hrtimer_work {
++      struct wiphy_work work;
++      struct wiphy *wiphy;
++      struct hrtimer timer;
++};
++
++enum hrtimer_restart wiphy_hrtimer_work_timer(struct hrtimer *t);
++
++static inline void wiphy_hrtimer_work_init(struct wiphy_hrtimer_work *hrwork,
++                                         wiphy_work_func_t func)
++{
++      hrtimer_setup(&hrwork->timer, wiphy_hrtimer_work_timer,
++                    CLOCK_BOOTTIME, HRTIMER_MODE_REL);
++      wiphy_work_init(&hrwork->work, func);
++}
++
++/**
++ * wiphy_hrtimer_work_queue - queue hrtimer work for the wiphy
++ * @wiphy: the wiphy to queue for
++ * @hrwork: the high resolution timer worker
++ * @delay: the delay given as a ktime_t
++ *
++ * Please refer to wiphy_delayed_work_queue(). The difference is that
++ * the hrtimer work uses a high resolution timer for scheduling. This
++ * may be needed if timeouts might be scheduled further in the future
++ * and the accuracy of the normal timer is not sufficient.
++ *
++ * Expect a delay of a few milliseconds as the timer is scheduled
++ * with some slack and some more time may pass between queueing the
++ * work and its start.
++ */
++void wiphy_hrtimer_work_queue(struct wiphy *wiphy,
++                            struct wiphy_hrtimer_work *hrwork,
++                            ktime_t delay);
++
++/**
++ * wiphy_hrtimer_work_cancel - cancel previously queued hrtimer work
++ * @wiphy: the wiphy, for debug purposes
++ * @hrtimer: the hrtimer work to cancel
++ *
++ * Cancel the work *without* waiting for it, this assumes being
++ * called under the wiphy mutex acquired by wiphy_lock().
++ */
++void wiphy_hrtimer_work_cancel(struct wiphy *wiphy,
++                             struct wiphy_hrtimer_work *hrtimer);
++
++/**
++ * wiphy_hrtimer_work_flush - flush previously queued hrtimer work
++ * @wiphy: the wiphy, for debug purposes
++ * @hrwork: the hrtimer work to flush
++ *
++ * Flush the work (i.e. run it if pending). This must be called
++ * under the wiphy mutex acquired by wiphy_lock().
++ */
++void wiphy_hrtimer_work_flush(struct wiphy *wiphy,
++                            struct wiphy_hrtimer_work *hrwork);
++
++/**
++ * wiphy_hrtimer_work_pending - Find out whether a wiphy hrtimer
++ * work item is currently pending.
++ *
++ * @wiphy: the wiphy, for debug purposes
++ * @hrwork: the hrtimer work in question
++ *
++ * Return: true if timer is pending, false otherwise
++ *
++ * Please refer to the wiphy_delayed_work_pending() documentation as
++ * this is the equivalent function for hrtimer based delayed work
++ * items.
++ */
++bool wiphy_hrtimer_work_pending(struct wiphy *wiphy,
++                              struct wiphy_hrtimer_work *hrwork);
++
+ /**
+  * enum ieee80211_ap_reg_power - regulatory power for an Access Point
+  *
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -1778,6 +1778,62 @@ bool wiphy_delayed_work_pending(struct w
+ }
+ EXPORT_SYMBOL_GPL(wiphy_delayed_work_pending);
++enum hrtimer_restart wiphy_hrtimer_work_timer(struct hrtimer *t)
++{
++      struct wiphy_hrtimer_work *hrwork =
++              container_of(t, struct wiphy_hrtimer_work, timer);
++
++      wiphy_work_queue(hrwork->wiphy, &hrwork->work);
++
++      return HRTIMER_NORESTART;
++}
++EXPORT_SYMBOL_GPL(wiphy_hrtimer_work_timer);
++
++void wiphy_hrtimer_work_queue(struct wiphy *wiphy,
++                            struct wiphy_hrtimer_work *hrwork,
++                            ktime_t delay)
++{
++      trace_wiphy_hrtimer_work_queue(wiphy, &hrwork->work, delay);
++
++      if (!delay) {
++              hrtimer_cancel(&hrwork->timer);
++              wiphy_work_queue(wiphy, &hrwork->work);
++              return;
++      }
++
++      hrwork->wiphy = wiphy;
++      hrtimer_start_range_ns(&hrwork->timer, delay,
++                             1000 * NSEC_PER_USEC, HRTIMER_MODE_REL);
++}
++EXPORT_SYMBOL_GPL(wiphy_hrtimer_work_queue);
++
++void wiphy_hrtimer_work_cancel(struct wiphy *wiphy,
++                             struct wiphy_hrtimer_work *hrwork)
++{
++      lockdep_assert_held(&wiphy->mtx);
++
++      hrtimer_cancel(&hrwork->timer);
++      wiphy_work_cancel(wiphy, &hrwork->work);
++}
++EXPORT_SYMBOL_GPL(wiphy_hrtimer_work_cancel);
++
++void wiphy_hrtimer_work_flush(struct wiphy *wiphy,
++                            struct wiphy_hrtimer_work *hrwork)
++{
++      lockdep_assert_held(&wiphy->mtx);
++
++      hrtimer_cancel(&hrwork->timer);
++      wiphy_work_flush(wiphy, &hrwork->work);
++}
++EXPORT_SYMBOL_GPL(wiphy_hrtimer_work_flush);
++
++bool wiphy_hrtimer_work_pending(struct wiphy *wiphy,
++                              struct wiphy_hrtimer_work *hrwork)
++{
++      return hrtimer_is_queued(&hrwork->timer);
++}
++EXPORT_SYMBOL_GPL(wiphy_hrtimer_work_pending);
++
+ static int __init cfg80211_init(void)
+ {
+       int err;
+--- a/net/wireless/trace.h
++++ b/net/wireless/trace.h
+@@ -304,6 +304,27 @@ TRACE_EVENT(wiphy_delayed_work_queue,
+                 __entry->delay)
+ );
++TRACE_EVENT(wiphy_hrtimer_work_queue,
++      TP_PROTO(struct wiphy *wiphy, struct wiphy_work *work,
++               ktime_t delay),
++      TP_ARGS(wiphy, work, delay),
++      TP_STRUCT__entry(
++              WIPHY_ENTRY
++              __field(void *, instance)
++              __field(void *, func)
++              __field(ktime_t, delay)
++      ),
++      TP_fast_assign(
++              WIPHY_ASSIGN;
++              __entry->instance = work;
++              __entry->func = work->func;
++              __entry->delay = delay;
++      ),
++      TP_printk(WIPHY_PR_FMT " instance=%p func=%pS delay=%llu",
++                WIPHY_PR_ARG, __entry->instance, __entry->func,
++                __entry->delay)
++);
++
+ TRACE_EVENT(wiphy_work_worker_start,
+       TP_PROTO(struct wiphy *wiphy),
+       TP_ARGS(wiphy),
diff --git a/queue-6.17/wifi-mac80211-use-wiphy_hrtimer_work-for-csa.switch_work.patch b/queue-6.17/wifi-mac80211-use-wiphy_hrtimer_work-for-csa.switch_work.patch
new file mode 100644 (file)
index 0000000..3d51da3
--- /dev/null
@@ -0,0 +1,134 @@
+From fbc1cc6973099f45e4c30b86f12b4435c7cb7d24 Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <benjamin.berg@intel.com>
+Date: Tue, 28 Oct 2025 12:58:40 +0200
+Subject: wifi: mac80211: use wiphy_hrtimer_work for csa.switch_work
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+commit fbc1cc6973099f45e4c30b86f12b4435c7cb7d24 upstream.
+
+The work item may be scheduled relatively far in the future. As the
+event happens at a specific point in time, the normal timer accuracy is
+not sufficient in that case.
+
+Switch to use wiphy_hrtimer_work so that the accuracy is sufficient. To
+make this work, use the same clock to store the timestamp.
+
+CC: stable@vger.kernel.org
+Fixes: ec3252bff7b6 ("wifi: mac80211: use wiphy work for channel switch")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Reviewed-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20251028125710.68258c7e4ac4.I4ff2b2cdffbbf858bf5f08baccc7a88c4f9efe6f@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mac80211/chan.c        |    2 +-
+ net/mac80211/ieee80211_i.h |    4 ++--
+ net/mac80211/link.c        |    4 ++--
+ net/mac80211/mlme.c        |   18 +++++++++---------
+ 4 files changed, 14 insertions(+), 14 deletions(-)
+
+--- a/net/mac80211/chan.c
++++ b/net/mac80211/chan.c
+@@ -1301,7 +1301,7 @@ ieee80211_link_chanctx_reservation_compl
+                                &link->csa.finalize_work);
+               break;
+       case NL80211_IFTYPE_STATION:
+-              wiphy_delayed_work_queue(sdata->local->hw.wiphy,
++              wiphy_hrtimer_work_queue(sdata->local->hw.wiphy,
+                                        &link->u.mgd.csa.switch_work, 0);
+               break;
+       case NL80211_IFTYPE_UNSPECIFIED:
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1009,10 +1009,10 @@ struct ieee80211_link_data_managed {
+       bool operating_11g_mode;
+       struct {
+-              struct wiphy_delayed_work switch_work;
++              struct wiphy_hrtimer_work switch_work;
+               struct cfg80211_chan_def ap_chandef;
+               struct ieee80211_parsed_tpe tpe;
+-              unsigned long time;
++              ktime_t time;
+               bool waiting_bcn;
+               bool ignored_same_chan;
+               bool blocked_tx;
+--- a/net/mac80211/link.c
++++ b/net/mac80211/link.c
+@@ -472,10 +472,10 @@ static int _ieee80211_set_active_links(s
+                * from there.
+                */
+               if (link->conf->csa_active)
+-                      wiphy_delayed_work_queue(local->hw.wiphy,
++                      wiphy_hrtimer_work_queue(local->hw.wiphy,
+                                                &link->u.mgd.csa.switch_work,
+                                                link->u.mgd.csa.time -
+-                                               jiffies);
++                                               ktime_get_boottime());
+       }
+       for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) {
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -2589,7 +2589,7 @@ void ieee80211_chswitch_done(struct ieee
+                       return;
+               }
+-              wiphy_delayed_work_queue(sdata->local->hw.wiphy,
++              wiphy_hrtimer_work_queue(sdata->local->hw.wiphy,
+                                        &link->u.mgd.csa.switch_work, 0);
+       }
+@@ -2748,7 +2748,8 @@ ieee80211_sta_process_chanswitch(struct
+               .timestamp = timestamp,
+               .device_timestamp = device_timestamp,
+       };
+-      unsigned long now;
++      u32 csa_time_tu;
++      ktime_t now;
+       int res;
+       lockdep_assert_wiphy(local->hw.wiphy);
+@@ -2978,10 +2979,9 @@ ieee80211_sta_process_chanswitch(struct
+                                         csa_ie.mode);
+       /* we may have to handle timeout for deactivated link in software */
+-      now = jiffies;
+-      link->u.mgd.csa.time = now +
+-                             TU_TO_JIFFIES((max_t(int, csa_ie.count, 1) - 1) *
+-                                           link->conf->beacon_int);
++      now = ktime_get_boottime();
++      csa_time_tu = (max_t(int, csa_ie.count, 1) - 1) * link->conf->beacon_int;
++      link->u.mgd.csa.time = now + us_to_ktime(ieee80211_tu_to_usec(csa_time_tu));
+       if (ieee80211_vif_link_active(&sdata->vif, link->link_id) &&
+           local->ops->channel_switch) {
+@@ -2996,7 +2996,7 @@ ieee80211_sta_process_chanswitch(struct
+       }
+       /* channel switch handled in software */
+-      wiphy_delayed_work_queue(local->hw.wiphy,
++      wiphy_hrtimer_work_queue(local->hw.wiphy,
+                                &link->u.mgd.csa.switch_work,
+                                link->u.mgd.csa.time - now);
+       return;
+@@ -8808,7 +8808,7 @@ void ieee80211_mgd_setup_link(struct iee
+       else
+               link->u.mgd.req_smps = IEEE80211_SMPS_OFF;
+-      wiphy_delayed_work_init(&link->u.mgd.csa.switch_work,
++      wiphy_hrtimer_work_init(&link->u.mgd.csa.switch_work,
+                               ieee80211_csa_switch_work);
+       ieee80211_clear_tpe(&link->conf->tpe);
+@@ -10023,7 +10023,7 @@ void ieee80211_mgd_stop_link(struct ieee
+                         &link->u.mgd.request_smps_work);
+       wiphy_work_cancel(link->sdata->local->hw.wiphy,
+                         &link->u.mgd.recalc_smps);
+-      wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy,
++      wiphy_hrtimer_work_cancel(link->sdata->local->hw.wiphy,
+                                 &link->u.mgd.csa.switch_work);
+ }
diff --git a/queue-6.17/wifi-mac80211-use-wiphy_hrtimer_work-for-ml_reconf_work.patch b/queue-6.17/wifi-mac80211-use-wiphy_hrtimer_work-for-ml_reconf_work.patch
new file mode 100644 (file)
index 0000000..ef2e6be
--- /dev/null
@@ -0,0 +1,80 @@
+From 3f654d53dff565095d83a84e3b6187526dadf4c8 Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <benjamin.berg@intel.com>
+Date: Tue, 28 Oct 2025 12:58:39 +0200
+Subject: wifi: mac80211: use wiphy_hrtimer_work for ml_reconf_work
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+commit 3f654d53dff565095d83a84e3b6187526dadf4c8 upstream.
+
+The work item may be scheduled relatively far in the future. As the
+event happens at a specific point in time, the normal timer accuracy is
+not sufficient in that case.
+
+Switch to use wiphy_hrtimer_work so that the accuracy is sufficient.
+
+CC: stable@vger.kernel.org
+Fixes: 8eb8dd2ffbbb ("wifi: mac80211: Support link removal using Reconfiguration ML element")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Reviewed-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20251028125710.24a7b54e9e37.I063c5c15bf7672f94cea75f83e486a3ca52d098f@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mac80211/ieee80211_i.h |    2 +-
+ net/mac80211/mlme.c        |   10 +++++-----
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -604,7 +604,7 @@ struct ieee80211_if_managed {
+       u8 *assoc_req_ies;
+       size_t assoc_req_ies_len;
+-      struct wiphy_delayed_work ml_reconf_work;
++      struct wiphy_hrtimer_work ml_reconf_work;
+       u16 removed_links;
+       /* TID-to-link mapping support */
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -4244,7 +4244,7 @@ static void ieee80211_set_disassoc(struc
+                                 &ifmgd->neg_ttlm_timeout_work);
+       sdata->u.mgd.removed_links = 0;
+-      wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
++      wiphy_hrtimer_work_cancel(sdata->local->hw.wiphy,
+                                 &sdata->u.mgd.ml_reconf_work);
+       wiphy_work_cancel(sdata->local->hw.wiphy,
+@@ -6868,7 +6868,7 @@ static void ieee80211_ml_reconfiguration
+               /* In case the removal was cancelled, abort it */
+               if (sdata->u.mgd.removed_links) {
+                       sdata->u.mgd.removed_links = 0;
+-                      wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
++                      wiphy_hrtimer_work_cancel(sdata->local->hw.wiphy,
+                                                 &sdata->u.mgd.ml_reconf_work);
+               }
+               return;
+@@ -6898,9 +6898,9 @@ static void ieee80211_ml_reconfiguration
+       }
+       sdata->u.mgd.removed_links = removed_links;
+-      wiphy_delayed_work_queue(sdata->local->hw.wiphy,
++      wiphy_hrtimer_work_queue(sdata->local->hw.wiphy,
+                                &sdata->u.mgd.ml_reconf_work,
+-                               TU_TO_JIFFIES(delay));
++                               us_to_ktime(ieee80211_tu_to_usec(delay)));
+ }
+ static int ieee80211_ttlm_set_links(struct ieee80211_sub_if_data *sdata,
+@@ -8752,7 +8752,7 @@ void ieee80211_sta_setup_sdata(struct ie
+                       ieee80211_csa_connection_drop_work);
+       wiphy_delayed_work_init(&ifmgd->tdls_peer_del_work,
+                               ieee80211_tdls_peer_del_work);
+-      wiphy_delayed_work_init(&ifmgd->ml_reconf_work,
++      wiphy_hrtimer_work_init(&ifmgd->ml_reconf_work,
+                               ieee80211_ml_reconf_work);
+       wiphy_delayed_work_init(&ifmgd->reconf.wk,
+                               ieee80211_ml_sta_reconf_timeout);
diff --git a/queue-6.17/wifi-mac80211-use-wiphy_hrtimer_work-for-ttlm_work.patch b/queue-6.17/wifi-mac80211-use-wiphy_hrtimer_work-for-ttlm_work.patch
new file mode 100644 (file)
index 0000000..85293b2
--- /dev/null
@@ -0,0 +1,117 @@
+From dfa865d490b1bd252045463588a91a4d3c82f3c8 Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <benjamin.berg@intel.com>
+Date: Tue, 28 Oct 2025 12:58:38 +0200
+Subject: wifi: mac80211: use wiphy_hrtimer_work for ttlm_work
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+commit dfa865d490b1bd252045463588a91a4d3c82f3c8 upstream.
+
+The work item may be scheduled relatively far in the future. As the
+event happens at a specific point in time, the normal timer accuracy is
+not sufficient in that case.
+
+Switch to use wiphy_hrtimer_work so that the accuracy is sufficient.
+
+CC: stable@vger.kernel.org
+Fixes: 702e80470a33 ("wifi: mac80211: support handling of advertised TID-to-link mapping")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Reviewed-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20251028125710.83c2c611545e.I35498a6d883ea24b0dc4910cf521aa768d2a0e90@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mac80211/ieee80211_i.h |    2 +-
+ net/mac80211/mlme.c        |   24 ++++++++++++------------
+ 2 files changed, 13 insertions(+), 13 deletions(-)
+
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -608,7 +608,7 @@ struct ieee80211_if_managed {
+       u16 removed_links;
+       /* TID-to-link mapping support */
+-      struct wiphy_delayed_work ttlm_work;
++      struct wiphy_hrtimer_work ttlm_work;
+       struct ieee80211_adv_ttlm_info ttlm_info;
+       struct wiphy_work teardown_ttlm_work;
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -45,7 +45,7 @@
+ #define IEEE80211_ASSOC_TIMEOUT_SHORT (HZ / 10)
+ #define IEEE80211_ASSOC_MAX_TRIES     3
+-#define IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS msecs_to_jiffies(100)
++#define IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS (100 * USEC_PER_MSEC)
+ #define IEEE80211_ADV_TTLM_ST_UNDERFLOW 0xff00
+ #define IEEE80211_NEG_TTLM_REQ_TIMEOUT (HZ / 5)
+@@ -4237,7 +4237,7 @@ static void ieee80211_set_disassoc(struc
+       memset(&sdata->u.mgd.ttlm_info, 0,
+              sizeof(sdata->u.mgd.ttlm_info));
+-      wiphy_delayed_work_cancel(sdata->local->hw.wiphy, &ifmgd->ttlm_work);
++      wiphy_hrtimer_work_cancel(sdata->local->hw.wiphy, &ifmgd->ttlm_work);
+       memset(&sdata->vif.neg_ttlm, 0, sizeof(sdata->vif.neg_ttlm));
+       wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
+@@ -7087,7 +7087,7 @@ static void ieee80211_process_adv_ttlm(s
+                       /* if a planned TID-to-link mapping was cancelled -
+                        * abort it
+                        */
+-                      wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
++                      wiphy_hrtimer_work_cancel(sdata->local->hw.wiphy,
+                                                 &sdata->u.mgd.ttlm_work);
+               } else if (sdata->u.mgd.ttlm_info.active) {
+                       /* if no TID-to-link element, set to default mapping in
+@@ -7122,7 +7122,7 @@ static void ieee80211_process_adv_ttlm(s
+               if (ttlm_info.switch_time) {
+                       u16 beacon_ts_tu, st_tu, delay;
+-                      u32 delay_jiffies;
++                      u64 delay_usec;
+                       u64 mask;
+                       /* The t2l map switch time is indicated with a partial
+@@ -7144,23 +7144,23 @@ static void ieee80211_process_adv_ttlm(s
+                       if (delay > IEEE80211_ADV_TTLM_ST_UNDERFLOW)
+                               return;
+-                      delay_jiffies = TU_TO_JIFFIES(delay);
++                      delay_usec = ieee80211_tu_to_usec(delay);
+                       /* Link switching can take time, so schedule it
+                        * 100ms before to be ready on time
+                        */
+-                      if (delay_jiffies > IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS)
+-                              delay_jiffies -=
++                      if (delay_usec > IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS)
++                              delay_usec -=
+                                       IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS;
+                       else
+-                              delay_jiffies = 0;
++                              delay_usec = 0;
+                       sdata->u.mgd.ttlm_info = ttlm_info;
+-                      wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
++                      wiphy_hrtimer_work_cancel(sdata->local->hw.wiphy,
+                                                 &sdata->u.mgd.ttlm_work);
+-                      wiphy_delayed_work_queue(sdata->local->hw.wiphy,
++                      wiphy_hrtimer_work_queue(sdata->local->hw.wiphy,
+                                                &sdata->u.mgd.ttlm_work,
+-                                               delay_jiffies);
++                                               us_to_ktime(delay_usec));
+                       return;
+               }
+       }
+@@ -8761,7 +8761,7 @@ void ieee80211_sta_setup_sdata(struct ie
+       timer_setup(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer, 0);
+       wiphy_delayed_work_init(&ifmgd->tx_tspec_wk,
+                               ieee80211_sta_handle_tspec_ac_params_wk);
+-      wiphy_delayed_work_init(&ifmgd->ttlm_work,
++      wiphy_hrtimer_work_init(&ifmgd->ttlm_work,
+                               ieee80211_tid_to_link_map_work);
+       wiphy_delayed_work_init(&ifmgd->neg_ttlm_timeout_work,
+                               ieee80211_neg_ttlm_timeout_work);
diff --git a/queue-6.17/x86-amd_node-fix-amd-root-device-caching.patch b/queue-6.17/x86-amd_node-fix-amd-root-device-caching.patch
new file mode 100644 (file)
index 0000000..617f900
--- /dev/null
@@ -0,0 +1,267 @@
+From 0a4b61d9c2e496b5f0a10e29e355a1465c8738bb Mon Sep 17 00:00:00 2001
+From: Yazen Ghannam <yazen.ghannam@amd.com>
+Date: Tue, 28 Oct 2025 21:35:42 +0000
+Subject: x86/amd_node: Fix AMD root device caching
+
+From: Yazen Ghannam <yazen.ghannam@amd.com>
+
+commit 0a4b61d9c2e496b5f0a10e29e355a1465c8738bb upstream.
+
+Recent AMD node rework removed the "search and count" method of caching AMD
+root devices. This depended on the value from a Data Fabric register that was
+expected to hold the PCI bus of one of the root devices attached to that
+fabric.
+
+However, this expectation is incorrect. The register, when read from PCI
+config space, returns the bitwise-OR of the buses of all attached root
+devices.
+
+This behavior is benign on AMD reference design boards, since the bus numbers
+are aligned. This results in a bitwise-OR value matching one of the buses. For
+example, 0x00 | 0x40 | 0xA0 | 0xE0 = 0xE0.
+
+This behavior breaks on boards where the bus numbers are not exactly aligned.
+For example, 0x00 | 0x07 | 0xE0 | 0x15 = 0x1F.
+
+The examples above are for AMD node 0. The first root device on other nodes
+will not be 0x00. The first root device for other nodes will depend on the
+total number of root devices, the system topology, and the specific PCI bus
+number assignment.
+
+For example, a system with 2 AMD nodes could have this:
+
+  Node 0 : 0x00 0x07 0x0e 0x15
+  Node 1 : 0x1c 0x23 0x2a 0x31
+
+The bus numbering style in the reference boards is not a requirement.  The
+numbering found in other boards is not incorrect. Therefore, the root device
+caching method needs to be adjusted.
+
+Go back to the "search and count" method used before the recent rework.
+Search for root devices using PCI class code rather than fixed PCI IDs.
+
+This keeps the goal of the rework (remove dependency on PCI IDs) while being
+able to support various board designs.
+
+Merge helper functions to reduce code duplication.
+
+  [ bp: Reflow comment. ]
+
+Fixes: 40a5f6ffdfc8 ("x86/amd_nb: Simplify root device search")
+Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/all/20251028-fix-amd-root-v2-1-843e38f8be2c@amd.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/include/asm/amd/node.h |    1 
+ arch/x86/kernel/amd_node.c      |  150 +++++++++++++---------------------------
+ 2 files changed, 51 insertions(+), 100 deletions(-)
+
+--- a/arch/x86/include/asm/amd/node.h
++++ b/arch/x86/include/asm/amd/node.h
+@@ -23,7 +23,6 @@
+ #define AMD_NODE0_PCI_SLOT    0x18
+ struct pci_dev *amd_node_get_func(u16 node, u8 func);
+-struct pci_dev *amd_node_get_root(u16 node);
+ static inline u16 amd_num_nodes(void)
+ {
+--- a/arch/x86/kernel/amd_node.c
++++ b/arch/x86/kernel/amd_node.c
+@@ -34,62 +34,6 @@ struct pci_dev *amd_node_get_func(u16 no
+       return pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(AMD_NODE0_PCI_SLOT + node, func));
+ }
+-#define DF_BLK_INST_CNT               0x040
+-#define       DF_CFG_ADDR_CNTL_LEGACY 0x084
+-#define       DF_CFG_ADDR_CNTL_DF4    0xC04
+-
+-#define DF_MAJOR_REVISION     GENMASK(27, 24)
+-
+-static u16 get_cfg_addr_cntl_offset(struct pci_dev *df_f0)
+-{
+-      u32 reg;
+-
+-      /*
+-       * Revision fields added for DF4 and later.
+-       *
+-       * Major revision of '0' is found pre-DF4. Field is Read-as-Zero.
+-       */
+-      if (pci_read_config_dword(df_f0, DF_BLK_INST_CNT, &reg))
+-              return 0;
+-
+-      if (reg & DF_MAJOR_REVISION)
+-              return DF_CFG_ADDR_CNTL_DF4;
+-
+-      return DF_CFG_ADDR_CNTL_LEGACY;
+-}
+-
+-struct pci_dev *amd_node_get_root(u16 node)
+-{
+-      struct pci_dev *root;
+-      u16 cntl_off;
+-      u8 bus;
+-
+-      if (!cpu_feature_enabled(X86_FEATURE_ZEN))
+-              return NULL;
+-
+-      /*
+-       * D18F0xXXX [Config Address Control] (DF::CfgAddressCntl)
+-       * Bits [7:0] (SecBusNum) holds the bus number of the root device for
+-       * this Data Fabric instance. The segment, device, and function will be 0.
+-       */
+-      struct pci_dev *df_f0 __free(pci_dev_put) = amd_node_get_func(node, 0);
+-      if (!df_f0)
+-              return NULL;
+-
+-      cntl_off = get_cfg_addr_cntl_offset(df_f0);
+-      if (!cntl_off)
+-              return NULL;
+-
+-      if (pci_read_config_byte(df_f0, cntl_off, &bus))
+-              return NULL;
+-
+-      /* Grab the pointer for the actual root device instance. */
+-      root = pci_get_domain_bus_and_slot(0, bus, 0);
+-
+-      pci_dbg(root, "is root for AMD node %u\n", node);
+-      return root;
+-}
+-
+ static struct pci_dev **amd_roots;
+ /* Protect the PCI config register pairs used for SMN. */
+@@ -274,51 +218,21 @@ DEFINE_SHOW_STORE_ATTRIBUTE(smn_node);
+ DEFINE_SHOW_STORE_ATTRIBUTE(smn_address);
+ DEFINE_SHOW_STORE_ATTRIBUTE(smn_value);
+-static int amd_cache_roots(void)
++static struct pci_dev *get_next_root(struct pci_dev *root)
+ {
+-      u16 node, num_nodes = amd_num_nodes();
+-
+-      amd_roots = kcalloc(num_nodes, sizeof(*amd_roots), GFP_KERNEL);
+-      if (!amd_roots)
+-              return -ENOMEM;
+-
+-      for (node = 0; node < num_nodes; node++)
+-              amd_roots[node] = amd_node_get_root(node);
+-
+-      return 0;
+-}
+-
+-static int reserve_root_config_spaces(void)
+-{
+-      struct pci_dev *root = NULL;
+-      struct pci_bus *bus = NULL;
+-
+-      while ((bus = pci_find_next_bus(bus))) {
+-              /* Root device is Device 0 Function 0 on each Primary Bus. */
+-              root = pci_get_slot(bus, 0);
+-              if (!root)
++      while ((root = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, root))) {
++              /* Root device is Device 0 Function 0. */
++              if (root->devfn)
+                       continue;
+               if (root->vendor != PCI_VENDOR_ID_AMD &&
+                   root->vendor != PCI_VENDOR_ID_HYGON)
+                       continue;
+-              pci_dbg(root, "Reserving PCI config space\n");
+-
+-              /*
+-               * There are a few SMN index/data pairs and other registers
+-               * that shouldn't be accessed by user space.
+-               * So reserve the entire PCI config space for simplicity rather
+-               * than covering specific registers piecemeal.
+-               */
+-              if (!pci_request_config_region_exclusive(root, 0, PCI_CFG_SPACE_SIZE, NULL)) {
+-                      pci_err(root, "Failed to reserve config space\n");
+-                      return -EEXIST;
+-              }
++              break;
+       }
+-      smn_exclusive = true;
+-      return 0;
++      return root;
+ }
+ static bool enable_dfs;
+@@ -332,7 +246,8 @@ __setup("amd_smn_debugfs_enable", amd_sm
+ static int __init amd_smn_init(void)
+ {
+-      int err;
++      u16 count, num_roots, roots_per_node, node, num_nodes;
++      struct pci_dev *root;
+       if (!cpu_feature_enabled(X86_FEATURE_ZEN))
+               return 0;
+@@ -342,13 +257,48 @@ static int __init amd_smn_init(void)
+       if (amd_roots)
+               return 0;
+-      err = amd_cache_roots();
+-      if (err)
+-              return err;
++      num_roots = 0;
++      root = NULL;
++      while ((root = get_next_root(root))) {
++              pci_dbg(root, "Reserving PCI config space\n");
+-      err = reserve_root_config_spaces();
+-      if (err)
+-              return err;
++              /*
++               * There are a few SMN index/data pairs and other registers
++               * that shouldn't be accessed by user space. So reserve the
++               * entire PCI config space for simplicity rather than covering
++               * specific registers piecemeal.
++               */
++              if (!pci_request_config_region_exclusive(root, 0, PCI_CFG_SPACE_SIZE, NULL)) {
++                      pci_err(root, "Failed to reserve config space\n");
++                      return -EEXIST;
++              }
++
++              num_roots++;
++      }
++
++      pr_debug("Found %d AMD root devices\n", num_roots);
++
++      if (!num_roots)
++              return -ENODEV;
++
++      num_nodes = amd_num_nodes();
++      amd_roots = kcalloc(num_nodes, sizeof(*amd_roots), GFP_KERNEL);
++      if (!amd_roots)
++              return -ENOMEM;
++
++      roots_per_node = num_roots / num_nodes;
++
++      count = 0;
++      node = 0;
++      root = NULL;
++      while (node < num_nodes && (root = get_next_root(root))) {
++              /* Use one root for each node and skip the rest. */
++              if (count++ % roots_per_node)
++                      continue;
++
++              pci_dbg(root, "is root for AMD node %u\n", node);
++              amd_roots[node++] = root;
++      }
+       if (enable_dfs) {
+               debugfs_dir = debugfs_create_dir("amd_smn", arch_debugfs_dir);
+@@ -358,6 +308,8 @@ static int __init amd_smn_init(void)
+               debugfs_create_file("value",    0600, debugfs_dir, NULL, &smn_value_fops);
+       }
++      smn_exclusive = true;
++
+       return 0;
+ }
diff --git a/queue-6.17/x86-cpu-amd-add-missing-terminator-for-zen5_rdseed_microcode.patch b/queue-6.17/x86-cpu-amd-add-missing-terminator-for-zen5_rdseed_microcode.patch
new file mode 100644 (file)
index 0000000..1ce888c
--- /dev/null
@@ -0,0 +1,32 @@
+From f1fdffe0afea02ba783acfe815b6a60e7180df40 Mon Sep 17 00:00:00 2001
+From: Mario Limonciello <mario.limonciello@amd.com>
+Date: Tue, 4 Nov 2025 10:10:06 -0600
+Subject: x86/CPU/AMD: Add missing terminator for zen5_rdseed_microcode
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+commit f1fdffe0afea02ba783acfe815b6a60e7180df40 upstream.
+
+Running x86_match_min_microcode_rev() on a Zen5 CPU trips up KASAN for an out
+of bounds access.
+
+Fixes: 607b9fb2ce248 ("x86/CPU/AMD: Add RDSEED fix for Zen5")
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20251104161007.269885-1-mario.limonciello@amd.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kernel/cpu/amd.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/x86/kernel/cpu/amd.c
++++ b/arch/x86/kernel/cpu/amd.c
+@@ -1021,6 +1021,7 @@ static void init_amd_zen4(struct cpuinfo
+ static const struct x86_cpu_id zen5_rdseed_microcode[] = {
+       ZEN_MODEL_STEP_UCODE(0x1a, 0x02, 0x1, 0x0b00215a),
+       ZEN_MODEL_STEP_UCODE(0x1a, 0x11, 0x0, 0x0b101054),
++      {},
+ };
+ static void init_amd_zen5(struct cpuinfo_x86 *c)
diff --git a/queue-6.17/x86-microcode-amd-add-more-known-models-to-entry-sign-checking.patch b/queue-6.17/x86-microcode-amd-add-more-known-models-to-entry-sign-checking.patch
new file mode 100644 (file)
index 0000000..d8edd56
--- /dev/null
@@ -0,0 +1,36 @@
+From d23550efc6800841b4d1639784afaebdea946ae0 Mon Sep 17 00:00:00 2001
+From: "Mario Limonciello (AMD)" <superm1@kernel.org>
+Date: Thu, 6 Nov 2025 12:28:54 -0600
+Subject: x86/microcode/AMD: Add more known models to entry sign checking
+
+From: Mario Limonciello (AMD) <superm1@kernel.org>
+
+commit d23550efc6800841b4d1639784afaebdea946ae0 upstream.
+
+Two Zen5 systems are missing from need_sha_check(). Add them.
+
+Fixes: 50cef76d5cb0 ("x86/microcode/AMD: Load only SHA256-checksummed patches")
+Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Cc: <stable@kernel.org>
+Link: https://patch.msgid.link/20251106182904.4143757-1-superm1@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kernel/cpu/microcode/amd.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/x86/kernel/cpu/microcode/amd.c
++++ b/arch/x86/kernel/cpu/microcode/amd.c
+@@ -220,10 +220,12 @@ static bool need_sha_check(u32 cur_rev)
+       case 0xaa001: return cur_rev <= 0xaa00116; break;
+       case 0xaa002: return cur_rev <= 0xaa00218; break;
+       case 0xb0021: return cur_rev <= 0xb002146; break;
++      case 0xb0081: return cur_rev <= 0xb008111; break;
+       case 0xb1010: return cur_rev <= 0xb101046; break;
+       case 0xb2040: return cur_rev <= 0xb204031; break;
+       case 0xb4040: return cur_rev <= 0xb404031; break;
+       case 0xb6000: return cur_rev <= 0xb600031; break;
++      case 0xb6080: return cur_rev <= 0xb608031; break;
+       case 0xb7000: return cur_rev <= 0xb700031; break;
+       default: break;
+       }
diff --git a/queue-6.17/xfs-fix-delalloc-write-failures-in-software-provided-atomic-writes.patch b/queue-6.17/xfs-fix-delalloc-write-failures-in-software-provided-atomic-writes.patch
new file mode 100644 (file)
index 0000000..698dc0d
--- /dev/null
@@ -0,0 +1,91 @@
+From 8d54eacd82a0623a963e0c150ad3b02970638b0d Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <djwong@kernel.org>
+Date: Tue, 4 Nov 2025 16:12:00 -0800
+Subject: xfs: fix delalloc write failures in software-provided atomic writes
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+commit 8d54eacd82a0623a963e0c150ad3b02970638b0d upstream.
+
+With the 20 Oct 2025 release of fstests, generic/521 fails for me on
+regular (aka non-block-atomic-writes) storage:
+
+QA output created by 521
+dowrite: write: Input/output error
+LOG DUMP (8553 total operations):
+1(  1 mod 256): SKIPPED (no operation)
+2(  2 mod 256): WRITE    0x7e000 thru 0x8dfff  (0x10000 bytes) HOLE
+3(  3 mod 256): READ     0x69000 thru 0x79fff  (0x11000 bytes)
+4(  4 mod 256): FALLOC   0x53c38 thru 0x5e853  (0xac1b bytes) INTERIOR
+5(  5 mod 256): COPY 0x55000 thru 0x59fff      (0x5000 bytes) to 0x25000 thru 0x29fff
+6(  6 mod 256): WRITE    0x74000 thru 0x88fff  (0x15000 bytes)
+7(  7 mod 256): ZERO     0xedb1 thru 0x11693   (0x28e3 bytes)
+
+with a warning in dmesg from iomap about XFS trying to give it a
+delalloc mapping for a directio write.  Fix the software atomic write
+iomap_begin code to convert the reservation into a written mapping.
+This doesn't fix the data corruption problems reported by generic/760,
+but it's a start.
+
+Cc: stable@vger.kernel.org # v6.16
+Fixes: bd1d2c21d5d249 ("xfs: add xfs_atomic_write_cow_iomap_begin()")
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Reviewed-by: John Garry <john.g.garry@oracle.com>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/xfs_iomap.c |   21 +++++++++++++++++++--
+ 1 file changed, 19 insertions(+), 2 deletions(-)
+
+--- a/fs/xfs/xfs_iomap.c
++++ b/fs/xfs/xfs_iomap.c
+@@ -1121,7 +1121,7 @@ xfs_atomic_write_cow_iomap_begin(
+               return -EAGAIN;
+       trace_xfs_iomap_atomic_write_cow(ip, offset, length);
+-
++retry:
+       xfs_ilock(ip, XFS_ILOCK_EXCL);
+       if (!ip->i_cowfp) {
+@@ -1132,6 +1132,8 @@ xfs_atomic_write_cow_iomap_begin(
+       if (!xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &cmap))
+               cmap.br_startoff = end_fsb;
+       if (cmap.br_startoff <= offset_fsb) {
++              if (isnullstartblock(cmap.br_startblock))
++                      goto convert_delay;
+               xfs_trim_extent(&cmap, offset_fsb, count_fsb);
+               goto found;
+       }
+@@ -1160,8 +1162,10 @@ xfs_atomic_write_cow_iomap_begin(
+       if (!xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &cmap))
+               cmap.br_startoff = end_fsb;
+       if (cmap.br_startoff <= offset_fsb) {
+-              xfs_trim_extent(&cmap, offset_fsb, count_fsb);
+               xfs_trans_cancel(tp);
++              if (isnullstartblock(cmap.br_startblock))
++                      goto convert_delay;
++              xfs_trim_extent(&cmap, offset_fsb, count_fsb);
+               goto found;
+       }
+@@ -1201,6 +1205,19 @@ found:
+       xfs_iunlock(ip, XFS_ILOCK_EXCL);
+       return xfs_bmbt_to_iomap(ip, iomap, &cmap, flags, IOMAP_F_SHARED, seq);
++convert_delay:
++      xfs_iunlock(ip, XFS_ILOCK_EXCL);
++      error = xfs_bmapi_convert_delalloc(ip, XFS_COW_FORK, offset, iomap,
++                      NULL);
++      if (error)
++              return error;
++
++      /*
++       * Try the lookup again, because the delalloc conversion might have
++       * turned the COW mapping into unwritten, but we need it to be in
++       * written state.
++       */
++      goto retry;
+ out_unlock:
+       xfs_iunlock(ip, XFS_ILOCK_EXCL);
+       return error;
diff --git a/queue-6.17/xfs-fix-various-problems-in-xfs_atomic_write_cow_iomap_begin.patch b/queue-6.17/xfs-fix-various-problems-in-xfs_atomic_write_cow_iomap_begin.patch
new file mode 100644 (file)
index 0000000..1668628
--- /dev/null
@@ -0,0 +1,167 @@
+From 8d7bba1e8314013ecc817a91624104ceb9352ddc Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <djwong@kernel.org>
+Date: Tue, 4 Nov 2025 16:15:38 -0800
+Subject: xfs: fix various problems in xfs_atomic_write_cow_iomap_begin
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+commit 8d7bba1e8314013ecc817a91624104ceb9352ddc upstream.
+
+I think there are several things wrong with this function:
+
+A) xfs_bmapi_write can return a much larger unwritten mapping than what
+   the caller asked for.  We convert part of that range to written, but
+   return the entire written mapping to iomap even though that's
+   inaccurate.
+
+B) The arguments to xfs_reflink_convert_cow_locked are wrong -- an
+   unwritten mapping could be *smaller* than the write range (or even
+   the hole range).  In this case, we convert too much file range to
+   written state because we then return a smaller mapping to iomap.
+
+C) It doesn't handle delalloc mappings.  This I covered in the patch
+   that I already sent to the list.
+
+D) Reassigning count_fsb to handle the hole means that if the second
+   cmap lookup attempt succeeds (due to racing with someone else) we
+   trim the mapping more than is strictly necessary.  The changing
+   meaning of count_fsb makes this harder to notice.
+
+E) The tracepoint is kinda wrong because @length is mutated.  That makes
+   it harder to chase the data flows through this function because you
+   can't just grep on the pos/bytecount strings.
+
+F) We don't actually check that the br_state = XFS_EXT_NORM assignment
+   is accurate, i.e that the cow fork actually contains a written
+   mapping for the range we're interested in
+
+G) Somewhat inadequate documentation of why we need to xfs_trim_extent
+   so aggressively in this function.
+
+H) Not sure why xfs_iomap_end_fsb is used here, the vfs already clamped
+   the write range to s_maxbytes.
+
+Fix these issues, and then the atomic writes regressions in generic/760,
+generic/617, generic/091, generic/263, and generic/521 all go away for
+me.
+
+Cc: stable@vger.kernel.org # v6.16
+Fixes: bd1d2c21d5d249 ("xfs: add xfs_atomic_write_cow_iomap_begin()")
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Reviewed-by: John Garry <john.g.garry@oracle.com>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/xfs_iomap.c |   61 +++++++++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 50 insertions(+), 11 deletions(-)
+
+--- a/fs/xfs/xfs_iomap.c
++++ b/fs/xfs/xfs_iomap.c
+@@ -1082,6 +1082,29 @@ const struct iomap_ops xfs_zoned_direct_
+ };
+ #endif /* CONFIG_XFS_RT */
++#ifdef DEBUG
++static void
++xfs_check_atomic_cow_conversion(
++      struct xfs_inode                *ip,
++      xfs_fileoff_t                   offset_fsb,
++      xfs_filblks_t                   count_fsb,
++      const struct xfs_bmbt_irec      *cmap)
++{
++      struct xfs_iext_cursor          icur;
++      struct xfs_bmbt_irec            cmap2 = { };
++
++      if (xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &cmap2))
++              xfs_trim_extent(&cmap2, offset_fsb, count_fsb);
++
++      ASSERT(cmap2.br_startoff == cmap->br_startoff);
++      ASSERT(cmap2.br_blockcount == cmap->br_blockcount);
++      ASSERT(cmap2.br_startblock == cmap->br_startblock);
++      ASSERT(cmap2.br_state == cmap->br_state);
++}
++#else
++# define xfs_check_atomic_cow_conversion(...) ((void)0)
++#endif
++
+ static int
+ xfs_atomic_write_cow_iomap_begin(
+       struct inode            *inode,
+@@ -1093,9 +1116,10 @@ xfs_atomic_write_cow_iomap_begin(
+ {
+       struct xfs_inode        *ip = XFS_I(inode);
+       struct xfs_mount        *mp = ip->i_mount;
+-      const xfs_fileoff_t             offset_fsb = XFS_B_TO_FSBT(mp, offset);
+-      xfs_fileoff_t           end_fsb = xfs_iomap_end_fsb(mp, offset, length);
+-      xfs_filblks_t           count_fsb = end_fsb - offset_fsb;
++      const xfs_fileoff_t     offset_fsb = XFS_B_TO_FSBT(mp, offset);
++      const xfs_fileoff_t     end_fsb = XFS_B_TO_FSB(mp, offset + length);
++      const xfs_filblks_t     count_fsb = end_fsb - offset_fsb;
++      xfs_filblks_t           hole_count_fsb;
+       int                     nmaps = 1;
+       xfs_filblks_t           resaligned;
+       struct xfs_bmbt_irec    cmap;
+@@ -1134,14 +1158,20 @@ retry:
+       if (cmap.br_startoff <= offset_fsb) {
+               if (isnullstartblock(cmap.br_startblock))
+                       goto convert_delay;
++
++              /*
++               * cmap could extend outside the write range due to previous
++               * speculative preallocations.  We must trim cmap to the write
++               * range because the cow fork treats written mappings to mean
++               * "write in progress".
++               */
+               xfs_trim_extent(&cmap, offset_fsb, count_fsb);
+               goto found;
+       }
+-      end_fsb = cmap.br_startoff;
+-      count_fsb = end_fsb - offset_fsb;
++      hole_count_fsb = cmap.br_startoff - offset_fsb;
+-      resaligned = xfs_aligned_fsb_count(offset_fsb, count_fsb,
++      resaligned = xfs_aligned_fsb_count(offset_fsb, hole_count_fsb,
+                       xfs_get_cowextsz_hint(ip));
+       xfs_iunlock(ip, XFS_ILOCK_EXCL);
+@@ -1177,7 +1207,7 @@ retry:
+        * atomic writes to that same range will be aligned (and don't require
+        * this COW-based method).
+        */
+-      error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb,
++      error = xfs_bmapi_write(tp, ip, offset_fsb, hole_count_fsb,
+                       XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC |
+                       XFS_BMAPI_EXTSZALIGN, 0, &cmap, &nmaps);
+       if (error) {
+@@ -1190,17 +1220,26 @@ retry:
+       if (error)
+               goto out_unlock;
++      /*
++       * cmap could map more blocks than the range we passed into bmapi_write
++       * because of EXTSZALIGN or adjacent pre-existing unwritten mappings
++       * that were merged.  Trim cmap to the original write range so that we
++       * don't convert more than we were asked to do for this write.
++       */
++      xfs_trim_extent(&cmap, offset_fsb, count_fsb);
++
+ found:
+       if (cmap.br_state != XFS_EXT_NORM) {
+-              error = xfs_reflink_convert_cow_locked(ip, offset_fsb,
+-                              count_fsb);
++              error = xfs_reflink_convert_cow_locked(ip, cmap.br_startoff,
++                              cmap.br_blockcount);
+               if (error)
+                       goto out_unlock;
+               cmap.br_state = XFS_EXT_NORM;
++              xfs_check_atomic_cow_conversion(ip, offset_fsb, count_fsb,
++                              &cmap);
+       }
+-      length = XFS_FSB_TO_B(mp, cmap.br_startoff + cmap.br_blockcount);
+-      trace_xfs_iomap_found(ip, offset, length - offset, XFS_COW_FORK, &cmap);
++      trace_xfs_iomap_found(ip, offset, length, XFS_COW_FORK, &cmap);
+       seq = xfs_iomap_inode_sequence(ip, IOMAP_F_SHARED);
+       xfs_iunlock(ip, XFS_ILOCK_EXCL);
+       return xfs_bmbt_to_iomap(ip, iomap, &cmap, flags, IOMAP_F_SHARED, seq);