From: Greg Kroah-Hartman Date: Fri, 7 Aug 2026 09:22:56 +0000 (+0200) Subject: 7.1-stable patches X-Git-Tag: v6.6.151~29 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ee2164211fce9168a4e7ea5de0994deee8c221f4;p=thirdparty%2Fkernel%2Fstable-queue.git 7.1-stable patches added patches: drm-exec-remove-the-index-parameter-from-drm_exec_for_each_locked_obj.patch drm-xe-drop-unused-param-from-xe_device_create.patch drm-xe-move-xe-info.devid-revid-initialization.patch drm-xe-move-xe-info.force_execlist-initialization.patch drm-xe-separate-early-xe_device-initialization.patch drm-xe-set-ttm-device-beneficial_order-to-9-2m.patch drm-xe-wait-on-external-bo-kernel-fences-in-exec-ioctl.patch media-chips-media-wave5-support-cbp-profile.patch usb-typec-ucsi-fix-race-condition-and-ordering-in-port-unregistration.patch usb-typec-ucsi-split-connector-lock-classes.patch --- diff --git a/queue-7.1/drm-exec-remove-the-index-parameter-from-drm_exec_for_each_locked_obj.patch b/queue-7.1/drm-exec-remove-the-index-parameter-from-drm_exec_for_each_locked_obj.patch new file mode 100644 index 0000000000..85c27cc25c --- /dev/null +++ b/queue-7.1/drm-exec-remove-the-index-parameter-from-drm_exec_for_each_locked_obj.patch @@ -0,0 +1,215 @@ +From stable+bounces-294379-greg=kroah.com@vger.kernel.org Sat Aug 1 16:04:58 2026 +From: Sasha Levin +Date: Sat, 1 Aug 2026 10:04:07 -0400 +Subject: drm/exec: Remove the index parameter from drm_exec_for_each_locked_obj[_reverse] +To: stable@vger.kernel.org +Cc: "Thomas Hellström" , "Christian König" , "Sasha Levin" +Message-ID: <20260801140408.3645911-1-sashal@kernel.org> + +From: Thomas Hellström + +[ Upstream commit ce44b78512e9102aea54ff6b6e521d6c8de9f31c ] + +Nobody makes any use of it. Possible internal future users can +instead use the _index variable. External users shouldn't use +it since the array it's pointing into is internal drm_exec state. + +v2: +- Use a unique id for the loop variable (Christian) + +Assisted-by: GitHub Copilot:claude-sonnet-4.6 +Signed-off-by: Thomas Hellström +Reviewed-by: Christian König +Link: https://patch.msgid.link/20260520101616.41284-2-thomas.hellstrom@linux.intel.com +Stable-dep-of: af80e2bfde93 ("drm/xe: Wait on external BO kernel fences in exec IOCTL") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 9 +++------ + drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c | 3 +-- + drivers/gpu/drm/drm_exec.c | 6 ++---- + drivers/gpu/drm/drm_gpuvm.c | 3 +-- + drivers/gpu/drm/xe/xe_vm.c | 3 +-- + include/drm/drm_exec.h | 20 ++++++++++++-------- + 6 files changed, 20 insertions(+), 24 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +@@ -854,7 +854,6 @@ static int amdgpu_cs_parser_bos(struct a + struct amdgpu_vm *vm = &fpriv->vm; + struct amdgpu_bo_list_entry *e; + struct drm_gem_object *obj; +- unsigned long index; + unsigned int i; + int r; + +@@ -965,7 +964,7 @@ static int amdgpu_cs_parser_bos(struct a + goto out_free_user_pages; + } + +- drm_exec_for_each_locked_object(&p->exec, index, obj) { ++ drm_exec_for_each_locked_object(&p->exec, obj) { + r = amdgpu_cs_bo_validate(p, gem_to_amdgpu_bo(obj)); + if (unlikely(r)) + goto out_free_user_pages; +@@ -1191,7 +1190,6 @@ static int amdgpu_cs_sync_rings(struct a + struct drm_gpu_scheduler *sched; + struct drm_gem_object *obj; + struct dma_fence *fence; +- unsigned long index; + unsigned int i; + int r; + +@@ -1202,7 +1200,7 @@ static int amdgpu_cs_sync_rings(struct a + return r; + } + +- drm_exec_for_each_locked_object(&p->exec, index, obj) { ++ drm_exec_for_each_locked_object(&p->exec, obj) { + struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); + + struct dma_resv *resv = bo->tbo.base.resv; +@@ -1271,7 +1269,6 @@ static int amdgpu_cs_submit(struct amdgp + struct amdgpu_vm *vm = &fpriv->vm; + struct amdgpu_bo_list_entry *e; + struct drm_gem_object *gobj; +- unsigned long index; + unsigned int i; + uint64_t seq; + int r; +@@ -1322,7 +1319,7 @@ static int amdgpu_cs_submit(struct amdgp + } + + p->fence = dma_fence_get(&leader->base.s_fence->finished); +- drm_exec_for_each_locked_object(&p->exec, index, gobj) { ++ drm_exec_for_each_locked_object(&p->exec, gobj) { + + ttm_bo_move_to_lru_tail_unlocked(&gem_to_amdgpu_bo(gobj)->tbo); + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c +@@ -121,7 +121,6 @@ int amdgpu_evf_mgr_rearm(struct amdgpu_e + { + struct amdgpu_eviction_fence *ev_fence; + struct drm_gem_object *obj; +- unsigned long index; + + /* Create and initialize a new eviction fence */ + ev_fence = kzalloc_obj(*ev_fence); +@@ -140,7 +139,7 @@ int amdgpu_evf_mgr_rearm(struct amdgpu_e + evf_mgr->ev_fence = &ev_fence->base; + + /* And add it to all existing BOs */ +- drm_exec_for_each_locked_object(exec, index, obj) { ++ drm_exec_for_each_locked_object(exec, obj) { + struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); + + amdgpu_evf_mgr_attach_fence(evf_mgr, bo); +--- a/drivers/gpu/drm/drm_exec.c ++++ b/drivers/gpu/drm/drm_exec.c +@@ -24,7 +24,6 @@ + * + * struct drm_gem_object *obj; + * struct drm_exec exec; +- * unsigned long index; + * int ret; + * + * drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); +@@ -40,7 +39,7 @@ + * goto error; + * } + * +- * drm_exec_for_each_locked_object(&exec, index, obj) { ++ * drm_exec_for_each_locked_object(&exec, obj) { + * dma_resv_add_fence(obj->resv, fence, DMA_RESV_USAGE_READ); + * ... + * } +@@ -56,9 +55,8 @@ + static void drm_exec_unlock_all(struct drm_exec *exec) + { + struct drm_gem_object *obj; +- unsigned long index; + +- drm_exec_for_each_locked_object_reverse(exec, index, obj) { ++ drm_exec_for_each_locked_object_reverse(exec, obj) { + dma_resv_unlock(obj->resv); + drm_gem_object_put(obj); + } +--- a/drivers/gpu/drm/drm_gpuvm.c ++++ b/drivers/gpu/drm/drm_gpuvm.c +@@ -1557,9 +1557,8 @@ drm_gpuvm_resv_add_fence(struct drm_gpuv + enum dma_resv_usage extobj_usage) + { + struct drm_gem_object *obj; +- unsigned long index; + +- drm_exec_for_each_locked_object(exec, index, obj) { ++ drm_exec_for_each_locked_object(exec, obj) { + dma_resv_assert_held(obj->resv); + dma_resv_add_fence(obj->resv, fence, + drm_gpuvm_is_extobj(gpuvm, obj) ? +--- a/drivers/gpu/drm/xe/xe_vm.c ++++ b/drivers/gpu/drm/xe/xe_vm.c +@@ -373,7 +373,6 @@ int xe_vm_validate_rebind(struct xe_vm * + unsigned int num_fences) + { + struct drm_gem_object *obj; +- unsigned long index; + int ret; + + do { +@@ -386,7 +385,7 @@ int xe_vm_validate_rebind(struct xe_vm * + return ret; + } while (!list_empty(&vm->gpuvm.evict.list)); + +- drm_exec_for_each_locked_object(exec, index, obj) { ++ drm_exec_for_each_locked_object(exec, obj) { + ret = dma_resv_reserve_fences(obj->resv, num_fences); + if (ret) + return ret; +--- a/include/drm/drm_exec.h ++++ b/include/drm/drm_exec.h +@@ -65,31 +65,35 @@ drm_exec_obj(struct drm_exec *exec, unsi + return index < exec->num_objects ? exec->objects[index] : NULL; + } + ++/* Helper for drm_exec_for_each_locked_object(). Internal use only. */ ++#define __drm_exec_for_each_locked_object(exec, obj, __index) \ ++ for (unsigned long __index = 0; ((obj) = drm_exec_obj(exec, __index)); ++__index) + /** + * drm_exec_for_each_locked_object - iterate over all the locked objects + * @exec: drm_exec object +- * @index: unsigned long index for the iteration + * @obj: the current GEM object + * + * Iterate over all the locked GEM objects inside the drm_exec object. + */ +-#define drm_exec_for_each_locked_object(exec, index, obj) \ +- for ((index) = 0; ((obj) = drm_exec_obj(exec, index)); ++(index)) ++#define drm_exec_for_each_locked_object(exec, obj) \ ++ __drm_exec_for_each_locked_object(exec, obj, __UNIQUE_ID(drm_exec)) + ++/* Helper for drm_exec_for_each_locked_object_reverse(). Internal use only. */ ++#define __drm_exec_for_each_locked_object_reverse(exec, obj, __index) \ ++ for (unsigned long __index = (exec)->num_objects - 1; \ ++ ((obj) = drm_exec_obj(exec, __index)); --__index) + /** + * drm_exec_for_each_locked_object_reverse - iterate over all the locked + * objects in reverse locking order + * @exec: drm_exec object +- * @index: unsigned long index for the iteration + * @obj: the current GEM object + * + * Iterate over all the locked GEM objects inside the drm_exec object in +- * reverse locking order. Note that @index may go below zero and wrap, ++ * reverse locking order. Note that the internal index may wrap around, + * but that will be caught by drm_exec_obj(), returning a NULL object. + */ +-#define drm_exec_for_each_locked_object_reverse(exec, index, obj) \ +- for ((index) = (exec)->num_objects - 1; \ +- ((obj) = drm_exec_obj(exec, index)); --(index)) ++#define drm_exec_for_each_locked_object_reverse(exec, obj) \ ++ __drm_exec_for_each_locked_object_reverse(exec, obj, __UNIQUE_ID(drm_exec)) + + /** + * drm_exec_until_all_locked - loop until all GEM objects are locked diff --git a/queue-7.1/drm-xe-drop-unused-param-from-xe_device_create.patch b/queue-7.1/drm-xe-drop-unused-param-from-xe_device_create.patch new file mode 100644 index 0000000000..dd603651d0 --- /dev/null +++ b/queue-7.1/drm-xe-drop-unused-param-from-xe_device_create.patch @@ -0,0 +1,71 @@ +From stable+bounces-294159-greg=kroah.com@vger.kernel.org Fri Jul 31 19:12:23 2026 +From: Sasha Levin +Date: Fri, 31 Jul 2026 12:56:54 -0400 +Subject: drm/xe: Drop unused param from xe_device_create() +To: stable@vger.kernel.org +Cc: Michal Wajdeczko , Raag Jadav , Gustavo Sousa , Sasha Levin +Message-ID: <20260731165658.883265-1-sashal@kernel.org> + +From: Michal Wajdeczko + +[ Upstream commit 8a09097b11ca4d436691f64c3cc0958006f36e33 ] + +We never used or need anything from the struct pci_device_id there. +And while around, add simple kernel-doc for this function. + +Signed-off-by: Michal Wajdeczko +Reviewed-by: Raag Jadav +Reviewed-by: Gustavo Sousa +Link: https://patch.msgid.link/20260526195452.20545-3-michal.wajdeczko@intel.com +Stable-dep-of: ba7fd1634228 ("drm/xe: Set TTM device beneficial_order to 9 (2M)") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/xe/xe_device.c | 11 +++++++++-- + drivers/gpu/drm/xe/xe_device.h | 3 +-- + drivers/gpu/drm/xe/xe_pci.c | 2 +- + 3 files changed, 11 insertions(+), 5 deletions(-) + +--- a/drivers/gpu/drm/xe/xe_device.c ++++ b/drivers/gpu/drm/xe/xe_device.c +@@ -435,8 +435,15 @@ static void xe_device_destroy(struct drm + ttm_device_fini(&xe->ttm); + } + +-struct xe_device *xe_device_create(struct pci_dev *pdev, +- const struct pci_device_id *ent) ++/** ++ * xe_device_create() - Create a new &xe_device instance ++ * @pdev: the parent &pci_dev ++ * ++ * Allocate and initialize a device managed Xe device structure. ++ * ++ * Return: pointer to new &xe_device on success, or ERR_PTR on failure. ++ */ ++struct xe_device *xe_device_create(struct pci_dev *pdev) + { + struct xe_device *xe; + int err; +--- a/drivers/gpu/drm/xe/xe_device.h ++++ b/drivers/gpu/drm/xe/xe_device.h +@@ -43,8 +43,7 @@ static inline struct xe_device *ttm_to_x + return container_of(ttm, struct xe_device, ttm); + } + +-struct xe_device *xe_device_create(struct pci_dev *pdev, +- const struct pci_device_id *ent); ++struct xe_device *xe_device_create(struct pci_dev *pdev); + int xe_device_probe_early(struct xe_device *xe); + int xe_device_probe(struct xe_device *xe); + void xe_device_remove(struct xe_device *xe); +--- a/drivers/gpu/drm/xe/xe_pci.c ++++ b/drivers/gpu/drm/xe/xe_pci.c +@@ -1091,7 +1091,7 @@ static int xe_pci_probe(struct pci_dev * + if (err) + return err; + +- xe = xe_device_create(pdev, ent); ++ xe = xe_device_create(pdev); + if (IS_ERR(xe)) + return PTR_ERR(xe); + diff --git a/queue-7.1/drm-xe-move-xe-info.devid-revid-initialization.patch b/queue-7.1/drm-xe-move-xe-info.devid-revid-initialization.patch new file mode 100644 index 0000000000..05144e4e9d --- /dev/null +++ b/queue-7.1/drm-xe-move-xe-info.devid-revid-initialization.patch @@ -0,0 +1,93 @@ +From stable+bounces-294161-greg=kroah.com@vger.kernel.org Fri Jul 31 19:12:20 2026 +From: Sasha Levin +Date: Fri, 31 Jul 2026 12:56:56 -0400 +Subject: drm/xe: Move xe->info.devid|revid initialization +To: stable@vger.kernel.org +Cc: Michal Wajdeczko , Gustavo Sousa , Sasha Levin +Message-ID: <20260731165658.883265-3-sashal@kernel.org> + +From: Michal Wajdeczko + +[ Upstream commit c03d9fbe77ec5002a2345b9be464683e0b157709 ] + +The xe_info_init_early() is a place where we initialize those of +the xe->info fields that do not require any additional hardware +probes. Move the initialization of the devid/revid also there, but +to avoid breaking the kunit helper, which also calls this function, +keep their initialization separate in sub-function so we can easily +stub it when running the kunit test. + +Signed-off-by: Michal Wajdeczko +Cc: Gustavo Sousa +Reviewed-by: Gustavo Sousa +Link: https://patch.msgid.link/20260526195452.20545-5-michal.wajdeczko@intel.com +Stable-dep-of: ba7fd1634228 ("drm/xe: Set TTM device beneficial_order to 9 (2M)") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/xe/tests/xe_pci.c | 6 ++++++ + drivers/gpu/drm/xe/xe_device.c | 2 -- + drivers/gpu/drm/xe/xe_pci.c | 12 ++++++++++++ + 3 files changed, 18 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/xe/tests/xe_pci.c ++++ b/drivers/gpu/drm/xe/tests/xe_pci.c +@@ -310,6 +310,11 @@ const void *xe_pci_id_gen_param(struct k + } + EXPORT_SYMBOL_IF_KUNIT(xe_pci_id_gen_param); + ++static void fake_init_devid(struct xe_device *xe) ++{ ++ /* Nothing to do, just keep zero. */ ++} ++ + static int fake_read_gmdid(struct xe_device *xe, enum xe_gmdid_type type, + u32 *ver, u32 *revid) + { +@@ -368,6 +373,7 @@ done: + xe->sriov.__mode = data && data->sriov_mode ? + data->sriov_mode : XE_SRIOV_MODE_NONE; + ++ kunit_activate_static_stub(test, init_devid, fake_init_devid); + kunit_activate_static_stub(test, read_gmdid, fake_read_gmdid); + kunit_activate_static_stub(test, xe_info_probe_tile_count, + fake_xe_info_probe_tile_count); +--- a/drivers/gpu/drm/xe/xe_device.c ++++ b/drivers/gpu/drm/xe/xe_device.c +@@ -473,8 +473,6 @@ struct xe_device *xe_device_create(struc + if (err) + return ERR_PTR(err); + +- xe->info.devid = pdev->device; +- xe->info.revid = pdev->revision; + xe->atomic_svm_timeslice_ms = 5; + xe->min_run_period_lr_ms = 5; + +--- a/drivers/gpu/drm/xe/xe_pci.c ++++ b/drivers/gpu/drm/xe/xe_pci.c +@@ -723,6 +723,16 @@ static int handle_gmdid(struct xe_device + return 0; + } + ++static void init_devid(struct xe_device *xe) ++{ ++ struct pci_dev *pdev = to_pci_dev(xe->drm.dev); ++ ++ KUNIT_STATIC_STUB_REDIRECT(init_devid, xe); ++ ++ xe->info.devid = pdev->device; ++ xe->info.revid = pdev->revision; ++} ++ + /* + * Initialize device info content that only depends on static driver_data + * passed to the driver at probe time from PCI ID table. +@@ -738,6 +748,8 @@ static int xe_info_init_early(struct xe_ + xe->info.subplatform = subplatform_desc ? + subplatform_desc->subplatform : XE_SUBPLATFORM_NONE; + ++ init_devid(xe); ++ + xe->info.dma_mask_size = desc->dma_mask_size; + xe->info.va_bits = desc->va_bits; + xe->info.vm_max_level = desc->vm_max_level; diff --git a/queue-7.1/drm-xe-move-xe-info.force_execlist-initialization.patch b/queue-7.1/drm-xe-move-xe-info.force_execlist-initialization.patch new file mode 100644 index 0000000000..2ef17c1acd --- /dev/null +++ b/queue-7.1/drm-xe-move-xe-info.force_execlist-initialization.patch @@ -0,0 +1,47 @@ +From stable+bounces-294160-greg=kroah.com@vger.kernel.org Fri Jul 31 19:15:48 2026 +From: Sasha Levin +Date: Fri, 31 Jul 2026 12:56:55 -0400 +Subject: drm/xe: Move xe->info.force_execlist initialization +To: stable@vger.kernel.org +Cc: Michal Wajdeczko , Gustavo Sousa , Sasha Levin +Message-ID: <20260731165658.883265-2-sashal@kernel.org> + +From: Michal Wajdeczko + +[ Upstream commit f1d581bb50ed54b71a8121d3d46fe2627fddd147 ] + +The xe_info_init_early() is a place where we initialize those of +the xe->info fields that do not require any additional hardware +probes. Move the initialization of the force_execlist flag there. + +Signed-off-by: Michal Wajdeczko +Reviewed-by: Gustavo Sousa +Link: https://patch.msgid.link/20260526195452.20545-4-michal.wajdeczko@intel.com +Stable-dep-of: ba7fd1634228 ("drm/xe: Set TTM device beneficial_order to 9 (2M)") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/xe/xe_device.c | 1 - + drivers/gpu/drm/xe/xe_pci.c | 1 + + 2 files changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/xe/xe_device.c ++++ b/drivers/gpu/drm/xe/xe_device.c +@@ -475,7 +475,6 @@ struct xe_device *xe_device_create(struc + + xe->info.devid = pdev->device; + xe->info.revid = pdev->revision; +- xe->info.force_execlist = xe_modparam.force_execlist; + xe->atomic_svm_timeslice_ms = 5; + xe->min_run_period_lr_ms = 5; + +--- a/drivers/gpu/drm/xe/xe_pci.c ++++ b/drivers/gpu/drm/xe/xe_pci.c +@@ -774,6 +774,7 @@ static int xe_info_init_early(struct xe_ + xe->info.probe_display = IS_ENABLED(CONFIG_DRM_XE_DISPLAY) && + xe_modparam.probe_display && + desc->has_display; ++ xe->info.force_execlist = xe_modparam.force_execlist; + + xe_assert(xe, desc->max_gt_per_tile > 0); + xe_assert(xe, desc->max_gt_per_tile <= XE_MAX_GT_PER_TILE); diff --git a/queue-7.1/drm-xe-separate-early-xe_device-initialization.patch b/queue-7.1/drm-xe-separate-early-xe_device-initialization.patch new file mode 100644 index 0000000000..32f1c3b21f --- /dev/null +++ b/queue-7.1/drm-xe-separate-early-xe_device-initialization.patch @@ -0,0 +1,130 @@ +From stable+bounces-294162-greg=kroah.com@vger.kernel.org Fri Jul 31 19:34:48 2026 +From: Sasha Levin +Date: Fri, 31 Jul 2026 12:56:57 -0400 +Subject: drm/xe: Separate early xe_device initialization +To: stable@vger.kernel.org +Cc: Michal Wajdeczko , Raag Jadav , Gustavo Sousa , Sasha Levin +Message-ID: <20260731165658.883265-4-sashal@kernel.org> + +From: Michal Wajdeczko + +[ Upstream commit 2841cea001b983db79dc1fdf160e65318dfda3cd ] + +We would like to initialize more of the xe_device struct also from +the kunit code, as it should be safe to use most of the generic drm +or xe components without doing any additional tweaks. Separate early +xe initialization code to a new function, so it can be reused. + +Signed-off-by: Michal Wajdeczko +Reviewed-by: Raag Jadav +Reviewed-by: Gustavo Sousa +Link: https://patch.msgid.link/20260526195452.20545-6-michal.wajdeczko@intel.com +Stable-dep-of: ba7fd1634228 ("drm/xe: Set TTM device beneficial_order to 9 (2M)") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/xe/xe_device.c | 39 ++++++++++++++++++++++++++++----------- + drivers/gpu/drm/xe/xe_device.h | 1 + + 2 files changed, 29 insertions(+), 11 deletions(-) + +--- a/drivers/gpu/drm/xe/xe_device.c ++++ b/drivers/gpu/drm/xe/xe_device.c +@@ -458,27 +458,45 @@ struct xe_device *xe_device_create(struc + if (IS_ERR(xe)) + return xe; + ++ err = xe_device_init_early(xe); ++ if (err) ++ return ERR_PTR(err); ++ ++ return xe; ++} ++ALLOW_ERROR_INJECTION(xe_device_create, ERRNO); /* See xe_pci_probe() */ ++ ++/** ++ * xe_device_init_early() - Initialize a new &xe_device instance ++ * @xe: the &xe_device to initialize ++ * ++ * Return: 0 on success or a negative error code on failure. ++ */ ++int xe_device_init_early(struct xe_device *xe) ++{ ++ int err; ++ + err = ttm_device_init(&xe->ttm, &xe_ttm_funcs, xe->drm.dev, + xe->drm.anon_inode->i_mapping, + xe->drm.vma_offset_manager, 0); +- if (WARN_ON(err)) +- return ERR_PTR(err); ++ if (err) ++ return err; + + xe_bo_dev_init(&xe->bo_device); + err = drmm_add_action_or_reset(&xe->drm, xe_device_destroy, NULL); + if (err) +- return ERR_PTR(err); ++ return err; + + err = xe_shrinker_create(xe); + if (err) +- return ERR_PTR(err); ++ return err; + + xe->atomic_svm_timeslice_ms = 5; + xe->min_run_period_lr_ms = 5; + + err = xe_irq_init(xe); + if (err) +- return ERR_PTR(err); ++ return err; + + xe_validation_device_init(&xe->val); + +@@ -488,7 +506,7 @@ struct xe_device *xe_device_create(struc + + err = xe_pagemap_shrinker_create(xe); + if (err) +- return ERR_PTR(err); ++ return err; + + xa_init_flags(&xe->usm.asid_to_vm, XA_FLAGS_ALLOC); + +@@ -507,7 +525,7 @@ struct xe_device *xe_device_create(struc + + err = xe_bo_pinned_init(xe); + if (err) +- return ERR_PTR(err); ++ return err; + + xe->preempt_fence_wq = alloc_ordered_workqueue("xe-preempt-fence-wq", + WQ_MEM_RECLAIM); +@@ -521,16 +539,15 @@ struct xe_device *xe_device_create(struc + * drmm_add_action_or_reset register above + */ + drm_err(&xe->drm, "Failed to allocate xe workqueues\n"); +- return ERR_PTR(-ENOMEM); ++ return -ENOMEM; + } + + err = drmm_mutex_init(&xe->drm, &xe->pmt.lock); + if (err) +- return ERR_PTR(err); ++ return err; + +- return xe; ++ return 0; + } +-ALLOW_ERROR_INJECTION(xe_device_create, ERRNO); /* See xe_pci_probe() */ + + static bool xe_driver_flr_disabled(struct xe_device *xe) + { +--- a/drivers/gpu/drm/xe/xe_device.h ++++ b/drivers/gpu/drm/xe/xe_device.h +@@ -44,6 +44,7 @@ static inline struct xe_device *ttm_to_x + } + + struct xe_device *xe_device_create(struct pci_dev *pdev); ++int xe_device_init_early(struct xe_device *xe); + int xe_device_probe_early(struct xe_device *xe); + int xe_device_probe(struct xe_device *xe); + void xe_device_remove(struct xe_device *xe); diff --git a/queue-7.1/drm-xe-set-ttm-device-beneficial_order-to-9-2m.patch b/queue-7.1/drm-xe-set-ttm-device-beneficial_order-to-9-2m.patch new file mode 100644 index 0000000000..15cbedc0a7 --- /dev/null +++ b/queue-7.1/drm-xe-set-ttm-device-beneficial_order-to-9-2m.patch @@ -0,0 +1,49 @@ +From stable+bounces-294164-greg=kroah.com@vger.kernel.org Fri Jul 31 19:12:13 2026 +From: Sasha Levin +Date: Fri, 31 Jul 2026 12:56:58 -0400 +Subject: drm/xe: Set TTM device beneficial_order to 9 (2M) +To: stable@vger.kernel.org +Cc: "Matthew Brost" , "Andi Shyti" , "Thomas Hellström" , "Sasha Levin" +Message-ID: <20260731165658.883265-5-sashal@kernel.org> + +From: Matthew Brost + +[ Upstream commit ba7fd163422877ad5a5cf31306a38c07d3932b0c ] + +Set the TTM device beneficial_order to 9 (2M), which is the sweet +spot for Xe when attempting reclaim on system memory BOs, as it matches +the large GPU page size. This ensures reclaim is attempted at the most +effective order for the driver. + +This fixes an issue where an order-10 (4M) allocation cannot be found +despite an abundance of memory. The 4M allocation triggers reclaim, +unnecessarily evicting the working set and hurting performance. Since +the TTM infrastructure was introduced recently, we are tagging the TTM +patch as the Fixes target, even though this resolves an Xe-side problem. + +Fixes: 7e9c548d3709 ("drm/ttm: Allow drivers to specify maximum beneficial TTM pool size") +Cc: stable@vger.kernel.org +Signed-off-by: Matthew Brost +Reviewed-by: Andi Shyti +Reviewed-by: Thomas Hellström +Link: https://patch.msgid.link/20260611235844.3725147-1-matthew.brost@intel.com +(cherry picked from commit 0d81db90d364cb3d733410829118759f28957c5a) +Signed-off-by: Matthew Brost +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/xe/xe_device.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/xe/xe_device.c ++++ b/drivers/gpu/drm/xe/xe_device.c +@@ -478,7 +478,8 @@ int xe_device_init_early(struct xe_devic + + err = ttm_device_init(&xe->ttm, &xe_ttm_funcs, xe->drm.dev, + xe->drm.anon_inode->i_mapping, +- xe->drm.vma_offset_manager, 0); ++ xe->drm.vma_offset_manager, ++ TTM_ALLOCATION_POOL_BENEFICIAL_ORDER(get_order(SZ_2M))); + if (err) + return err; + diff --git a/queue-7.1/drm-xe-wait-on-external-bo-kernel-fences-in-exec-ioctl.patch b/queue-7.1/drm-xe-wait-on-external-bo-kernel-fences-in-exec-ioctl.patch new file mode 100644 index 0000000000..d43f1d68e1 --- /dev/null +++ b/queue-7.1/drm-xe-wait-on-external-bo-kernel-fences-in-exec-ioctl.patch @@ -0,0 +1,80 @@ +From stable+bounces-294380-greg=kroah.com@vger.kernel.org Sat Aug 1 16:04:17 2026 +From: Sasha Levin +Date: Sat, 1 Aug 2026 10:04:08 -0400 +Subject: drm/xe: Wait on external BO kernel fences in exec IOCTL +To: stable@vger.kernel.org +Cc: "Matthew Brost" , "Matthew Auld" , "Thomas Hellström" , "Sasha Levin" +Message-ID: <20260801140408.3645911-2-sashal@kernel.org> + +From: Matthew Brost + +[ Upstream commit af80e2bfde9312c76b60cf9274248dce0410b30d ] + +Before arming a user job, xe_exec_ioctl() only added the VM's +dma-resv KERNEL slot as a dependency. That slot covers rebinds and +the kernel operations of the VM's private BOs, but not external BOs +(bo->vm == NULL), which carry their kernel operations (evictions, +moves, ...) in their own dma-resv KERNEL slot. + +The DMA_RESV_USAGE_KERNEL slot is the cross-driver contract for +memory management operations that must complete before the BO or its +backing store may be used: any accessor is required to wait on the +KERNEL fences before touching the resv. By skipping the external BOs' +KERNEL slots, the exec path violated that contract and could schedule +a user job while a kernel operation on an external BO mapped by the VM +was still in flight, racing against it and potentially reading or +writing memory that was being moved. + +Replace the VM-only dependency with an iteration over every object +locked by the exec, adding each object's KERNEL slot as a job +dependency. This covers the VM resv (rebinds and private BOs) as well +as every external BO, mirroring the drm_gpuvm_resv_add_fence() call +that later publishes the job fence to the same set of objects. +Long-running mode continues to skip this, as before. + +Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") +Cc: stable@vger.kernel.org +Assisted-by: GitHub_Copilot:claude-opus-4.8 +Signed-off-by: Matthew Brost +Reviewed-by: Matthew Auld +Link: https://patch.msgid.link/20260702215805.4011228-1-matthew.brost@intel.com +(cherry picked from commit a6b842acf3ddd1efc53a56de9260cfa718fb35e7) +Signed-off-by: Thomas Hellström +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/xe/xe_exec.c | 22 ++++++++++++++++------ + 1 file changed, 16 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/xe/xe_exec.c ++++ b/drivers/gpu/drm/xe/xe_exec.c +@@ -292,13 +292,23 @@ retry: + goto err_exec; + } + +- /* Wait behind rebinds */ ++ /* ++ * Wait behind rebinds and any kernel operations (evictions, defrag ++ * moves, ...) on the VM and all external BOs. The VM's private BOs ++ * carry their kernel ops in the VM dma-resv KERNEL slot, while each ++ * external BO carries them in its own dma-resv KERNEL slot; both are ++ * covered by iterating every object locked by the exec, mirroring the ++ * drm_gpuvm_resv_add_fence() below. ++ */ + if (!xe_vm_in_lr_mode(vm)) { +- err = xe_sched_job_add_deps(job, +- xe_vm_resv(vm), +- DMA_RESV_USAGE_KERNEL); +- if (err) +- goto err_put_job; ++ struct drm_gem_object *obj; ++ ++ drm_exec_for_each_locked_object(exec, obj) { ++ err = xe_sched_job_add_deps(job, obj->resv, ++ DMA_RESV_USAGE_KERNEL); ++ if (err) ++ goto err_put_job; ++ } + } + + for (i = 0; i < num_syncs && !err; i++) diff --git a/queue-7.1/media-chips-media-wave5-support-cbp-profile.patch b/queue-7.1/media-chips-media-wave5-support-cbp-profile.patch new file mode 100644 index 0000000000..726fd04a85 --- /dev/null +++ b/queue-7.1/media-chips-media-wave5-support-cbp-profile.patch @@ -0,0 +1,82 @@ +From stable+bounces-294964-greg=kroah.com@vger.kernel.org Tue Aug 4 03:08:50 2026 +From: Sasha Levin +Date: Mon, 3 Aug 2026 21:06:29 -0400 +Subject: media: chips-media: wave5: Support CBP profile +To: stable@vger.kernel.org +Cc: Jackson Lee , Nas Chung , Brandon Brnich , Nicolas Dufresne , Hans Verkuil , Sasha Levin +Message-ID: <20260804010629.2350099-1-sashal@kernel.org> + +From: Jackson Lee + +[ Upstream commit f8505f9d6b223a26854003bfdba1a0772457886d ] + +Constrained Baseline Profile (CBP) and Baseline Profile (BP) have been +treated as the same. +Introduce the ability to differentiate between the two. + +Fixes: 9707a6254a8a ("media: chips-media: wave5: Add the v4l2 layer") +Cc: stable@vger.kernel.org +Signed-off-by: Jackson Lee +Signed-off-by: Nas Chung +Tested-by: Brandon Brnich +Reviewed-by: Nicolas Dufresne +Signed-off-by: Nicolas Dufresne +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/platform/chips-media/wave5/wave5-hw.c | 3 +++ + drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c | 5 ++++- + drivers/media/platform/chips-media/wave5/wave5-vpuapi.h | 1 + + 3 files changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/media/platform/chips-media/wave5/wave5-hw.c ++++ b/drivers/media/platform/chips-media/wave5/wave5-hw.c +@@ -1762,6 +1762,9 @@ int wave5_vpu_enc_init_seq(struct vpu_in + (p_param->skip_intra_trans << 25) | + (p_param->strong_intra_smooth_enable << 27) | + (p_param->en_still_picture << 30); ++ else if (inst->std == W_AVC_ENC) ++ reg_val |= (p_param->constraint_set1_flag << 29); ++ + vpu_write_reg(inst->dev, W5_CMD_ENC_SEQ_SPS_PARAM, reg_val); + + reg_val = (p_param->lossless_enable) | +--- a/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c ++++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c +@@ -915,6 +915,8 @@ static int wave5_vpu_enc_s_ctrl(struct v + case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: + inst->enc_param.profile = H264_PROFILE_BP; + inst->bit_depth = 8; ++ if (ctrl->val == V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) ++ inst->enc_param.constraint_set1_flag = 1; + break; + case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: + inst->enc_param.profile = H264_PROFILE_MP; +@@ -1190,6 +1192,7 @@ static int wave5_set_enc_openparam(struc + open_param->wave_param.intra_period = input.avc_idr_period; + } + } else { ++ open_param->wave_param.constraint_set1_flag = input.constraint_set1_flag; + open_param->wave_param.avc_idr_period = input.avc_idr_period; + } + open_param->wave_param.entropy_coding_mode = input.entropy_coding_mode; +@@ -1662,7 +1665,7 @@ static int wave5_vpu_open_enc(struct fil + -6, 6, 1, 0); + v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, + V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM, +- 0, 1, 1, 1); ++ 0, 1, 1, 0); + v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, + V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION, + 0, 1, 1, 0); +--- a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h ++++ b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h +@@ -570,6 +570,7 @@ struct enc_wave_param { + u32 transform8x8_enable: 1; /* enable 8x8 intra prediction and 8x8 transform */ + u32 mb_level_rc_enable: 1; /* enable MB-level rate control */ + u32 forced_idr_header_enable: 1; /* enable header encoding before IDR frame */ ++ u32 constraint_set1_flag: 1; /* enable CBP */ + }; + + struct enc_open_param { diff --git a/queue-7.1/series b/queue-7.1/series index dfe6efdcbd..52bb83ce0d 100644 --- a/queue-7.1/series +++ b/queue-7.1/series @@ -424,3 +424,13 @@ drm-xe-rtp-toggle-deny-bit-to-de-whitelist-oa-regs.patch drm-xe-rtp-de-whitelist-oa-registers-for-all-hwe-s-f.patch drm-xe-oa-de-whitelist-oa-registers-on-oa-stream-ope.patch drm-xe-rtp-ensure-locking-ref-counting-for-oa-whitel.patch +usb-typec-ucsi-split-connector-lock-classes.patch +usb-typec-ucsi-fix-race-condition-and-ordering-in-port-unregistration.patch +drm-xe-drop-unused-param-from-xe_device_create.patch +drm-xe-move-xe-info.force_execlist-initialization.patch +drm-xe-move-xe-info.devid-revid-initialization.patch +drm-xe-separate-early-xe_device-initialization.patch +drm-xe-set-ttm-device-beneficial_order-to-9-2m.patch +drm-exec-remove-the-index-parameter-from-drm_exec_for_each_locked_obj.patch +drm-xe-wait-on-external-bo-kernel-fences-in-exec-ioctl.patch +media-chips-media-wave5-support-cbp-profile.patch diff --git a/queue-7.1/usb-typec-ucsi-fix-race-condition-and-ordering-in-port-unregistration.patch b/queue-7.1/usb-typec-ucsi-fix-race-condition-and-ordering-in-port-unregistration.patch new file mode 100644 index 0000000000..09a562a3a8 --- /dev/null +++ b/queue-7.1/usb-typec-ucsi-fix-race-condition-and-ordering-in-port-unregistration.patch @@ -0,0 +1,173 @@ +From stable+bounces-291214-greg=kroah.com@vger.kernel.org Thu Jul 30 16:06:58 2026 +From: Sasha Levin +Date: Thu, 30 Jul 2026 10:06:26 -0400 +Subject: usb: typec: ucsi: Fix race condition and ordering in port unregistration +To: stable@vger.kernel.org +Cc: Andrei Kuchynski , stable , Benson Leung , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20260730140626.2464203-2-sashal@kernel.org> + +From: Andrei Kuchynski + +[ Upstream commit 7aa7d4bf9d3fa9a6a47b640ad103ab433b7ff261 ] + +A synchronization issue exists during port unregistration where pending +partner work items can race against workqueue destruction, leading to +use-after-free conditions: + + cros_ec_ucsi cros_ec_ucsi.3.auto: error -ETIMEDOUT: PPM init failed + BUG: kernel NULL pointer dereference, address: 0000000000000000 + RIP: 0010:__queue_work+0x83/0x4a0 + Call Trace: + + __cfi_delayed_work_timer_fn+0x10/0x10 + run_timer_softirq+0x3b6/0xbd0 + sched_clock_cpu+0xc/0x110 + irq_exit_rcu+0x18d/0x330 + fred_sysvec_apic_timer_interrupt+0x5e/0x80 + +Fix this by ensuring strict ordering and proper serialization during +teardown: + +1. Move ucsi_unregister_partner() to the beginning of the teardown +sequence and protect it under the connector mutex lock. +2. Ensure all pending partner tasks are explicitly flushed and finished +before the workqueue is destroyed. +3. Switch from mod_delayed_work() to a cancel_delayed_work() and +queue_delayed_work() sequence. This guarantees that items currently marked +as pending won't be scheduled an additional time, preventing a double +release of resources which leads to the following crash: + + Oops: general protection fault, probably for non-canonical address + 0xdead000000000122: 0000 [#1] SMP NOPTI + Workqueue: cros_ec_ucsi.3.auto-con2 ucsi_poll_worker + RIP: 0010:ucsi_poll_worker+0x65/0x1e0 + Call Trace: + + process_scheduled_works+0x218/0x6d0 + worker_thread+0x188/0x3f0 + __cfi_worker_thread+0x10/0x10 + kthread+0x226/0x2a0 + +To ensure these rules are applied identically across both the normal +teardown and the ucsi_init() error paths, consolidate the cleanup logic +into a new helper, ucsi_unregister_port(). + +Cc: stable +Fixes: b9aa02ca39a4 ("usb: typec: ucsi: Add polling mechanism for partner tasks like alt mode checking") +Fixes: b13abcb7ddd8 ("usb: typec: ucsi: Fix NULL pointer access") +Fixes: fac4b8633fd6 ("usb: ucsi: Ensure connector delayed work items are flushed") +Signed-off-by: Andrei Kuchynski +Reviewed-by: Benson Leung +Link: https://patch.msgid.link/20260707141736.1635698-1-akuchynski@chromium.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/ucsi/ucsi.c | 82 +++++++++++++++++++----------------------- + 1 file changed, 39 insertions(+), 43 deletions(-) + +--- a/drivers/usb/typec/ucsi/ucsi.c ++++ b/drivers/usb/typec/ucsi/ucsi.c +@@ -1951,6 +1951,42 @@ out_unlock: + return ret; + } + ++static void ucsi_unregister_port(struct ucsi_connector *con) ++{ ++ struct ucsi_work *uwork; ++ ++ if (con->wq) { ++ mutex_lock(&con->lock); ++ ucsi_unregister_partner(con); ++ /* ++ * queue delayed items immediately so they can execute ++ * and free themselves before the wq is destroyed ++ */ ++ list_for_each_entry(uwork, &con->partner_tasks, node) { ++ if (cancel_delayed_work(&uwork->work)) ++ queue_delayed_work(con->wq, &uwork->work, 0); ++ } ++ mutex_unlock(&con->lock); ++ ++ destroy_workqueue(con->wq); ++ con->wq = NULL; ++ } else { ++ ucsi_unregister_partner(con); ++ } ++ ++ ucsi_unregister_altmodes(con, UCSI_RECIPIENT_CON); ++ ucsi_unregister_port_psy(con); ++ ++ usb_power_delivery_unregister_capabilities(con->port_sink_caps); ++ con->port_sink_caps = NULL; ++ usb_power_delivery_unregister_capabilities(con->port_source_caps); ++ con->port_source_caps = NULL; ++ usb_power_delivery_unregister(con->pd); ++ con->pd = NULL; ++ typec_unregister_port(con->port); ++ con->port = NULL; ++} ++ + static u64 ucsi_get_supported_notifications(struct ucsi *ucsi) + { + u16 features = ucsi->cap.features; +@@ -2077,22 +2113,8 @@ err_unregister: + for (i = 0; i < ucsi->cap.num_connectors; i++) + lockdep_unregister_key(&connector[i].lock_key); + +- for (con = connector; con->port; con++) { +- if (con->wq) +- destroy_workqueue(con->wq); +- ucsi_unregister_partner(con); +- ucsi_unregister_altmodes(con, UCSI_RECIPIENT_CON); +- ucsi_unregister_port_psy(con); +- +- usb_power_delivery_unregister_capabilities(con->port_sink_caps); +- con->port_sink_caps = NULL; +- usb_power_delivery_unregister_capabilities(con->port_source_caps); +- con->port_source_caps = NULL; +- usb_power_delivery_unregister(con->pd); +- con->pd = NULL; +- typec_unregister_port(con->port); +- con->port = NULL; +- } ++ for (con = connector; con->port; con++) ++ ucsi_unregister_port(con); + kfree(connector); + err_reset: + memset(&ucsi->cap, 0, sizeof(ucsi->cap)); +@@ -2320,33 +2342,7 @@ void ucsi_unregister(struct ucsi *ucsi) + + for (i = 0; i < ucsi->cap.num_connectors; i++) { + cancel_work_sync(&ucsi->connector[i].work); +- +- if (ucsi->connector[i].wq) { +- struct ucsi_work *uwork; +- +- mutex_lock(&ucsi->connector[i].lock); +- /* +- * queue delayed items immediately so they can execute +- * and free themselves before the wq is destroyed +- */ +- list_for_each_entry(uwork, &ucsi->connector[i].partner_tasks, node) +- mod_delayed_work(ucsi->connector[i].wq, &uwork->work, 0); +- mutex_unlock(&ucsi->connector[i].lock); +- destroy_workqueue(ucsi->connector[i].wq); +- } +- +- ucsi_unregister_partner(&ucsi->connector[i]); +- ucsi_unregister_altmodes(&ucsi->connector[i], +- UCSI_RECIPIENT_CON); +- ucsi_unregister_port_psy(&ucsi->connector[i]); +- +- usb_power_delivery_unregister_capabilities(ucsi->connector[i].port_sink_caps); +- ucsi->connector[i].port_sink_caps = NULL; +- usb_power_delivery_unregister_capabilities(ucsi->connector[i].port_source_caps); +- ucsi->connector[i].port_source_caps = NULL; +- usb_power_delivery_unregister(ucsi->connector[i].pd); +- ucsi->connector[i].pd = NULL; +- typec_unregister_port(ucsi->connector[i].port); ++ ucsi_unregister_port(&ucsi->connector[i]); + lockdep_unregister_key(&ucsi->connector[i].lock_key); + } + diff --git a/queue-7.1/usb-typec-ucsi-split-connector-lock-classes.patch b/queue-7.1/usb-typec-ucsi-split-connector-lock-classes.patch new file mode 100644 index 0000000000..0659af9f04 --- /dev/null +++ b/queue-7.1/usb-typec-ucsi-split-connector-lock-classes.patch @@ -0,0 +1,124 @@ +From sashal@kernel.org Thu Jul 30 16:06:29 2026 +From: Sasha Levin +Date: Thu, 30 Jul 2026 10:06:25 -0400 +Subject: usb: typec: ucsi: split connector lock classes +To: stable@vger.kernel.org +Cc: Sergey Senozhatsky , Heikki Krogerus , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20260730140626.2464203-1-sashal@kernel.org> + +From: Sergey Senozhatsky + +[ Upstream commit 8c22256bbafad3dc5fdbe9f684d045b67ff06a68 ] + +Lockdep detects a possible recursive locking scenario during +ucsi init: + +[ 5.418616] ============================================ +[ 5.418634] WARNING: possible recursive locking detected +[ 5.418706] -------------------------------------------- +[ 5.418725] kworker/4:1/82 is trying to acquire lock: +[ 5.418759] ffff888119a34648 (&con->lock){+.+.}-{3:3}, at: ucsi_init_work+0x1a78/0x2eb0 [typec_ucsi] +[ 5.418801] + but task is already holding lock: +[ 5.418835] ffff888119a34080 (&con->lock){+.+.}-{3:3}, at: ucsi_init_work+0x1a78/0x2eb0 [typec_ucsi] +[ 5.418884] + other info that might help us debug this: +[ 5.418904] Possible unsafe locking scenario: + +[ 5.418937] CPU0 +[ 5.418956] ---- +[ 5.418991] lock(&con->lock); +[ 5.419013] lock(&con->lock); +[ 5.419033] + *** DEADLOCK *** + +[ 5.419387] Call Trace: +[ 5.419406] +[ 5.419425] dump_stack_lvl+0x61/0xa0 +[ 5.419448] print_deadlock_bug+0x4a6/0x650 +[ 5.419483] __lock_acquire+0x62b6/0x7f50 +[ 5.419507] lock_acquire+0x11b/0x390 +[ 5.419654] __mutex_lock+0xbc/0xcd0 +[ 5.419741] ucsi_init_work+0x1a78/0x2eb0 +[ 5.419785] ? worker_thread+0xf53/0x2bc0 +[ 5.419819] worker_thread+0xff4/0x2bc0 +[ 5.419842] kthread+0x2a7/0x330 +[ 5.419863] ? __pfx_worker_thread+0x10/0x10 +[ 5.419896] ? __pfx_kthread+0x10/0x10 +[ 5.419916] ret_from_fork+0x38/0x70 +[ 5.419936] ? __pfx_kthread+0x10/0x10 +[ 5.419969] ret_from_fork_asm+0x1b/0x30 +[ 5.419991] +[ 5.420009] ---[ end trace 0000000000000000 ]--- + +The problem is that all connector locks belong to the same +lockdep lock class, so the following loop: + + for (i = 0; i < ucsi->cap.num_connectors; i++) + ucsi_register_port(connector[i]) + mutex_lock(&connector[i]->lock) + +looks like a recursive acquire of the same mutex. Put each connector +lock into a dedicated lock class so that lockdep doesn't see it as a +possible recursion. + +Signed-off-by: Sergey Senozhatsky +Reviewed-by: Heikki Krogerus +Link: https://patch.msgid.link/20260515060042.136083-1-senozhatsky@chromium.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 7aa7d4bf9d3f ("usb: typec: ucsi: Fix race condition and ordering in port unregistration") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/ucsi/ucsi.c | 8 ++++++++ + drivers/usb/typec/ucsi/ucsi.h | 1 + + 2 files changed, 9 insertions(+) + +--- a/drivers/usb/typec/ucsi/ucsi.c ++++ b/drivers/usb/typec/ucsi/ucsi.c +@@ -1796,6 +1796,7 @@ static int ucsi_register_port(struct ucs + INIT_WORK(&con->work, ucsi_handle_connector_change); + init_completion(&con->complete); + mutex_init(&con->lock); ++ lockdep_set_class(&con->lock, &con->lock_key); + INIT_LIST_HEAD(&con->partner_tasks); + con->ucsi = ucsi; + +@@ -2041,6 +2042,9 @@ static int ucsi_init(struct ucsi *ucsi) + goto err_reset; + } + ++ for (i = 0; i < ucsi->cap.num_connectors; i++) ++ lockdep_register_key(&connector[i].lock_key); ++ + /* Register all connectors */ + for (i = 0; i < ucsi->cap.num_connectors; i++) { + connector[i].num = i + 1; +@@ -2070,6 +2074,9 @@ static int ucsi_init(struct ucsi *ucsi) + return 0; + + err_unregister: ++ for (i = 0; i < ucsi->cap.num_connectors; i++) ++ lockdep_unregister_key(&connector[i].lock_key); ++ + for (con = connector; con->port; con++) { + if (con->wq) + destroy_workqueue(con->wq); +@@ -2340,6 +2347,7 @@ void ucsi_unregister(struct ucsi *ucsi) + usb_power_delivery_unregister(ucsi->connector[i].pd); + ucsi->connector[i].pd = NULL; + typec_unregister_port(ucsi->connector[i].port); ++ lockdep_unregister_key(&ucsi->connector[i].lock_key); + } + + kfree(ucsi->connector); +--- a/drivers/usb/typec/ucsi/ucsi.h ++++ b/drivers/usb/typec/ucsi/ucsi.h +@@ -517,6 +517,7 @@ struct ucsi_connector { + + struct ucsi *ucsi; + struct mutex lock; /* port lock */ ++ struct lock_class_key lock_key; + struct work_struct work; + struct completion complete; + struct workqueue_struct *wq;