]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
7.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Aug 2026 09:22:56 +0000 (11:22 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Aug 2026 09:22:56 +0000 (11:22 +0200)
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

queue-7.1/drm-exec-remove-the-index-parameter-from-drm_exec_for_each_locked_obj.patch [new file with mode: 0644]
queue-7.1/drm-xe-drop-unused-param-from-xe_device_create.patch [new file with mode: 0644]
queue-7.1/drm-xe-move-xe-info.devid-revid-initialization.patch [new file with mode: 0644]
queue-7.1/drm-xe-move-xe-info.force_execlist-initialization.patch [new file with mode: 0644]
queue-7.1/drm-xe-separate-early-xe_device-initialization.patch [new file with mode: 0644]
queue-7.1/drm-xe-set-ttm-device-beneficial_order-to-9-2m.patch [new file with mode: 0644]
queue-7.1/drm-xe-wait-on-external-bo-kernel-fences-in-exec-ioctl.patch [new file with mode: 0644]
queue-7.1/media-chips-media-wave5-support-cbp-profile.patch [new file with mode: 0644]
queue-7.1/series
queue-7.1/usb-typec-ucsi-fix-race-condition-and-ordering-in-port-unregistration.patch [new file with mode: 0644]
queue-7.1/usb-typec-ucsi-split-connector-lock-classes.patch [new file with mode: 0644]

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 (file)
index 0000000..85c27cc
--- /dev/null
@@ -0,0 +1,215 @@
+From stable+bounces-294379-greg=kroah.com@vger.kernel.org Sat Aug  1 16:04:58 2026
+From: Sasha Levin <sashal@kernel.org>
+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" <thomas.hellstrom@linux.intel.com>, "Christian König" <christian.koenig@amd.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260801140408.3645911-1-sashal@kernel.org>
+
+From: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+
+[ 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 <thomas.hellstrom@linux.intel.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+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 <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..dd60365
--- /dev/null
@@ -0,0 +1,71 @@
+From stable+bounces-294159-greg=kroah.com@vger.kernel.org Fri Jul 31 19:12:23 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <michal.wajdeczko@intel.com>, Raag Jadav <raag.jadav@intel.com>, Gustavo Sousa <gustavo.sousa@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260731165658.883265-1-sashal@kernel.org>
+
+From: Michal Wajdeczko <michal.wajdeczko@intel.com>
+
+[ 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 <michal.wajdeczko@intel.com>
+Reviewed-by: Raag Jadav <raag.jadav@intel.com>
+Reviewed-by: Gustavo Sousa <gustavo.sousa@intel.com>
+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 <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..05144e4
--- /dev/null
@@ -0,0 +1,93 @@
+From stable+bounces-294161-greg=kroah.com@vger.kernel.org Fri Jul 31 19:12:20 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <michal.wajdeczko@intel.com>, Gustavo Sousa <gustavo.sousa@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260731165658.883265-3-sashal@kernel.org>
+
+From: Michal Wajdeczko <michal.wajdeczko@intel.com>
+
+[ 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 <michal.wajdeczko@intel.com>
+Cc: Gustavo Sousa <gustavo.sousa@intel.com>
+Reviewed-by: Gustavo Sousa <gustavo.sousa@intel.com>
+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 <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..2ef17c1
--- /dev/null
@@ -0,0 +1,47 @@
+From stable+bounces-294160-greg=kroah.com@vger.kernel.org Fri Jul 31 19:15:48 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <michal.wajdeczko@intel.com>, Gustavo Sousa <gustavo.sousa@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260731165658.883265-2-sashal@kernel.org>
+
+From: Michal Wajdeczko <michal.wajdeczko@intel.com>
+
+[ 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 <michal.wajdeczko@intel.com>
+Reviewed-by: Gustavo Sousa <gustavo.sousa@intel.com>
+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 <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..32f1c3b
--- /dev/null
@@ -0,0 +1,130 @@
+From stable+bounces-294162-greg=kroah.com@vger.kernel.org Fri Jul 31 19:34:48 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <michal.wajdeczko@intel.com>, Raag Jadav <raag.jadav@intel.com>, Gustavo Sousa <gustavo.sousa@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260731165658.883265-4-sashal@kernel.org>
+
+From: Michal Wajdeczko <michal.wajdeczko@intel.com>
+
+[ 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 <michal.wajdeczko@intel.com>
+Reviewed-by: Raag Jadav <raag.jadav@intel.com>
+Reviewed-by: Gustavo Sousa <gustavo.sousa@intel.com>
+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 <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..15cbedc
--- /dev/null
@@ -0,0 +1,49 @@
+From stable+bounces-294164-greg=kroah.com@vger.kernel.org Fri Jul 31 19:12:13 2026
+From: Sasha Levin <sashal@kernel.org>
+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" <matthew.brost@intel.com>, "Andi Shyti" <andi.shyti@linux.intel.com>, "Thomas Hellström" <thomas.hellstrom@linux.intel.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260731165658.883265-5-sashal@kernel.org>
+
+From: Matthew Brost <matthew.brost@intel.com>
+
+[ 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 <matthew.brost@intel.com>
+Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
+Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Link: https://patch.msgid.link/20260611235844.3725147-1-matthew.brost@intel.com
+(cherry picked from commit 0d81db90d364cb3d733410829118759f28957c5a)
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..d43f1d6
--- /dev/null
@@ -0,0 +1,80 @@
+From stable+bounces-294380-greg=kroah.com@vger.kernel.org Sat Aug  1 16:04:17 2026
+From: Sasha Levin <sashal@kernel.org>
+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.brost@intel.com>, "Matthew Auld" <matthew.auld@intel.com>, "Thomas Hellström" <thomas.hellstrom@linux.intel.com>, "Sasha Levin" <sashal@nvidia.com>
+Message-ID: <20260801140408.3645911-2-sashal@kernel.org>
+
+From: Matthew Brost <matthew.brost@intel.com>
+
+[ 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 <matthew.brost@intel.com>
+Reviewed-by: Matthew Auld <matthew.auld@intel.com>
+Link: https://patch.msgid.link/20260702215805.4011228-1-matthew.brost@intel.com
+(cherry picked from commit a6b842acf3ddd1efc53a56de9260cfa718fb35e7)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..726fd04
--- /dev/null
@@ -0,0 +1,82 @@
+From stable+bounces-294964-greg=kroah.com@vger.kernel.org Tue Aug  4 03:08:50 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <jackson.lee@chipsnmedia.com>, Nas Chung <nas.chung@chipsnmedia.com>, Brandon Brnich <b-brnich@ti.com>, Nicolas Dufresne <nicolas.dufresne@collabora.com>, Hans Verkuil <hverkuil+cisco@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260804010629.2350099-1-sashal@kernel.org>
+
+From: Jackson Lee <jackson.lee@chipsnmedia.com>
+
+[ 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 <jackson.lee@chipsnmedia.com>
+Signed-off-by: Nas Chung <nas.chung@chipsnmedia.com>
+Tested-by: Brandon Brnich <b-brnich@ti.com>
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 {
index dfe6efdcbdca9e8130f75e5fd6fcc1253a0ec7eb..52bb83ce0dc9378f25ac2f3348547eaa51d346a7 100644 (file)
@@ -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 (file)
index 0000000..09a562a
--- /dev/null
@@ -0,0 +1,173 @@
+From stable+bounces-291214-greg=kroah.com@vger.kernel.org Thu Jul 30 16:06:58 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <akuchynski@chromium.org>, stable <stable@kernel.org>, Benson Leung <bleung@chromium.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260730140626.2464203-2-sashal@kernel.org>
+
+From: Andrei Kuchynski <akuchynski@chromium.org>
+
+[ 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:
+    <IRQ>
+    __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:
+  <TASK>
+    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 <stable@kernel.org>
+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 <akuchynski@chromium.org>
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Link: https://patch.msgid.link/20260707141736.1635698-1-akuchynski@chromium.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..0659af9
--- /dev/null
@@ -0,0 +1,124 @@
+From sashal@kernel.org Thu Jul 30 16:06:29 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <senozhatsky@chromium.org>, Heikki Krogerus <heikki.krogerus@linux.intel.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260730140626.2464203-1-sashal@kernel.org>
+
+From: Sergey Senozhatsky <senozhatsky@chromium.org>
+
+[ 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]  <TASK>
+[    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]  </TASK>
+[    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 <senozhatsky@chromium.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://patch.msgid.link/20260515060042.136083-1-senozhatsky@chromium.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 7aa7d4bf9d3f ("usb: typec: ucsi: Fix race condition and ordering in port unregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;