From: Greg Kroah-Hartman Date: Mon, 28 Jul 2025 16:14:56 +0000 (+0200) Subject: 6.1-stable patches X-Git-Tag: v6.6.101~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1ff7c827ebb3541160baabb732c75e2d7258af12;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: drm-amdkfd-don-t-call-mmput-from-mmu-notifier-callback.patch usb-typec-tcpm-allow-switching-to-mode-accessory-to-mux-properly.patch usb-typec-tcpm-allow-to-use-sink-in-accessory-mode.patch usb-typec-tcpm-apply-vbus-before-data-bringup-in-tcpm_src_attach.patch --- diff --git a/queue-6.1/drm-amdkfd-don-t-call-mmput-from-mmu-notifier-callback.patch b/queue-6.1/drm-amdkfd-don-t-call-mmput-from-mmu-notifier-callback.patch new file mode 100644 index 0000000000..3c14348ecf --- /dev/null +++ b/queue-6.1/drm-amdkfd-don-t-call-mmput-from-mmu-notifier-callback.patch @@ -0,0 +1,204 @@ +From cf234231fcbc7d391e2135b9518613218cc5347f Mon Sep 17 00:00:00 2001 +From: Philip Yang +Date: Fri, 20 Jun 2025 18:32:32 -0400 +Subject: drm/amdkfd: Don't call mmput from MMU notifier callback + +From: Philip Yang + +commit cf234231fcbc7d391e2135b9518613218cc5347f upstream. + +If the process is exiting, the mmput inside mmu notifier callback from +compactd or fork or numa balancing could release the last reference +of mm struct to call exit_mmap and free_pgtable, this triggers deadlock +with below backtrace. + +The deadlock will leak kfd process as mmu notifier release is not called +and cause VRAM leaking. + +The fix is to take mm reference mmget_non_zero when adding prange to the +deferred list to pair with mmput in deferred list work. + +If prange split and add into pchild list, the pchild work_item.mm is not +used, so remove the mm parameter from svm_range_unmap_split and +svm_range_add_child. + +The backtrace of hung task: + + INFO: task python:348105 blocked for more than 64512 seconds. + Call Trace: + __schedule+0x1c3/0x550 + schedule+0x46/0xb0 + rwsem_down_write_slowpath+0x24b/0x4c0 + unlink_anon_vmas+0xb1/0x1c0 + free_pgtables+0xa9/0x130 + exit_mmap+0xbc/0x1a0 + mmput+0x5a/0x140 + svm_range_cpu_invalidate_pagetables+0x2b/0x40 [amdgpu] + mn_itree_invalidate+0x72/0xc0 + __mmu_notifier_invalidate_range_start+0x48/0x60 + try_to_unmap_one+0x10fa/0x1400 + rmap_walk_anon+0x196/0x460 + try_to_unmap+0xbb/0x210 + migrate_page_unmap+0x54d/0x7e0 + migrate_pages_batch+0x1c3/0xae0 + migrate_pages_sync+0x98/0x240 + migrate_pages+0x25c/0x520 + compact_zone+0x29d/0x590 + compact_zone_order+0xb6/0xf0 + try_to_compact_pages+0xbe/0x220 + __alloc_pages_direct_compact+0x96/0x1a0 + __alloc_pages_slowpath+0x410/0x930 + __alloc_pages_nodemask+0x3a9/0x3e0 + do_huge_pmd_anonymous_page+0xd7/0x3e0 + __handle_mm_fault+0x5e3/0x5f0 + handle_mm_fault+0xf7/0x2e0 + hmm_vma_fault.isra.0+0x4d/0xa0 + walk_pmd_range.isra.0+0xa8/0x310 + walk_pud_range+0x167/0x240 + walk_pgd_range+0x55/0x100 + __walk_page_range+0x87/0x90 + walk_page_range+0xf6/0x160 + hmm_range_fault+0x4f/0x90 + amdgpu_hmm_range_get_pages+0x123/0x230 [amdgpu] + amdgpu_ttm_tt_get_user_pages+0xb1/0x150 [amdgpu] + init_user_pages+0xb1/0x2a0 [amdgpu] + amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu+0x543/0x7d0 [amdgpu] + kfd_ioctl_alloc_memory_of_gpu+0x24c/0x4e0 [amdgpu] + kfd_ioctl+0x29d/0x500 [amdgpu] + +Fixes: fa582c6f3684 ("drm/amdkfd: Use mmget_not_zero in MMU notifier") +Signed-off-by: Philip Yang +Reviewed-by: Felix Kuehling +Signed-off-by: Alex Deucher +(cherry picked from commit a29e067bd38946f752b0ef855f3dfff87e77bec7) +Cc: stable@vger.kernel.org +[ updated additional svm_range_add_child calls in svm_range_split_by_granularity to remove mm parameter ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 47 ++++++++++++++++------------------- + 1 file changed, 22 insertions(+), 25 deletions(-) + +--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +@@ -1076,13 +1076,12 @@ svm_range_split_head(struct svm_range *p + } + + static void +-svm_range_add_child(struct svm_range *prange, struct mm_struct *mm, +- struct svm_range *pchild, enum svm_work_list_ops op) ++svm_range_add_child(struct svm_range *prange, struct svm_range *pchild, enum svm_work_list_ops op) + { + pr_debug("add child 0x%p [0x%lx 0x%lx] to prange 0x%p child list %d\n", + pchild, pchild->start, pchild->last, prange, op); + +- pchild->work_item.mm = mm; ++ pchild->work_item.mm = NULL; + pchild->work_item.op = op; + list_add_tail(&pchild->child_list, &prange->child_list); + } +@@ -1128,14 +1127,14 @@ svm_range_split_by_granularity(struct kf + r = svm_range_split(prange, start, prange->last, &head); + if (r) + return r; +- svm_range_add_child(parent, mm, head, SVM_OP_ADD_RANGE); ++ svm_range_add_child(parent, head, SVM_OP_ADD_RANGE); + } + + if (last < prange->last) { + r = svm_range_split(prange, prange->start, last, &tail); + if (r) + return r; +- svm_range_add_child(parent, mm, tail, SVM_OP_ADD_RANGE); ++ svm_range_add_child(parent, tail, SVM_OP_ADD_RANGE); + } + + /* xnack on, update mapping on GPUs with ACCESS_IN_PLACE */ +@@ -2265,15 +2264,17 @@ svm_range_add_list_work(struct svm_range + prange->work_item.op != SVM_OP_UNMAP_RANGE) + prange->work_item.op = op; + } else { +- prange->work_item.op = op; +- +- /* Pairs with mmput in deferred_list_work */ +- mmget(mm); +- prange->work_item.mm = mm; +- list_add_tail(&prange->deferred_list, +- &prange->svms->deferred_range_list); +- pr_debug("add prange 0x%p [0x%lx 0x%lx] to work list op %d\n", +- prange, prange->start, prange->last, op); ++ /* Pairs with mmput in deferred_list_work. ++ * If process is exiting and mm is gone, don't update mmu notifier. ++ */ ++ if (mmget_not_zero(mm)) { ++ prange->work_item.mm = mm; ++ prange->work_item.op = op; ++ list_add_tail(&prange->deferred_list, ++ &prange->svms->deferred_range_list); ++ pr_debug("add prange 0x%p [0x%lx 0x%lx] to work list op %d\n", ++ prange, prange->start, prange->last, op); ++ } + } + spin_unlock(&svms->deferred_list_lock); + } +@@ -2287,8 +2288,7 @@ void schedule_deferred_list_work(struct + } + + static void +-svm_range_unmap_split(struct mm_struct *mm, struct svm_range *parent, +- struct svm_range *prange, unsigned long start, ++svm_range_unmap_split(struct svm_range *parent, struct svm_range *prange, unsigned long start, + unsigned long last) + { + struct svm_range *head; +@@ -2309,12 +2309,12 @@ svm_range_unmap_split(struct mm_struct * + svm_range_split(tail, last + 1, tail->last, &head); + + if (head != prange && tail != prange) { +- svm_range_add_child(parent, mm, head, SVM_OP_UNMAP_RANGE); +- svm_range_add_child(parent, mm, tail, SVM_OP_ADD_RANGE); ++ svm_range_add_child(parent, head, SVM_OP_UNMAP_RANGE); ++ svm_range_add_child(parent, tail, SVM_OP_ADD_RANGE); + } else if (tail != prange) { +- svm_range_add_child(parent, mm, tail, SVM_OP_UNMAP_RANGE); ++ svm_range_add_child(parent, tail, SVM_OP_UNMAP_RANGE); + } else if (head != prange) { +- svm_range_add_child(parent, mm, head, SVM_OP_UNMAP_RANGE); ++ svm_range_add_child(parent, head, SVM_OP_UNMAP_RANGE); + } else if (parent != prange) { + prange->work_item.op = SVM_OP_UNMAP_RANGE; + } +@@ -2353,14 +2353,14 @@ svm_range_unmap_from_cpu(struct mm_struc + l = min(last, pchild->last); + if (l >= s) + svm_range_unmap_from_gpus(pchild, s, l, trigger); +- svm_range_unmap_split(mm, prange, pchild, start, last); ++ svm_range_unmap_split(prange, pchild, start, last); + mutex_unlock(&pchild->lock); + } + s = max(start, prange->start); + l = min(last, prange->last); + if (l >= s) + svm_range_unmap_from_gpus(prange, s, l, trigger); +- svm_range_unmap_split(mm, prange, prange, start, last); ++ svm_range_unmap_split(prange, prange, start, last); + + if (unmap_parent) + svm_range_add_list_work(svms, prange, mm, SVM_OP_UNMAP_RANGE); +@@ -2403,8 +2403,6 @@ svm_range_cpu_invalidate_pagetables(stru + + if (range->event == MMU_NOTIFY_RELEASE) + return true; +- if (!mmget_not_zero(mni->mm)) +- return true; + + start = mni->interval_tree.start; + last = mni->interval_tree.last; +@@ -2431,7 +2429,6 @@ svm_range_cpu_invalidate_pagetables(stru + } + + svm_range_unlock(prange); +- mmput(mni->mm); + + return true; + } diff --git a/queue-6.1/series b/queue-6.1/series index 5b3a2c5ebd..5f772a7612 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -40,3 +40,7 @@ nilfs2-reject-invalid-file-types-when-reading-inodes.patch selftests-mptcp-connect-also-cover-alt-modes.patch selftests-mptcp-connect-also-cover-checksum.patch mm-zsmalloc-do-not-pass-__gfp_movable-if-config_compaction-n.patch +drm-amdkfd-don-t-call-mmput-from-mmu-notifier-callback.patch +usb-typec-tcpm-allow-to-use-sink-in-accessory-mode.patch +usb-typec-tcpm-allow-switching-to-mode-accessory-to-mux-properly.patch +usb-typec-tcpm-apply-vbus-before-data-bringup-in-tcpm_src_attach.patch diff --git a/queue-6.1/usb-typec-tcpm-allow-switching-to-mode-accessory-to-mux-properly.patch b/queue-6.1/usb-typec-tcpm-allow-switching-to-mode-accessory-to-mux-properly.patch new file mode 100644 index 0000000000..102bfaeadd --- /dev/null +++ b/queue-6.1/usb-typec-tcpm-allow-switching-to-mode-accessory-to-mux-properly.patch @@ -0,0 +1,120 @@ +From 8a50da849151e7e12b43c1d8fe7ad302223aef6b Mon Sep 17 00:00:00 2001 +From: Michael Grzeschik +Date: Fri, 4 Apr 2025 00:43:06 +0200 +Subject: usb: typec: tcpm: allow switching to mode accessory to mux properly + +From: Michael Grzeschik + +commit 8a50da849151e7e12b43c1d8fe7ad302223aef6b upstream. + +The funciton tcpm_acc_attach is not setting the proper state when +calling tcpm_set_role. The function tcpm_set_role is currently only +handling TYPEC_STATE_USB. For the tcpm_acc_attach to switch into other +modal states tcpm_set_role needs to be extended by an extra state +parameter. This patch is handling the proper state change when calling +tcpm_acc_attach. + +Signed-off-by: Michael Grzeschik +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20250404-ml-topic-tcpm-v1-3-b99f44badce8@pengutronix.de +Stable-dep-of: bec15191d523 ("usb: typec: tcpm: apply vbus before data bringup in tcpm_src_attach") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/tcpm/tcpm.c | 27 ++++++++++++++++++--------- + 1 file changed, 18 insertions(+), 9 deletions(-) + +--- a/drivers/usb/typec/tcpm/tcpm.c ++++ b/drivers/usb/typec/tcpm/tcpm.c +@@ -1032,7 +1032,7 @@ static int tcpm_set_attached_state(struc + port->data_role); + } + +-static int tcpm_set_roles(struct tcpm_port *port, bool attached, ++static int tcpm_set_roles(struct tcpm_port *port, bool attached, int state, + enum typec_role role, enum typec_data_role data) + { + enum typec_orientation orientation; +@@ -1069,7 +1069,7 @@ static int tcpm_set_roles(struct tcpm_po + } + } + +- ret = tcpm_mux_set(port, TYPEC_STATE_USB, usb_role, orientation); ++ ret = tcpm_mux_set(port, state, usb_role, orientation); + if (ret < 0) + return ret; + +@@ -3686,7 +3686,8 @@ static int tcpm_src_attach(struct tcpm_p + + tcpm_enable_auto_vbus_discharge(port, true); + +- ret = tcpm_set_roles(port, true, TYPEC_SOURCE, tcpm_data_role_for_source(port)); ++ ret = tcpm_set_roles(port, true, TYPEC_STATE_USB, ++ TYPEC_SOURCE, tcpm_data_role_for_source(port)); + if (ret < 0) + return ret; + +@@ -3844,7 +3845,8 @@ static int tcpm_snk_attach(struct tcpm_p + + tcpm_enable_auto_vbus_discharge(port, true); + +- ret = tcpm_set_roles(port, true, TYPEC_SINK, tcpm_data_role_for_sink(port)); ++ ret = tcpm_set_roles(port, true, TYPEC_STATE_USB, ++ TYPEC_SINK, tcpm_data_role_for_sink(port)); + if (ret < 0) + return ret; + +@@ -3868,6 +3870,7 @@ static int tcpm_acc_attach(struct tcpm_p + int ret; + enum typec_role role; + enum typec_data_role data; ++ int state = TYPEC_STATE_USB; + + if (port->attached) + return 0; +@@ -3876,7 +3879,13 @@ static int tcpm_acc_attach(struct tcpm_p + data = tcpm_port_is_sink(port) ? tcpm_data_role_for_sink(port) + : tcpm_data_role_for_source(port); + +- ret = tcpm_set_roles(port, true, role, data); ++ if (tcpm_port_is_audio(port)) ++ state = TYPEC_MODE_AUDIO; ++ ++ if (tcpm_port_is_debug(port)) ++ state = TYPEC_MODE_DEBUG; ++ ++ ret = tcpm_set_roles(port, true, state, role, data); + if (ret < 0) + return ret; + +@@ -4556,7 +4565,7 @@ static void run_state_machine(struct tcp + */ + tcpm_set_vconn(port, false); + tcpm_set_vbus(port, false); +- tcpm_set_roles(port, port->self_powered, TYPEC_SOURCE, ++ tcpm_set_roles(port, port->self_powered, TYPEC_STATE_USB, TYPEC_SOURCE, + tcpm_data_role_for_source(port)); + /* + * If tcpc fails to notify vbus off, TCPM will wait for PD_T_SAFE_0V + +@@ -4588,7 +4597,7 @@ static void run_state_machine(struct tcp + tcpm_set_vconn(port, false); + if (port->pd_capable) + tcpm_set_charge(port, false); +- tcpm_set_roles(port, port->self_powered, TYPEC_SINK, ++ tcpm_set_roles(port, port->self_powered, TYPEC_STATE_USB, TYPEC_SINK, + tcpm_data_role_for_sink(port)); + /* + * VBUS may or may not toggle, depending on the adapter. +@@ -4693,10 +4702,10 @@ static void run_state_machine(struct tcp + case DR_SWAP_CHANGE_DR: + tcpm_unregister_altmodes(port); + if (port->data_role == TYPEC_HOST) +- tcpm_set_roles(port, true, port->pwr_role, ++ tcpm_set_roles(port, true, TYPEC_STATE_USB, port->pwr_role, + TYPEC_DEVICE); + else +- tcpm_set_roles(port, true, port->pwr_role, ++ tcpm_set_roles(port, true, TYPEC_STATE_USB, port->pwr_role, + TYPEC_HOST); + tcpm_ams_finish(port); + tcpm_set_state(port, ready_state(port), 0); diff --git a/queue-6.1/usb-typec-tcpm-allow-to-use-sink-in-accessory-mode.patch b/queue-6.1/usb-typec-tcpm-allow-to-use-sink-in-accessory-mode.patch new file mode 100644 index 0000000000..c000241d29 --- /dev/null +++ b/queue-6.1/usb-typec-tcpm-allow-to-use-sink-in-accessory-mode.patch @@ -0,0 +1,44 @@ +From 64843d0ba96d3eae297025562111d57585273366 Mon Sep 17 00:00:00 2001 +From: Michael Grzeschik +Date: Fri, 4 Apr 2025 00:43:04 +0200 +Subject: usb: typec: tcpm: allow to use sink in accessory mode + +From: Michael Grzeschik + +commit 64843d0ba96d3eae297025562111d57585273366 upstream. + +Since the function tcpm_acc_attach is not setting the data and role for +for the sink case we extend it to check for it first. + +Signed-off-by: Michael Grzeschik +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20250404-ml-topic-tcpm-v1-1-b99f44badce8@pengutronix.de +Stable-dep-of: bec15191d523 ("usb: typec: tcpm: apply vbus before data bringup in tcpm_src_attach") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/tcpm/tcpm.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/usb/typec/tcpm/tcpm.c ++++ b/drivers/usb/typec/tcpm/tcpm.c +@@ -3866,12 +3866,17 @@ static void tcpm_snk_detach(struct tcpm_ + static int tcpm_acc_attach(struct tcpm_port *port) + { + int ret; ++ enum typec_role role; ++ enum typec_data_role data; + + if (port->attached) + return 0; + +- ret = tcpm_set_roles(port, true, TYPEC_SOURCE, +- tcpm_data_role_for_source(port)); ++ role = tcpm_port_is_sink(port) ? TYPEC_SINK : TYPEC_SOURCE; ++ data = tcpm_port_is_sink(port) ? tcpm_data_role_for_sink(port) ++ : tcpm_data_role_for_source(port); ++ ++ ret = tcpm_set_roles(port, true, role, data); + if (ret < 0) + return ret; + diff --git a/queue-6.1/usb-typec-tcpm-apply-vbus-before-data-bringup-in-tcpm_src_attach.patch b/queue-6.1/usb-typec-tcpm-apply-vbus-before-data-bringup-in-tcpm_src_attach.patch new file mode 100644 index 0000000000..5498936e89 --- /dev/null +++ b/queue-6.1/usb-typec-tcpm-apply-vbus-before-data-bringup-in-tcpm_src_attach.patch @@ -0,0 +1,101 @@ +From bec15191d52300defa282e3fd83820f69e447116 Mon Sep 17 00:00:00 2001 +From: RD Babiera +Date: Wed, 18 Jun 2025 23:06:04 +0000 +Subject: usb: typec: tcpm: apply vbus before data bringup in tcpm_src_attach + +From: RD Babiera + +commit bec15191d52300defa282e3fd83820f69e447116 upstream. + +This patch fixes Type-C compliance test TD 4.7.6 - Try.SNK DRP Connect +SNKAS. + +tVbusON has a limit of 275ms when entering SRC_ATTACHED. Compliance +testers can interpret the TryWait.Src to Attached.Src transition after +Try.Snk as being in Attached.Src the entire time, so ~170ms is lost +to the debounce timer. + +Setting the data role can be a costly operation in host mode, and when +completed after 100ms can cause Type-C compliance test check TD 4.7.5.V.4 +to fail. + +Turn VBUS on before tcpm_set_roles to meet timing requirement. + +Fixes: f0690a25a140 ("staging: typec: USB Type-C Port Manager (tcpm)") +Cc: stable +Signed-off-by: RD Babiera +Reviewed-by: Badhri Jagan Sridharan +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20250618230606.3272497-2-rdbabiera@google.com +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/tcpm/tcpm.c | 34 +++++++++++++++++----------------- + 1 file changed, 17 insertions(+), 17 deletions(-) + +--- a/drivers/usb/typec/tcpm/tcpm.c ++++ b/drivers/usb/typec/tcpm/tcpm.c +@@ -3686,17 +3686,6 @@ static int tcpm_src_attach(struct tcpm_p + + tcpm_enable_auto_vbus_discharge(port, true); + +- ret = tcpm_set_roles(port, true, TYPEC_STATE_USB, +- TYPEC_SOURCE, tcpm_data_role_for_source(port)); +- if (ret < 0) +- return ret; +- +- if (port->pd_supported) { +- ret = port->tcpc->set_pd_rx(port->tcpc, true); +- if (ret < 0) +- goto out_disable_mux; +- } +- + /* + * USB Type-C specification, version 1.2, + * chapter 4.5.2.2.8.1 (Attached.SRC Requirements) +@@ -3706,13 +3695,24 @@ static int tcpm_src_attach(struct tcpm_p + (polarity == TYPEC_POLARITY_CC2 && port->cc1 == TYPEC_CC_RA)) { + ret = tcpm_set_vconn(port, true); + if (ret < 0) +- goto out_disable_pd; ++ return ret; + } + + ret = tcpm_set_vbus(port, true); + if (ret < 0) + goto out_disable_vconn; + ++ ret = tcpm_set_roles(port, true, TYPEC_STATE_USB, TYPEC_SOURCE, ++ tcpm_data_role_for_source(port)); ++ if (ret < 0) ++ goto out_disable_vbus; ++ ++ if (port->pd_supported) { ++ ret = port->tcpc->set_pd_rx(port->tcpc, true); ++ if (ret < 0) ++ goto out_disable_mux; ++ } ++ + port->pd_capable = false; + + port->partner = NULL; +@@ -3722,14 +3722,14 @@ static int tcpm_src_attach(struct tcpm_p + + return 0; + +-out_disable_vconn: +- tcpm_set_vconn(port, false); +-out_disable_pd: +- if (port->pd_supported) +- port->tcpc->set_pd_rx(port->tcpc, false); + out_disable_mux: + tcpm_mux_set(port, TYPEC_STATE_SAFE, USB_ROLE_NONE, + TYPEC_ORIENTATION_NONE); ++out_disable_vbus: ++ tcpm_set_vbus(port, false); ++out_disable_vconn: ++ tcpm_set_vconn(port, false); ++ + return ret; + } +