From 93127fcbafac1f662571e32ed37e45b83577d09d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 4 Feb 2026 11:12:37 +0100 Subject: [PATCH] 6.6-stable patches added patches: alsa-usb-audio-fix-missing-unlock-at-error-path-of-maxpacksize-check.patch drm-amdgpu-fix-null-pointer-dereference-in-amdgpu_gmc_filter_faults_remove.patch drm-amdkfd-don-t-use-sw-fault-filter-if-retry-cam-enabled.patch drm-msm-a6xx-fix-bogus-hwcg-register-updates.patch ksmbd-fix-recursive-locking-in-rpc-handle-list-access.patch mptcp-avoid-dup-sub_closed-events-after-disconnect.patch perf-sched-fix-perf-crash-with-new-is_user_task-helper.patch pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch pinctrl-qcom-sm8350-lpass-lpi-merge-with-sc7280-to-fix-i2s2-and-swr-tx-pins.patch writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch xsk-fix-race-condition-in-af_xdp-generic-rx-path.patch --- ...k-at-error-path-of-maxpacksize-check.patch | 42 +++ ...e-in-amdgpu_gmc_filter_faults_remove.patch | 79 +++++ ...sw-fault-filter-if-retry-cam-enabled.patch | 39 +++ ...a6xx-fix-bogus-hwcg-register-updates.patch | 56 ++++ ...ve-locking-in-rpc-handle-list-access.patch | 158 ++++++++++ ...p-sub_closed-events-after-disconnect.patch | 56 ++++ ...f-crash-with-new-is_user_task-helper.patch | 116 ++++++++ ...t-.get_direction-for-the-gpio-driver.patch | 64 +++++ ...h-sc7280-to-fix-i2s2-and-swr-tx-pins.patch | 270 ++++++++++++++++++ queue-6.6/series | 11 + ...-when-dirtytime_expire_interval-is-0.patch | 77 +++++ ...-condition-in-af_xdp-generic-rx-path.patch | 116 ++++++++ 12 files changed, 1084 insertions(+) create mode 100644 queue-6.6/alsa-usb-audio-fix-missing-unlock-at-error-path-of-maxpacksize-check.patch create mode 100644 queue-6.6/drm-amdgpu-fix-null-pointer-dereference-in-amdgpu_gmc_filter_faults_remove.patch create mode 100644 queue-6.6/drm-amdkfd-don-t-use-sw-fault-filter-if-retry-cam-enabled.patch create mode 100644 queue-6.6/drm-msm-a6xx-fix-bogus-hwcg-register-updates.patch create mode 100644 queue-6.6/ksmbd-fix-recursive-locking-in-rpc-handle-list-access.patch create mode 100644 queue-6.6/mptcp-avoid-dup-sub_closed-events-after-disconnect.patch create mode 100644 queue-6.6/perf-sched-fix-perf-crash-with-new-is_user_task-helper.patch create mode 100644 queue-6.6/pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch create mode 100644 queue-6.6/pinctrl-qcom-sm8350-lpass-lpi-merge-with-sc7280-to-fix-i2s2-and-swr-tx-pins.patch create mode 100644 queue-6.6/writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch create mode 100644 queue-6.6/xsk-fix-race-condition-in-af_xdp-generic-rx-path.patch diff --git a/queue-6.6/alsa-usb-audio-fix-missing-unlock-at-error-path-of-maxpacksize-check.patch b/queue-6.6/alsa-usb-audio-fix-missing-unlock-at-error-path-of-maxpacksize-check.patch new file mode 100644 index 0000000000..d0c4fa4246 --- /dev/null +++ b/queue-6.6/alsa-usb-audio-fix-missing-unlock-at-error-path-of-maxpacksize-check.patch @@ -0,0 +1,42 @@ +From fdf0dc82eb60091772ecea73cbc5a8fb7562fc45 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Wed, 26 Nov 2025 11:08:31 +0100 +Subject: ALSA: usb-audio: Fix missing unlock at error path of maxpacksize check + +From: Takashi Iwai + +commit fdf0dc82eb60091772ecea73cbc5a8fb7562fc45 upstream. + +The recent backport of the upstream commit 05a1fc5efdd8 ("ALSA: +usb-audio: Fix potential overflow of PCM transfer buffer") on the +older stable kernels like 6.12.y was broken since it doesn't consider +the mutex unlock, where the upstream code manages with guard(). +In the older code, we still need an explicit unlock. + +This is a fix that corrects the error path, applied only on old stable +trees. + +Reported-by: Pavel Machek +Closes: https://lore.kernel.org/aSWtH0AZH5+aeb+a@duo.ucw.cz +Fixes: 98e9d5e33bda ("ALSA: usb-audio: Fix potential overflow of PCM transfer buffer") +Reviewed-by: Pavel Machek +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +Signed-off-by: Wentao Guan +Signed-off-by: Greg Kroah-Hartman +--- + sound/usb/endpoint.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/sound/usb/endpoint.c ++++ b/sound/usb/endpoint.c +@@ -1386,7 +1386,8 @@ int snd_usb_endpoint_set_params(struct s + if (ep->packsize[1] > ep->maxpacksize) { + usb_audio_dbg(chip, "Too small maxpacksize %u for rate %u / pps %u\n", + ep->maxpacksize, ep->cur_rate, ep->pps); +- return -EINVAL; ++ err = -EINVAL; ++ goto unlock; + } + + /* calculate the frequency in 16.16 format */ diff --git a/queue-6.6/drm-amdgpu-fix-null-pointer-dereference-in-amdgpu_gmc_filter_faults_remove.patch b/queue-6.6/drm-amdgpu-fix-null-pointer-dereference-in-amdgpu_gmc_filter_faults_remove.patch new file mode 100644 index 0000000000..98551d7160 --- /dev/null +++ b/queue-6.6/drm-amdgpu-fix-null-pointer-dereference-in-amdgpu_gmc_filter_faults_remove.patch @@ -0,0 +1,79 @@ +From stable+bounces-213324-greg=kroah.com@vger.kernel.org Wed Feb 4 01:26:57 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 19:26:45 -0500 +Subject: drm/amdgpu: fix NULL pointer dereference in amdgpu_gmc_filter_faults_remove +To: stable@vger.kernel.org +Cc: "Jon Doron" , "Timur Kristóf" , "Philip Yang" , "Alex Deucher" , "Sasha Levin" +Message-ID: <20260204002645.1462394-2-sashal@kernel.org> + +From: Jon Doron + +[ Upstream commit 8b1ecc9377bc641533cd9e76dfa3aee3cd04a007 ] + +On APUs such as Raven and Renoir (GC 9.1.0, 9.2.2, 9.3.0), the ih1 and +ih2 interrupt ring buffers are not initialized. This is by design, as +these secondary IH rings are only available on discrete GPUs. See +vega10_ih_sw_init() which explicitly skips ih1/ih2 initialization when +AMD_IS_APU is set. + +However, amdgpu_gmc_filter_faults_remove() unconditionally uses ih1 to +get the timestamp of the last interrupt entry. When retry faults are +enabled on APUs (noretry=0), this function is called from the SVM page +fault recovery path, resulting in a NULL pointer dereference when +amdgpu_ih_decode_iv_ts_helper() attempts to access ih->ring[]. + +The crash manifests as: + + BUG: kernel NULL pointer dereference, address: 0000000000000004 + RIP: 0010:amdgpu_ih_decode_iv_ts_helper+0x22/0x40 [amdgpu] + Call Trace: + amdgpu_gmc_filter_faults_remove+0x60/0x130 [amdgpu] + svm_range_restore_pages+0xae5/0x11c0 [amdgpu] + amdgpu_vm_handle_fault+0xc8/0x340 [amdgpu] + gmc_v9_0_process_interrupt+0x191/0x220 [amdgpu] + amdgpu_irq_dispatch+0xed/0x2c0 [amdgpu] + amdgpu_ih_process+0x84/0x100 [amdgpu] + +This issue was exposed by commit 1446226d32a4 ("drm/amdgpu: Remove GC HW +IP 9.3.0 from noretry=1") which changed the default for Renoir APU from +noretry=1 to noretry=0, enabling retry fault handling and thus +exercising the buggy code path. + +Fix this by adding a check for ih1.ring_size before attempting to use +it. Also restore the soft_ih support from commit dd299441654f ("drm/amdgpu: +Rework retry fault removal"). This is needed if the hardware doesn't +support secondary HW IH rings. + +v2: additional updates (Alex) + +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3814 +Fixes: dd299441654f ("drm/amdgpu: Rework retry fault removal") +Reviewed-by: Timur Kristóf +Reviewed-by: Philip Yang +Signed-off-by: Jon Doron +Signed-off-by: Alex Deucher +(cherry picked from commit 6ce8d536c80aa1f059e82184f0d1994436b1d526) +Cc: stable@vger.kernel.org +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +@@ -454,8 +454,13 @@ void amdgpu_gmc_filter_faults_remove(str + + if (adev->irq.retry_cam_enabled) + return; ++ else if (adev->irq.ih1.ring_size) ++ ih = &adev->irq.ih1; ++ else if (adev->irq.ih_soft.enabled) ++ ih = &adev->irq.ih_soft; ++ else ++ return; + +- ih = &adev->irq.ih1; + /* Get the WPTR of the last entry in IH ring */ + last_wptr = amdgpu_ih_get_wptr(adev, ih); + /* Order wptr with ring data. */ diff --git a/queue-6.6/drm-amdkfd-don-t-use-sw-fault-filter-if-retry-cam-enabled.patch b/queue-6.6/drm-amdkfd-don-t-use-sw-fault-filter-if-retry-cam-enabled.patch new file mode 100644 index 0000000000..bf761dc5c5 --- /dev/null +++ b/queue-6.6/drm-amdkfd-don-t-use-sw-fault-filter-if-retry-cam-enabled.patch @@ -0,0 +1,39 @@ +From stable+bounces-213323-greg=kroah.com@vger.kernel.org Wed Feb 4 01:26:52 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 19:26:44 -0500 +Subject: drm/amdkfd: Don't use sw fault filter if retry cam enabled +To: stable@vger.kernel.org +Cc: "Philip Yang" , "Christian König" , "Alex Deucher" , "Sasha Levin" +Message-ID: <20260204002645.1462394-1-sashal@kernel.org> + +From: Philip Yang + +[ Upstream commit e61801f162ddcf8874c820639483ec4849b0fb0b ] + +If retry cam enabled, we don't use sw retry fault filter and add fault +into sw filter ring, so we shouldn't remove fault from sw filter. + +Signed-off-by: Philip Yang +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +Stable-dep-of: 8b1ecc9377bc ("drm/amdgpu: fix NULL pointer dereference in amdgpu_gmc_filter_faults_remove") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +@@ -452,7 +452,10 @@ void amdgpu_gmc_filter_faults_remove(str + uint32_t hash; + uint64_t tmp; + +- ih = adev->irq.retry_cam_enabled ? &adev->irq.ih_soft : &adev->irq.ih1; ++ if (adev->irq.retry_cam_enabled) ++ return; ++ ++ ih = &adev->irq.ih1; + /* Get the WPTR of the last entry in IH ring */ + last_wptr = amdgpu_ih_get_wptr(adev, ih); + /* Order wptr with ring data. */ diff --git a/queue-6.6/drm-msm-a6xx-fix-bogus-hwcg-register-updates.patch b/queue-6.6/drm-msm-a6xx-fix-bogus-hwcg-register-updates.patch new file mode 100644 index 0000000000..80c281fbf4 --- /dev/null +++ b/queue-6.6/drm-msm-a6xx-fix-bogus-hwcg-register-updates.patch @@ -0,0 +1,56 @@ +From stable+bounces-213313-greg=kroah.com@vger.kernel.org Tue Feb 3 22:19:01 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 16:17:52 -0500 +Subject: drm/msm/a6xx: fix bogus hwcg register updates +To: stable@vger.kernel.org +Cc: Johan Hovold , Bjorn Andersson , Konrad Dybcio , Konrad Dybcio , Akhil P Oommen , Rob Clark , Sasha Levin +Message-ID: <20260203211752.1413731-1-sashal@kernel.org> + +From: Johan Hovold + +[ Upstream commit dedb897f11c5d7e32c0e0a0eff7cec23a8047167 ] + +The hw clock gating register sequence consists of register value pairs +that are written to the GPU during initialisation. + +The a690 hwcg sequence has two GMU registers in it that used to amount +to random writes in the GPU mapping, but since commit 188db3d7fe66 +("drm/msm/a6xx: Rebase GMU register offsets") they trigger a fault as +the updated offsets now lie outside the mapping. This in turn breaks +boot of machines like the Lenovo ThinkPad X13s. + +Note that the updates of these GMU registers is already taken care of +properly since commit 40c297eb245b ("drm/msm/a6xx: Set GMU CGC +properties on a6xx too"), but for some reason these two entries were +left in the table. + +Fixes: 5e7665b5e484 ("drm/msm/adreno: Add Adreno A690 support") +Cc: stable@vger.kernel.org # 6.5 +Cc: Bjorn Andersson +Cc: Konrad Dybcio +Signed-off-by: Johan Hovold +Reviewed-by: Konrad Dybcio +Reviewed-by: Akhil P Oommen +Fixes: 188db3d7fe66 ("drm/msm/a6xx: Rebase GMU register offsets") +Patchwork: https://patchwork.freedesktop.org/patch/695778/ +Message-ID: <20251221164552.19990-1-johan@kernel.org> +Signed-off-by: Rob Clark +(cherry picked from commit dcbd2f8280eea2c965453ed8c3c69d6f121e950b) +[ Applied fix to a6xx_gpu.c instead of a6xx_catalog.c ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +@@ -690,8 +690,6 @@ const struct adreno_reglist a690_hwcg[] + {REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111}, + {REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555}, + {REG_A6XX_GPU_GMU_AO_GMU_CGC_MODE_CNTL, 0x20200}, +- {REG_A6XX_GPU_GMU_AO_GMU_CGC_DELAY_CNTL, 0x10111}, +- {REG_A6XX_GPU_GMU_AO_GMU_CGC_HYST_CNTL, 0x5555}, + {} + }; + diff --git a/queue-6.6/ksmbd-fix-recursive-locking-in-rpc-handle-list-access.patch b/queue-6.6/ksmbd-fix-recursive-locking-in-rpc-handle-list-access.patch new file mode 100644 index 0000000000..056d9a4b8b --- /dev/null +++ b/queue-6.6/ksmbd-fix-recursive-locking-in-rpc-handle-list-access.patch @@ -0,0 +1,158 @@ +From stable+bounces-213337-greg=kroah.com@vger.kernel.org Wed Feb 4 03:22:32 2026 +From: Li hongliang <1468888505@139.com> +Date: Wed, 4 Feb 2026 10:22:05 +0800 +Subject: ksmbd: fix recursive locking in RPC handle list access +To: mmakassikis@freebox.fr, gregkh@linuxfoundation.org, stable@vger.kernel.org, ysk@kzalloc.com +Cc: patches@lists.linux.dev, linux-kernel@vger.kernel.org, linkinjeon@kernel.org, sfrench@samba.org, senozhatsky@chromium.org, tom@talpey.com, akendo@akendo.eu, set_pte_at@outlook.com, linux-cifs@vger.kernel.org, stfrench@microsoft.com +Message-ID: <20260204022205.3204230-1-1468888505@139.com> + +From: Marios Makassikis + +[ Upstream commit 88f170814fea74911ceab798a43cbd7c5599bed4 ] + +Since commit 305853cce3794 ("ksmbd: Fix race condition in RPC handle list +access"), ksmbd_session_rpc_method() attempts to lock sess->rpc_lock. + +This causes hung connections / tasks when a client attempts to open +a named pipe. Using Samba's rpcclient tool: + + $ rpcclient //192.168.1.254 -U user%password + $ rpcclient $> srvinfo + + +Kernel side: + "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. + task:kworker/0:0 state:D stack:0 pid:5021 tgid:5021 ppid:2 flags:0x00200000 + Workqueue: ksmbd-io handle_ksmbd_work + Call trace: + __schedule from schedule+0x3c/0x58 + schedule from schedule_preempt_disabled+0xc/0x10 + schedule_preempt_disabled from rwsem_down_read_slowpath+0x1b0/0x1d8 + rwsem_down_read_slowpath from down_read+0x28/0x30 + down_read from ksmbd_session_rpc_method+0x18/0x3c + ksmbd_session_rpc_method from ksmbd_rpc_open+0x34/0x68 + ksmbd_rpc_open from ksmbd_session_rpc_open+0x194/0x228 + ksmbd_session_rpc_open from create_smb2_pipe+0x8c/0x2c8 + create_smb2_pipe from smb2_open+0x10c/0x27ac + smb2_open from handle_ksmbd_work+0x238/0x3dc + handle_ksmbd_work from process_scheduled_works+0x160/0x25c + process_scheduled_works from worker_thread+0x16c/0x1e8 + worker_thread from kthread+0xa8/0xb8 + kthread from ret_from_fork+0x14/0x38 + Exception stack(0x8529ffb0 to 0x8529fff8) + +The task deadlocks because the lock is already held: + ksmbd_session_rpc_open + down_write(&sess->rpc_lock) + ksmbd_rpc_open + ksmbd_session_rpc_method + down_read(&sess->rpc_lock) <-- deadlock + +Adjust ksmbd_session_rpc_method() callers to take the lock when necessary. + +Fixes: 305853cce3794 ("ksmbd: Fix race condition in RPC handle list access") +Signed-off-by: Marios Makassikis +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Li hongliang <1468888505@139.com> +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/server/mgmt/user_session.c | 7 ++----- + fs/smb/server/smb2pdu.c | 9 ++++++++- + fs/smb/server/transport_ipc.c | 12 ++++++++++++ + 3 files changed, 22 insertions(+), 6 deletions(-) + +--- a/fs/smb/server/mgmt/user_session.c ++++ b/fs/smb/server/mgmt/user_session.c +@@ -147,14 +147,11 @@ void ksmbd_session_rpc_close(struct ksmb + int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id) + { + struct ksmbd_session_rpc *entry; +- int method; + +- down_read(&sess->rpc_lock); ++ lockdep_assert_held(&sess->rpc_lock); + entry = xa_load(&sess->rpc_handle_list, id); +- method = entry ? entry->method : 0; +- up_read(&sess->rpc_lock); + +- return method; ++ return entry ? entry->method : 0; + } + + void ksmbd_session_destroy(struct ksmbd_session *sess) +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -4614,8 +4614,15 @@ static int smb2_get_info_file_pipe(struc + * pipe without opening it, checking error condition here + */ + id = req->VolatileFileId; +- if (!ksmbd_session_rpc_method(sess, id)) ++ ++ lockdep_assert_not_held(&sess->rpc_lock); ++ ++ down_read(&sess->rpc_lock); ++ if (!ksmbd_session_rpc_method(sess, id)) { ++ up_read(&sess->rpc_lock); + return -ENOENT; ++ } ++ up_read(&sess->rpc_lock); + + ksmbd_debug(SMB, "FileInfoClass %u, FileId 0x%llx\n", + req->FileInfoClass, req->VolatileFileId); +--- a/fs/smb/server/transport_ipc.c ++++ b/fs/smb/server/transport_ipc.c +@@ -778,6 +778,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_writ + if (!msg) + return NULL; + ++ lockdep_assert_not_held(&sess->rpc_lock); ++ ++ down_read(&sess->rpc_lock); + msg->type = KSMBD_EVENT_RPC_REQUEST; + req = (struct ksmbd_rpc_command *)msg->payload; + req->handle = handle; +@@ -786,6 +789,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_writ + req->flags |= KSMBD_RPC_WRITE_METHOD; + req->payload_sz = payload_sz; + memcpy(req->payload, payload, payload_sz); ++ up_read(&sess->rpc_lock); + + resp = ipc_msg_send_request(msg, req->handle); + ipc_msg_free(msg); +@@ -802,6 +806,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_read + if (!msg) + return NULL; + ++ lockdep_assert_not_held(&sess->rpc_lock); ++ ++ down_read(&sess->rpc_lock); + msg->type = KSMBD_EVENT_RPC_REQUEST; + req = (struct ksmbd_rpc_command *)msg->payload; + req->handle = handle; +@@ -809,6 +816,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_read + req->flags |= rpc_context_flags(sess); + req->flags |= KSMBD_RPC_READ_METHOD; + req->payload_sz = 0; ++ up_read(&sess->rpc_lock); + + resp = ipc_msg_send_request(msg, req->handle); + ipc_msg_free(msg); +@@ -829,6 +837,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_ioct + if (!msg) + return NULL; + ++ lockdep_assert_not_held(&sess->rpc_lock); ++ ++ down_read(&sess->rpc_lock); + msg->type = KSMBD_EVENT_RPC_REQUEST; + req = (struct ksmbd_rpc_command *)msg->payload; + req->handle = handle; +@@ -837,6 +848,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_ioct + req->flags |= KSMBD_RPC_IOCTL_METHOD; + req->payload_sz = payload_sz; + memcpy(req->payload, payload, payload_sz); ++ up_read(&sess->rpc_lock); + + resp = ipc_msg_send_request(msg, req->handle); + ipc_msg_free(msg); diff --git a/queue-6.6/mptcp-avoid-dup-sub_closed-events-after-disconnect.patch b/queue-6.6/mptcp-avoid-dup-sub_closed-events-after-disconnect.patch new file mode 100644 index 0000000000..4bbef12308 --- /dev/null +++ b/queue-6.6/mptcp-avoid-dup-sub_closed-events-after-disconnect.patch @@ -0,0 +1,56 @@ +From stable+bounces-213298-greg=kroah.com@vger.kernel.org Tue Feb 3 19:05:05 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 13:04:30 -0500 +Subject: mptcp: avoid dup SUB_CLOSED events after disconnect +To: stable@vger.kernel.org +Cc: "Matthieu Baerts (NGI0)" , Marco Angaroni , Geliang Tang , Jakub Kicinski , Sasha Levin +Message-ID: <20260203180430.1352713-1-sashal@kernel.org> + +From: "Matthieu Baerts (NGI0)" + +[ Upstream commit 280d654324e33f8e6e3641f76764694c7b64c5db ] + +In case of subflow disconnect(), which can also happen with the first +subflow in case of errors like timeout or reset, mptcp_subflow_ctx_reset +will reset most fields from the mptcp_subflow_context structure, +including close_event_done. Then, when another subflow is closed, yet +another SUB_CLOSED event for the disconnected initial subflow is sent. +Because of the previous reset, there are no source address and +destination port. + +A solution is then to also check the subflow's local id: it shouldn't be +negative anyway. + +Another solution would be not to reset subflow->close_event_done at +disconnect time, but when reused. But then, probably the whole reset +could be done when being reused. Let's not change this logic, similar +to TCP with tcp_disconnect(). + +Fixes: d82809b6c5f2 ("mptcp: avoid duplicated SUB_CLOSED events") +Cc: stable@vger.kernel.org +Reported-by: Marco Angaroni +Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/603 +Reviewed-by: Geliang Tang +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20260127-net-mptcp-dup-nl-events-v1-1-7f71e1bc4feb@kernel.org +Signed-off-by: Jakub Kicinski +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/protocol.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -2554,8 +2554,8 @@ out: + void mptcp_close_ssk(struct sock *sk, struct sock *ssk, + struct mptcp_subflow_context *subflow) + { +- /* The first subflow can already be closed and still in the list */ +- if (subflow->close_event_done) ++ /* The first subflow can already be closed or disconnected */ ++ if (subflow->close_event_done || READ_ONCE(subflow->local_id) < 0) + return; + + subflow->close_event_done = true; diff --git a/queue-6.6/perf-sched-fix-perf-crash-with-new-is_user_task-helper.patch b/queue-6.6/perf-sched-fix-perf-crash-with-new-is_user_task-helper.patch new file mode 100644 index 0000000000..67d945e210 --- /dev/null +++ b/queue-6.6/perf-sched-fix-perf-crash-with-new-is_user_task-helper.patch @@ -0,0 +1,116 @@ +From stable+bounces-213307-greg=kroah.com@vger.kernel.org Tue Feb 3 21:27:51 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 15:27:45 -0500 +Subject: perf: sched: Fix perf crash with new is_user_task() helper +To: stable@vger.kernel.org +Cc: Steven Rostedt , Guenter Roeck , "Peter Zijlstra (Intel)" , Sasha Levin +Message-ID: <20260203202745.1391918-1-sashal@kernel.org> + +From: Steven Rostedt + +[ Upstream commit 76ed27608f7dd235b727ebbb12163438c2fbb617 ] + +In order to do a user space stacktrace the current task needs to be a user +task that has executed in user space. It use to be possible to test if a +task is a user task or not by simply checking the task_struct mm field. If +it was non NULL, it was a user task and if not it was a kernel task. + +But things have changed over time, and some kernel tasks now have their +own mm field. + +An idea was made to instead test PF_KTHREAD and two functions were used to +wrap this check in case it became more complex to test if a task was a +user task or not[1]. But this was rejected and the C code simply checked +the PF_KTHREAD directly. + +It was later found that not all kernel threads set PF_KTHREAD. The io-uring +helpers instead set PF_USER_WORKER and this needed to be added as well. + +But checking the flags is still not enough. There's a very small window +when a task exits that it frees its mm field and it is set back to NULL. +If perf were to trigger at this moment, the flags test would say its a +user space task but when perf would read the mm field it would crash with +at NULL pointer dereference. + +Now there are flags that can be used to test if a task is exiting, but +they are set in areas that perf may still want to profile the user space +task (to see where it exited). The only real test is to check both the +flags and the mm field. + +Instead of making this modification in every location, create a new +is_user_task() helper function that does all the tests needed to know if +it is safe to read the user space memory or not. + +[1] https://lore.kernel.org/all/20250425204120.639530125@goodmis.org/ + +Fixes: 90942f9fac05 ("perf: Use current->flags & PF_KTHREAD|PF_USER_WORKER instead of current->mm == NULL") +Closes: https://lore.kernel.org/all/0d877e6f-41a7-4724-875d-0b0a27b8a545@roeck-us.net/ +Reported-by: Guenter Roeck +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Peter Zijlstra (Intel) +Tested-by: Guenter Roeck +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260129102821.46484722@gandalf.local.home +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/sched.h | 5 +++++ + kernel/events/callchain.c | 2 +- + kernel/events/core.c | 6 +++--- + 3 files changed, 9 insertions(+), 4 deletions(-) + +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1800,6 +1800,11 @@ static __always_inline bool is_percpu_th + #endif + } + ++static __always_inline bool is_user_task(struct task_struct *task) ++{ ++ return task->mm && !(task->flags & (PF_KTHREAD | PF_USER_WORKER)); ++} ++ + /* Per-process atomic flags. */ + #define PFA_NO_NEW_PRIVS 0 /* May not gain new privileges. */ + #define PFA_SPREAD_PAGE 1 /* Spread page cache over cpuset */ +--- a/kernel/events/callchain.c ++++ b/kernel/events/callchain.c +@@ -206,7 +206,7 @@ get_perf_callchain(struct pt_regs *regs, + + if (user && !crosstask) { + if (!user_mode(regs)) { +- if (current->flags & (PF_KTHREAD | PF_USER_WORKER)) ++ if (!is_user_task(current)) + regs = NULL; + else + regs = task_pt_regs(current); +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -6985,7 +6985,7 @@ static void perf_sample_regs_user(struct + if (user_mode(regs)) { + regs_user->abi = perf_reg_abi(current); + regs_user->regs = regs; +- } else if (!(current->flags & (PF_KTHREAD | PF_USER_WORKER))) { ++ } else if (is_user_task(current)) { + perf_get_regs_user(regs_user, regs); + } else { + regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE; +@@ -7612,7 +7612,7 @@ static u64 perf_virt_to_phys(u64 virt) + * Try IRQ-safe get_user_page_fast_only first. + * If failed, leave phys_addr as 0. + */ +- if (!(current->flags & (PF_KTHREAD | PF_USER_WORKER))) { ++ if (is_user_task(current)) { + struct page *p; + + pagefault_disable(); +@@ -7725,7 +7725,7 @@ perf_callchain(struct perf_event *event, + { + bool kernel = !event->attr.exclude_callchain_kernel; + bool user = !event->attr.exclude_callchain_user && +- !(current->flags & (PF_KTHREAD | PF_USER_WORKER)); ++ is_user_task(current); + /* Disallow cross-task user callchains. */ + bool crosstask = event->ctx->task && event->ctx->task != current; + const u32 max_stack = event->attr.sample_max_stack; diff --git a/queue-6.6/pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch b/queue-6.6/pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch new file mode 100644 index 0000000000..27de80d03c --- /dev/null +++ b/queue-6.6/pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch @@ -0,0 +1,64 @@ +From stable+bounces-213317-greg=kroah.com@vger.kernel.org Wed Feb 4 00:29:51 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 18:29:44 -0500 +Subject: pinctrl: lpass-lpi: implement .get_direction() for the GPIO driver +To: stable@vger.kernel.org +Cc: Bartosz Golaszewski , Abel Vesa , Konrad Dybcio , Abel Vesa , Linus Walleij , Sasha Levin +Message-ID: <20260203232944.1435982-1-sashal@kernel.org> + +From: Bartosz Golaszewski + +[ Upstream commit 4f0d22ec60cee420125f4055af76caa0f373a3fe ] + +GPIO controller driver should typically implement the .get_direction() +callback as GPIOLIB internals may try to use it to determine the state +of a pin. Add it for the LPASS LPI driver. + +Reported-by: Abel Vesa +Cc: stable@vger.kernel.org +Fixes: 6e261d1090d6 ("pinctrl: qcom: Add sm8250 lpass lpi pinctrl driver") +Signed-off-by: Bartosz Golaszewski +Reviewed-by: Konrad Dybcio +Tested-by: Konrad Dybcio # X1E CRD +Tested-by: Abel Vesa +Signed-off-by: Linus Walleij +[ PIN_CONFIG_LEVEL => PIN_CONFIG_OUTPUT ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pinctrl/qcom/pinctrl-lpass-lpi.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c ++++ b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c +@@ -279,6 +279,22 @@ static const struct pinconf_ops lpi_gpio + .pin_config_group_set = lpi_config_set, + }; + ++static int lpi_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) ++{ ++ unsigned long config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, 0); ++ struct lpi_pinctrl *state = gpiochip_get_data(chip); ++ unsigned long arg; ++ int ret; ++ ++ ret = lpi_config_get(state->ctrl, pin, &config); ++ if (ret) ++ return ret; ++ ++ arg = pinconf_to_config_argument(config); ++ ++ return arg ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN; ++} ++ + static int lpi_gpio_direction_input(struct gpio_chip *chip, unsigned int pin) + { + struct lpi_pinctrl *state = gpiochip_get_data(chip); +@@ -377,6 +393,7 @@ static void lpi_gpio_dbg_show(struct seq + #endif + + static const struct gpio_chip lpi_gpio_template = { ++ .get_direction = lpi_gpio_get_direction, + .direction_input = lpi_gpio_direction_input, + .direction_output = lpi_gpio_direction_output, + .get = lpi_gpio_get, diff --git a/queue-6.6/pinctrl-qcom-sm8350-lpass-lpi-merge-with-sc7280-to-fix-i2s2-and-swr-tx-pins.patch b/queue-6.6/pinctrl-qcom-sm8350-lpass-lpi-merge-with-sc7280-to-fix-i2s2-and-swr-tx-pins.patch new file mode 100644 index 0000000000..01287eecb3 --- /dev/null +++ b/queue-6.6/pinctrl-qcom-sm8350-lpass-lpi-merge-with-sc7280-to-fix-i2s2-and-swr-tx-pins.patch @@ -0,0 +1,270 @@ +From stable+bounces-213282-greg=kroah.com@vger.kernel.org Tue Feb 3 18:05:03 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 12:04:00 -0500 +Subject: pinctrl: qcom: sm8350-lpass-lpi: Merge with SC7280 to fix I2S2 and SWR TX pins +To: stable@vger.kernel.org +Cc: Krzysztof Kozlowski , Bartosz Golaszewski , Konrad Dybcio , Linus Walleij , Sasha Levin +Message-ID: <20260203170400.1324051-1-sashal@kernel.org> + +From: Krzysztof Kozlowski + +[ Upstream commit 1fbe3abb449c5ef2178e1c3e3e8b9a43a7a410ac ] + +Qualcomm SC7280 and SM8350 SoCs have slightly different LPASS audio +blocks (v9.4.5 and v9.2), however the LPASS LPI pin controllers are +exactly the same. The driver for SM8350 has two issues, which can be +fixed by simply moving over to SC7280 driver which has them correct: + +1. "i2s2_data_groups" listed twice GPIO12, but should have both GPIO12 + and GPIO13, + +2. "swr_tx_data_groups" contained GPIO5 for "swr_tx_data2" function, but + that function is also available on GPIO14, thus listing it twice is + not necessary. OTOH, GPIO5 has also "swr_rx_data1", so selecting + swr_rx_data function should not block the TX one. + +Fixes: be9f6d56381d ("pinctrl: qcom: sm8350-lpass-lpi: add SM8350 LPASS TLMM") +Cc: stable@vger.kernel.org +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Bartosz Golaszewski +Reviewed-by: Konrad Dybcio +Signed-off-by: Linus Walleij +[ Context, no dedicated config option ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pinctrl/qcom/Kconfig | 15 -- + drivers/pinctrl/qcom/Makefile | 1 + drivers/pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c | 3 + drivers/pinctrl/qcom/pinctrl-sm8350-lpass-lpi.c | 167 ------------------------ + 4 files changed, 6 insertions(+), 180 deletions(-) + delete mode 100644 drivers/pinctrl/qcom/pinctrl-sm8350-lpass-lpi.c + +--- a/drivers/pinctrl/qcom/Kconfig ++++ b/drivers/pinctrl/qcom/Kconfig +@@ -60,13 +60,14 @@ config PINCTRL_LPASS_LPI + (Low Power Island) found on the Qualcomm Technologies Inc SoCs. + + config PINCTRL_SC7280_LPASS_LPI +- tristate "Qualcomm Technologies Inc SC7280 LPASS LPI pin controller driver" ++ tristate "Qualcomm Technologies Inc SC7280 and SM8350 LPASS LPI pin controller driver" + depends on ARM64 || COMPILE_TEST + depends on PINCTRL_LPASS_LPI + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI +- (Low Power Island) found on the Qualcomm Technologies Inc SC7280 platform. ++ (Low Power Island) found on the Qualcomm Technologies Inc SC7280 ++ and SM8350 platforms. + + config PINCTRL_SM6115_LPASS_LPI + tristate "Qualcomm Technologies Inc SM6115 LPASS LPI pin controller driver" +@@ -86,16 +87,6 @@ config PINCTRL_SM8250_LPASS_LPI + Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI + (Low Power Island) found on the Qualcomm Technologies Inc SM8250 platform. + +-config PINCTRL_SM8350_LPASS_LPI +- tristate "Qualcomm Technologies Inc SM8350 LPASS LPI pin controller driver" +- depends on ARM64 || COMPILE_TEST +- depends on PINCTRL_LPASS_LPI +- help +- This is the pinctrl, pinmux, pinconf and gpiolib driver for the +- Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI +- (Low Power Island) found on the Qualcomm Technologies Inc SM8350 +- platform. +- + config PINCTRL_SM8450_LPASS_LPI + tristate "Qualcomm Technologies Inc SM8450 LPASS LPI pin controller driver" + depends on ARM64 || COMPILE_TEST +--- a/drivers/pinctrl/qcom/Makefile ++++ b/drivers/pinctrl/qcom/Makefile +@@ -53,7 +53,6 @@ obj-$(CONFIG_PINCTRL_SM8150) += pinctrl- + obj-$(CONFIG_PINCTRL_SM8250) += pinctrl-sm8250.o + obj-$(CONFIG_PINCTRL_SM8250_LPASS_LPI) += pinctrl-sm8250-lpass-lpi.o + obj-$(CONFIG_PINCTRL_SM8350) += pinctrl-sm8350.o +-obj-$(CONFIG_PINCTRL_SM8350_LPASS_LPI) += pinctrl-sm8350-lpass-lpi.o + obj-$(CONFIG_PINCTRL_SM8450) += pinctrl-sm8450.o + obj-$(CONFIG_PINCTRL_SM8450_LPASS_LPI) += pinctrl-sm8450-lpass-lpi.o + obj-$(CONFIG_PINCTRL_SM8550) += pinctrl-sm8550.o +--- a/drivers/pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c ++++ b/drivers/pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c +@@ -147,6 +147,9 @@ static const struct of_device_id lpi_pin + { + .compatible = "qcom,sc7280-lpass-lpi-pinctrl", + .data = &sc7280_lpi_data, ++ }, { ++ .compatible = "qcom,sm8350-lpass-lpi-pinctrl", ++ .data = &sc7280_lpi_data, + }, + { } + }; +--- a/drivers/pinctrl/qcom/pinctrl-sm8350-lpass-lpi.c ++++ /dev/null +@@ -1,167 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-only +-/* +- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. +- * Copyright (c) 2020-2023 Linaro Ltd. +- */ +- +-#include +-#include +-#include +- +-#include "pinctrl-lpass-lpi.h" +- +-enum lpass_lpi_functions { +- LPI_MUX_dmic1_clk, +- LPI_MUX_dmic1_data, +- LPI_MUX_dmic2_clk, +- LPI_MUX_dmic2_data, +- LPI_MUX_dmic3_clk, +- LPI_MUX_dmic3_data, +- LPI_MUX_i2s1_clk, +- LPI_MUX_i2s1_data, +- LPI_MUX_i2s1_ws, +- LPI_MUX_i2s2_clk, +- LPI_MUX_i2s2_data, +- LPI_MUX_i2s2_ws, +- LPI_MUX_qua_mi2s_data, +- LPI_MUX_qua_mi2s_sclk, +- LPI_MUX_qua_mi2s_ws, +- LPI_MUX_swr_rx_clk, +- LPI_MUX_swr_rx_data, +- LPI_MUX_swr_tx_clk, +- LPI_MUX_swr_tx_data, +- LPI_MUX_wsa_swr_clk, +- LPI_MUX_wsa_swr_data, +- LPI_MUX_gpio, +- LPI_MUX__, +-}; +- +-static int gpio0_pins[] = { 0 }; +-static int gpio1_pins[] = { 1 }; +-static int gpio2_pins[] = { 2 }; +-static int gpio3_pins[] = { 3 }; +-static int gpio4_pins[] = { 4 }; +-static int gpio5_pins[] = { 5 }; +-static int gpio6_pins[] = { 6 }; +-static int gpio7_pins[] = { 7 }; +-static int gpio8_pins[] = { 8 }; +-static int gpio9_pins[] = { 9 }; +-static int gpio10_pins[] = { 10 }; +-static int gpio11_pins[] = { 11 }; +-static int gpio12_pins[] = { 12 }; +-static int gpio13_pins[] = { 13 }; +-static int gpio14_pins[] = { 14 }; +- +-static const struct pinctrl_pin_desc sm8350_lpi_pins[] = { +- PINCTRL_PIN(0, "gpio0"), +- PINCTRL_PIN(1, "gpio1"), +- PINCTRL_PIN(2, "gpio2"), +- PINCTRL_PIN(3, "gpio3"), +- PINCTRL_PIN(4, "gpio4"), +- PINCTRL_PIN(5, "gpio5"), +- PINCTRL_PIN(6, "gpio6"), +- PINCTRL_PIN(7, "gpio7"), +- PINCTRL_PIN(8, "gpio8"), +- PINCTRL_PIN(9, "gpio9"), +- PINCTRL_PIN(10, "gpio10"), +- PINCTRL_PIN(11, "gpio11"), +- PINCTRL_PIN(12, "gpio12"), +- PINCTRL_PIN(13, "gpio13"), +- PINCTRL_PIN(14, "gpio14"), +-}; +- +-static const char * const swr_tx_clk_groups[] = { "gpio0" }; +-static const char * const swr_tx_data_groups[] = { "gpio1", "gpio2", "gpio5", "gpio14" }; +-static const char * const swr_rx_clk_groups[] = { "gpio3" }; +-static const char * const swr_rx_data_groups[] = { "gpio4", "gpio5" }; +-static const char * const dmic1_clk_groups[] = { "gpio6" }; +-static const char * const dmic1_data_groups[] = { "gpio7" }; +-static const char * const dmic2_clk_groups[] = { "gpio8" }; +-static const char * const dmic2_data_groups[] = { "gpio9" }; +-static const char * const i2s2_clk_groups[] = { "gpio10" }; +-static const char * const i2s2_ws_groups[] = { "gpio11" }; +-static const char * const dmic3_clk_groups[] = { "gpio12" }; +-static const char * const dmic3_data_groups[] = { "gpio13" }; +-static const char * const qua_mi2s_sclk_groups[] = { "gpio0" }; +-static const char * const qua_mi2s_ws_groups[] = { "gpio1" }; +-static const char * const qua_mi2s_data_groups[] = { "gpio2", "gpio3", "gpio4" }; +-static const char * const i2s1_clk_groups[] = { "gpio6" }; +-static const char * const i2s1_ws_groups[] = { "gpio7" }; +-static const char * const i2s1_data_groups[] = { "gpio8", "gpio9" }; +-static const char * const wsa_swr_clk_groups[] = { "gpio10" }; +-static const char * const wsa_swr_data_groups[] = { "gpio11" }; +-static const char * const i2s2_data_groups[] = { "gpio12", "gpio12" }; +- +-static const struct lpi_pingroup sm8350_groups[] = { +- LPI_PINGROUP(0, 0, swr_tx_clk, qua_mi2s_sclk, _, _), +- LPI_PINGROUP(1, 2, swr_tx_data, qua_mi2s_ws, _, _), +- LPI_PINGROUP(2, 4, swr_tx_data, qua_mi2s_data, _, _), +- LPI_PINGROUP(3, 8, swr_rx_clk, qua_mi2s_data, _, _), +- LPI_PINGROUP(4, 10, swr_rx_data, qua_mi2s_data, _, _), +- LPI_PINGROUP(5, 12, swr_tx_data, swr_rx_data, _, _), +- LPI_PINGROUP(6, LPI_NO_SLEW, dmic1_clk, i2s1_clk, _, _), +- LPI_PINGROUP(7, LPI_NO_SLEW, dmic1_data, i2s1_ws, _, _), +- LPI_PINGROUP(8, LPI_NO_SLEW, dmic2_clk, i2s1_data, _, _), +- LPI_PINGROUP(9, LPI_NO_SLEW, dmic2_data, i2s1_data, _, _), +- LPI_PINGROUP(10, 16, i2s2_clk, wsa_swr_clk, _, _), +- LPI_PINGROUP(11, 18, i2s2_ws, wsa_swr_data, _, _), +- LPI_PINGROUP(12, LPI_NO_SLEW, dmic3_clk, i2s2_data, _, _), +- LPI_PINGROUP(13, LPI_NO_SLEW, dmic3_data, i2s2_data, _, _), +- LPI_PINGROUP(14, 6, swr_tx_data, _, _, _), +-}; +- +-static const struct lpi_function sm8350_functions[] = { +- LPI_FUNCTION(dmic1_clk), +- LPI_FUNCTION(dmic1_data), +- LPI_FUNCTION(dmic2_clk), +- LPI_FUNCTION(dmic2_data), +- LPI_FUNCTION(dmic3_clk), +- LPI_FUNCTION(dmic3_data), +- LPI_FUNCTION(i2s1_clk), +- LPI_FUNCTION(i2s1_data), +- LPI_FUNCTION(i2s1_ws), +- LPI_FUNCTION(i2s2_clk), +- LPI_FUNCTION(i2s2_data), +- LPI_FUNCTION(i2s2_ws), +- LPI_FUNCTION(qua_mi2s_data), +- LPI_FUNCTION(qua_mi2s_sclk), +- LPI_FUNCTION(qua_mi2s_ws), +- LPI_FUNCTION(swr_rx_clk), +- LPI_FUNCTION(swr_rx_data), +- LPI_FUNCTION(swr_tx_clk), +- LPI_FUNCTION(swr_tx_data), +- LPI_FUNCTION(wsa_swr_clk), +- LPI_FUNCTION(wsa_swr_data), +-}; +- +-static const struct lpi_pinctrl_variant_data sm8350_lpi_data = { +- .pins = sm8350_lpi_pins, +- .npins = ARRAY_SIZE(sm8350_lpi_pins), +- .groups = sm8350_groups, +- .ngroups = ARRAY_SIZE(sm8350_groups), +- .functions = sm8350_functions, +- .nfunctions = ARRAY_SIZE(sm8350_functions), +-}; +- +-static const struct of_device_id lpi_pinctrl_of_match[] = { +- { +- .compatible = "qcom,sm8350-lpass-lpi-pinctrl", +- .data = &sm8350_lpi_data, +- }, +- { } +-}; +-MODULE_DEVICE_TABLE(of, lpi_pinctrl_of_match); +- +-static struct platform_driver lpi_pinctrl_driver = { +- .driver = { +- .name = "qcom-sm8350-lpass-lpi-pinctrl", +- .of_match_table = lpi_pinctrl_of_match, +- }, +- .probe = lpi_pinctrl_probe, +- .remove = lpi_pinctrl_remove, +-}; +-module_platform_driver(lpi_pinctrl_driver); +- +-MODULE_AUTHOR("Krzysztof Kozlowski "); +-MODULE_DESCRIPTION("QTI SM8350 LPI GPIO pin control driver"); +-MODULE_LICENSE("GPL"); diff --git a/queue-6.6/series b/queue-6.6/series index 2120e5fd42..676cd1ffe6 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -54,3 +54,14 @@ team-move-team-device-type-change-at-the-end-of-team_port_add.patch drm-radeon-delete-radeon_fence_process-in-is_signaled-no-deadlock.patch btrfs-prevent-use-after-free-on-page-private-data-in-btrfs_subpage_clear_uptodate.patch net-sched-act_ife-convert-comma-to-semicolon.patch +alsa-usb-audio-fix-missing-unlock-at-error-path-of-maxpacksize-check.patch +pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch +drm-msm-a6xx-fix-bogus-hwcg-register-updates.patch +perf-sched-fix-perf-crash-with-new-is_user_task-helper.patch +writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch +mptcp-avoid-dup-sub_closed-events-after-disconnect.patch +pinctrl-qcom-sm8350-lpass-lpi-merge-with-sc7280-to-fix-i2s2-and-swr-tx-pins.patch +drm-amdkfd-don-t-use-sw-fault-filter-if-retry-cam-enabled.patch +drm-amdgpu-fix-null-pointer-dereference-in-amdgpu_gmc_filter_faults_remove.patch +xsk-fix-race-condition-in-af_xdp-generic-rx-path.patch +ksmbd-fix-recursive-locking-in-rpc-handle-list-access.patch diff --git a/queue-6.6/writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch b/queue-6.6/writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch new file mode 100644 index 0000000000..ae96c5df16 --- /dev/null +++ b/queue-6.6/writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch @@ -0,0 +1,77 @@ +From stable+bounces-213301-greg=kroah.com@vger.kernel.org Tue Feb 3 21:12:28 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 15:12:22 -0500 +Subject: writeback: fix 100% CPU usage when dirtytime_expire_interval is 0 +To: stable@vger.kernel.org +Cc: Laveesh Bansal , Jan Kara , Christian Brauner , Sasha Levin +Message-ID: <20260203201222.1381303-1-sashal@kernel.org> + +From: Laveesh Bansal + +[ Upstream commit 543467d6fe97e27e22a26e367fda972dbefebbff ] + +When vm.dirtytime_expire_seconds is set to 0, wakeup_dirtytime_writeback() +schedules delayed work with a delay of 0, causing immediate execution. +The function then reschedules itself with 0 delay again, creating an +infinite busy loop that causes 100% kworker CPU usage. + +Fix by: +- Only scheduling delayed work in wakeup_dirtytime_writeback() when + dirtytime_expire_interval is non-zero +- Cancelling the delayed work in dirtytime_interval_handler() when + the interval is set to 0 +- Adding a guard in start_dirtytime_writeback() for defensive coding + +Tested by booting kernel in QEMU with virtme-ng: +- Before fix: kworker CPU spikes to ~73% +- After fix: CPU remains at normal levels +- Setting interval back to non-zero correctly resumes writeback + +Fixes: a2f4870697a5 ("fs: make sure the timestamps for lazytime inodes eventually get written") +Cc: stable@vger.kernel.org +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220227 +Signed-off-by: Laveesh Bansal +Link: https://patch.msgid.link/20260106145059.543282-2-laveeshb@laveeshbansal.com +Reviewed-by: Jan Kara +Signed-off-by: Christian Brauner +[ adapted system_percpu_wq to system_wq for the workqueue used in dirtytime_interval_handler() ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/fs-writeback.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/fs/fs-writeback.c ++++ b/fs/fs-writeback.c +@@ -2382,12 +2382,14 @@ static void wakeup_dirtytime_writeback(s + wb_wakeup(wb); + } + rcu_read_unlock(); +- schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ); ++ if (dirtytime_expire_interval) ++ schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ); + } + + static int __init start_dirtytime_writeback(void) + { +- schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ); ++ if (dirtytime_expire_interval) ++ schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ); + return 0; + } + __initcall(start_dirtytime_writeback); +@@ -2398,8 +2400,12 @@ int dirtytime_interval_handler(struct ct + int ret; + + ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); +- if (ret == 0 && write) +- mod_delayed_work(system_wq, &dirtytime_work, 0); ++ if (ret == 0 && write) { ++ if (dirtytime_expire_interval) ++ mod_delayed_work(system_wq, &dirtytime_work, 0); ++ else ++ cancel_delayed_work_sync(&dirtytime_work); ++ } + return ret; + } + diff --git a/queue-6.6/xsk-fix-race-condition-in-af_xdp-generic-rx-path.patch b/queue-6.6/xsk-fix-race-condition-in-af_xdp-generic-rx-path.patch new file mode 100644 index 0000000000..b7aa113f2a --- /dev/null +++ b/queue-6.6/xsk-fix-race-condition-in-af_xdp-generic-rx-path.patch @@ -0,0 +1,116 @@ +From jianqkang@sina.cn Wed Feb 4 09:29:27 2026 +From: Jianqiang kang +Date: Wed, 4 Feb 2026 16:29:20 +0800 +Subject: xsk: Fix race condition in AF_XDP generic RX path +To: gregkh@linuxfoundation.org, stable@vger.kernel.org, e.kubanski@partner.samsung.com +Cc: patches@lists.linux.dev, linux-kernel@vger.kernel.org, bjorn@kernel.org, magnus.karlsson@intel.com, maciej.fijalkowski@intel.com, jonathan.lemon@gmail.com, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, ast@kernel.org, daniel@iogearbox.net, hawk@kernel.org, john.fastabend@gmail.com, i.maximets@samsung.com, netdev@vger.kernel.org, bpf@vger.kernel.org +Message-ID: <20260204082920.3304571-1-jianqkang@sina.cn> + +From: "e.kubanski" + +[ Upstream commit a1356ac7749cafc4e27aa62c0c4604b5dca4983e ] + +Move rx_lock from xsk_socket to xsk_buff_pool. +Fix synchronization for shared umem mode in +generic RX path where multiple sockets share +single xsk_buff_pool. + +RX queue is exclusive to xsk_socket, while FILL +queue can be shared between multiple sockets. +This could result in race condition where two +CPU cores access RX path of two different sockets +sharing the same umem. + +Protect both queues by acquiring spinlock in shared +xsk_buff_pool. + +Lock contention may be minimized in the future by some +per-thread FQ buffering. + +It's safe and necessary to move spin_lock_bh(rx_lock) +after xsk_rcv_check(): +* xs->pool and spinlock_init is synchronized by + xsk_bind() -> xsk_is_bound() memory barriers. +* xsk_rcv_check() may return true at the moment + of xsk_release() or xsk_unbind_dev(), + however this will not cause any data races or + race conditions. xsk_unbind_dev() removes xdp + socket from all maps and waits for completion + of all outstanding rx operations. Packets in + RX path will either complete safely or drop. + +Signed-off-by: Eryk Kubanski +Fixes: bf0bdd1343efb ("xdp: fix race on generic receive path") +Acked-by: Magnus Karlsson +Link: https://patch.msgid.link/20250416101908.10919-1-e.kubanski@partner.samsung.com +Signed-off-by: Jakub Kicinski +[ Conflict is resolved when backporting this fix. ] +Signed-off-by: Jianqiang kang +Signed-off-by: Greg Kroah-Hartman +--- + include/net/xdp_sock.h | 3 --- + include/net/xsk_buff_pool.h | 2 ++ + net/xdp/xsk.c | 6 +++--- + net/xdp/xsk_buff_pool.c | 1 + + 4 files changed, 6 insertions(+), 6 deletions(-) + +--- a/include/net/xdp_sock.h ++++ b/include/net/xdp_sock.h +@@ -63,9 +63,6 @@ struct xdp_sock { + + struct xsk_queue *tx ____cacheline_aligned_in_smp; + struct list_head tx_list; +- /* Protects generic receive. */ +- spinlock_t rx_lock; +- + /* Statistics */ + u64 rx_dropped; + u64 rx_queue_full; +--- a/include/net/xsk_buff_pool.h ++++ b/include/net/xsk_buff_pool.h +@@ -54,6 +54,8 @@ struct xsk_buff_pool { + refcount_t users; + struct xdp_umem *umem; + struct work_struct work; ++ /* Protects generic receive in shared and non-shared umem mode. */ ++ spinlock_t rx_lock; + struct list_head free_list; + struct list_head xskb_list; + u32 heads_cnt; +--- a/net/xdp/xsk.c ++++ b/net/xdp/xsk.c +@@ -339,13 +339,14 @@ int xsk_generic_rcv(struct xdp_sock *xs, + u32 len = xdp_get_buff_len(xdp); + int err; + +- spin_lock_bh(&xs->rx_lock); + err = xsk_rcv_check(xs, xdp, len); + if (!err) { ++ spin_lock_bh(&xs->pool->rx_lock); + err = __xsk_rcv(xs, xdp, len); + xsk_flush(xs); ++ spin_unlock_bh(&xs->pool->rx_lock); + } +- spin_unlock_bh(&xs->rx_lock); ++ + return err; + } + +@@ -1647,7 +1648,6 @@ static int xsk_create(struct net *net, s + xs = xdp_sk(sk); + xs->state = XSK_READY; + mutex_init(&xs->mutex); +- spin_lock_init(&xs->rx_lock); + + INIT_LIST_HEAD(&xs->map_list); + spin_lock_init(&xs->map_list_lock); +--- a/net/xdp/xsk_buff_pool.c ++++ b/net/xdp/xsk_buff_pool.c +@@ -85,6 +85,7 @@ struct xsk_buff_pool *xp_create_and_assi + XDP_PACKET_HEADROOM; + pool->umem = umem; + pool->addrs = umem->addrs; ++ spin_lock_init(&pool->rx_lock); + INIT_LIST_HEAD(&pool->free_list); + INIT_LIST_HEAD(&pool->xskb_list); + INIT_LIST_HEAD(&pool->xsk_tx_list); -- 2.47.3