]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Aug 2026 13:05:37 +0000 (15:05 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Aug 2026 13:05:37 +0000 (15:05 +0200)
added patches:
drm-amdgpu-fix-context-pstate-override-handling.patch
drm-amdgpu-gfx-fix-cleaner-shader-ib-buffer-overflow.patch
drm-amdgpu-give-each-kernel-job-a-unique-id.patch
drm-amdgpu-respect-placement-requirements-in-amdgpu_gtt_mgr-functions.patch
drm-exec-remove-the-index-parameter-from-drm_exec_for_each_locked_obj.patch
drm-fb-helper-allocate-and-release-fb_info-in-single-place.patch
drm-i915-hdcp-move-to-using-intel_display-in-intel_hdcp.patch
drm-i915-hdcp-require-monotonically-increasing-seq_num_v.patch
drm-i915-vrr-check-has_vrr-first-in-intel_vrr_is_capable.patch
drm-i915-vrr-require-valid-min-max-vfreq-for-vrr.patch
drm-sched-store-the-drm-client_id-in-drm_sched_fence.patch
drm-tegra-fbdev-remove-offset-into-framebuffer-memory.patch
drm-xe-hold-a-dma-buf-reference-for-imported-bos.patch
drm-xe-rename-___xe_bo_create_locked.patch
drm-xe-wait-on-external-bo-kernel-fences-in-exec-ioctl.patch

16 files changed:
queue-6.12/drm-amdgpu-fix-context-pstate-override-handling.patch [new file with mode: 0644]
queue-6.12/drm-amdgpu-gfx-fix-cleaner-shader-ib-buffer-overflow.patch [new file with mode: 0644]
queue-6.12/drm-amdgpu-give-each-kernel-job-a-unique-id.patch [new file with mode: 0644]
queue-6.12/drm-amdgpu-respect-placement-requirements-in-amdgpu_gtt_mgr-functions.patch [new file with mode: 0644]
queue-6.12/drm-exec-remove-the-index-parameter-from-drm_exec_for_each_locked_obj.patch [new file with mode: 0644]
queue-6.12/drm-fb-helper-allocate-and-release-fb_info-in-single-place.patch [new file with mode: 0644]
queue-6.12/drm-i915-hdcp-move-to-using-intel_display-in-intel_hdcp.patch [new file with mode: 0644]
queue-6.12/drm-i915-hdcp-require-monotonically-increasing-seq_num_v.patch [new file with mode: 0644]
queue-6.12/drm-i915-vrr-check-has_vrr-first-in-intel_vrr_is_capable.patch [new file with mode: 0644]
queue-6.12/drm-i915-vrr-require-valid-min-max-vfreq-for-vrr.patch [new file with mode: 0644]
queue-6.12/drm-sched-store-the-drm-client_id-in-drm_sched_fence.patch [new file with mode: 0644]
queue-6.12/drm-tegra-fbdev-remove-offset-into-framebuffer-memory.patch [new file with mode: 0644]
queue-6.12/drm-xe-hold-a-dma-buf-reference-for-imported-bos.patch [new file with mode: 0644]
queue-6.12/drm-xe-rename-___xe_bo_create_locked.patch [new file with mode: 0644]
queue-6.12/drm-xe-wait-on-external-bo-kernel-fences-in-exec-ioctl.patch [new file with mode: 0644]
queue-6.12/series

diff --git a/queue-6.12/drm-amdgpu-fix-context-pstate-override-handling.patch b/queue-6.12/drm-amdgpu-fix-context-pstate-override-handling.patch
new file mode 100644 (file)
index 0000000..48070e4
--- /dev/null
@@ -0,0 +1,165 @@
+From stable+bounces-294146-greg=kroah.com@vger.kernel.org Fri Jul 31 18:47:58 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2026 12:25:30 -0400
+Subject: drm/amdgpu: Fix context pstate override handling
+To: stable@vger.kernel.org
+Cc: "Tvrtko Ursulin" <tvrtko.ursulin@igalia.com>, "Chengming Gui" <Jack.Gui@amd.com>, "Alex Deucher" <alexander.deucher@amd.com>, "Christian König" <christian.koenig@amd.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260731162530.789974-1-sashal@kernel.org>
+
+From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
+
+[ Upstream commit c1dc4ccb82c9e56325d8e7514ca4c90bd1efb351 ]
+
+There are several problems in the context pstate handling code.
+
+The most serious ones are potential use-after-free and NULL pointer
+dereferences at context initialization time. Both are due
+amdgpu_ctx_init() not holding the adev->pm.stable_pstate_ctx_lock, which
+is otherwise used from both sysfs and the context code itself for
+modifying and clearing the stored context pointer.
+
+Second issue is that context fini can trample over the pstate
+configuration set via sysfs. This is due the restore state
+(ctx->stable_pstate) being saved at context init time, and not if, or when
+the context actually changes the pstate. As the context exits it will
+therefore incorrectly restore to what was set before the sysfs override
+was requested.
+
+The simplest fix is to drastically simplify how the state is tracked, by
+clearly defining the points at which pstate ownership is taken and
+released, and to handle all transitions under the correct lock.
+
+Instead of at context init time, the previous state is saved only at the
+point the context overrides the current state, and is restored on context
+exit only if the context is still the owner of the current override state.
+
+Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
+Fixes: 79610d304133 ("drm/amdgpu: fix pstate setting issue")
+Cc: Chengming Gui <Jack.Gui@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: "Christian König" <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 1b5e413713c0a93bc1818394d0ce49aaad21bd27)
+Cc: <stable@vger.kernel.org> # v6.1+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c |   71 ++++++++++++++++++--------------
+ 1 file changed, 42 insertions(+), 29 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+@@ -321,7 +321,6 @@ static int amdgpu_ctx_init(struct amdgpu
+                          struct drm_file *filp, struct amdgpu_ctx *ctx)
+ {
+       struct amdgpu_fpriv *fpriv = filp->driver_priv;
+-      u32 current_stable_pstate;
+       int r;
+       r = amdgpu_ctx_priority_permit(filp, priority);
+@@ -339,37 +338,22 @@ static int amdgpu_ctx_init(struct amdgpu
+       ctx->generation = amdgpu_vm_generation(mgr->adev, &fpriv->vm);
+       ctx->init_priority = priority;
+       ctx->override_priority = AMDGPU_CTX_PRIORITY_UNSET;
+-
+-      r = amdgpu_ctx_get_stable_pstate(ctx, &current_stable_pstate);
+-      if (r)
+-              return r;
+-
+-      if (mgr->adev->pm.stable_pstate_ctx)
+-              ctx->stable_pstate = mgr->adev->pm.stable_pstate_ctx->stable_pstate;
+-      else
+-              ctx->stable_pstate = current_stable_pstate;
++      ctx->stable_pstate = AMDGPU_CTX_STABLE_PSTATE_NONE;
+       ctx->ctx_mgr = &(fpriv->ctx_mgr);
+       return 0;
+ }
+-static int amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx,
+-                                      u32 stable_pstate)
++static int __amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx,
++                                        u32 stable_pstate)
+ {
+       struct amdgpu_device *adev = ctx->mgr->adev;
+       enum amd_dpm_forced_level level;
++      struct amdgpu_ctx *current_ctx;
+       u32 current_stable_pstate;
+-      int r;
+-
+-      mutex_lock(&adev->pm.stable_pstate_ctx_lock);
+-      if (adev->pm.stable_pstate_ctx && adev->pm.stable_pstate_ctx != ctx) {
+-              r = -EBUSY;
+-              goto done;
+-      }
++      int r = 0;
+-      r = amdgpu_ctx_get_stable_pstate(ctx, &current_stable_pstate);
+-      if (r || (stable_pstate == current_stable_pstate))
+-              goto done;
++      lockdep_assert_held(&adev->pm.stable_pstate_ctx_lock);
+       switch (stable_pstate) {
+       case AMDGPU_CTX_STABLE_PSTATE_NONE:
+@@ -388,17 +372,41 @@ static int amdgpu_ctx_set_stable_pstate(
+               level = AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
+               break;
+       default:
+-              r = -EINVAL;
+-              goto done;
++              return -EINVAL;
+       }
++      current_ctx = adev->pm.stable_pstate_ctx;
++      if (current_ctx && current_ctx != ctx)
++              return -EBUSY;
++
++      r = amdgpu_ctx_get_stable_pstate(ctx, &current_stable_pstate);
++      if (r || current_stable_pstate == stable_pstate)
++              return r;
++
+       r = amdgpu_dpm_force_performance_level(adev, level);
++      if (r)
++              return r;
+-      if (level == AMD_DPM_FORCED_LEVEL_AUTO)
+-              adev->pm.stable_pstate_ctx = NULL;
+-      else
++      if (!current_ctx) {
+               adev->pm.stable_pstate_ctx = ctx;
+-done:
++              /*
++               * Serialized by context taking ownership for the first time
++               * while holding adev->pm.stable_pstate_ctx_lock).
++               */
++              WRITE_ONCE(ctx->stable_pstate, current_stable_pstate);
++      }
++
++      return 0;
++}
++
++static int amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx,
++                                      u32 stable_pstate)
++{
++      struct amdgpu_device *adev = ctx->mgr->adev;
++      int r;
++
++      mutex_lock(&adev->pm.stable_pstate_ctx_lock);
++      r = __amdgpu_ctx_set_stable_pstate(ctx, stable_pstate);
+       mutex_unlock(&adev->pm.stable_pstate_ctx_lock);
+       return r;
+@@ -424,7 +432,12 @@ static void amdgpu_ctx_fini(struct kref
+       }
+       if (drm_dev_enter(adev_to_drm(adev), &idx)) {
+-              amdgpu_ctx_set_stable_pstate(ctx, ctx->stable_pstate);
++              mutex_lock(&adev->pm.stable_pstate_ctx_lock);
++              if (adev->pm.stable_pstate_ctx == ctx) {
++                      __amdgpu_ctx_set_stable_pstate(ctx, ctx->stable_pstate);
++                      adev->pm.stable_pstate_ctx = NULL;
++              }
++              mutex_unlock(&adev->pm.stable_pstate_ctx_lock);
+               drm_dev_exit(idx);
+       }
diff --git a/queue-6.12/drm-amdgpu-gfx-fix-cleaner-shader-ib-buffer-overflow.patch b/queue-6.12/drm-amdgpu-gfx-fix-cleaner-shader-ib-buffer-overflow.patch
new file mode 100644 (file)
index 0000000..086286d
--- /dev/null
@@ -0,0 +1,74 @@
+From stable+bounces-294122-greg=kroah.com@vger.kernel.org Fri Jul 31 17:54:19 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2026 11:49:59 -0400
+Subject: drm/amdgpu/gfx: fix cleaner shader IB buffer overflow
+To: stable@vger.kernel.org
+Cc: Asad Kamal <asad.kamal@amd.com>, Lijo Lazar <lijo.lazar@amd.com>, Alex Deucher <alexander.deucher@amd.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260731154959.602805-3-sashal@kernel.org>
+
+From: Asad Kamal <asad.kamal@amd.com>
+
+[ Upstream commit 3e864bf2a32a1cbdf1e0f9c5a5a4176e8575f4a3 ]
+
+The cleaner shader sysfs path allocates a 16-dword (64 byte) IB but
+incorrectly fills (align_mask + 1) dwords. On GFX rings align_mask is
+0xff, so the loop wrote 256 dwords into a 64-byte buffer, causing a
+kernel page fault.
+
+The IB only needs to be a minimal NOP shell to schedule the job; the
+cleaner shader itself is emitted on the ring via emit_cleaner_shader().
+Fill 16 dwords to match the allocation.
+
+v2: Use ib_size_dw variable (Lijo)
+
+Fixes: d361ad5d2fc0 ("drm/amdgpu: Add sysfs interface for running cleaner shader")
+Suggested-by: Lijo Lazar <lijo.lazar@amd.com>
+Signed-off-by: Asad Kamal <asad.kamal@amd.com>
+Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit bf21af331ebf72d0935fd70c73192414a422c03a)
+CC: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c |   10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+@@ -1426,12 +1426,13 @@ static int amdgpu_gfx_run_cleaner_shader
+       struct amdgpu_device *adev = ring->adev;
+       struct drm_gpu_scheduler *sched = &ring->sched;
+       struct drm_sched_entity entity;
++      unsigned int ib_size_dw = 16;
+       static atomic_t counter;
+       struct dma_fence *f;
+       struct amdgpu_job *job;
+       struct amdgpu_ib *ib;
+       void *owner;
+-      int i, r;
++      int r;
+       /* Initialize the scheduler entity */
+       r = drm_sched_entity_init(&entity, DRM_SCHED_PRIORITY_NORMAL,
+@@ -1449,7 +1450,7 @@ static int amdgpu_gfx_run_cleaner_shader
+       owner = (void *)(unsigned long)atomic_inc_return(&counter);
+       r = amdgpu_job_alloc_with_ib(ring->adev, &entity, owner,
+-                                   64, 0, &job,
++                                   ib_size_dw * sizeof(uint32_t), 0, &job,
+                                    AMDGPU_KERNEL_JOB_ID_CLEANER_SHADER);
+       if (r)
+               goto err;
+@@ -1457,9 +1458,8 @@ static int amdgpu_gfx_run_cleaner_shader
+       job->enforce_isolation = true;
+       ib = &job->ibs[0];
+-      for (i = 0; i <= ring->funcs->align_mask; ++i)
+-              ib->ptr[i] = ring->funcs->nop;
+-      ib->length_dw = ring->funcs->align_mask + 1;
++      memset32(ib->ptr, ring->funcs->nop, ib_size_dw);
++      ib->length_dw = ib_size_dw;
+       f = amdgpu_job_submit(job);
diff --git a/queue-6.12/drm-amdgpu-give-each-kernel-job-a-unique-id.patch b/queue-6.12/drm-amdgpu-give-each-kernel-job-a-unique-id.patch
new file mode 100644 (file)
index 0000000..5435685
--- /dev/null
@@ -0,0 +1,520 @@
+From stable+bounces-294123-greg=kroah.com@vger.kernel.org Fri Jul 31 18:01:33 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2026 11:49:58 -0400
+Subject: drm/amdgpu: give each kernel job a unique id
+To: stable@vger.kernel.org
+Cc: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>, Alex Deucher <alexander.deucher@amd.com>, Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260731154959.602805-2-sashal@kernel.org>
+
+From: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
+
+[ Upstream commit 256576ed6895b81290690ae3e2b9f62eb7c642fc ]
+
+Userspace jobs have drm_file.client_id as a unique identifier
+as job's owners. For kernel jobs, we can allocate arbitrary
+values - the risk of overlap with userspace ids is small (given
+that it's a u64 value).
+In the unlikely case the overlap happens, it'll only impact
+trace events.
+
+Since this ID is traced in the gpu_scheduler trace events, this
+allows to determine the source of each job sent to the hardware.
+
+To make grepping easier, the IDs are defined as they will appear
+in the trace output.
+
+Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
+Link: https://lore.kernel.org/r/20250604122827.2191-1-pierre-eric.pelloux-prayer@amd.com
+Stable-dep-of: 3e864bf2a32a ("drm/amdgpu/gfx: fix cleaner shader IB buffer overflow")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c     |    3 ++-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c     |    2 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_job.c     |    5 +++--
+ drivers/gpu/drm/amd/amdgpu/amdgpu_job.h     |   19 ++++++++++++++++++-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c    |    3 ++-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_object.c  |    3 ++-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c     |   28 +++++++++++++++++-----------
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h     |    3 ++-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c     |    3 ++-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c     |    5 +++--
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c     |    8 ++++----
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c      |    6 ++++--
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h      |    2 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c  |    4 +++-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c   |    4 +++-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c |   12 +++++++-----
+ drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c       |    6 ++++--
+ drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c       |    6 ++++--
+ drivers/gpu/drm/amd/amdkfd/kfd_migrate.c    |    3 ++-
+ 19 files changed, 84 insertions(+), 41 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+@@ -1449,7 +1449,8 @@ static int amdgpu_gfx_run_cleaner_shader
+       owner = (void *)(unsigned long)atomic_inc_return(&counter);
+       r = amdgpu_job_alloc_with_ib(ring->adev, &entity, owner,
+-                                   64, 0, &job);
++                                   64, 0, &job,
++                                   AMDGPU_KERNEL_JOB_ID_CLEANER_SHADER);
+       if (r)
+               goto err;
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+@@ -664,7 +664,7 @@ void amdgpu_gmc_flush_gpu_tlb(struct amd
+       r = amdgpu_job_alloc_with_ib(ring->adev, &adev->mman.high_pr,
+                                    AMDGPU_FENCE_OWNER_UNDEFINED,
+                                    16 * 4, AMDGPU_IB_POOL_IMMEDIATE,
+-                                   &job);
++                                   &job, AMDGPU_KERNEL_JOB_ID_FLUSH_GPU_TLB);
+       if (r)
+               goto error_alloc;
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+@@ -218,11 +218,12 @@ int amdgpu_job_alloc(struct amdgpu_devic
+ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev,
+                            struct drm_sched_entity *entity, void *owner,
+                            size_t size, enum amdgpu_ib_pool_type pool_type,
+-                           struct amdgpu_job **job)
++                           struct amdgpu_job **job, u64 k_job_id)
+ {
+       int r;
+-      r = amdgpu_job_alloc(adev, NULL, entity, owner, 1, job, 0);
++      r = amdgpu_job_alloc(adev, NULL, entity, owner, 1, job,
++                           k_job_id);
+       if (r)
+               return r;
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
+@@ -44,6 +44,22 @@
+ struct amdgpu_fence;
+ enum amdgpu_ib_pool_type;
++/* Internal kernel job ids. (decreasing values, starting from U64_MAX). */
++#define AMDGPU_KERNEL_JOB_ID_VM_UPDATE              (18446744073709551615ULL)
++#define AMDGPU_KERNEL_JOB_ID_VM_UPDATE_PDES         (18446744073709551614ULL)
++#define AMDGPU_KERNEL_JOB_ID_VM_UPDATE_RANGE        (18446744073709551613ULL)
++#define AMDGPU_KERNEL_JOB_ID_VM_PT_CLEAR            (18446744073709551612ULL)
++#define AMDGPU_KERNEL_JOB_ID_TTM_MAP_BUFFER         (18446744073709551611ULL)
++#define AMDGPU_KERNEL_JOB_ID_TTM_ACCESS_MEMORY_SDMA (18446744073709551610ULL)
++#define AMDGPU_KERNEL_JOB_ID_TTM_COPY_BUFFER        (18446744073709551609ULL)
++#define AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE       (18446744073709551608ULL)
++#define AMDGPU_KERNEL_JOB_ID_MOVE_BLIT              (18446744073709551607ULL)
++#define AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER       (18446744073709551606ULL)
++#define AMDGPU_KERNEL_JOB_ID_CLEANER_SHADER         (18446744073709551605ULL)
++#define AMDGPU_KERNEL_JOB_ID_FLUSH_GPU_TLB          (18446744073709551604ULL)
++#define AMDGPU_KERNEL_JOB_ID_KFD_GART_MAP           (18446744073709551603ULL)
++#define AMDGPU_KERNEL_JOB_ID_VCN_RING_TEST          (18446744073709551602ULL)
++
+ struct amdgpu_job {
+       struct drm_sched_job    base;
+       struct amdgpu_vm        *vm;
+@@ -95,7 +111,8 @@ int amdgpu_job_alloc(struct amdgpu_devic
+ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev,
+                            struct drm_sched_entity *entity, void *owner,
+                            size_t size, enum amdgpu_ib_pool_type pool_type,
+-                           struct amdgpu_job **job);
++                           struct amdgpu_job **job,
++                           u64 k_job_id);
+ void amdgpu_job_set_resources(struct amdgpu_job *job, struct amdgpu_bo *gds,
+                             struct amdgpu_bo *gws, struct amdgpu_bo *oa);
+ void amdgpu_job_free_resources(struct amdgpu_job *job);
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c
+@@ -192,7 +192,8 @@ static int amdgpu_jpeg_dec_set_reg(struc
+       int i, r;
+       r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL, ib_size_dw * 4,
+-                                   AMDGPU_IB_POOL_DIRECT, &job);
++                                   AMDGPU_IB_POOL_DIRECT, &job,
++                                   AMDGPU_KERNEL_JOB_ID_VCN_RING_TEST);
+       if (r)
+               return r;
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+@@ -1269,7 +1269,8 @@ void amdgpu_bo_release_notify(struct ttm
+       if (r)
+               goto out;
+-      r = amdgpu_fill_buffer(abo, 0, &bo->base._resv, &fence, true);
++      r = amdgpu_fill_buffer(abo, 0, &bo->base._resv, &fence, true,
++                             AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE);
+       if (WARN_ON(r))
+               goto out;
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+@@ -229,7 +229,8 @@ static int amdgpu_ttm_map_buffer(struct
+       r = amdgpu_job_alloc_with_ib(adev, &adev->mman.high_pr,
+                                    AMDGPU_FENCE_OWNER_UNDEFINED,
+                                    num_dw * 4 + num_bytes,
+-                                   AMDGPU_IB_POOL_DELAYED, &job);
++                                   AMDGPU_IB_POOL_DELAYED, &job,
++                                   AMDGPU_KERNEL_JOB_ID_TTM_MAP_BUFFER);
+       if (r)
+               return r;
+@@ -408,7 +409,7 @@ static int amdgpu_move_blit(struct ttm_b
+               struct dma_fence *wipe_fence = NULL;
+               r = amdgpu_fill_buffer(abo, 0, NULL, &wipe_fence,
+-                                     false);
++                                     false, AMDGPU_KERNEL_JOB_ID_MOVE_BLIT);
+               if (r) {
+                       goto error;
+               } else if (wipe_fence) {
+@@ -1530,7 +1531,8 @@ static int amdgpu_ttm_access_memory_sdma
+       r = amdgpu_job_alloc_with_ib(adev, &adev->mman.high_pr,
+                                    AMDGPU_FENCE_OWNER_UNDEFINED,
+                                    num_dw * 4, AMDGPU_IB_POOL_DELAYED,
+-                                   &job);
++                                   &job,
++                                   AMDGPU_KERNEL_JOB_ID_TTM_ACCESS_MEMORY_SDMA);
+       if (r)
+               goto out;
+@@ -2175,7 +2177,7 @@ static int amdgpu_ttm_prepare_job(struct
+                                 struct dma_resv *resv,
+                                 bool vm_needs_flush,
+                                 struct amdgpu_job **job,
+-                                bool delayed)
++                                bool delayed, u64 k_job_id)
+ {
+       enum amdgpu_ib_pool_type pool = direct_submit ?
+               AMDGPU_IB_POOL_DIRECT :
+@@ -2185,7 +2187,7 @@ static int amdgpu_ttm_prepare_job(struct
+                                                   &adev->mman.high_pr;
+       r = amdgpu_job_alloc_with_ib(adev, entity,
+                                    AMDGPU_FENCE_OWNER_UNDEFINED,
+-                                   num_dw * 4, pool, job);
++                                   num_dw * 4, pool, job, k_job_id);
+       if (r)
+               return r;
+@@ -2224,7 +2226,8 @@ int amdgpu_copy_buffer(struct amdgpu_rin
+       num_loops = DIV_ROUND_UP(byte_count, max_bytes);
+       num_dw = ALIGN(num_loops * adev->mman.buffer_funcs->copy_num_dw, 8);
+       r = amdgpu_ttm_prepare_job(adev, direct_submit, num_dw,
+-                                 resv, vm_needs_flush, &job, false);
++                                 resv, vm_needs_flush, &job, false,
++                                 AMDGPU_KERNEL_JOB_ID_TTM_COPY_BUFFER);
+       if (r)
+               return r;
+@@ -2259,7 +2262,8 @@ static int amdgpu_ttm_fill_mem(struct am
+                              uint64_t dst_addr, uint32_t byte_count,
+                              struct dma_resv *resv,
+                              struct dma_fence **fence,
+-                             bool vm_needs_flush, bool delayed)
++                             bool vm_needs_flush, bool delayed,
++                             u64 k_job_id)
+ {
+       struct amdgpu_device *adev = ring->adev;
+       unsigned int num_loops, num_dw;
+@@ -2272,7 +2276,7 @@ static int amdgpu_ttm_fill_mem(struct am
+       num_loops = DIV_ROUND_UP_ULL(byte_count, max_bytes);
+       num_dw = ALIGN(num_loops * adev->mman.buffer_funcs->fill_num_dw, 8);
+       r = amdgpu_ttm_prepare_job(adev, false, num_dw, resv, vm_needs_flush,
+-                                 &job, delayed);
++                                 &job, delayed, k_job_id);
+       if (r)
+               return r;
+@@ -2342,7 +2346,8 @@ int amdgpu_ttm_clear_buffer(struct amdgp
+                       goto err;
+               r = amdgpu_ttm_fill_mem(ring, 0, addr, size, resv,
+-                                      &next, true, true);
++                                      &next, true, true,
++                                      AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
+               if (r)
+                       goto err;
+@@ -2361,7 +2366,8 @@ int amdgpu_fill_buffer(struct amdgpu_bo
+                       uint32_t src_data,
+                       struct dma_resv *resv,
+                       struct dma_fence **f,
+-                      bool delayed)
++                      bool delayed,
++                      u64 k_job_id)
+ {
+       struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
+       struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
+@@ -2390,7 +2396,7 @@ int amdgpu_fill_buffer(struct amdgpu_bo
+                       goto error;
+               r = amdgpu_ttm_fill_mem(ring, src_data, to, cur_size, resv,
+-                                      &next, true, delayed);
++                                      &next, true, delayed, k_job_id);
+               if (r)
+                       goto error;
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+@@ -180,7 +180,8 @@ int amdgpu_fill_buffer(struct amdgpu_bo
+                       uint32_t src_data,
+                       struct dma_resv *resv,
+                       struct dma_fence **fence,
+-                      bool delayed);
++                      bool delayed,
++                      u64 k_job_id);
+ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo);
+ void amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo);
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+@@ -1164,7 +1164,8 @@ static int amdgpu_uvd_send_msg(struct am
+       r = amdgpu_job_alloc_with_ib(ring->adev, &adev->uvd.entity,
+                                    AMDGPU_FENCE_OWNER_UNDEFINED,
+                                    64, direct ? AMDGPU_IB_POOL_DIRECT :
+-                                   AMDGPU_IB_POOL_DELAYED, &job);
++                                   AMDGPU_IB_POOL_DELAYED, &job,
++                                   AMDGPU_KERNEL_JOB_ID_VCN_RING_TEST);
+       if (r)
+               return r;
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+@@ -449,7 +449,7 @@ static int amdgpu_vce_get_create_msg(str
+       r = amdgpu_job_alloc_with_ib(ring->adev, &ring->adev->vce.entity,
+                                    AMDGPU_FENCE_OWNER_UNDEFINED,
+                                    ib_size_dw * 4, AMDGPU_IB_POOL_DIRECT,
+-                                   &job);
++                                   &job, AMDGPU_KERNEL_JOB_ID_VCN_RING_TEST);
+       if (r)
+               return r;
+@@ -540,7 +540,8 @@ static int amdgpu_vce_get_destroy_msg(st
+                                    AMDGPU_FENCE_OWNER_UNDEFINED,
+                                    ib_size_dw * 4,
+                                    direct ? AMDGPU_IB_POOL_DIRECT :
+-                                   AMDGPU_IB_POOL_DELAYED, &job);
++                                   AMDGPU_IB_POOL_DELAYED, &job,
++                                   AMDGPU_KERNEL_JOB_ID_VCN_RING_TEST);
+       if (r)
+               return r;
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+@@ -553,7 +553,7 @@ static int amdgpu_vcn_dec_send_msg(struc
+       r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
+                                    64, AMDGPU_IB_POOL_DIRECT,
+-                                   &job);
++                                   &job, AMDGPU_KERNEL_JOB_ID_VCN_RING_TEST);
+       if (r)
+               goto err;
+@@ -733,7 +733,7 @@ static int amdgpu_vcn_dec_sw_send_msg(st
+       r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
+                                    ib_size_dw * 4, AMDGPU_IB_POOL_DIRECT,
+-                                   &job);
++                                   &job, AMDGPU_KERNEL_JOB_ID_VCN_RING_TEST);
+       if (r)
+               goto err;
+@@ -863,7 +863,7 @@ static int amdgpu_vcn_enc_get_create_msg
+       r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
+                                    ib_size_dw * 4, AMDGPU_IB_POOL_DIRECT,
+-                                   &job);
++                                   &job, AMDGPU_KERNEL_JOB_ID_VCN_RING_TEST);
+       if (r)
+               return r;
+@@ -930,7 +930,7 @@ static int amdgpu_vcn_enc_get_destroy_ms
+       r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
+                                    ib_size_dw * 4, AMDGPU_IB_POOL_DIRECT,
+-                                   &job);
++                                   &job, AMDGPU_KERNEL_JOB_ID_VCN_RING_TEST);
+       if (r)
+               return r;
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+@@ -838,7 +838,8 @@ int amdgpu_vm_update_pdes(struct amdgpu_
+       params.vm = vm;
+       params.immediate = immediate;
+-      r = vm->update_funcs->prepare(&params, NULL);
++      r = vm->update_funcs->prepare(&params, NULL,
++                                    AMDGPU_KERNEL_JOB_ID_VM_UPDATE_PDES);
+       if (r)
+               goto error;
+@@ -1007,7 +1008,8 @@ int amdgpu_vm_update_range(struct amdgpu
+               dma_fence_put(tmp);
+       }
+-      r = vm->update_funcs->prepare(&params, sync);
++      r = vm->update_funcs->prepare(&params, sync,
++                                    AMDGPU_KERNEL_JOB_ID_VM_UPDATE_RANGE);
+       if (r)
+               goto error_free;
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+@@ -305,7 +305,7 @@ struct amdgpu_vm_update_params {
+ struct amdgpu_vm_update_funcs {
+       int (*map_table)(struct amdgpu_bo_vm *bo);
+       int (*prepare)(struct amdgpu_vm_update_params *p,
+-                     struct amdgpu_sync *sync);
++                     struct amdgpu_sync *sync, u64 k_job_id);
+       int (*update)(struct amdgpu_vm_update_params *p,
+                     struct amdgpu_bo_vm *bo, uint64_t pe, uint64_t addr,
+                     unsigned count, uint32_t incr, uint64_t flags);
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
+@@ -42,12 +42,14 @@ static int amdgpu_vm_cpu_map_table(struc
+  *
+  * @p: see amdgpu_vm_update_params definition
+  * @sync: sync obj with fences to wait on
++ * @k_job_id: the id for tracing/debug purposes
+  *
+  * Returns:
+  * Negativ errno, 0 for success.
+  */
+ static int amdgpu_vm_cpu_prepare(struct amdgpu_vm_update_params *p,
+-                               struct amdgpu_sync *sync)
++                               struct amdgpu_sync *sync,
++                               u64 k_job_id)
+ {
+       if (!sync)
+               return 0;
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
+@@ -26,6 +26,7 @@
+ #include "amdgpu.h"
+ #include "amdgpu_trace.h"
+ #include "amdgpu_vm.h"
++#include "amdgpu_job.h"
+ /*
+  * amdgpu_vm_pt_cursor - state for for_each_amdgpu_vm_pt
+@@ -395,7 +396,8 @@ int amdgpu_vm_pt_clear(struct amdgpu_dev
+       params.vm = vm;
+       params.immediate = immediate;
+-      r = vm->update_funcs->prepare(&params, NULL);
++      r = vm->update_funcs->prepare(&params, NULL,
++                                    AMDGPU_KERNEL_JOB_ID_VM_PT_CLEAR);
+       if (r)
+               goto exit;
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
+@@ -40,7 +40,7 @@ static int amdgpu_vm_sdma_map_table(stru
+ /* Allocate a new job for @count PTE updates */
+ static int amdgpu_vm_sdma_alloc_job(struct amdgpu_vm_update_params *p,
+-                                  unsigned int count)
++                                  unsigned int count, u64 k_job_id)
+ {
+       enum amdgpu_ib_pool_type pool = p->immediate ? AMDGPU_IB_POOL_IMMEDIATE
+               : AMDGPU_IB_POOL_DELAYED;
+@@ -56,7 +56,7 @@ static int amdgpu_vm_sdma_alloc_job(stru
+       ndw = min(ndw, AMDGPU_VM_SDMA_MAX_NUM_DW);
+       r = amdgpu_job_alloc_with_ib(p->adev, entity, AMDGPU_FENCE_OWNER_VM,
+-                                   ndw * 4, pool, &p->job);
++                                   ndw * 4, pool, &p->job, k_job_id);
+       if (r)
+               return r;
+@@ -69,16 +69,17 @@ static int amdgpu_vm_sdma_alloc_job(stru
+  *
+  * @p: see amdgpu_vm_update_params definition
+  * @sync: amdgpu_sync object with fences to wait for
++ * @k_job_id: identifier of the job, for tracing purpose
+  *
+  * Returns:
+  * Negativ errno, 0 for success.
+  */
+ static int amdgpu_vm_sdma_prepare(struct amdgpu_vm_update_params *p,
+-                                struct amdgpu_sync *sync)
++                                struct amdgpu_sync *sync, u64 k_job_id)
+ {
+       int r;
+-      r = amdgpu_vm_sdma_alloc_job(p, 0);
++      r = amdgpu_vm_sdma_alloc_job(p, 0, k_job_id);
+       if (r)
+               return r;
+@@ -249,7 +250,8 @@ static int amdgpu_vm_sdma_update(struct
+                       if (r)
+                               return r;
+-                      r = amdgpu_vm_sdma_alloc_job(p, count);
++                      r = amdgpu_vm_sdma_alloc_job(p, count,
++                                                   AMDGPU_KERNEL_JOB_ID_VM_UPDATE);
+                       if (r)
+                               return r;
+               }
+--- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
+@@ -217,7 +217,8 @@ static int uvd_v6_0_enc_get_create_msg(s
+       int i, r;
+       r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL, ib_size_dw * 4,
+-                                   AMDGPU_IB_POOL_DIRECT, &job);
++                                   AMDGPU_IB_POOL_DIRECT, &job,
++                                   AMDGPU_KERNEL_JOB_ID_VCN_RING_TEST);
+       if (r)
+               return r;
+@@ -281,7 +282,8 @@ static int uvd_v6_0_enc_get_destroy_msg(
+       int i, r;
+       r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL, ib_size_dw * 4,
+-                                   AMDGPU_IB_POOL_DIRECT, &job);
++                                   AMDGPU_IB_POOL_DIRECT, &job,
++                                   AMDGPU_KERNEL_JOB_ID_VCN_RING_TEST);
+       if (r)
+               return r;
+--- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
+@@ -225,7 +225,8 @@ static int uvd_v7_0_enc_get_create_msg(s
+       int i, r;
+       r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL, ib_size_dw * 4,
+-                                   AMDGPU_IB_POOL_DIRECT, &job);
++                                   AMDGPU_IB_POOL_DIRECT, &job,
++                                   AMDGPU_KERNEL_JOB_ID_VCN_RING_TEST);
+       if (r)
+               return r;
+@@ -288,7 +289,8 @@ static int uvd_v7_0_enc_get_destroy_msg(
+       int i, r;
+       r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL, ib_size_dw * 4,
+-                                   AMDGPU_IB_POOL_DIRECT, &job);
++                                   AMDGPU_IB_POOL_DIRECT, &job,
++                                   AMDGPU_KERNEL_JOB_ID_VCN_RING_TEST);
+       if (r)
+               return r;
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
+@@ -68,7 +68,8 @@ svm_migrate_gart_map(struct amdgpu_ring
+                                    AMDGPU_FENCE_OWNER_UNDEFINED,
+                                    num_dw * 4 + num_bytes,
+                                    AMDGPU_IB_POOL_DELAYED,
+-                                   &job);
++                                   &job,
++                                   AMDGPU_KERNEL_JOB_ID_KFD_GART_MAP);
+       if (r)
+               return r;
diff --git a/queue-6.12/drm-amdgpu-respect-placement-requirements-in-amdgpu_gtt_mgr-functions.patch b/queue-6.12/drm-amdgpu-respect-placement-requirements-in-amdgpu_gtt_mgr-functions.patch
new file mode 100644 (file)
index 0000000..bd1d26e
--- /dev/null
@@ -0,0 +1,75 @@
+From stable+bounces-294155-greg=kroah.com@vger.kernel.org Fri Jul 31 19:25:03 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2026 12:39:01 -0400
+Subject: drm/amdgpu: Respect placement requirements in amdgpu_gtt_mgr functions
+To: stable@vger.kernel.org
+Cc: "Timur Kristóf" <timur.kristof@gmail.com>, "Christian König" <christian.koenig@amd.com>, "Alex Deucher" <alexander.deucher@amd.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260731163901.838294-1-sashal@kernel.org>
+
+From: Timur Kristóf <timur.kristof@gmail.com>
+
+[ Upstream commit 8882f8897e554053af9e72f4c2da8b1e2cce56c7 ]
+
+When testing intersection and compatibility, respect
+the actual placement requirements. This is a pre-requisite
+for ensuring that UVD CS BOs do not cross 256M segments.
+
+Fixes: ded910f368a5 ("drm/amdgpu: Implement intersect/compatible functions")
+Suggested-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit bc06579ca29dee9c245a41b12e39c7bb6938af5d)
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c |   30 ++++++++++++++++++++++++++--
+ 1 file changed, 28 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
+@@ -217,7 +217,20 @@ static bool amdgpu_gtt_mgr_intersects(st
+                                     const struct ttm_place *place,
+                                     size_t size)
+ {
+-      return !place->lpfn || amdgpu_gtt_mgr_has_gart_addr(res);
++      const struct drm_mm_node *const node = &to_ttm_range_mgr_node(res)->mm_nodes[0];
++      const u32 num_pages = PFN_UP(size);
++
++      if (!place->lpfn)
++              return true;
++
++      if (!amdgpu_gtt_mgr_has_gart_addr(res))
++              return false;
++
++      if (place->fpfn >= (node->start + num_pages) ||
++          (place->lpfn && place->lpfn <= node->start))
++              return false;
++
++      return true;
+ }
+ /**
+@@ -235,7 +248,20 @@ static bool amdgpu_gtt_mgr_compatible(st
+                                     const struct ttm_place *place,
+                                     size_t size)
+ {
+-      return !place->lpfn || amdgpu_gtt_mgr_has_gart_addr(res);
++      const struct drm_mm_node *const node = &to_ttm_range_mgr_node(res)->mm_nodes[0];
++      const u32 num_pages = PFN_UP(size);
++
++      if (!place->lpfn)
++              return true;
++
++      if (!amdgpu_gtt_mgr_has_gart_addr(res))
++              return false;
++
++      if (node->start < place->fpfn ||
++          (place->lpfn && (node->start + num_pages) > place->lpfn))
++              return false;
++
++      return true;
+ }
+ /**
diff --git a/queue-6.12/drm-exec-remove-the-index-parameter-from-drm_exec_for_each_locked_obj.patch b/queue-6.12/drm-exec-remove-the-index-parameter-from-drm_exec_for_each_locked_obj.patch
new file mode 100644 (file)
index 0000000..4f7505c
--- /dev/null
@@ -0,0 +1,195 @@
+From stable+bounces-294439-greg=kroah.com@vger.kernel.org Sun Aug  2 01:43:31 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat,  1 Aug 2026 19:43:19 -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: <20260801234320.1848118-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/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 ++++++++++++--------
+ 5 files changed, 19 insertions(+), 22 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+@@ -848,7 +848,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;
+@@ -969,7 +968,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;
+@@ -1207,7 +1206,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;
+@@ -1218,7 +1216,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;
+@@ -1286,7 +1284,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;
+@@ -1337,7 +1334,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/drm_exec.c
++++ b/drivers/gpu/drm/drm_exec.c
+@@ -22,7 +22,6 @@
+  *
+  *    struct drm_gem_object *obj;
+  *    struct drm_exec exec;
+- *    unsigned long index;
+  *    int ret;
+  *
+  *    drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
+@@ -38,7 +37,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);
+  *            ...
+  *    }
+@@ -54,9 +53,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
+@@ -1451,9 +1451,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
+@@ -418,7 +418,6 @@ int xe_vm_validate_rebind(struct xe_vm *
+                         unsigned int num_fences)
+ {
+       struct drm_gem_object *obj;
+-      unsigned long index;
+       int ret;
+       do {
+@@ -431,7 +430,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-6.12/drm-fb-helper-allocate-and-release-fb_info-in-single-place.patch b/queue-6.12/drm-fb-helper-allocate-and-release-fb_info-in-single-place.patch
new file mode 100644 (file)
index 0000000..992553e
--- /dev/null
@@ -0,0 +1,528 @@
+From stable+bounces-294034-greg=kroah.com@vger.kernel.org Fri Jul 31 13:13:59 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2026 07:10:51 -0400
+Subject: drm/fb-helper: Allocate and release fb_info in single place
+To: stable@vger.kernel.org
+Cc: "Thomas Zimmermann" <tzimmermann@suse.de>, "Christian König" <christian.koenig@amd.com>, "Dmitry Baryshkov" <dmitry.baryshkov@oss.qualcomm.com>, "Javier Martinez Canillas" <javierm@redhat.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260731111052.3596094-1-sashal@kernel.org>
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit 63c971af40365ee706c7e24f6a7900d693518f09 ]
+
+Move the calls to drm_fb_helper_alloc_info() from drivers into a
+single place in fbdev helpers. Allocates struct fb_info for a new
+framebuffer device. Then call drm_fb_helper_single_fb_probe() to
+create an fbdev screen buffer. Also release the instance on errors
+by calling drm_fb_helper_release_info().
+
+Simplifies the code and fixes the error cleanup for some of the
+drivers.
+
+Regular release of the struct fb_info instance still happens in
+drm_fb_helper_fini() as before.
+
+v2:
+- remove error rollback in driver implementations (kernel test robot)
+- initialize info in TTM implementation (kernel test robot)
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Acked-by: Christian König <christian.koenig@amd.com> # radeon
+Acked-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> # msm
+Acked-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://patch.msgid.link/20251027081245.80262-1-tzimmermann@suse.de
+Stable-dep-of: a18b6e30ecd6 ("drm/tegra: fbdev: Remove offset into framebuffer memory")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/armada/armada_fbdev.c      |   12 --------
+ drivers/gpu/drm/drm_fb_helper.c            |   39 ++++++++---------------------
+ drivers/gpu/drm/drm_fbdev_dma.c            |   12 +-------
+ drivers/gpu/drm/drm_fbdev_shmem.c          |   12 +-------
+ drivers/gpu/drm/drm_fbdev_ttm.c            |   12 +-------
+ drivers/gpu/drm/exynos/exynos_drm_fbdev.c  |    9 ------
+ drivers/gpu/drm/gma500/fbdev.c             |   13 ---------
+ drivers/gpu/drm/i915/display/intel_fbdev.c |    9 ------
+ drivers/gpu/drm/msm/msm_fbdev.c            |    9 ------
+ drivers/gpu/drm/omapdrm/omap_fbdev.c       |    9 ------
+ drivers/gpu/drm/radeon/radeon_fbdev.c      |   13 ---------
+ drivers/gpu/drm/tegra/fbdev.c              |    9 ------
+ include/drm/drm_fb_helper.h                |   12 --------
+ 13 files changed, 26 insertions(+), 144 deletions(-)
+
+--- a/drivers/gpu/drm/armada/armada_fbdev.c
++++ b/drivers/gpu/drm/armada/armada_fbdev.c
+@@ -43,10 +43,10 @@ static int armada_fbdev_create(struct dr
+       struct drm_fb_helper_surface_size *sizes)
+ {
+       struct drm_device *dev = fbh->dev;
++      struct fb_info *info = fbh->info;
+       struct drm_mode_fb_cmd2 mode;
+       struct armada_framebuffer *dfb;
+       struct armada_gem_object *obj;
+-      struct fb_info *info;
+       int size, ret;
+       void *ptr;
+@@ -87,12 +87,6 @@ static int armada_fbdev_create(struct dr
+       if (IS_ERR(dfb))
+               return PTR_ERR(dfb);
+-      info = drm_fb_helper_alloc_info(fbh);
+-      if (IS_ERR(info)) {
+-              ret = PTR_ERR(info);
+-              goto err_fballoc;
+-      }
+-
+       info->fbops = &armada_fb_ops;
+       info->fix.smem_start = obj->phys_addr;
+       info->fix.smem_len = obj->obj.size;
+@@ -107,10 +101,6 @@ static int armada_fbdev_create(struct dr
+               (unsigned long long)obj->phys_addr);
+       return 0;
+-
+- err_fballoc:
+-      dfb->fb.funcs->destroy(&dfb->fb);
+-      return ret;
+ }
+ static int armada_fb_probe(struct drm_fb_helper *fbh,
+--- a/drivers/gpu/drm/drm_fb_helper.c
++++ b/drivers/gpu/drm/drm_fb_helper.c
+@@ -485,20 +485,7 @@ int drm_fb_helper_init(struct drm_device
+ }
+ EXPORT_SYMBOL(drm_fb_helper_init);
+-/**
+- * drm_fb_helper_alloc_info - allocate fb_info and some of its members
+- * @fb_helper: driver-allocated fbdev helper
+- *
+- * A helper to alloc fb_info and the member cmap. Called by the driver
+- * within the struct &drm_driver.fbdev_probe callback function. Drivers do
+- * not need to release the allocated fb_info structure themselves, this is
+- * automatically done when calling drm_fb_helper_fini().
+- *
+- * RETURNS:
+- * fb_info pointer if things went okay, pointer containing error code
+- * otherwise
+- */
+-struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper)
++static struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper)
+ {
+       struct device *dev = fb_helper->dev->dev;
+       struct fb_info *info;
+@@ -525,17 +512,8 @@ err_release:
+       framebuffer_release(info);
+       return ERR_PTR(ret);
+ }
+-EXPORT_SYMBOL(drm_fb_helper_alloc_info);
+-/**
+- * drm_fb_helper_release_info - release fb_info and its members
+- * @fb_helper: driver-allocated fbdev helper
+- *
+- * A helper to release fb_info and the member cmap.  Drivers do not
+- * need to release the allocated fb_info structure themselves, this is
+- * automatically done when calling drm_fb_helper_fini().
+- */
+-void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper)
++static void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper)
+ {
+       struct fb_info *info = fb_helper->info;
+@@ -548,7 +526,6 @@ void drm_fb_helper_release_info(struct d
+               fb_dealloc_cmap(&info->cmap);
+       framebuffer_release(info);
+ }
+-EXPORT_SYMBOL(drm_fb_helper_release_info);
+ /**
+  * drm_fb_helper_unregister_info - unregister fb_info framebuffer device
+@@ -1803,6 +1780,11 @@ __drm_fb_helper_initial_config_and_unloc
+       height = dev->mode_config.max_height;
+       drm_client_modeset_probe(&fb_helper->client, width, height);
++
++      info = drm_fb_helper_alloc_info(fb_helper);
++      if (IS_ERR(info))
++              return PTR_ERR(info);
++
+       ret = drm_fb_helper_single_fb_probe(fb_helper);
+       if (ret < 0) {
+               if (ret == -EAGAIN) {
+@@ -1811,13 +1793,12 @@ __drm_fb_helper_initial_config_and_unloc
+               }
+               mutex_unlock(&fb_helper->lock);
+-              return ret;
++              goto err_drm_fb_helper_release_info;
+       }
+       drm_setup_crtcs_fb(fb_helper);
+       fb_helper->deferred_setup = false;
+-      info = fb_helper->info;
+       info->var.pixclock = 0;
+       /* Need to drop locks to avoid recursive deadlock in
+@@ -1840,6 +1821,10 @@ __drm_fb_helper_initial_config_and_unloc
+       mutex_unlock(&kernel_fb_helper_lock);
+       return 0;
++
++err_drm_fb_helper_release_info:
++      drm_fb_helper_release_info(fb_helper);
++      return ret;
+ }
+ /**
+--- a/drivers/gpu/drm/drm_fbdev_dma.c
++++ b/drivers/gpu/drm/drm_fbdev_dma.c
+@@ -280,9 +280,9 @@ int drm_fbdev_dma_driver_fbdev_probe(str
+ {
+       struct drm_client_dev *client = &fb_helper->client;
+       struct drm_device *dev = fb_helper->dev;
++      struct fb_info *info = fb_helper->info;
+       struct drm_client_buffer *buffer;
+       struct drm_framebuffer *fb;
+-      struct fb_info *info;
+       u32 format;
+       struct iosys_map map;
+       int ret;
+@@ -312,12 +312,6 @@ int drm_fbdev_dma_driver_fbdev_probe(str
+       fb_helper->buffer = buffer;
+       fb_helper->fb = fb;
+-      info = drm_fb_helper_alloc_info(fb_helper);
+-      if (IS_ERR(info)) {
+-              ret = PTR_ERR(info);
+-              goto err_drm_client_buffer_vunmap;
+-      }
+-
+       drm_fb_helper_fill_info(info, fb_helper, sizes);
+       if (fb->funcs->dirty)
+@@ -325,12 +319,10 @@ int drm_fbdev_dma_driver_fbdev_probe(str
+       else
+               ret = drm_fbdev_dma_driver_fbdev_probe_tail(fb_helper, sizes);
+       if (ret)
+-              goto err_drm_fb_helper_release_info;
++              goto err_drm_client_buffer_vunmap;
+       return 0;
+-err_drm_fb_helper_release_info:
+-      drm_fb_helper_release_info(fb_helper);
+ err_drm_client_buffer_vunmap:
+       fb_helper->fb = NULL;
+       fb_helper->buffer = NULL;
+--- a/drivers/gpu/drm/drm_fbdev_shmem.c
++++ b/drivers/gpu/drm/drm_fbdev_shmem.c
+@@ -110,10 +110,10 @@ static int drm_fbdev_shmem_helper_fb_pro
+ {
+       struct drm_client_dev *client = &fb_helper->client;
+       struct drm_device *dev = fb_helper->dev;
++      struct fb_info *info = fb_helper->info;
+       struct drm_client_buffer *buffer;
+       struct drm_gem_shmem_object *shmem;
+       struct drm_framebuffer *fb;
+-      struct fb_info *info;
+       u32 format;
+       struct iosys_map map;
+       int ret;
+@@ -142,12 +142,6 @@ static int drm_fbdev_shmem_helper_fb_pro
+       fb_helper->buffer = buffer;
+       fb_helper->fb = fb;
+-      info = drm_fb_helper_alloc_info(fb_helper);
+-      if (IS_ERR(info)) {
+-              ret = PTR_ERR(info);
+-              goto err_drm_client_buffer_vunmap;
+-      }
+-
+       drm_fb_helper_fill_info(info, fb_helper, sizes);
+       info->fbops = &drm_fbdev_shmem_fb_ops;
+@@ -168,12 +162,10 @@ static int drm_fbdev_shmem_helper_fb_pro
+       info->fbdefio = &fb_helper->fbdefio;
+       ret = fb_deferred_io_init(info);
+       if (ret)
+-              goto err_drm_fb_helper_release_info;
++              goto err_drm_client_buffer_vunmap;
+       return 0;
+-err_drm_fb_helper_release_info:
+-      drm_fb_helper_release_info(fb_helper);
+ err_drm_client_buffer_vunmap:
+       fb_helper->fb = NULL;
+       fb_helper->buffer = NULL;
+--- a/drivers/gpu/drm/drm_fbdev_ttm.c
++++ b/drivers/gpu/drm/drm_fbdev_ttm.c
+@@ -185,8 +185,8 @@ int drm_fbdev_ttm_driver_fbdev_probe(str
+ {
+       struct drm_client_dev *client = &fb_helper->client;
+       struct drm_device *dev = fb_helper->dev;
++      struct fb_info *info = fb_helper->info;
+       struct drm_client_buffer *buffer;
+-      struct fb_info *info;
+       size_t screen_size;
+       void *screen_buffer;
+       u32 format;
+@@ -214,12 +214,6 @@ int drm_fbdev_ttm_driver_fbdev_probe(str
+               goto err_drm_client_framebuffer_delete;
+       }
+-      info = drm_fb_helper_alloc_info(fb_helper);
+-      if (IS_ERR(info)) {
+-              ret = PTR_ERR(info);
+-              goto err_vfree;
+-      }
+-
+       drm_fb_helper_fill_info(info, fb_helper, sizes);
+       info->fbops = &drm_fbdev_ttm_fb_ops;
+@@ -236,12 +230,10 @@ int drm_fbdev_ttm_driver_fbdev_probe(str
+       info->fbdefio = &fb_helper->fbdefio;
+       ret = fb_deferred_io_init(info);
+       if (ret)
+-              goto err_drm_fb_helper_release_info;
++              goto err_vfree;
+       return 0;
+-err_drm_fb_helper_release_info:
+-      drm_fb_helper_release_info(fb_helper);
+ err_vfree:
+       vfree(screen_buffer);
+ err_drm_client_framebuffer_delete:
+--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+@@ -60,18 +60,11 @@ static int exynos_drm_fbdev_update(struc
+                                  struct drm_fb_helper_surface_size *sizes,
+                                  struct exynos_drm_gem *exynos_gem)
+ {
+-      struct fb_info *fbi;
++      struct fb_info *fbi = helper->info;
+       struct drm_framebuffer *fb = helper->fb;
+       unsigned int size = fb->width * fb->height * fb->format->cpp[0];
+       unsigned long offset;
+-      fbi = drm_fb_helper_alloc_info(helper);
+-      if (IS_ERR(fbi)) {
+-              DRM_DEV_ERROR(to_dma_dev(helper->dev),
+-                            "failed to allocate fb info.\n");
+-              return PTR_ERR(fbi);
+-      }
+-
+       fbi->fbops = &exynos_drm_fb_ops;
+       drm_fb_helper_fill_info(fbi, helper, sizes);
+--- a/drivers/gpu/drm/gma500/fbdev.c
++++ b/drivers/gpu/drm/gma500/fbdev.c
+@@ -110,7 +110,7 @@ static int psb_fbdev_fb_probe(struct drm
+       struct drm_device *dev = fb_helper->dev;
+       struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
+       struct pci_dev *pdev = to_pci_dev(dev->dev);
+-      struct fb_info *info;
++      struct fb_info *info = fb_helper->info;
+       struct drm_framebuffer *fb;
+       struct drm_mode_fb_cmd2 mode_cmd = { };
+       int size;
+@@ -165,12 +165,6 @@ static int psb_fbdev_fb_probe(struct drm
+       fb_helper->fb = fb;
+-      info = drm_fb_helper_alloc_info(fb_helper);
+-      if (IS_ERR(info)) {
+-              ret = PTR_ERR(info);
+-              goto err_drm_framebuffer_unregister_private;
+-      }
+-
+       info->fbops = &psb_fbdev_fb_ops;
+       /* Accessed stolen memory directly */
+@@ -194,11 +188,6 @@ static int psb_fbdev_fb_probe(struct drm
+       return 0;
+-err_drm_framebuffer_unregister_private:
+-      drm_framebuffer_unregister_private(fb);
+-      fb->obj[0] = NULL;
+-      drm_framebuffer_cleanup(fb);
+-      kfree(fb);
+ err_drm_gem_object_put:
+       drm_gem_object_put(obj);
+       return ret;
+--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
++++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
+@@ -183,7 +183,7 @@ static int intelfb_create(struct drm_fb_
+               .type = I915_GTT_VIEW_NORMAL,
+       };
+       intel_wakeref_t wakeref;
+-      struct fb_info *info;
++      struct fb_info *info = helper->info;
+       struct i915_vma *vma;
+       unsigned long flags = 0;
+       bool prealloc = false;
+@@ -236,13 +236,6 @@ static int intelfb_create(struct drm_fb_
+               goto out_unlock;
+       }
+-      info = drm_fb_helper_alloc_info(helper);
+-      if (IS_ERR(info)) {
+-              drm_err(&dev_priv->drm, "Failed to allocate fb_info (%pe)\n", info);
+-              ret = PTR_ERR(info);
+-              goto out_unpin;
+-      }
+-
+       ifbdev->helper.fb = &fb->base;
+       info->fbops = &intelfb_ops;
+--- a/drivers/gpu/drm/msm/msm_fbdev.c
++++ b/drivers/gpu/drm/msm/msm_fbdev.c
+@@ -70,9 +70,9 @@ static int msm_fbdev_create(struct drm_f
+ {
+       struct drm_device *dev = helper->dev;
+       struct msm_drm_private *priv = dev->dev_private;
++      struct fb_info *fbi = helper->info;
+       struct drm_framebuffer *fb = NULL;
+       struct drm_gem_object *bo;
+-      struct fb_info *fbi = NULL;
+       uint64_t paddr;
+       uint32_t format;
+       int ret, pitch;
+@@ -105,13 +105,6 @@ static int msm_fbdev_create(struct drm_f
+               goto fail;
+       }
+-      fbi = drm_fb_helper_alloc_info(helper);
+-      if (IS_ERR(fbi)) {
+-              DRM_DEV_ERROR(dev->dev, "failed to allocate fb info\n");
+-              ret = PTR_ERR(fbi);
+-              goto fail;
+-      }
+-
+       DBG("fbi=%p, dev=%p", fbi, dev);
+       helper->fb = fb;
+--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
++++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
+@@ -131,9 +131,9 @@ static int omap_fbdev_create(struct drm_
+       struct omap_fbdev *fbdev = to_omap_fbdev(helper);
+       struct drm_device *dev = helper->dev;
+       struct omap_drm_private *priv = dev->dev_private;
++      struct fb_info *fbi = helper->info;
+       struct drm_framebuffer *fb = NULL;
+       union omap_gem_size gsize;
+-      struct fb_info *fbi = NULL;
+       struct drm_mode_fb_cmd2 mode_cmd = {0};
+       struct drm_gem_object *bo;
+       dma_addr_t dma_addr;
+@@ -199,13 +199,6 @@ static int omap_fbdev_create(struct drm_
+               goto fail;
+       }
+-      fbi = drm_fb_helper_alloc_info(helper);
+-      if (IS_ERR(fbi)) {
+-              dev_err(dev->dev, "failed to allocate fb info\n");
+-              ret = PTR_ERR(fbi);
+-              goto fail;
+-      }
+-
+       DBG("fbi=%p, dev=%p", fbi, dev);
+       helper->fb = fb;
+--- a/drivers/gpu/drm/radeon/radeon_fbdev.c
++++ b/drivers/gpu/drm/radeon/radeon_fbdev.c
+@@ -207,7 +207,7 @@ static int radeon_fbdev_fb_helper_fb_pro
+ {
+       struct radeon_device *rdev = fb_helper->dev->dev_private;
+       struct drm_mode_fb_cmd2 mode_cmd = { };
+-      struct fb_info *info;
++      struct fb_info *info = fb_helper->info;
+       struct drm_gem_object *gobj;
+       struct radeon_bo *rbo;
+       struct drm_framebuffer *fb;
+@@ -245,13 +245,6 @@ static int radeon_fbdev_fb_helper_fb_pro
+       /* setup helper */
+       fb_helper->fb = fb;
+-      /* okay we have an object now allocate the framebuffer */
+-      info = drm_fb_helper_alloc_info(fb_helper);
+-      if (IS_ERR(info)) {
+-              ret = PTR_ERR(info);
+-              goto err_drm_framebuffer_unregister_private;
+-      }
+-
+       info->fbops = &radeon_fbdev_fb_ops;
+       /* radeon resume is fragile and needs a vt switch to help it along */
+@@ -277,10 +270,6 @@ static int radeon_fbdev_fb_helper_fb_pro
+       return 0;
+-err_drm_framebuffer_unregister_private:
+-      fb_helper->fb = NULL;
+-      drm_framebuffer_unregister_private(fb);
+-      drm_framebuffer_cleanup(fb);
+ err_kfree:
+       kfree(fb);
+ err_radeon_fbdev_destroy_pinned_object:
+--- a/drivers/gpu/drm/tegra/fbdev.c
++++ b/drivers/gpu/drm/tegra/fbdev.c
+@@ -72,10 +72,10 @@ static int tegra_fbdev_probe(struct drm_
+       struct tegra_drm *tegra = helper->dev->dev_private;
+       struct drm_device *drm = helper->dev;
+       struct drm_mode_fb_cmd2 cmd = { 0 };
++      struct fb_info *info = helper->info;
+       unsigned int bytes_per_pixel;
+       struct drm_framebuffer *fb;
+       unsigned long offset;
+-      struct fb_info *info;
+       struct tegra_bo *bo;
+       size_t size;
+       int err;
+@@ -96,13 +96,6 @@ static int tegra_fbdev_probe(struct drm_
+       if (IS_ERR(bo))
+               return PTR_ERR(bo);
+-      info = drm_fb_helper_alloc_info(helper);
+-      if (IS_ERR(info)) {
+-              dev_err(drm->dev, "failed to allocate framebuffer info\n");
+-              drm_gem_object_put(&bo->gem);
+-              return PTR_ERR(info);
+-      }
+-
+       fb = tegra_fb_alloc(drm, &cmd, &bo, 1);
+       if (IS_ERR(fb)) {
+               err = PTR_ERR(fb);
+--- a/include/drm/drm_fb_helper.h
++++ b/include/drm/drm_fb_helper.h
+@@ -246,8 +246,6 @@ int drm_fb_helper_check_var(struct fb_va
+ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper);
+-struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper);
+-void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper);
+ void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper);
+ void drm_fb_helper_fill_info(struct fb_info *info,
+                            struct drm_fb_helper *fb_helper,
+@@ -328,16 +326,6 @@ drm_fb_helper_restore_fbdev_mode_unlocke
+       return 0;
+ }
+-static inline struct fb_info *
+-drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper)
+-{
+-      return NULL;
+-}
+-
+-static inline void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper)
+-{
+-}
+-
+ static inline void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper)
+ {
+ }
diff --git a/queue-6.12/drm-i915-hdcp-move-to-using-intel_display-in-intel_hdcp.patch b/queue-6.12/drm-i915-hdcp-move-to-using-intel_display-in-intel_hdcp.patch
new file mode 100644 (file)
index 0000000..bcafffc
--- /dev/null
@@ -0,0 +1,2068 @@
+From stable+bounces-294456-greg=kroah.com@vger.kernel.org Sun Aug  2 03:50:28 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat,  1 Aug 2026 21:49:33 -0400
+Subject: drm/i915/hdcp: Move to using intel_display in intel_hdcp
+To: stable@vger.kernel.org
+Cc: Suraj Kandpal <suraj.kandpal@intel.com>, Jani Nikula <jani.nikula@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260802014934.510825-1-sashal@kernel.org>
+
+From: Suraj Kandpal <suraj.kandpal@intel.com>
+
+[ Upstream commit e35bf8f6a0ff06ceeff15bb032351cd5d006f92b ]
+
+Move to using intel_display wherever possible in intel_hdcp.c
+as a part of code refactor.
+
+--v2
+-Move intel_display to the first line wherever possible [Jani]
+-use the closest reference when using to_intel_display [Jani]
+
+Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com>
+Reviewed-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240911090540.643155-2-suraj.kandpal@intel.com
+Stable-dep-of: db9e64c983dc ("drm/i915/hdcp: require monotonically increasing seq_num_v")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/display/intel_hdcp.c             |  685 +++++++++---------
+ drivers/gpu/drm/i915/display/intel_hdcp_gsc.c         |    9 
+ drivers/gpu/drm/i915/display/intel_hdcp_gsc.h         |    5 
+ drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h |    3 
+ drivers/gpu/drm/xe/display/xe_hdcp_gsc.c              |    7 
+ 5 files changed, 361 insertions(+), 348 deletions(-)
+
+--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
++++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
+@@ -35,20 +35,20 @@ static void
+ intel_hdcp_disable_hdcp_line_rekeying(struct intel_encoder *encoder,
+                                     struct intel_hdcp *hdcp)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       /* Here we assume HDMI is in TMDS mode of operation */
+       if (encoder->type != INTEL_OUTPUT_HDMI)
+               return;
+-      if (DISPLAY_VER(dev_priv) >= 14) {
+-              if (IS_DISPLAY_VER_STEP(dev_priv, IP_VER(14, 0), STEP_D0, STEP_FOREVER))
+-                      intel_de_rmw(dev_priv, MTL_CHICKEN_TRANS(hdcp->cpu_transcoder),
++      if (DISPLAY_VER(display) >= 14) {
++              if (IS_DISPLAY_VER_STEP(display, IP_VER(14, 0), STEP_D0, STEP_FOREVER))
++                      intel_de_rmw(display, MTL_CHICKEN_TRANS(hdcp->cpu_transcoder),
+                                    0, HDCP_LINE_REKEY_DISABLE);
+-              else if (IS_DISPLAY_VER_STEP(dev_priv, IP_VER(14, 1), STEP_B0, STEP_FOREVER) ||
+-                       IS_DISPLAY_VER_STEP(dev_priv, IP_VER(20, 0), STEP_B0, STEP_FOREVER))
+-                      intel_de_rmw(dev_priv,
+-                                   TRANS_DDI_FUNC_CTL(dev_priv, hdcp->cpu_transcoder),
++              else if (IS_DISPLAY_VER_STEP(display, IP_VER(14, 1), STEP_B0, STEP_FOREVER) ||
++                       IS_DISPLAY_VER_STEP(display, IP_VER(20, 0), STEP_B0, STEP_FOREVER))
++                      intel_de_rmw(display,
++                                   TRANS_DDI_FUNC_CTL(display, hdcp->cpu_transcoder),
+                                    0, TRANS_DDI_HDCP_LINE_REKEY_DISABLE);
+       }
+ }
+@@ -95,10 +95,10 @@ static int
+ intel_hdcp_required_content_stream(struct intel_atomic_state *state,
+                                  struct intel_digital_port *dig_port)
+ {
++      struct intel_display *display = to_intel_display(state);
+       struct drm_connector_list_iter conn_iter;
+       struct intel_digital_port *conn_dig_port;
+       struct intel_connector *connector;
+-      struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+       struct hdcp_port_data *data = &dig_port->hdcp_port_data;
+       bool enforce_type0 = false;
+       int k;
+@@ -111,7 +111,7 @@ intel_hdcp_required_content_stream(struc
+       if (!dig_port->hdcp_mst_type1_capable)
+               enforce_type0 = true;
+-      drm_connector_list_iter_begin(&i915->drm, &conn_iter);
++      drm_connector_list_iter_begin(display->drm, &conn_iter);
+       for_each_intel_connector_iter(connector, &conn_iter) {
+               if (connector->base.status == connector_status_disconnected)
+                       continue;
+@@ -133,7 +133,7 @@ intel_hdcp_required_content_stream(struc
+       }
+       drm_connector_list_iter_end(&conn_iter);
+-      if (drm_WARN_ON(&i915->drm, data->k > INTEL_NUM_PIPES(i915) || data->k == 0))
++      if (drm_WARN_ON(display->drm, data->k > INTEL_NUM_PIPES(display) || data->k == 0))
+               return -EINVAL;
+       /*
+@@ -181,7 +181,7 @@ static
+ int intel_hdcp_read_valid_bksv(struct intel_digital_port *dig_port,
+                              const struct intel_hdcp_shim *shim, u8 *bksv)
+ {
+-      struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
++      struct intel_display *display = to_intel_display(dig_port);
+       int ret, i, tries = 2;
+       /* HDCP spec states that we must retry the bksv if it is invalid */
+@@ -193,7 +193,7 @@ int intel_hdcp_read_valid_bksv(struct in
+                       break;
+       }
+       if (i == tries) {
+-              drm_dbg_kms(&i915->drm, "Bksv is invalid\n");
++              drm_dbg_kms(display->drm, "Bksv is invalid\n");
+               return -ENODEV;
+       }
+@@ -232,7 +232,7 @@ bool intel_hdcp_get_capability(struct in
+  */
+ static bool intel_hdcp2_prerequisite(struct intel_connector *connector)
+ {
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_hdcp *hdcp = &connector->hdcp;
+       /* I915 support for HDCP2.2 */
+@@ -240,18 +240,18 @@ static bool intel_hdcp2_prerequisite(str
+               return false;
+       /* If MTL+ make sure gsc is loaded and proxy is setup */
+-      if (intel_hdcp_gsc_cs_required(i915)) {
+-              if (!intel_hdcp_gsc_check_status(i915))
++      if (intel_hdcp_gsc_cs_required(display)) {
++              if (!intel_hdcp_gsc_check_status(display))
+                       return false;
+       }
+       /* MEI/GSC interface is solid depending on which is used */
+-      mutex_lock(&i915->display.hdcp.hdcp_mutex);
+-      if (!i915->display.hdcp.comp_added ||  !i915->display.hdcp.arbiter) {
+-              mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++      mutex_lock(&display->hdcp.hdcp_mutex);
++      if (!display->hdcp.comp_added || !display->hdcp.arbiter) {
++              mutex_unlock(&display->hdcp.hdcp_mutex);
+               return false;
+       }
+-      mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++      mutex_unlock(&display->hdcp.hdcp_mutex);
+       return true;
+ }
+@@ -287,19 +287,19 @@ void intel_hdcp_get_remote_capability(st
+               *hdcp2_capable = false;
+ }
+-static bool intel_hdcp_in_use(struct drm_i915_private *i915,
++static bool intel_hdcp_in_use(struct intel_display *display,
+                             enum transcoder cpu_transcoder, enum port port)
+ {
+-      return intel_de_read(i915,
+-                           HDCP_STATUS(i915, cpu_transcoder, port)) &
++      return intel_de_read(display,
++                           HDCP_STATUS(display, cpu_transcoder, port)) &
+               HDCP_STATUS_ENC;
+ }
+-static bool intel_hdcp2_in_use(struct drm_i915_private *i915,
++static bool intel_hdcp2_in_use(struct intel_display *display,
+                              enum transcoder cpu_transcoder, enum port port)
+ {
+-      return intel_de_read(i915,
+-                           HDCP2_STATUS(i915, cpu_transcoder, port)) &
++      return intel_de_read(display,
++                           HDCP2_STATUS(display, cpu_transcoder, port)) &
+               LINK_ENCRYPTION_STATUS;
+ }
+@@ -324,8 +324,9 @@ static int intel_hdcp_poll_ksv_fifo(stru
+       return 0;
+ }
+-static bool hdcp_key_loadable(struct drm_i915_private *i915)
++static bool hdcp_key_loadable(struct intel_display *display)
+ {
++      struct drm_i915_private *i915 = to_i915(display->drm);
+       enum i915_power_well_id id;
+       intel_wakeref_t wakeref;
+       bool enabled = false;
+@@ -352,19 +353,20 @@ static bool hdcp_key_loadable(struct drm
+       return enabled;
+ }
+-static void intel_hdcp_clear_keys(struct drm_i915_private *i915)
++static void intel_hdcp_clear_keys(struct intel_display *display)
+ {
+-      intel_de_write(i915, HDCP_KEY_CONF, HDCP_CLEAR_KEYS_TRIGGER);
+-      intel_de_write(i915, HDCP_KEY_STATUS,
++      intel_de_write(display, HDCP_KEY_CONF, HDCP_CLEAR_KEYS_TRIGGER);
++      intel_de_write(display, HDCP_KEY_STATUS,
+                      HDCP_KEY_LOAD_DONE | HDCP_KEY_LOAD_STATUS | HDCP_FUSE_IN_PROGRESS | HDCP_FUSE_ERROR | HDCP_FUSE_DONE);
+ }
+-static int intel_hdcp_load_keys(struct drm_i915_private *i915)
++static int intel_hdcp_load_keys(struct intel_display *display)
+ {
++      struct drm_i915_private *i915 = to_i915(display->drm);
+       int ret;
+       u32 val;
+-      val = intel_de_read(i915, HDCP_KEY_STATUS);
++      val = intel_de_read(display, HDCP_KEY_STATUS);
+       if ((val & HDCP_KEY_LOAD_DONE) && (val & HDCP_KEY_LOAD_STATUS))
+               return 0;
+@@ -373,7 +375,7 @@ static int intel_hdcp_load_keys(struct d
+        * out of reset. So if Key is not already loaded, its an error state.
+        */
+       if (IS_HASWELL(i915) || IS_BROADWELL(i915))
+-              if (!(intel_de_read(i915, HDCP_KEY_STATUS) & HDCP_KEY_LOAD_DONE))
++              if (!(intel_de_read(display, HDCP_KEY_STATUS) & HDCP_KEY_LOAD_DONE))
+                       return -ENXIO;
+       /*
+@@ -384,20 +386,20 @@ static int intel_hdcp_load_keys(struct d
+        * process from other platforms. These platforms use the GT Driver
+        * Mailbox interface.
+        */
+-      if (DISPLAY_VER(i915) == 9 && !IS_BROXTON(i915)) {
++      if (DISPLAY_VER(display) == 9 && !IS_BROXTON(i915)) {
+               ret = snb_pcode_write(&i915->uncore, SKL_PCODE_LOAD_HDCP_KEYS, 1);
+               if (ret) {
+-                      drm_err(&i915->drm,
++                      drm_err(display->drm,
+                               "Failed to initiate HDCP key load (%d)\n",
+                               ret);
+                       return ret;
+               }
+       } else {
+-              intel_de_write(i915, HDCP_KEY_CONF, HDCP_KEY_LOAD_TRIGGER);
++              intel_de_write(display, HDCP_KEY_CONF, HDCP_KEY_LOAD_TRIGGER);
+       }
+       /* Wait for the keys to load (500us) */
+-      ret = intel_de_wait_custom(i915, HDCP_KEY_STATUS,
++      ret = intel_de_wait_custom(display, HDCP_KEY_STATUS,
+                                  HDCP_KEY_LOAD_DONE, HDCP_KEY_LOAD_DONE,
+                                  10, 1, &val);
+       if (ret)
+@@ -406,27 +408,27 @@ static int intel_hdcp_load_keys(struct d
+               return -ENXIO;
+       /* Send Aksv over to PCH display for use in authentication */
+-      intel_de_write(i915, HDCP_KEY_CONF, HDCP_AKSV_SEND_TRIGGER);
++      intel_de_write(display, HDCP_KEY_CONF, HDCP_AKSV_SEND_TRIGGER);
+       return 0;
+ }
+ /* Returns updated SHA-1 index */
+-static int intel_write_sha_text(struct drm_i915_private *i915, u32 sha_text)
++static int intel_write_sha_text(struct intel_display *display, u32 sha_text)
+ {
+-      intel_de_write(i915, HDCP_SHA_TEXT, sha_text);
+-      if (intel_de_wait_for_set(i915, HDCP_REP_CTL, HDCP_SHA1_READY, 1)) {
+-              drm_err(&i915->drm, "Timed out waiting for SHA1 ready\n");
++      intel_de_write(display, HDCP_SHA_TEXT, sha_text);
++      if (intel_de_wait_for_set(display, HDCP_REP_CTL, HDCP_SHA1_READY, 1)) {
++              drm_err(display->drm, "Timed out waiting for SHA1 ready\n");
+               return -ETIMEDOUT;
+       }
+       return 0;
+ }
+ static
+-u32 intel_hdcp_get_repeater_ctl(struct drm_i915_private *i915,
++u32 intel_hdcp_get_repeater_ctl(struct intel_display *display,
+                               enum transcoder cpu_transcoder, enum port port)
+ {
+-      if (DISPLAY_VER(i915) >= 12) {
++      if (DISPLAY_VER(display) >= 12) {
+               switch (cpu_transcoder) {
+               case TRANSCODER_A:
+                       return HDCP_TRANSA_REP_PRESENT |
+@@ -441,7 +443,7 @@ u32 intel_hdcp_get_repeater_ctl(struct d
+                       return HDCP_TRANSD_REP_PRESENT |
+                              HDCP_TRANSD_SHA1_M0;
+               default:
+-                      drm_err(&i915->drm, "Unknown transcoder %d\n",
++                      drm_err(display->drm, "Unknown transcoder %d\n",
+                               cpu_transcoder);
+                       return 0;
+               }
+@@ -459,7 +461,7 @@ u32 intel_hdcp_get_repeater_ctl(struct d
+       case PORT_E:
+               return HDCP_DDIE_REP_PRESENT | HDCP_DDIE_SHA1_M0;
+       default:
+-              drm_err(&i915->drm, "Unknown port %d\n", port);
++              drm_err(display->drm, "Unknown port %d\n", port);
+               return 0;
+       }
+ }
+@@ -469,8 +471,8 @@ int intel_hdcp_validate_v_prime(struct i
+                               const struct intel_hdcp_shim *shim,
+                               u8 *ksv_fifo, u8 num_downstream, u8 *bstatus)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       enum transcoder cpu_transcoder = connector->hdcp.cpu_transcoder;
+       enum port port = dig_port->base.port;
+       u32 vprime, sha_text, sha_leftovers, rep_ctl;
+@@ -481,7 +483,7 @@ int intel_hdcp_validate_v_prime(struct i
+               ret = shim->read_v_prime_part(dig_port, i, &vprime);
+               if (ret)
+                       return ret;
+-              intel_de_write(i915, HDCP_SHA_V_PRIME(i), vprime);
++              intel_de_write(display, HDCP_SHA_V_PRIME(i), vprime);
+       }
+       /*
+@@ -497,8 +499,8 @@ int intel_hdcp_validate_v_prime(struct i
+       sha_idx = 0;
+       sha_text = 0;
+       sha_leftovers = 0;
+-      rep_ctl = intel_hdcp_get_repeater_ctl(i915, cpu_transcoder, port);
+-      intel_de_write(i915, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32);
++      rep_ctl = intel_hdcp_get_repeater_ctl(display, cpu_transcoder, port);
++      intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32);
+       for (i = 0; i < num_downstream; i++) {
+               unsigned int sha_empty;
+               u8 *ksv = &ksv_fifo[i * DRM_HDCP_KSV_LEN];
+@@ -510,14 +512,14 @@ int intel_hdcp_validate_v_prime(struct i
+                       sha_text |= ksv[j] << off;
+               }
+-              ret = intel_write_sha_text(i915, sha_text);
++              ret = intel_write_sha_text(display, sha_text);
+               if (ret < 0)
+                       return ret;
+               /* Programming guide writes this every 64 bytes */
+               sha_idx += sizeof(sha_text);
+               if (!(sha_idx % 64))
+-                      intel_de_write(i915, HDCP_REP_CTL,
++                      intel_de_write(display, HDCP_REP_CTL,
+                                      rep_ctl | HDCP_SHA1_TEXT_32);
+               /* Store the leftover bytes from the ksv in sha_text */
+@@ -534,7 +536,7 @@ int intel_hdcp_validate_v_prime(struct i
+               if (sizeof(sha_text) > sha_leftovers)
+                       continue;
+-              ret = intel_write_sha_text(i915, sha_text);
++              ret = intel_write_sha_text(display, sha_text);
+               if (ret < 0)
+                       return ret;
+               sha_leftovers = 0;
+@@ -550,73 +552,73 @@ int intel_hdcp_validate_v_prime(struct i
+        */
+       if (sha_leftovers == 0) {
+               /* Write 16 bits of text, 16 bits of M0 */
+-              intel_de_write(i915, HDCP_REP_CTL,
++              intel_de_write(display, HDCP_REP_CTL,
+                              rep_ctl | HDCP_SHA1_TEXT_16);
+-              ret = intel_write_sha_text(i915,
++              ret = intel_write_sha_text(display,
+                                          bstatus[0] << 8 | bstatus[1]);
+               if (ret < 0)
+                       return ret;
+               sha_idx += sizeof(sha_text);
+               /* Write 32 bits of M0 */
+-              intel_de_write(i915, HDCP_REP_CTL,
++              intel_de_write(display, HDCP_REP_CTL,
+                              rep_ctl | HDCP_SHA1_TEXT_0);
+-              ret = intel_write_sha_text(i915, 0);
++              ret = intel_write_sha_text(display, 0);
+               if (ret < 0)
+                       return ret;
+               sha_idx += sizeof(sha_text);
+               /* Write 16 bits of M0 */
+-              intel_de_write(i915, HDCP_REP_CTL,
++              intel_de_write(display, HDCP_REP_CTL,
+                              rep_ctl | HDCP_SHA1_TEXT_16);
+-              ret = intel_write_sha_text(i915, 0);
++              ret = intel_write_sha_text(display, 0);
+               if (ret < 0)
+                       return ret;
+               sha_idx += sizeof(sha_text);
+       } else if (sha_leftovers == 1) {
+               /* Write 24 bits of text, 8 bits of M0 */
+-              intel_de_write(i915, HDCP_REP_CTL,
++              intel_de_write(display, HDCP_REP_CTL,
+                              rep_ctl | HDCP_SHA1_TEXT_24);
+               sha_text |= bstatus[0] << 16 | bstatus[1] << 8;
+               /* Only 24-bits of data, must be in the LSB */
+               sha_text = (sha_text & 0xffffff00) >> 8;
+-              ret = intel_write_sha_text(i915, sha_text);
++              ret = intel_write_sha_text(display, sha_text);
+               if (ret < 0)
+                       return ret;
+               sha_idx += sizeof(sha_text);
+               /* Write 32 bits of M0 */
+-              intel_de_write(i915, HDCP_REP_CTL,
++              intel_de_write(display, HDCP_REP_CTL,
+                              rep_ctl | HDCP_SHA1_TEXT_0);
+-              ret = intel_write_sha_text(i915, 0);
++              ret = intel_write_sha_text(display, 0);
+               if (ret < 0)
+                       return ret;
+               sha_idx += sizeof(sha_text);
+               /* Write 24 bits of M0 */
+-              intel_de_write(i915, HDCP_REP_CTL,
++              intel_de_write(display, HDCP_REP_CTL,
+                              rep_ctl | HDCP_SHA1_TEXT_8);
+-              ret = intel_write_sha_text(i915, 0);
++              ret = intel_write_sha_text(display, 0);
+               if (ret < 0)
+                       return ret;
+               sha_idx += sizeof(sha_text);
+       } else if (sha_leftovers == 2) {
+               /* Write 32 bits of text */
+-              intel_de_write(i915, HDCP_REP_CTL,
++              intel_de_write(display, HDCP_REP_CTL,
+                              rep_ctl | HDCP_SHA1_TEXT_32);
+               sha_text |= bstatus[0] << 8 | bstatus[1];
+-              ret = intel_write_sha_text(i915, sha_text);
++              ret = intel_write_sha_text(display, sha_text);
+               if (ret < 0)
+                       return ret;
+               sha_idx += sizeof(sha_text);
+               /* Write 64 bits of M0 */
+-              intel_de_write(i915, HDCP_REP_CTL,
++              intel_de_write(display, HDCP_REP_CTL,
+                              rep_ctl | HDCP_SHA1_TEXT_0);
+               for (i = 0; i < 2; i++) {
+-                      ret = intel_write_sha_text(i915, 0);
++                      ret = intel_write_sha_text(display, 0);
+                       if (ret < 0)
+                               return ret;
+                       sha_idx += sizeof(sha_text);
+@@ -626,56 +628,56 @@ int intel_hdcp_validate_v_prime(struct i
+                * Terminate the SHA-1 stream by hand. For the other leftover
+                * cases this is appended by the hardware.
+                */
+-              intel_de_write(i915, HDCP_REP_CTL,
++              intel_de_write(display, HDCP_REP_CTL,
+                              rep_ctl | HDCP_SHA1_TEXT_32);
+               sha_text = DRM_HDCP_SHA1_TERMINATOR << 24;
+-              ret = intel_write_sha_text(i915, sha_text);
++              ret = intel_write_sha_text(display, sha_text);
+               if (ret < 0)
+                       return ret;
+               sha_idx += sizeof(sha_text);
+       } else if (sha_leftovers == 3) {
+               /* Write 32 bits of text (filled from LSB) */
+-              intel_de_write(i915, HDCP_REP_CTL,
++              intel_de_write(display, HDCP_REP_CTL,
+                              rep_ctl | HDCP_SHA1_TEXT_32);
+               sha_text |= bstatus[0];
+-              ret = intel_write_sha_text(i915, sha_text);
++              ret = intel_write_sha_text(display, sha_text);
+               if (ret < 0)
+                       return ret;
+               sha_idx += sizeof(sha_text);
+               /* Write 8 bits of text (filled from LSB), 24 bits of M0 */
+-              intel_de_write(i915, HDCP_REP_CTL,
++              intel_de_write(display, HDCP_REP_CTL,
+                              rep_ctl | HDCP_SHA1_TEXT_8);
+-              ret = intel_write_sha_text(i915, bstatus[1]);
++              ret = intel_write_sha_text(display, bstatus[1]);
+               if (ret < 0)
+                       return ret;
+               sha_idx += sizeof(sha_text);
+               /* Write 32 bits of M0 */
+-              intel_de_write(i915, HDCP_REP_CTL,
++              intel_de_write(display, HDCP_REP_CTL,
+                              rep_ctl | HDCP_SHA1_TEXT_0);
+-              ret = intel_write_sha_text(i915, 0);
++              ret = intel_write_sha_text(display, 0);
+               if (ret < 0)
+                       return ret;
+               sha_idx += sizeof(sha_text);
+               /* Write 8 bits of M0 */
+-              intel_de_write(i915, HDCP_REP_CTL,
++              intel_de_write(display, HDCP_REP_CTL,
+                              rep_ctl | HDCP_SHA1_TEXT_24);
+-              ret = intel_write_sha_text(i915, 0);
++              ret = intel_write_sha_text(display, 0);
+               if (ret < 0)
+                       return ret;
+               sha_idx += sizeof(sha_text);
+       } else {
+-              drm_dbg_kms(&i915->drm, "Invalid number of leftovers %d\n",
++              drm_dbg_kms(display->drm, "Invalid number of leftovers %d\n",
+                           sha_leftovers);
+               return -EINVAL;
+       }
+-      intel_de_write(i915, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32);
++      intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32);
+       /* Fill up to 64-4 bytes with zeros (leave the last write for length) */
+       while ((sha_idx % 64) < (64 - sizeof(sha_text))) {
+-              ret = intel_write_sha_text(i915, 0);
++              ret = intel_write_sha_text(display, 0);
+               if (ret < 0)
+                       return ret;
+               sha_idx += sizeof(sha_text);
+@@ -687,20 +689,20 @@ int intel_hdcp_validate_v_prime(struct i
+        *  - 10 bytes for BINFO/BSTATUS(2), M0(8)
+        */
+       sha_text = (num_downstream * 5 + 10) * 8;
+-      ret = intel_write_sha_text(i915, sha_text);
++      ret = intel_write_sha_text(display, sha_text);
+       if (ret < 0)
+               return ret;
+       /* Tell the HW we're done with the hash and wait for it to ACK */
+-      intel_de_write(i915, HDCP_REP_CTL,
++      intel_de_write(display, HDCP_REP_CTL,
+                      rep_ctl | HDCP_SHA1_COMPLETE_HASH);
+-      if (intel_de_wait_for_set(i915, HDCP_REP_CTL,
++      if (intel_de_wait_for_set(display, HDCP_REP_CTL,
+                                 HDCP_SHA1_COMPLETE, 1)) {
+-              drm_err(&i915->drm, "Timed out waiting for SHA1 complete\n");
++              drm_err(display->drm, "Timed out waiting for SHA1 complete\n");
+               return -ETIMEDOUT;
+       }
+-      if (!(intel_de_read(i915, HDCP_REP_CTL) & HDCP_SHA1_V_MATCH)) {
+-              drm_dbg_kms(&i915->drm, "SHA-1 mismatch, HDCP failed\n");
++      if (!(intel_de_read(display, HDCP_REP_CTL) & HDCP_SHA1_V_MATCH)) {
++              drm_dbg_kms(display->drm, "SHA-1 mismatch, HDCP failed\n");
+               return -ENXIO;
+       }
+@@ -711,15 +713,15 @@ int intel_hdcp_validate_v_prime(struct i
+ static
+ int intel_hdcp_auth_downstream(struct intel_connector *connector)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       const struct intel_hdcp_shim *shim = connector->hdcp.shim;
+       u8 bstatus[2], num_downstream, *ksv_fifo;
+       int ret, i, tries = 3;
+       ret = intel_hdcp_poll_ksv_fifo(dig_port, shim);
+       if (ret) {
+-              drm_dbg_kms(&i915->drm,
++              drm_dbg_kms(display->drm,
+                           "KSV list failed to become ready (%d)\n", ret);
+               return ret;
+       }
+@@ -730,7 +732,7 @@ int intel_hdcp_auth_downstream(struct in
+       if (DRM_HDCP_MAX_DEVICE_EXCEEDED(bstatus[0]) ||
+           DRM_HDCP_MAX_CASCADE_EXCEEDED(bstatus[1])) {
+-              drm_dbg_kms(&i915->drm, "Max Topology Limit Exceeded\n");
++              drm_dbg_kms(display->drm, "Max Topology Limit Exceeded\n");
+               return -EPERM;
+       }
+@@ -743,14 +745,14 @@ int intel_hdcp_auth_downstream(struct in
+        */
+       num_downstream = DRM_HDCP_NUM_DOWNSTREAM(bstatus[0]);
+       if (num_downstream == 0) {
+-              drm_dbg_kms(&i915->drm,
++              drm_dbg_kms(display->drm,
+                           "Repeater with zero downstream devices\n");
+               return -EINVAL;
+       }
+       ksv_fifo = kcalloc(DRM_HDCP_KSV_LEN, num_downstream, GFP_KERNEL);
+       if (!ksv_fifo) {
+-              drm_dbg_kms(&i915->drm, "Out of mem: ksv_fifo\n");
++              drm_dbg_kms(display->drm, "Out of mem: ksv_fifo\n");
+               return -ENOMEM;
+       }
+@@ -758,9 +760,9 @@ int intel_hdcp_auth_downstream(struct in
+       if (ret)
+               goto err;
+-      if (drm_hdcp_check_ksvs_revoked(&i915->drm, ksv_fifo,
++      if (drm_hdcp_check_ksvs_revoked(display->drm, ksv_fifo,
+                                       num_downstream) > 0) {
+-              drm_err(&i915->drm, "Revoked Ksv(s) in ksv_fifo\n");
++              drm_err(display->drm, "Revoked Ksv(s) in ksv_fifo\n");
+               ret = -EPERM;
+               goto err;
+       }
+@@ -778,12 +780,12 @@ int intel_hdcp_auth_downstream(struct in
+       }
+       if (i == tries) {
+-              drm_dbg_kms(&i915->drm,
++              drm_dbg_kms(display->drm,
+                           "V Prime validation failed.(%d)\n", ret);
+               goto err;
+       }
+-      drm_dbg_kms(&i915->drm, "HDCP is enabled (%d downstream devices)\n",
++      drm_dbg_kms(display->drm, "HDCP is enabled (%d downstream devices)\n",
+                   num_downstream);
+       ret = 0;
+ err:
+@@ -794,8 +796,8 @@ err:
+ /* Implements Part 1 of the HDCP authorization procedure */
+ static int intel_hdcp_auth(struct intel_connector *connector)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct intel_hdcp *hdcp = &connector->hdcp;
+       const struct intel_hdcp_shim *shim = hdcp->shim;
+       enum transcoder cpu_transcoder = connector->hdcp.cpu_transcoder;
+@@ -827,7 +829,7 @@ static int intel_hdcp_auth(struct intel_
+               if (ret)
+                       return ret;
+               if (!hdcp_capable) {
+-                      drm_dbg_kms(&i915->drm,
++                      drm_dbg_kms(display->drm,
+                                   "Panel is not HDCP capable\n");
+                       return -EINVAL;
+               }
+@@ -835,24 +837,24 @@ static int intel_hdcp_auth(struct intel_
+       /* Initialize An with 2 random values and acquire it */
+       for (i = 0; i < 2; i++)
+-              intel_de_write(i915,
+-                             HDCP_ANINIT(i915, cpu_transcoder, port),
++              intel_de_write(display,
++                             HDCP_ANINIT(display, cpu_transcoder, port),
+                              get_random_u32());
+-      intel_de_write(i915, HDCP_CONF(i915, cpu_transcoder, port),
++      intel_de_write(display, HDCP_CONF(display, cpu_transcoder, port),
+                      HDCP_CONF_CAPTURE_AN);
+       /* Wait for An to be acquired */
+-      if (intel_de_wait_for_set(i915,
+-                                HDCP_STATUS(i915, cpu_transcoder, port),
++      if (intel_de_wait_for_set(display,
++                                HDCP_STATUS(display, cpu_transcoder, port),
+                                 HDCP_STATUS_AN_READY, 1)) {
+-              drm_err(&i915->drm, "Timed out waiting for An\n");
++              drm_err(display->drm, "Timed out waiting for An\n");
+               return -ETIMEDOUT;
+       }
+-      an.reg[0] = intel_de_read(i915,
+-                                HDCP_ANLO(i915, cpu_transcoder, port));
+-      an.reg[1] = intel_de_read(i915,
+-                                HDCP_ANHI(i915, cpu_transcoder, port));
++      an.reg[0] = intel_de_read(display,
++                                HDCP_ANLO(display, cpu_transcoder, port));
++      an.reg[1] = intel_de_read(display,
++                                HDCP_ANHI(display, cpu_transcoder, port));
+       ret = shim->write_an_aksv(dig_port, an.shim);
+       if (ret)
+               return ret;
+@@ -865,34 +867,34 @@ static int intel_hdcp_auth(struct intel_
+       if (ret < 0)
+               return ret;
+-      if (drm_hdcp_check_ksvs_revoked(&i915->drm, bksv.shim, 1) > 0) {
+-              drm_err(&i915->drm, "BKSV is revoked\n");
++      if (drm_hdcp_check_ksvs_revoked(display->drm, bksv.shim, 1) > 0) {
++              drm_err(display->drm, "BKSV is revoked\n");
+               return -EPERM;
+       }
+-      intel_de_write(i915, HDCP_BKSVLO(i915, cpu_transcoder, port),
++      intel_de_write(display, HDCP_BKSVLO(display, cpu_transcoder, port),
+                      bksv.reg[0]);
+-      intel_de_write(i915, HDCP_BKSVHI(i915, cpu_transcoder, port),
++      intel_de_write(display, HDCP_BKSVHI(display, cpu_transcoder, port),
+                      bksv.reg[1]);
+       ret = shim->repeater_present(dig_port, &repeater_present);
+       if (ret)
+               return ret;
+       if (repeater_present)
+-              intel_de_write(i915, HDCP_REP_CTL,
+-                             intel_hdcp_get_repeater_ctl(i915, cpu_transcoder, port));
++              intel_de_write(display, HDCP_REP_CTL,
++                             intel_hdcp_get_repeater_ctl(display, cpu_transcoder, port));
+       ret = shim->toggle_signalling(dig_port, cpu_transcoder, true);
+       if (ret)
+               return ret;
+-      intel_de_write(i915, HDCP_CONF(i915, cpu_transcoder, port),
++      intel_de_write(display, HDCP_CONF(display, cpu_transcoder, port),
+                      HDCP_CONF_AUTH_AND_ENC);
+       /* Wait for R0 ready */
+-      if (wait_for(intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)) &
++      if (wait_for(intel_de_read(display, HDCP_STATUS(display, cpu_transcoder, port)) &
+                    (HDCP_STATUS_R0_READY | HDCP_STATUS_ENC), 1)) {
+-              drm_err(&i915->drm, "Timed out waiting for R0 ready\n");
++              drm_err(display->drm, "Timed out waiting for R0 ready\n");
+               return -ETIMEDOUT;
+       }
+@@ -918,30 +920,30 @@ static int intel_hdcp_auth(struct intel_
+               ret = shim->read_ri_prime(dig_port, ri.shim);
+               if (ret)
+                       return ret;
+-              intel_de_write(i915,
+-                             HDCP_RPRIME(i915, cpu_transcoder, port),
++              intel_de_write(display,
++                             HDCP_RPRIME(display, cpu_transcoder, port),
+                              ri.reg);
+               /* Wait for Ri prime match */
+-              if (!wait_for(intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)) &
++              if (!wait_for(intel_de_read(display, HDCP_STATUS(display, cpu_transcoder, port)) &
+                             (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1))
+                       break;
+       }
+       if (i == tries) {
+-              drm_dbg_kms(&i915->drm,
++              drm_dbg_kms(display->drm,
+                           "Timed out waiting for Ri prime match (%x)\n",
+-                          intel_de_read(i915,
+-                                        HDCP_STATUS(i915, cpu_transcoder, port)));
++                          intel_de_read(display,
++                                        HDCP_STATUS(display, cpu_transcoder, port)));
+               return -ETIMEDOUT;
+       }
+       /* Wait for encryption confirmation */
+-      if (intel_de_wait_for_set(i915,
+-                                HDCP_STATUS(i915, cpu_transcoder, port),
++      if (intel_de_wait_for_set(display,
++                                HDCP_STATUS(display, cpu_transcoder, port),
+                                 HDCP_STATUS_ENC,
+                                 HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
+-              drm_err(&i915->drm, "Timed out waiting for encryption\n");
++              drm_err(display->drm, "Timed out waiting for encryption\n");
+               return -ETIMEDOUT;
+       }
+@@ -949,42 +951,42 @@ static int intel_hdcp_auth(struct intel_
+       if (shim->stream_encryption) {
+               ret = shim->stream_encryption(connector, true);
+               if (ret) {
+-                      drm_err(&i915->drm, "[CONNECTOR:%d:%s] Failed to enable HDCP 1.4 stream enc\n",
++                      drm_err(display->drm, "[CONNECTOR:%d:%s] Failed to enable HDCP 1.4 stream enc\n",
+                               connector->base.base.id, connector->base.name);
+                       return ret;
+               }
+-              drm_dbg_kms(&i915->drm, "HDCP 1.4 transcoder: %s stream encrypted\n",
++              drm_dbg_kms(display->drm, "HDCP 1.4 transcoder: %s stream encrypted\n",
+                           transcoder_name(hdcp->stream_transcoder));
+       }
+       if (repeater_present)
+               return intel_hdcp_auth_downstream(connector);
+-      drm_dbg_kms(&i915->drm, "HDCP is enabled (no repeater present)\n");
++      drm_dbg_kms(display->drm, "HDCP is enabled (no repeater present)\n");
+       return 0;
+ }
+ static int _intel_hdcp_disable(struct intel_connector *connector)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct intel_hdcp *hdcp = &connector->hdcp;
+       enum port port = dig_port->base.port;
+       enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
+       u32 repeater_ctl;
+       int ret;
+-      drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] HDCP is being disabled...\n",
++      drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP is being disabled...\n",
+                   connector->base.base.id, connector->base.name);
+       if (hdcp->shim->stream_encryption) {
+               ret = hdcp->shim->stream_encryption(connector, false);
+               if (ret) {
+-                      drm_err(&i915->drm, "[CONNECTOR:%d:%s] Failed to disable HDCP 1.4 stream enc\n",
++                      drm_err(display->drm, "[CONNECTOR:%d:%s] Failed to disable HDCP 1.4 stream enc\n",
+                               connector->base.base.id, connector->base.name);
+                       return ret;
+               }
+-              drm_dbg_kms(&i915->drm, "HDCP 1.4 transcoder: %s stream encryption disabled\n",
++              drm_dbg_kms(display->drm, "HDCP 1.4 transcoder: %s stream encryption disabled\n",
+                           transcoder_name(hdcp->stream_transcoder));
+               /*
+                * If there are other connectors on this port using HDCP,
+@@ -996,51 +998,51 @@ static int _intel_hdcp_disable(struct in
+       }
+       hdcp->hdcp_encrypted = false;
+-      intel_de_write(i915, HDCP_CONF(i915, cpu_transcoder, port), 0);
+-      if (intel_de_wait_for_clear(i915,
+-                                  HDCP_STATUS(i915, cpu_transcoder, port),
++      intel_de_write(display, HDCP_CONF(display, cpu_transcoder, port), 0);
++      if (intel_de_wait_for_clear(display,
++                                  HDCP_STATUS(display, cpu_transcoder, port),
+                                   ~0, HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
+-              drm_err(&i915->drm,
++              drm_err(display->drm,
+                       "Failed to disable HDCP, timeout clearing status\n");
+               return -ETIMEDOUT;
+       }
+-      repeater_ctl = intel_hdcp_get_repeater_ctl(i915, cpu_transcoder,
++      repeater_ctl = intel_hdcp_get_repeater_ctl(display, cpu_transcoder,
+                                                  port);
+-      intel_de_rmw(i915, HDCP_REP_CTL, repeater_ctl, 0);
++      intel_de_rmw(display, HDCP_REP_CTL, repeater_ctl, 0);
+       ret = hdcp->shim->toggle_signalling(dig_port, cpu_transcoder, false);
+       if (ret) {
+-              drm_err(&i915->drm, "Failed to disable HDCP signalling\n");
++              drm_err(display->drm, "Failed to disable HDCP signalling\n");
+               return ret;
+       }
+-      drm_dbg_kms(&i915->drm, "HDCP is disabled\n");
++      drm_dbg_kms(display->drm, "HDCP is disabled\n");
+       return 0;
+ }
+ static int intel_hdcp1_enable(struct intel_connector *connector)
+ {
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_hdcp *hdcp = &connector->hdcp;
+       int i, ret, tries = 3;
+-      drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] HDCP is being enabled...\n",
++      drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP is being enabled...\n",
+                   connector->base.base.id, connector->base.name);
+-      if (!hdcp_key_loadable(i915)) {
+-              drm_err(&i915->drm, "HDCP key Load is not possible\n");
++      if (!hdcp_key_loadable(display)) {
++              drm_err(display->drm, "HDCP key Load is not possible\n");
+               return -ENXIO;
+       }
+       for (i = 0; i < KEY_LOAD_TRIES; i++) {
+-              ret = intel_hdcp_load_keys(i915);
++              ret = intel_hdcp_load_keys(display);
+               if (!ret)
+                       break;
+-              intel_hdcp_clear_keys(i915);
++              intel_hdcp_clear_keys(display);
+       }
+       if (ret) {
+-              drm_err(&i915->drm, "Could not load HDCP keys, (%d)\n",
++              drm_err(display->drm, "Could not load HDCP keys, (%d)\n",
+                       ret);
+               return ret;
+       }
+@@ -1053,13 +1055,13 @@ static int intel_hdcp1_enable(struct int
+                       return 0;
+               }
+-              drm_dbg_kms(&i915->drm, "HDCP Auth failure (%d)\n", ret);
++              drm_dbg_kms(display->drm, "HDCP Auth failure (%d)\n", ret);
+               /* Ensuring HDCP encryption and signalling are stopped. */
+               _intel_hdcp_disable(connector);
+       }
+-      drm_dbg_kms(&i915->drm,
++      drm_dbg_kms(display->drm,
+                   "HDCP authentication failed (%d tries/%d)\n", tries, ret);
+       return ret;
+ }
+@@ -1072,20 +1074,20 @@ static struct intel_connector *intel_hdc
+ static void intel_hdcp_update_value(struct intel_connector *connector,
+                                   u64 value, bool update_property)
+ {
+-      struct drm_device *dev = connector->base.dev;
++      struct intel_display *display = to_intel_display(connector);
++      struct drm_i915_private *i915 = to_i915(display->drm);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+       struct intel_hdcp *hdcp = &connector->hdcp;
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+-      drm_WARN_ON(connector->base.dev, !mutex_is_locked(&hdcp->mutex));
++      drm_WARN_ON(display->drm, !mutex_is_locked(&hdcp->mutex));
+       if (hdcp->value == value)
+               return;
+-      drm_WARN_ON(dev, !mutex_is_locked(&dig_port->hdcp_mutex));
++      drm_WARN_ON(display->drm, !mutex_is_locked(&dig_port->hdcp_mutex));
+       if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
+-              if (!drm_WARN_ON(dev, dig_port->num_hdcp_streams == 0))
++              if (!drm_WARN_ON(display->drm, dig_port->num_hdcp_streams == 0))
+                       dig_port->num_hdcp_streams--;
+       } else if (value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
+               dig_port->num_hdcp_streams++;
+@@ -1102,8 +1104,8 @@ static void intel_hdcp_update_value(stru
+ /* Implements Part 3 of the HDCP authorization procedure */
+ static int intel_hdcp_check_link(struct intel_connector *connector)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct intel_hdcp *hdcp = &connector->hdcp;
+       enum port port = dig_port->base.port;
+       enum transcoder cpu_transcoder;
+@@ -1121,12 +1123,12 @@ static int intel_hdcp_check_link(struct
+               goto out;
+       }
+-      if (drm_WARN_ON(&i915->drm,
+-                      !intel_hdcp_in_use(i915, cpu_transcoder, port))) {
+-              drm_err(&i915->drm,
++      if (drm_WARN_ON(display->drm,
++                      !intel_hdcp_in_use(display, cpu_transcoder, port))) {
++              drm_err(display->drm,
+                       "[CONNECTOR:%d:%s] HDCP link stopped encryption,%x\n",
+                       connector->base.base.id, connector->base.name,
+-                      intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)));
++                      intel_de_read(display, HDCP_STATUS(display, cpu_transcoder, port)));
+               ret = -ENXIO;
+               intel_hdcp_update_value(connector,
+                                       DRM_MODE_CONTENT_PROTECTION_DESIRED,
+@@ -1142,13 +1144,13 @@ static int intel_hdcp_check_link(struct
+               goto out;
+       }
+-      drm_dbg_kms(&i915->drm,
++      drm_dbg_kms(display->drm,
+                   "[CONNECTOR:%d:%s] HDCP link failed, retrying authentication\n",
+                   connector->base.base.id, connector->base.name);
+       ret = _intel_hdcp_disable(connector);
+       if (ret) {
+-              drm_err(&i915->drm, "Failed to disable hdcp (%d)\n", ret);
++              drm_err(display->drm, "Failed to disable hdcp (%d)\n", ret);
+               intel_hdcp_update_value(connector,
+                                       DRM_MODE_CONTENT_PROTECTION_DESIRED,
+                                       true);
+@@ -1169,9 +1171,9 @@ static void intel_hdcp_prop_work(struct
+       struct intel_hdcp *hdcp = container_of(work, struct intel_hdcp,
+                                              prop_work);
+       struct intel_connector *connector = intel_hdcp_to_connector(hdcp);
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
++      struct intel_display *display = to_intel_display(connector);
+-      drm_modeset_lock(&i915->drm.mode_config.connection_mutex, NULL);
++      drm_modeset_lock(&display->drm->mode_config.connection_mutex, NULL);
+       mutex_lock(&hdcp->mutex);
+       /*
+@@ -1184,7 +1186,7 @@ static void intel_hdcp_prop_work(struct
+                                                  hdcp->value);
+       mutex_unlock(&hdcp->mutex);
+-      drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
++      drm_modeset_unlock(&display->drm->mode_config.connection_mutex);
+       drm_connector_put(&connector->base);
+ }
+@@ -1199,25 +1201,25 @@ static int
+ hdcp2_prepare_ake_init(struct intel_connector *connector,
+                      struct hdcp2_ake_init *ake_data)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+       struct hdcp_port_data *data = &dig_port->hdcp_port_data;
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct i915_hdcp_arbiter *arbiter;
+       int ret;
+-      mutex_lock(&i915->display.hdcp.hdcp_mutex);
+-      arbiter = i915->display.hdcp.arbiter;
++      mutex_lock(&display->hdcp.hdcp_mutex);
++      arbiter = display->hdcp.arbiter;
+       if (!arbiter || !arbiter->ops) {
+-              mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++              mutex_unlock(&display->hdcp.hdcp_mutex);
+               return -EINVAL;
+       }
+       ret = arbiter->ops->initiate_hdcp2_session(arbiter->hdcp_dev, data, ake_data);
+       if (ret)
+-              drm_dbg_kms(&i915->drm, "Prepare_ake_init failed. %d\n",
++              drm_dbg_kms(display->drm, "Prepare_ake_init failed. %d\n",
+                           ret);
+-      mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++      mutex_unlock(&display->hdcp.hdcp_mutex);
+       return ret;
+ }
+@@ -1229,17 +1231,17 @@ hdcp2_verify_rx_cert_prepare_km(struct i
+                               struct hdcp2_ake_no_stored_km *ek_pub_km,
+                               size_t *msg_sz)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+       struct hdcp_port_data *data = &dig_port->hdcp_port_data;
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct i915_hdcp_arbiter *arbiter;
+       int ret;
+-      mutex_lock(&i915->display.hdcp.hdcp_mutex);
+-      arbiter = i915->display.hdcp.arbiter;
++      mutex_lock(&display->hdcp.hdcp_mutex);
++      arbiter = display->hdcp.arbiter;
+       if (!arbiter || !arbiter->ops) {
+-              mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++              mutex_unlock(&display->hdcp.hdcp_mutex);
+               return -EINVAL;
+       }
+@@ -1247,9 +1249,9 @@ hdcp2_verify_rx_cert_prepare_km(struct i
+                                                        rx_cert, paired,
+                                                        ek_pub_km, msg_sz);
+       if (ret < 0)
+-              drm_dbg_kms(&i915->drm, "Verify rx_cert failed. %d\n",
++              drm_dbg_kms(display->drm, "Verify rx_cert failed. %d\n",
+                           ret);
+-      mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++      mutex_unlock(&display->hdcp.hdcp_mutex);
+       return ret;
+ }
+@@ -1257,24 +1259,24 @@ hdcp2_verify_rx_cert_prepare_km(struct i
+ static int hdcp2_verify_hprime(struct intel_connector *connector,
+                              struct hdcp2_ake_send_hprime *rx_hprime)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+       struct hdcp_port_data *data = &dig_port->hdcp_port_data;
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct i915_hdcp_arbiter *arbiter;
+       int ret;
+-      mutex_lock(&i915->display.hdcp.hdcp_mutex);
+-      arbiter = i915->display.hdcp.arbiter;
++      mutex_lock(&display->hdcp.hdcp_mutex);
++      arbiter = display->hdcp.arbiter;
+       if (!arbiter || !arbiter->ops) {
+-              mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++              mutex_unlock(&display->hdcp.hdcp_mutex);
+               return -EINVAL;
+       }
+       ret = arbiter->ops->verify_hprime(arbiter->hdcp_dev, data, rx_hprime);
+       if (ret < 0)
+-              drm_dbg_kms(&i915->drm, "Verify hprime failed. %d\n", ret);
+-      mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++              drm_dbg_kms(display->drm, "Verify hprime failed. %d\n", ret);
++      mutex_unlock(&display->hdcp.hdcp_mutex);
+       return ret;
+ }
+@@ -1283,25 +1285,25 @@ static int
+ hdcp2_store_pairing_info(struct intel_connector *connector,
+                        struct hdcp2_ake_send_pairing_info *pairing_info)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+       struct hdcp_port_data *data = &dig_port->hdcp_port_data;
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct i915_hdcp_arbiter *arbiter;
+       int ret;
+-      mutex_lock(&i915->display.hdcp.hdcp_mutex);
+-      arbiter = i915->display.hdcp.arbiter;
++      mutex_lock(&display->hdcp.hdcp_mutex);
++      arbiter = display->hdcp.arbiter;
+       if (!arbiter || !arbiter->ops) {
+-              mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++              mutex_unlock(&display->hdcp.hdcp_mutex);
+               return -EINVAL;
+       }
+       ret = arbiter->ops->store_pairing_info(arbiter->hdcp_dev, data, pairing_info);
+       if (ret < 0)
+-              drm_dbg_kms(&i915->drm, "Store pairing info failed. %d\n",
++              drm_dbg_kms(display->drm, "Store pairing info failed. %d\n",
+                           ret);
+-      mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++      mutex_unlock(&display->hdcp.hdcp_mutex);
+       return ret;
+ }
+@@ -1310,25 +1312,25 @@ static int
+ hdcp2_prepare_lc_init(struct intel_connector *connector,
+                     struct hdcp2_lc_init *lc_init)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+       struct hdcp_port_data *data = &dig_port->hdcp_port_data;
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct i915_hdcp_arbiter *arbiter;
+       int ret;
+-      mutex_lock(&i915->display.hdcp.hdcp_mutex);
+-      arbiter = i915->display.hdcp.arbiter;
++      mutex_lock(&display->hdcp.hdcp_mutex);
++      arbiter = display->hdcp.arbiter;
+       if (!arbiter || !arbiter->ops) {
+-              mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++              mutex_unlock(&display->hdcp.hdcp_mutex);
+               return -EINVAL;
+       }
+       ret = arbiter->ops->initiate_locality_check(arbiter->hdcp_dev, data, lc_init);
+       if (ret < 0)
+-              drm_dbg_kms(&i915->drm, "Prepare lc_init failed. %d\n",
++              drm_dbg_kms(display->drm, "Prepare lc_init failed. %d\n",
+                           ret);
+-      mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++      mutex_unlock(&display->hdcp.hdcp_mutex);
+       return ret;
+ }
+@@ -1337,25 +1339,25 @@ static int
+ hdcp2_verify_lprime(struct intel_connector *connector,
+                   struct hdcp2_lc_send_lprime *rx_lprime)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+       struct hdcp_port_data *data = &dig_port->hdcp_port_data;
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct i915_hdcp_arbiter *arbiter;
+       int ret;
+-      mutex_lock(&i915->display.hdcp.hdcp_mutex);
+-      arbiter = i915->display.hdcp.arbiter;
++      mutex_lock(&display->hdcp.hdcp_mutex);
++      arbiter = display->hdcp.arbiter;
+       if (!arbiter || !arbiter->ops) {
+-              mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++              mutex_unlock(&display->hdcp.hdcp_mutex);
+               return -EINVAL;
+       }
+       ret = arbiter->ops->verify_lprime(arbiter->hdcp_dev, data, rx_lprime);
+       if (ret < 0)
+-              drm_dbg_kms(&i915->drm, "Verify L_Prime failed. %d\n",
++              drm_dbg_kms(display->drm, "Verify L_Prime failed. %d\n",
+                           ret);
+-      mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++      mutex_unlock(&display->hdcp.hdcp_mutex);
+       return ret;
+ }
+@@ -1363,25 +1365,25 @@ hdcp2_verify_lprime(struct intel_connect
+ static int hdcp2_prepare_skey(struct intel_connector *connector,
+                             struct hdcp2_ske_send_eks *ske_data)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+       struct hdcp_port_data *data = &dig_port->hdcp_port_data;
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct i915_hdcp_arbiter *arbiter;
+       int ret;
+-      mutex_lock(&i915->display.hdcp.hdcp_mutex);
+-      arbiter = i915->display.hdcp.arbiter;
++      mutex_lock(&display->hdcp.hdcp_mutex);
++      arbiter = display->hdcp.arbiter;
+       if (!arbiter || !arbiter->ops) {
+-              mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++              mutex_unlock(&display->hdcp.hdcp_mutex);
+               return -EINVAL;
+       }
+       ret = arbiter->ops->get_session_key(arbiter->hdcp_dev, data, ske_data);
+       if (ret < 0)
+-              drm_dbg_kms(&i915->drm, "Get session key failed. %d\n",
++              drm_dbg_kms(display->drm, "Get session key failed. %d\n",
+                           ret);
+-      mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++      mutex_unlock(&display->hdcp.hdcp_mutex);
+       return ret;
+ }
+@@ -1392,17 +1394,17 @@ hdcp2_verify_rep_topology_prepare_ack(st
+                                                               *rep_topology,
+                                     struct hdcp2_rep_send_ack *rep_send_ack)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+       struct hdcp_port_data *data = &dig_port->hdcp_port_data;
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct i915_hdcp_arbiter *arbiter;
+       int ret;
+-      mutex_lock(&i915->display.hdcp.hdcp_mutex);
+-      arbiter = i915->display.hdcp.arbiter;
++      mutex_lock(&display->hdcp.hdcp_mutex);
++      arbiter = display->hdcp.arbiter;
+       if (!arbiter || !arbiter->ops) {
+-              mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++              mutex_unlock(&display->hdcp.hdcp_mutex);
+               return -EINVAL;
+       }
+@@ -1411,9 +1413,9 @@ hdcp2_verify_rep_topology_prepare_ack(st
+                                                           rep_topology,
+                                                           rep_send_ack);
+       if (ret < 0)
+-              drm_dbg_kms(&i915->drm,
++              drm_dbg_kms(display->drm,
+                           "Verify rep topology failed. %d\n", ret);
+-      mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++      mutex_unlock(&display->hdcp.hdcp_mutex);
+       return ret;
+ }
+@@ -1422,71 +1424,71 @@ static int
+ hdcp2_verify_mprime(struct intel_connector *connector,
+                   struct hdcp2_rep_stream_ready *stream_ready)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+       struct hdcp_port_data *data = &dig_port->hdcp_port_data;
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct i915_hdcp_arbiter *arbiter;
+       int ret;
+-      mutex_lock(&i915->display.hdcp.hdcp_mutex);
+-      arbiter = i915->display.hdcp.arbiter;
++      mutex_lock(&display->hdcp.hdcp_mutex);
++      arbiter = display->hdcp.arbiter;
+       if (!arbiter || !arbiter->ops) {
+-              mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++              mutex_unlock(&display->hdcp.hdcp_mutex);
+               return -EINVAL;
+       }
+       ret = arbiter->ops->verify_mprime(arbiter->hdcp_dev, data, stream_ready);
+       if (ret < 0)
+-              drm_dbg_kms(&i915->drm, "Verify mprime failed. %d\n", ret);
+-      mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++              drm_dbg_kms(display->drm, "Verify mprime failed. %d\n", ret);
++      mutex_unlock(&display->hdcp.hdcp_mutex);
+       return ret;
+ }
+ static int hdcp2_authenticate_port(struct intel_connector *connector)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+       struct hdcp_port_data *data = &dig_port->hdcp_port_data;
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct i915_hdcp_arbiter *arbiter;
+       int ret;
+-      mutex_lock(&i915->display.hdcp.hdcp_mutex);
+-      arbiter = i915->display.hdcp.arbiter;
++      mutex_lock(&display->hdcp.hdcp_mutex);
++      arbiter = display->hdcp.arbiter;
+       if (!arbiter || !arbiter->ops) {
+-              mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++              mutex_unlock(&display->hdcp.hdcp_mutex);
+               return -EINVAL;
+       }
+       ret = arbiter->ops->enable_hdcp_authentication(arbiter->hdcp_dev, data);
+       if (ret < 0)
+-              drm_dbg_kms(&i915->drm, "Enable hdcp auth failed. %d\n",
++              drm_dbg_kms(display->drm, "Enable hdcp auth failed. %d\n",
+                           ret);
+-      mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++      mutex_unlock(&display->hdcp.hdcp_mutex);
+       return ret;
+ }
+ static int hdcp2_close_session(struct intel_connector *connector)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct i915_hdcp_arbiter *arbiter;
+       int ret;
+-      mutex_lock(&i915->display.hdcp.hdcp_mutex);
+-      arbiter = i915->display.hdcp.arbiter;
++      mutex_lock(&display->hdcp.hdcp_mutex);
++      arbiter = display->hdcp.arbiter;
+       if (!arbiter || !arbiter->ops) {
+-              mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++              mutex_unlock(&display->hdcp.hdcp_mutex);
+               return -EINVAL;
+       }
+       ret = arbiter->ops->close_hdcp_session(arbiter->hdcp_dev,
+                                            &dig_port->hdcp_port_data);
+-      mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++      mutex_unlock(&display->hdcp.hdcp_mutex);
+       return ret;
+ }
+@@ -1499,7 +1501,7 @@ static int hdcp2_deauthenticate_port(str
+ /* Authentication flow starts from here */
+ static int hdcp2_authentication_key_exchange(struct intel_connector *connector)
+ {
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_hdcp *hdcp = &connector->hdcp;
+       union {
+               struct hdcp2_ake_init ake_init;
+@@ -1531,16 +1533,16 @@ static int hdcp2_authentication_key_exch
+               return ret;
+       if (msgs.send_cert.rx_caps[0] != HDCP_2_2_RX_CAPS_VERSION_VAL) {
+-              drm_dbg_kms(&i915->drm, "cert.rx_caps dont claim HDCP2.2\n");
++              drm_dbg_kms(display->drm, "cert.rx_caps dont claim HDCP2.2\n");
+               return -EINVAL;
+       }
+       hdcp->is_repeater = HDCP_2_2_RX_REPEATER(msgs.send_cert.rx_caps[2]);
+-      if (drm_hdcp_check_ksvs_revoked(&i915->drm,
++      if (drm_hdcp_check_ksvs_revoked(display->drm,
+                                       msgs.send_cert.cert_rx.receiver_id,
+                                       1) > 0) {
+-              drm_err(&i915->drm, "Receiver ID is revoked\n");
++              drm_err(display->drm, "Receiver ID is revoked\n");
+               return -EPERM;
+       }
+@@ -1691,8 +1693,8 @@ out:
+ static
+ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct intel_hdcp *hdcp = &connector->hdcp;
+       union {
+               struct hdcp2_rep_send_receiverid_list recvid_list;
+@@ -1712,7 +1714,7 @@ int hdcp2_authenticate_repeater_topology
+       if (HDCP_2_2_MAX_CASCADE_EXCEEDED(rx_info[1]) ||
+           HDCP_2_2_MAX_DEVS_EXCEEDED(rx_info[1])) {
+-              drm_dbg_kms(&i915->drm, "Topology Max Size Exceeded\n");
++              drm_dbg_kms(display->drm, "Topology Max Size Exceeded\n");
+               return -EINVAL;
+       }
+@@ -1725,7 +1727,7 @@ int hdcp2_authenticate_repeater_topology
+               !HDCP_2_2_HDCP_2_0_REP_CONNECTED(rx_info[1]);
+       if (!dig_port->hdcp_mst_type1_capable && hdcp->content_type) {
+-              drm_dbg_kms(&i915->drm,
++              drm_dbg_kms(display->drm,
+                           "HDCP1.x or 2.0 Legacy Device Downstream\n");
+               return -EINVAL;
+       }
+@@ -1735,23 +1737,23 @@ int hdcp2_authenticate_repeater_topology
+               drm_hdcp_be24_to_cpu((const u8 *)msgs.recvid_list.seq_num_v);
+       if (!hdcp->hdcp2_encrypted && seq_num_v) {
+-              drm_dbg_kms(&i915->drm,
++              drm_dbg_kms(display->drm,
+                           "Non zero Seq_num_v at first RecvId_List msg\n");
+               return -EINVAL;
+       }
+       if (seq_num_v < hdcp->seq_num_v) {
+               /* Roll over of the seq_num_v from repeater. Reauthenticate. */
+-              drm_dbg_kms(&i915->drm, "Seq_num_v roll over.\n");
++              drm_dbg_kms(display->drm, "Seq_num_v roll over.\n");
+               return -EINVAL;
+       }
+       device_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 |
+                     HDCP_2_2_DEV_COUNT_LO(rx_info[1]));
+-      if (drm_hdcp_check_ksvs_revoked(&i915->drm,
++      if (drm_hdcp_check_ksvs_revoked(display->drm,
+                                       msgs.recvid_list.receiver_ids,
+                                       device_cnt) > 0) {
+-              drm_err(&i915->drm, "Revoked receiver ID(s) is in list\n");
++              drm_err(display->drm, "Revoked receiver ID(s) is in list\n");
+               return -EPERM;
+       }
+@@ -1772,27 +1774,27 @@ int hdcp2_authenticate_repeater_topology
+ static int hdcp2_authenticate_sink(struct intel_connector *connector)
+ {
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_hdcp *hdcp = &connector->hdcp;
+       const struct intel_hdcp_shim *shim = hdcp->shim;
+       int ret;
+       ret = hdcp2_authentication_key_exchange(connector);
+       if (ret < 0) {
+-              drm_dbg_kms(&i915->drm, "AKE Failed. Err : %d\n", ret);
++              drm_dbg_kms(display->drm, "AKE Failed. Err : %d\n", ret);
+               return ret;
+       }
+       ret = hdcp2_locality_check(connector);
+       if (ret < 0) {
+-              drm_dbg_kms(&i915->drm,
++              drm_dbg_kms(display->drm,
+                           "Locality Check failed. Err : %d\n", ret);
+               return ret;
+       }
+       ret = hdcp2_session_key_exchange(connector);
+       if (ret < 0) {
+-              drm_dbg_kms(&i915->drm, "SKE Failed. Err : %d\n", ret);
++              drm_dbg_kms(display->drm, "SKE Failed. Err : %d\n", ret);
+               return ret;
+       }
+@@ -1807,7 +1809,7 @@ static int hdcp2_authenticate_sink(struc
+       if (hdcp->is_repeater) {
+               ret = hdcp2_authenticate_repeater_topology(connector);
+               if (ret < 0) {
+-                      drm_dbg_kms(&i915->drm,
++                      drm_dbg_kms(display->drm,
+                                   "Repeater Auth Failed. Err: %d\n", ret);
+                       return ret;
+               }
+@@ -1818,17 +1820,17 @@ static int hdcp2_authenticate_sink(struc
+ static int hdcp2_enable_stream_encryption(struct intel_connector *connector)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct hdcp_port_data *data = &dig_port->hdcp_port_data;
+       struct intel_hdcp *hdcp = &connector->hdcp;
+       enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
+       enum port port = dig_port->base.port;
+       int ret = 0;
+-      if (!(intel_de_read(i915, HDCP2_STATUS(i915, cpu_transcoder, port)) &
++      if (!(intel_de_read(display, HDCP2_STATUS(display, cpu_transcoder, port)) &
+                           LINK_ENCRYPTION_STATUS)) {
+-              drm_err(&i915->drm, "[CONNECTOR:%d:%s] HDCP 2.2 Link is not encrypted\n",
++              drm_err(display->drm, "[CONNECTOR:%d:%s] HDCP 2.2 Link is not encrypted\n",
+                       connector->base.base.id, connector->base.name);
+               ret = -EPERM;
+               goto link_recover;
+@@ -1837,11 +1839,11 @@ static int hdcp2_enable_stream_encryptio
+       if (hdcp->shim->stream_2_2_encryption) {
+               ret = hdcp->shim->stream_2_2_encryption(connector, true);
+               if (ret) {
+-                      drm_err(&i915->drm, "[CONNECTOR:%d:%s] Failed to enable HDCP 2.2 stream enc\n",
++                      drm_err(display->drm, "[CONNECTOR:%d:%s] Failed to enable HDCP 2.2 stream enc\n",
+                               connector->base.base.id, connector->base.name);
+                       return ret;
+               }
+-              drm_dbg_kms(&i915->drm, "HDCP 2.2 transcoder: %s stream encrypted\n",
++              drm_dbg_kms(display->drm, "HDCP 2.2 transcoder: %s stream encrypted\n",
+                           transcoder_name(hdcp->stream_transcoder));
+       }
+@@ -1849,7 +1851,7 @@ static int hdcp2_enable_stream_encryptio
+ link_recover:
+       if (hdcp2_deauthenticate_port(connector) < 0)
+-              drm_dbg_kms(&i915->drm, "Port deauth failed.\n");
++              drm_dbg_kms(display->drm, "Port deauth failed.\n");
+       dig_port->hdcp_auth_status = false;
+       data->k = 0;
+@@ -1859,35 +1861,35 @@ link_recover:
+ static int hdcp2_enable_encryption(struct intel_connector *connector)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct intel_hdcp *hdcp = &connector->hdcp;
+       enum port port = dig_port->base.port;
+       enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
+       int ret;
+-      drm_WARN_ON(&i915->drm,
+-                  intel_de_read(i915, HDCP2_STATUS(i915, cpu_transcoder, port)) &
++      drm_WARN_ON(display->drm,
++                  intel_de_read(display, HDCP2_STATUS(display, cpu_transcoder, port)) &
+                   LINK_ENCRYPTION_STATUS);
+       if (hdcp->shim->toggle_signalling) {
+               ret = hdcp->shim->toggle_signalling(dig_port, cpu_transcoder,
+                                                   true);
+               if (ret) {
+-                      drm_err(&i915->drm,
++                      drm_err(display->drm,
+                               "Failed to enable HDCP signalling. %d\n",
+                               ret);
+                       return ret;
+               }
+       }
+-      if (intel_de_read(i915, HDCP2_STATUS(i915, cpu_transcoder, port)) &
++      if (intel_de_read(display, HDCP2_STATUS(display, cpu_transcoder, port)) &
+           LINK_AUTH_STATUS)
+               /* Link is Authenticated. Now set for Encryption */
+-              intel_de_rmw(i915, HDCP2_CTL(i915, cpu_transcoder, port),
++              intel_de_rmw(display, HDCP2_CTL(display, cpu_transcoder, port),
+                            0, CTL_LINK_ENCRYPTION_REQ);
+-      ret = intel_de_wait_for_set(i915,
+-                                  HDCP2_STATUS(i915, cpu_transcoder,
++      ret = intel_de_wait_for_set(display,
++                                  HDCP2_STATUS(display, cpu_transcoder,
+                                                port),
+                                   LINK_ENCRYPTION_STATUS,
+                                   HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS);
+@@ -1898,32 +1900,33 @@ static int hdcp2_enable_encryption(struc
+ static int hdcp2_disable_encryption(struct intel_connector *connector)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct intel_hdcp *hdcp = &connector->hdcp;
+       enum port port = dig_port->base.port;
+       enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
+       int ret;
+-      drm_WARN_ON(&i915->drm, !(intel_de_read(i915, HDCP2_STATUS(i915, cpu_transcoder, port)) &
+-                                    LINK_ENCRYPTION_STATUS));
++      drm_WARN_ON(display->drm,
++                  !(intel_de_read(display, HDCP2_STATUS(display, cpu_transcoder, port)) &
++                                  LINK_ENCRYPTION_STATUS));
+-      intel_de_rmw(i915, HDCP2_CTL(i915, cpu_transcoder, port),
++      intel_de_rmw(display, HDCP2_CTL(display, cpu_transcoder, port),
+                    CTL_LINK_ENCRYPTION_REQ, 0);
+-      ret = intel_de_wait_for_clear(i915,
+-                                    HDCP2_STATUS(i915, cpu_transcoder,
++      ret = intel_de_wait_for_clear(display,
++                                    HDCP2_STATUS(display, cpu_transcoder,
+                                                  port),
+                                     LINK_ENCRYPTION_STATUS,
+                                     HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS);
+       if (ret == -ETIMEDOUT)
+-              drm_dbg_kms(&i915->drm, "Disable Encryption Timedout");
++              drm_dbg_kms(display->drm, "Disable Encryption Timedout");
+       if (hdcp->shim->toggle_signalling) {
+               ret = hdcp->shim->toggle_signalling(dig_port, cpu_transcoder,
+                                                   false);
+               if (ret) {
+-                      drm_err(&i915->drm,
++                      drm_err(display->drm,
+                               "Failed to disable HDCP signalling. %d\n",
+                               ret);
+                       return ret;
+@@ -1936,7 +1939,7 @@ static int hdcp2_disable_encryption(stru
+ static int
+ hdcp2_propagate_stream_management_info(struct intel_connector *connector)
+ {
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
++      struct intel_display *display = to_intel_display(connector);
+       int i, tries = 3, ret;
+       if (!connector->hdcp.is_repeater)
+@@ -1949,12 +1952,12 @@ hdcp2_propagate_stream_management_info(s
+               /* Lets restart the auth incase of seq_num_m roll over */
+               if (connector->hdcp.seq_num_m > HDCP_2_2_SEQ_NUM_MAX) {
+-                      drm_dbg_kms(&i915->drm,
++                      drm_dbg_kms(display->drm,
+                                   "seq_num_m roll over.(%d)\n", ret);
+                       break;
+               }
+-              drm_dbg_kms(&i915->drm,
++              drm_dbg_kms(display->drm,
+                           "HDCP2 stream management %d of %d Failed.(%d)\n",
+                           i + 1, tries, ret);
+       }
+@@ -1965,8 +1968,8 @@ hdcp2_propagate_stream_management_info(s
+ static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state,
+                                         struct intel_connector *connector)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       int ret = 0, i, tries = 3;
+       for (i = 0; i < tries && !dig_port->hdcp_auth_status; i++) {
+@@ -1974,7 +1977,7 @@ static int hdcp2_authenticate_and_encryp
+               if (!ret) {
+                       ret = intel_hdcp_prepare_streams(state, connector);
+                       if (ret) {
+-                              drm_dbg_kms(&i915->drm,
++                              drm_dbg_kms(display->drm,
+                                           "Prepare stream failed.(%d)\n",
+                                           ret);
+                               break;
+@@ -1982,7 +1985,7 @@ static int hdcp2_authenticate_and_encryp
+                       ret = hdcp2_propagate_stream_management_info(connector);
+                       if (ret) {
+-                              drm_dbg_kms(&i915->drm,
++                              drm_dbg_kms(display->drm,
+                                           "Stream management failed.(%d)\n",
+                                           ret);
+                               break;
+@@ -1991,15 +1994,15 @@ static int hdcp2_authenticate_and_encryp
+                       ret = hdcp2_authenticate_port(connector);
+                       if (!ret)
+                               break;
+-                      drm_dbg_kms(&i915->drm, "HDCP2 port auth failed.(%d)\n",
++                      drm_dbg_kms(display->drm, "HDCP2 port auth failed.(%d)\n",
+                                   ret);
+               }
+               /* Clearing the mei hdcp session */
+-              drm_dbg_kms(&i915->drm, "HDCP2.2 Auth %d of %d Failed.(%d)\n",
++              drm_dbg_kms(display->drm, "HDCP2.2 Auth %d of %d Failed.(%d)\n",
+                           i + 1, tries, ret);
+               if (hdcp2_deauthenticate_port(connector) < 0)
+-                      drm_dbg_kms(&i915->drm, "Port deauth failed.\n");
++                      drm_dbg_kms(display->drm, "Port deauth failed.\n");
+       }
+       if (!ret && !dig_port->hdcp_auth_status) {
+@@ -2010,10 +2013,10 @@ static int hdcp2_authenticate_and_encryp
+               msleep(HDCP_2_2_DELAY_BEFORE_ENCRYPTION_EN);
+               ret = hdcp2_enable_encryption(connector);
+               if (ret < 0) {
+-                      drm_dbg_kms(&i915->drm,
++                      drm_dbg_kms(display->drm,
+                                   "Encryption Enable Failed.(%d)\n", ret);
+                       if (hdcp2_deauthenticate_port(connector) < 0)
+-                              drm_dbg_kms(&i915->drm, "Port deauth failed.\n");
++                              drm_dbg_kms(display->drm, "Port deauth failed.\n");
+               }
+       }
+@@ -2026,11 +2029,11 @@ static int hdcp2_authenticate_and_encryp
+ static int _intel_hdcp2_enable(struct intel_atomic_state *state,
+                              struct intel_connector *connector)
+ {
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_hdcp *hdcp = &connector->hdcp;
+       int ret;
+-      drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] HDCP2.2 is being enabled. Type: %d\n",
++      drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP2.2 is being enabled. Type: %d\n",
+                   connector->base.base.id, connector->base.name,
+                   hdcp->content_type);
+@@ -2038,12 +2041,12 @@ static int _intel_hdcp2_enable(struct in
+       ret = hdcp2_authenticate_and_encrypt(state, connector);
+       if (ret) {
+-              drm_dbg_kms(&i915->drm, "HDCP2 Type%d  Enabling Failed. (%d)\n",
++              drm_dbg_kms(display->drm, "HDCP2 Type%d  Enabling Failed. (%d)\n",
+                           hdcp->content_type, ret);
+               return ret;
+       }
+-      drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] HDCP2.2 is enabled. Type %d\n",
++      drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP2.2 is enabled. Type %d\n",
+                   connector->base.base.id, connector->base.name,
+                   hdcp->content_type);
+@@ -2054,23 +2057,23 @@ static int _intel_hdcp2_enable(struct in
+ static int
+ _intel_hdcp2_disable(struct intel_connector *connector, bool hdcp2_link_recovery)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct hdcp_port_data *data = &dig_port->hdcp_port_data;
+       struct intel_hdcp *hdcp = &connector->hdcp;
+       int ret;
+-      drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] HDCP2.2 is being Disabled\n",
++      drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP2.2 is being Disabled\n",
+                   connector->base.base.id, connector->base.name);
+       if (hdcp->shim->stream_2_2_encryption) {
+               ret = hdcp->shim->stream_2_2_encryption(connector, false);
+               if (ret) {
+-                      drm_err(&i915->drm, "[CONNECTOR:%d:%s] Failed to disable HDCP 2.2 stream enc\n",
++                      drm_err(display->drm, "[CONNECTOR:%d:%s] Failed to disable HDCP 2.2 stream enc\n",
+                               connector->base.base.id, connector->base.name);
+                       return ret;
+               }
+-              drm_dbg_kms(&i915->drm, "HDCP 2.2 transcoder: %s stream encryption disabled\n",
++              drm_dbg_kms(display->drm, "HDCP 2.2 transcoder: %s stream encryption disabled\n",
+                           transcoder_name(hdcp->stream_transcoder));
+               if (dig_port->num_hdcp_streams > 0 && !hdcp2_link_recovery)
+@@ -2080,7 +2083,7 @@ _intel_hdcp2_disable(struct intel_connec
+       ret = hdcp2_disable_encryption(connector);
+       if (hdcp2_deauthenticate_port(connector) < 0)
+-              drm_dbg_kms(&i915->drm, "Port deauth failed.\n");
++              drm_dbg_kms(display->drm, "Port deauth failed.\n");
+       connector->hdcp.hdcp2_encrypted = false;
+       dig_port->hdcp_auth_status = false;
+@@ -2092,8 +2095,8 @@ _intel_hdcp2_disable(struct intel_connec
+ /* Implements the Link Integrity Check for HDCP2.2 */
+ static int intel_hdcp2_check_link(struct intel_connector *connector)
+ {
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct intel_hdcp *hdcp = &connector->hdcp;
+       enum port port = dig_port->base.port;
+       enum transcoder cpu_transcoder;
+@@ -2110,11 +2113,11 @@ static int intel_hdcp2_check_link(struct
+               goto out;
+       }
+-      if (drm_WARN_ON(&i915->drm,
+-                      !intel_hdcp2_in_use(i915, cpu_transcoder, port))) {
+-              drm_err(&i915->drm,
++      if (drm_WARN_ON(display->drm,
++                      !intel_hdcp2_in_use(display, cpu_transcoder, port))) {
++              drm_err(display->drm,
+                       "HDCP2.2 link stopped the encryption, %x\n",
+-                      intel_de_read(i915, HDCP2_STATUS(i915, cpu_transcoder, port)));
++                      intel_de_read(display, HDCP2_STATUS(display, cpu_transcoder, port)));
+               ret = -ENXIO;
+               _intel_hdcp2_disable(connector, true);
+               intel_hdcp_update_value(connector,
+@@ -2137,17 +2140,17 @@ static int intel_hdcp2_check_link(struct
+               if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+                       goto out;
+-              drm_dbg_kms(&i915->drm,
++              drm_dbg_kms(display->drm,
+                           "HDCP2.2 Downstream topology change\n");
+       } else {
+-              drm_dbg_kms(&i915->drm,
++              drm_dbg_kms(display->drm,
+                           "[CONNECTOR:%d:%s] HDCP2.2 link failed, retrying auth\n",
+                           connector->base.base.id, connector->base.name);
+       }
+       ret = _intel_hdcp2_disable(connector, true);
+       if (ret) {
+-              drm_err(&i915->drm,
++              drm_err(display->drm,
+                       "[CONNECTOR:%d:%s] Failed to disable hdcp2.2 (%d)\n",
+                       connector->base.base.id, connector->base.name, ret);
+               intel_hdcp_update_value(connector,
+@@ -2169,7 +2172,8 @@ static void intel_hdcp_check_work(struct
+                                              struct intel_hdcp,
+                                              check_work);
+       struct intel_connector *connector = intel_hdcp_to_connector(hdcp);
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
++      struct intel_display *display = to_intel_display(connector);
++      struct drm_i915_private *i915 = to_i915(display->drm);
+       if (drm_connector_is_unregistered(&connector->base))
+               return;
+@@ -2186,13 +2190,12 @@ static int i915_hdcp_component_bind(stru
+                                   struct device *mei_kdev, void *data)
+ {
+       struct intel_display *display = to_intel_display(drv_kdev);
+-      struct drm_i915_private *i915 = to_i915(display->drm);
+-      drm_dbg(&i915->drm, "I915 HDCP comp bind\n");
+-      mutex_lock(&i915->display.hdcp.hdcp_mutex);
+-      i915->display.hdcp.arbiter = (struct i915_hdcp_arbiter *)data;
+-      i915->display.hdcp.arbiter->hdcp_dev = mei_kdev;
+-      mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++      drm_dbg(display->drm, "I915 HDCP comp bind\n");
++      mutex_lock(&display->hdcp.hdcp_mutex);
++      display->hdcp.arbiter = (struct i915_hdcp_arbiter *)data;
++      display->hdcp.arbiter->hdcp_dev = mei_kdev;
++      mutex_unlock(&display->hdcp.hdcp_mutex);
+       return 0;
+ }
+@@ -2201,12 +2204,11 @@ static void i915_hdcp_component_unbind(s
+                                      struct device *mei_kdev, void *data)
+ {
+       struct intel_display *display = to_intel_display(drv_kdev);
+-      struct drm_i915_private *i915 = to_i915(display->drm);
+-      drm_dbg(&i915->drm, "I915 HDCP comp unbind\n");
+-      mutex_lock(&i915->display.hdcp.hdcp_mutex);
+-      i915->display.hdcp.arbiter = NULL;
+-      mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++      drm_dbg(display->drm, "I915 HDCP comp unbind\n");
++      mutex_lock(&display->hdcp.hdcp_mutex);
++      display->hdcp.arbiter = NULL;
++      mutex_unlock(&display->hdcp.hdcp_mutex);
+ }
+ static const struct component_ops i915_hdcp_ops = {
+@@ -2240,11 +2242,11 @@ static int initialize_hdcp_port_data(str
+                                    struct intel_digital_port *dig_port,
+                                    const struct intel_hdcp_shim *shim)
+ {
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
++      struct intel_display *display = to_intel_display(connector);
+       struct hdcp_port_data *data = &dig_port->hdcp_port_data;
+       enum port port = dig_port->base.port;
+-      if (DISPLAY_VER(i915) < 12)
++      if (DISPLAY_VER(display) < 12)
+               data->hdcp_ddi = intel_get_hdcp_ddi_index(port);
+       else
+               /*
+@@ -2264,11 +2266,11 @@ static int initialize_hdcp_port_data(str
+       data->protocol = (u8)shim->protocol;
+       if (!data->streams)
+-              data->streams = kcalloc(INTEL_NUM_PIPES(i915),
++              data->streams = kcalloc(INTEL_NUM_PIPES(display),
+                                       sizeof(struct hdcp2_streamid_type),
+                                       GFP_KERNEL);
+       if (!data->streams) {
+-              drm_err(&i915->drm, "Out of Memory\n");
++              drm_err(display->drm, "Out of Memory\n");
+               return -ENOMEM;
+       }
+@@ -2277,13 +2279,15 @@ static int initialize_hdcp_port_data(str
+ static bool is_hdcp2_supported(struct drm_i915_private *i915)
+ {
+-      if (intel_hdcp_gsc_cs_required(i915))
++      struct intel_display *display = to_intel_display(&i915->drm);
++
++      if (intel_hdcp_gsc_cs_required(display))
+               return true;
+       if (!IS_ENABLED(CONFIG_INTEL_MEI_HDCP))
+               return false;
+-      return (DISPLAY_VER(i915) >= 10 ||
++      return (DISPLAY_VER(display) >= 10 ||
+               IS_KABYLAKE(i915) ||
+               IS_COFFEELAKE(i915) ||
+               IS_COMETLAKE(i915));
+@@ -2291,28 +2295,29 @@ static bool is_hdcp2_supported(struct dr
+ void intel_hdcp_component_init(struct drm_i915_private *i915)
+ {
++      struct intel_display *display = to_intel_display(&i915->drm);
+       int ret;
+       if (!is_hdcp2_supported(i915))
+               return;
+-      mutex_lock(&i915->display.hdcp.hdcp_mutex);
+-      drm_WARN_ON(&i915->drm, i915->display.hdcp.comp_added);
++      mutex_lock(&display->hdcp.hdcp_mutex);
++      drm_WARN_ON(display->drm, display->hdcp.comp_added);
+-      i915->display.hdcp.comp_added = true;
+-      mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+-      if (intel_hdcp_gsc_cs_required(i915))
++      display->hdcp.comp_added = true;
++      mutex_unlock(&display->hdcp.hdcp_mutex);
++      if (intel_hdcp_gsc_cs_required(display))
+               ret = intel_hdcp_gsc_init(i915);
+       else
+-              ret = component_add_typed(i915->drm.dev, &i915_hdcp_ops,
++              ret = component_add_typed(display->drm->dev, &i915_hdcp_ops,
+                                         I915_COMPONENT_HDCP);
+       if (ret < 0) {
+-              drm_dbg_kms(&i915->drm, "Failed at fw component add(%d)\n",
++              drm_dbg_kms(display->drm, "Failed at fw component add(%d)\n",
+                           ret);
+-              mutex_lock(&i915->display.hdcp.hdcp_mutex);
+-              i915->display.hdcp.comp_added = false;
+-              mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++              mutex_lock(&display->hdcp.hdcp_mutex);
++              display->hdcp.comp_added = false;
++              mutex_unlock(&display->hdcp.hdcp_mutex);
+               return;
+       }
+ }
+@@ -2321,13 +2326,13 @@ static void intel_hdcp2_init(struct inte
+                            struct intel_digital_port *dig_port,
+                            const struct intel_hdcp_shim *shim)
+ {
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
++      struct intel_display *display = to_intel_display(connector);
+       struct intel_hdcp *hdcp = &connector->hdcp;
+       int ret;
+       ret = initialize_hdcp_port_data(connector, dig_port, shim);
+       if (ret) {
+-              drm_dbg_kms(&i915->drm, "Mei hdcp data init failed\n");
++              drm_dbg_kms(display->drm, "Mei hdcp data init failed\n");
+               return;
+       }
+@@ -2371,7 +2376,8 @@ static int _intel_hdcp_enable(struct int
+                             const struct intel_crtc_state *pipe_config,
+                             const struct drm_connector_state *conn_state)
+ {
+-      struct drm_i915_private *i915 = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
++      struct drm_i915_private *i915 = to_i915(display->drm);
+       struct intel_connector *connector =
+               to_intel_connector(conn_state->connector);
+       struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+@@ -2383,14 +2389,14 @@ static int _intel_hdcp_enable(struct int
+               return -ENOENT;
+       if (!connector->encoder) {
+-              drm_err(&i915->drm, "[CONNECTOR:%d:%s] encoder is not initialized\n",
++              drm_err(display->drm, "[CONNECTOR:%d:%s] encoder is not initialized\n",
+                       connector->base.base.id, connector->base.name);
+               return -ENODEV;
+       }
+       mutex_lock(&hdcp->mutex);
+       mutex_lock(&dig_port->hdcp_mutex);
+-      drm_WARN_ON(&i915->drm,
++      drm_WARN_ON(display->drm,
+                   hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
+       hdcp->content_type = (u8)conn_state->hdcp_content_type;
+@@ -2555,19 +2561,21 @@ void intel_hdcp_update_pipe(struct intel
+ void intel_hdcp_component_fini(struct drm_i915_private *i915)
+ {
+-      mutex_lock(&i915->display.hdcp.hdcp_mutex);
+-      if (!i915->display.hdcp.comp_added) {
+-              mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++      struct intel_display *display = to_intel_display(&i915->drm);
++
++      mutex_lock(&display->hdcp.hdcp_mutex);
++      if (!display->hdcp.comp_added) {
++              mutex_unlock(&display->hdcp.hdcp_mutex);
+               return;
+       }
+-      i915->display.hdcp.comp_added = false;
+-      mutex_unlock(&i915->display.hdcp.hdcp_mutex);
++      display->hdcp.comp_added = false;
++      mutex_unlock(&display->hdcp.hdcp_mutex);
+-      if (intel_hdcp_gsc_cs_required(i915))
++      if (intel_hdcp_gsc_cs_required(display))
+               intel_hdcp_gsc_fini(i915);
+       else
+-              component_del(i915->drm.dev, &i915_hdcp_ops);
++              component_del(display->drm->dev, &i915_hdcp_ops);
+ }
+ void intel_hdcp_cleanup(struct intel_connector *connector)
+@@ -2657,7 +2665,8 @@ void intel_hdcp_atomic_check(struct drm_
+ void intel_hdcp_handle_cp_irq(struct intel_connector *connector)
+ {
+       struct intel_hdcp *hdcp = &connector->hdcp;
+-      struct drm_i915_private *i915 = to_i915(connector->base.dev);
++      struct intel_display *display = to_intel_display(connector);
++      struct drm_i915_private *i915 = to_i915(display->drm);
+       if (!hdcp->shim)
+               return;
+--- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
++++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
+@@ -19,18 +19,19 @@ struct intel_hdcp_gsc_message {
+       void *hdcp_cmd_out;
+ };
+-bool intel_hdcp_gsc_cs_required(struct drm_i915_private *i915)
++bool intel_hdcp_gsc_cs_required(struct intel_display *display)
+ {
+-      return DISPLAY_VER(i915) >= 14;
++      return DISPLAY_VER(display) >= 14;
+ }
+-bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915)
++bool intel_hdcp_gsc_check_status(struct intel_display *display)
+ {
++      struct drm_i915_private *i915 = to_i915(display->drm);
+       struct intel_gt *gt = i915->media_gt;
+       struct intel_gsc_uc *gsc = gt ? &gt->uc.gsc : NULL;
+       if (!gsc || !intel_uc_fw_is_running(&gsc->fw)) {
+-              drm_dbg_kms(&i915->drm,
++              drm_dbg_kms(display->drm,
+                           "GSC components required for HDCP2.2 are not ready\n");
+               return false;
+       }
+--- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h
++++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h
+@@ -10,14 +10,15 @@
+ #include <linux/types.h>
+ struct drm_i915_private;
++struct intel_display;
+ struct intel_hdcp_gsc_message;
+-bool intel_hdcp_gsc_cs_required(struct drm_i915_private *i915);
++bool intel_hdcp_gsc_cs_required(struct intel_display *display);
+ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in,
+                               size_t msg_in_len, u8 *msg_out,
+                               size_t msg_out_len);
+ int intel_hdcp_gsc_init(struct drm_i915_private *i915);
+ void intel_hdcp_gsc_fini(struct drm_i915_private *i915);
+-bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915);
++bool intel_hdcp_gsc_check_status(struct intel_display *display);
+ #endif /* __INTEL_HDCP_GCS_H__ */
+--- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h
++++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h
+@@ -22,11 +22,12 @@ struct hdcp2_ske_send_eks;
+ struct hdcp2_rep_send_receiverid_list;
+ struct hdcp2_rep_send_ack;
+ struct hdcp2_rep_stream_ready;
++struct intel_display;
+ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in,
+                               size_t msg_in_len, u8 *msg_out,
+                               size_t msg_out_len);
+-bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915);
++bool intel_hdcp_gsc_check_status(struct intel_display *display);
+ int
+ intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data,
+                               struct hdcp2_ake_init *ake_data);
+--- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
++++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
+@@ -30,13 +30,14 @@ struct intel_hdcp_gsc_message {
+ #define HDCP_GSC_HEADER_SIZE sizeof(struct intel_gsc_mtl_header)
+-bool intel_hdcp_gsc_cs_required(struct xe_device *xe)
++bool intel_hdcp_gsc_cs_required(struct intel_display *display)
+ {
+-      return DISPLAY_VER(xe) >= 14;
++      return DISPLAY_VER(display) >= 14;
+ }
+-bool intel_hdcp_gsc_check_status(struct xe_device *xe)
++bool intel_hdcp_gsc_check_status(struct intel_display *display)
+ {
++      struct xe_device *xe = to_xe_device(display->drm);
+       struct xe_tile *tile = xe_device_get_root_tile(xe);
+       struct xe_gt *gt = tile->media_gt;
+       struct xe_gsc *gsc;
diff --git a/queue-6.12/drm-i915-hdcp-require-monotonically-increasing-seq_num_v.patch b/queue-6.12/drm-i915-hdcp-require-monotonically-increasing-seq_num_v.patch
new file mode 100644 (file)
index 0000000..482ceba
--- /dev/null
@@ -0,0 +1,54 @@
+From stable+bounces-294455-greg=kroah.com@vger.kernel.org Sun Aug  2 03:50:18 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat,  1 Aug 2026 21:49:34 -0400
+Subject: drm/i915/hdcp: require monotonically increasing seq_num_v
+To: stable@vger.kernel.org
+Cc: Jani Nikula <jani.nikula@intel.com>, Martin Hodo <martin.hodo@intel.com>, Suraj Kandpal <suraj.kandpal@intel.com>, Joonas Lahtinen <joonas.lahtinen@linux.intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260802014934.510825-2-sashal@kernel.org>
+
+From: Jani Nikula <jani.nikula@intel.com>
+
+[ Upstream commit db9e64c983dcb07ff256bd455f258c44aa530ff8 ]
+
+The HDCP 2.2 specification requires the seq_num_v to be monotonically
+increasing, and repeated seq_num_v needs to be treated as an integrity
+failure. Make it so.
+
+For the first message, seq_num_v must be zero, and is already
+checked. We can only check for less-than-or-equal for the subsequent
+messages, where hdcp2_encrypted is true.
+
+Discovered using AI-assisted static analysis confirmed by Intel Product
+Security.
+
+Reported-by: Martin Hodo <martin.hodo@intel.com>
+Fixes: d849178e2c9e ("drm/i915: Implement HDCP2.2 repeater authentication")
+Cc: stable@vger.kernel.org # v5.2+
+Cc: Suraj Kandpal <suraj.kandpal@intel.com>
+Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
+Link: https://patch.msgid.link/20260625104407.1025614-1-jani.nikula@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+(cherry picked from commit 58a224375c81179b52558c53d8857b93196d2687)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/display/intel_hdcp.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
++++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
+@@ -1742,9 +1742,10 @@ int hdcp2_authenticate_repeater_topology
+               return -EINVAL;
+       }
+-      if (seq_num_v < hdcp->seq_num_v) {
+-              /* Roll over of the seq_num_v from repeater. Reauthenticate. */
+-              drm_dbg_kms(display->drm, "Seq_num_v roll over.\n");
++      if (hdcp->hdcp2_encrypted && seq_num_v <= hdcp->seq_num_v) {
++              /* Reauthenticate on Seq_num_v repeat or rollover */
++              drm_dbg_kms(display->drm, "Seq_num_v %s\n",
++                          seq_num_v == hdcp->seq_num_v ? "repeat" : "rollover");
+               return -EINVAL;
+       }
diff --git a/queue-6.12/drm-i915-vrr-check-has_vrr-first-in-intel_vrr_is_capable.patch b/queue-6.12/drm-i915-vrr-check-has_vrr-first-in-intel_vrr_is_capable.patch
new file mode 100644 (file)
index 0000000..a963acd
--- /dev/null
@@ -0,0 +1,48 @@
+From stable+bounces-294451-greg=kroah.com@vger.kernel.org Sun Aug  2 03:49:36 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat,  1 Aug 2026 21:49:19 -0400
+Subject: drm/i915/vrr: Check HAS_VRR() first in intel_vrr_is_capable()
+To: stable@vger.kernel.org
+Cc: "Ville Syrjälä" <ville.syrjala@linux.intel.com>, "Ankit Nautiyal" <ankit.k.nautiyal@intel.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260802014920.506109-1-sashal@kernel.org>
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+[ Upstream commit 4b274b0b61ab2a529e5c22e9aa033f3028e639fc ]
+
+There's no point in doing all the other checks in
+intel_vrr_is_capable() if the platform doesn't support VRR at all
+Check HAS_VRR() before wasting time on the other checks.
+
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-23-ville.syrjala@linux.intel.com
+Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
+Stable-dep-of: f8a9262c7a6f ("drm/i915/vrr: require valid min/max vfreq for VRR")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/display/intel_vrr.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/i915/display/intel_vrr.c
++++ b/drivers/gpu/drm/i915/display/intel_vrr.c
+@@ -21,6 +21,9 @@ bool intel_vrr_is_capable(struct intel_c
+       const struct drm_display_info *info = &connector->base.display_info;
+       struct intel_dp *intel_dp;
++      if (!HAS_VRR(display))
++              return false;
++
+       /*
+        * DP Sink is capable of VRR video timings if
+        * Ignore MSA bit is set in DPCD.
+@@ -43,8 +46,7 @@ bool intel_vrr_is_capable(struct intel_c
+               return false;
+       }
+-      return HAS_VRR(display) &&
+-              info->monitor_range.max_vfreq - info->monitor_range.min_vfreq > 10;
++      return info->monitor_range.max_vfreq - info->monitor_range.min_vfreq > 10;
+ }
+ bool intel_vrr_is_in_range(struct intel_connector *connector, int vrefresh)
diff --git a/queue-6.12/drm-i915-vrr-require-valid-min-max-vfreq-for-vrr.patch b/queue-6.12/drm-i915-vrr-require-valid-min-max-vfreq-for-vrr.patch
new file mode 100644 (file)
index 0000000..7a8498d
--- /dev/null
@@ -0,0 +1,49 @@
+From stable+bounces-294452-greg=kroah.com@vger.kernel.org Sun Aug  2 03:49:38 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat,  1 Aug 2026 21:49:20 -0400
+Subject: drm/i915/vrr: require valid min/max vfreq for VRR
+To: stable@vger.kernel.org
+Cc: Jani Nikula <jani.nikula@intel.com>, Martin Hodo <martin.hodo@intel.com>, Ankit Nautiyal <ankit.k.nautiyal@intel.com>, Joonas Lahtinen <joonas.lahtinen@linux.intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260802014920.506109-2-sashal@kernel.org>
+
+From: Jani Nikula <jani.nikula@intel.com>
+
+[ Upstream commit f8a9262c7a6fc2de9802e14b0228114f0333869e ]
+
+Ensure the EDID provided min/max vfreq are valid. Most scenarios are
+already covered (by coincidence) through the checks in
+intel_vrr_is_capable() and intel_vrr_is_in_range(), but be more explicit
+about it. At worst, a zero min_vfreq could lead to a division by zero in
+intel_vrr_compute_vmax().
+
+Discovered using AI-assisted static analysis confirmed by Intel Product
+Security.
+
+Reported-by: Martin Hodo <martin.hodo@intel.com>
+Fixes: 117cd09ba528 ("drm/i915/display/dp: Compute VRR state in atomic_check")
+Cc: stable@vger.kernel.org # v5.12+
+Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
+Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
+Link: https://patch.msgid.link/20260625131040.1051272-1-jani.nikula@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+(cherry picked from commit 1765cf59f517b02f3b0591fe5120930d08bddeb6)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/display/intel_vrr.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/gpu/drm/i915/display/intel_vrr.c
++++ b/drivers/gpu/drm/i915/display/intel_vrr.c
+@@ -46,6 +46,10 @@ bool intel_vrr_is_capable(struct intel_c
+               return false;
+       }
++      if (!info->monitor_range.min_vfreq || !info->monitor_range.max_vfreq ||
++          info->monitor_range.min_vfreq > info->monitor_range.max_vfreq)
++              return false;
++
+       return info->monitor_range.max_vfreq - info->monitor_range.min_vfreq > 10;
+ }
diff --git a/queue-6.12/drm-sched-store-the-drm-client_id-in-drm_sched_fence.patch b/queue-6.12/drm-sched-store-the-drm-client_id-in-drm_sched_fence.patch
new file mode 100644 (file)
index 0000000..2e1ea55
--- /dev/null
@@ -0,0 +1,449 @@
+From stable+bounces-294121-greg=kroah.com@vger.kernel.org Fri Jul 31 17:58:27 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2026 11:49:57 -0400
+Subject: drm/sched: Store the drm client_id in drm_sched_fence
+To: stable@vger.kernel.org
+Cc: "Pierre-Eric Pelloux-Prayer" <pierre-eric.pelloux-prayer@amd.com>, "Christian König" <christian.koenig@amd.com>, "Philipp Stanner" <phasta@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260731154959.602805-1-sashal@kernel.org>
+
+From: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
+
+[ Upstream commit 2956554823cedb390b7ec4534afa898176317638 ]
+
+This will be used in a later commit to trace the drm client_id in
+some of the gpu_scheduler trace events.
+
+This requires changing all the users of drm_sched_job_init to
+add an extra parameter.
+
+The newly added drm_client_id field in the drm_sched_fence is a bit
+of a duplicate of the owner one. One suggestion I received was to
+merge those 2 fields - this can't be done right now as amdgpu uses
+some special values (AMDGPU_FENCE_OWNER_*) that can't really be
+translated into a client id. Christian is working on getting rid of
+those; when it's done we should be able to squash owner/drm_client_id
+together.
+
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
+Signed-off-by: Philipp Stanner <phasta@kernel.org>
+Link: https://lore.kernel.org/r/20250526125505.2360-3-pierre-eric.pelloux-prayer@amd.com
+Stable-dep-of: 3e864bf2a32a ("drm/amdgpu/gfx: fix cleaner shader IB buffer overflow")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c   |    2 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c       |    3 ++-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_job.c      |    8 +++++---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_job.h      |    3 ++-
+ drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c |    2 +-
+ drivers/gpu/drm/imagination/pvr_job.c        |    2 +-
+ drivers/gpu/drm/imagination/pvr_queue.c      |    5 +++--
+ drivers/gpu/drm/imagination/pvr_queue.h      |    2 +-
+ drivers/gpu/drm/lima/lima_gem.c              |    2 +-
+ drivers/gpu/drm/lima/lima_sched.c            |    6 ++++--
+ drivers/gpu/drm/lima/lima_sched.h            |    3 ++-
+ drivers/gpu/drm/msm/msm_gem_submit.c         |    8 +++++---
+ drivers/gpu/drm/nouveau/nouveau_sched.c      |    3 ++-
+ drivers/gpu/drm/panfrost/panfrost_drv.c      |    2 +-
+ drivers/gpu/drm/panthor/panthor_drv.c        |    3 ++-
+ drivers/gpu/drm/panthor/panthor_mmu.c        |    2 +-
+ drivers/gpu/drm/panthor/panthor_sched.c      |    5 +++--
+ drivers/gpu/drm/panthor/panthor_sched.h      |    3 ++-
+ drivers/gpu/drm/scheduler/sched_fence.c      |    4 +++-
+ drivers/gpu/drm/scheduler/sched_main.c       |    7 +++++--
+ drivers/gpu/drm/v3d/v3d_submit.c             |    2 +-
+ drivers/gpu/drm/xe/xe_sched_job.c            |    3 ++-
+ include/drm/gpu_scheduler.h                  |   12 ++++++++++--
+ 23 files changed, 60 insertions(+), 32 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+@@ -681,7 +681,7 @@ int amdgpu_amdkfd_submit_ib(struct amdgp
+               goto err;
+       }
+-      ret = amdgpu_job_alloc(adev, NULL, NULL, NULL, 1, &job);
++      ret = amdgpu_job_alloc(adev, NULL, NULL, NULL, 1, &job, 0);
+       if (ret)
+               goto err;
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+@@ -297,7 +297,8 @@ static int amdgpu_cs_pass1(struct amdgpu
+       for (i = 0; i < p->gang_size; ++i) {
+               ret = amdgpu_job_alloc(p->adev, vm, p->entities[i], vm,
+-                                     num_ibs[i], &p->jobs[i]);
++                                     num_ibs[i], &p->jobs[i],
++                                     p->filp->client_id);
+               if (ret)
+                       goto free_all_kdata;
+               p->jobs[i]->enforce_isolation = p->adev->enforce_isolation[fpriv->xcp_id];
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+@@ -187,7 +187,8 @@ exit:
+ int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+                    struct drm_sched_entity *entity, void *owner,
+-                   unsigned int num_ibs, struct amdgpu_job **job)
++                   unsigned int num_ibs, struct amdgpu_job **job,
++                   u64 drm_client_id)
+ {
+       if (num_ibs == 0)
+               return -EINVAL;
+@@ -210,7 +211,8 @@ int amdgpu_job_alloc(struct amdgpu_devic
+       if (!entity)
+               return 0;
+-      return drm_sched_job_init(&(*job)->base, entity, 1, owner);
++      return drm_sched_job_init(&(*job)->base, entity, 1, owner,
++                                drm_client_id);
+ }
+ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev,
+@@ -220,7 +222,7 @@ int amdgpu_job_alloc_with_ib(struct amdg
+ {
+       int r;
+-      r = amdgpu_job_alloc(adev, NULL, entity, owner, 1, job);
++      r = amdgpu_job_alloc(adev, NULL, entity, owner, 1, job, 0);
+       if (r)
+               return r;
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
+@@ -90,7 +90,8 @@ static inline struct amdgpu_ring *amdgpu
+ int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+                    struct drm_sched_entity *entity, void *owner,
+-                   unsigned int num_ibs, struct amdgpu_job **job);
++                   unsigned int num_ibs, struct amdgpu_job **job,
++                   u64 drm_client_id);
+ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev,
+                            struct drm_sched_entity *entity, void *owner,
+                            size_t size, enum amdgpu_ib_pool_type pool_type,
+--- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
+@@ -535,7 +535,7 @@ int etnaviv_ioctl_gem_submit(struct drm_
+       ret = drm_sched_job_init(&submit->sched_job,
+                                &ctx->sched_entity[args->pipe],
+-                               1, submit->ctx);
++                               1, submit->ctx, file->client_id);
+       if (ret)
+               goto err_submit_put;
+--- a/drivers/gpu/drm/imagination/pvr_job.c
++++ b/drivers/gpu/drm/imagination/pvr_job.c
+@@ -453,7 +453,7 @@ create_job(struct pvr_device *pvr_dev,
+       if (err)
+               goto err_put_job;
+-      err = pvr_queue_job_init(job);
++      err = pvr_queue_job_init(job, pvr_file->file->client_id);
+       if (err)
+               goto err_put_job;
+--- a/drivers/gpu/drm/imagination/pvr_queue.c
++++ b/drivers/gpu/drm/imagination/pvr_queue.c
+@@ -1088,6 +1088,7 @@ static int pvr_queue_cleanup_fw_context(
+ /**
+  * pvr_queue_job_init() - Initialize queue related fields in a pvr_job object.
+  * @job: The job to initialize.
++ * @drm_client_id: drm_file.client_id submitting the job
+  *
+  * Bind the job to a queue and allocate memory to guarantee pvr_queue_job_arm()
+  * and pvr_queue_job_push() can't fail. We also make sure the context type is
+@@ -1097,7 +1098,7 @@ static int pvr_queue_cleanup_fw_context(
+  *  * 0 on success, or
+  *  * An error code if something failed.
+  */
+-int pvr_queue_job_init(struct pvr_job *job)
++int pvr_queue_job_init(struct pvr_job *job, u64 drm_client_id)
+ {
+       /* Fragment jobs need at least one native fence wait on the geometry job fence. */
+       u32 min_native_dep_count = job->type == DRM_PVR_JOB_TYPE_FRAGMENT ? 1 : 0;
+@@ -1114,7 +1115,7 @@ int pvr_queue_job_init(struct pvr_job *j
+       if (!pvr_cccb_cmdseq_can_fit(&queue->cccb, job_cmds_size(job, min_native_dep_count)))
+               return -E2BIG;
+-      err = drm_sched_job_init(&job->base, &queue->entity, 1, THIS_MODULE);
++      err = drm_sched_job_init(&job->base, &queue->entity, 1, THIS_MODULE, drm_client_id);
+       if (err)
+               return err;
+--- a/drivers/gpu/drm/imagination/pvr_queue.h
++++ b/drivers/gpu/drm/imagination/pvr_queue.h
+@@ -143,7 +143,7 @@ struct pvr_queue {
+ bool pvr_queue_fence_is_ufo_backed(struct dma_fence *f);
+-int pvr_queue_job_init(struct pvr_job *job);
++int pvr_queue_job_init(struct pvr_job *job, u64 drm_client_id);
+ void pvr_queue_job_cleanup(struct pvr_job *job);
+--- a/drivers/gpu/drm/lima/lima_gem.c
++++ b/drivers/gpu/drm/lima/lima_gem.c
+@@ -341,7 +341,7 @@ int lima_gem_submit(struct drm_file *fil
+       err = lima_sched_task_init(
+               submit->task, submit->ctx->context + submit->pipe,
+-              bos, submit->nr_bos, vm);
++              bos, submit->nr_bos, vm, file->client_id);
+       if (err)
+               goto err_out1;
+--- a/drivers/gpu/drm/lima/lima_sched.c
++++ b/drivers/gpu/drm/lima/lima_sched.c
+@@ -113,7 +113,8 @@ static inline struct lima_sched_pipe *to
+ int lima_sched_task_init(struct lima_sched_task *task,
+                        struct lima_sched_context *context,
+                        struct lima_bo **bos, int num_bos,
+-                       struct lima_vm *vm)
++                       struct lima_vm *vm,
++                       u64 drm_client_id)
+ {
+       int err, i;
+@@ -124,7 +125,8 @@ int lima_sched_task_init(struct lima_sch
+       for (i = 0; i < num_bos; i++)
+               drm_gem_object_get(&bos[i]->base.base);
+-      err = drm_sched_job_init(&task->base, &context->base, 1, vm);
++      err = drm_sched_job_init(&task->base, &context->base, 1, vm,
++                               drm_client_id);
+       if (err) {
+               kfree(task->bos);
+               return err;
+--- a/drivers/gpu/drm/lima/lima_sched.h
++++ b/drivers/gpu/drm/lima/lima_sched.h
+@@ -88,7 +88,8 @@ struct lima_sched_pipe {
+ int lima_sched_task_init(struct lima_sched_task *task,
+                        struct lima_sched_context *context,
+                        struct lima_bo **bos, int num_bos,
+-                       struct lima_vm *vm);
++                       struct lima_vm *vm,
++                       u64 drm_client_id);
+ void lima_sched_task_fini(struct lima_sched_task *task);
+ int lima_sched_context_init(struct lima_sched_pipe *pipe,
+--- a/drivers/gpu/drm/msm/msm_gem_submit.c
++++ b/drivers/gpu/drm/msm/msm_gem_submit.c
+@@ -30,7 +30,7 @@
+ static struct msm_gem_submit *submit_create(struct drm_device *dev,
+               struct msm_gpu *gpu,
+               struct msm_gpu_submitqueue *queue, uint32_t nr_bos,
+-              uint32_t nr_cmds)
++              uint32_t nr_cmds, u64 drm_client_id)
+ {
+       static atomic_t ident = ATOMIC_INIT(0);
+       struct msm_gem_submit *submit;
+@@ -54,7 +54,8 @@ static struct msm_gem_submit *submit_cre
+               return ERR_PTR(ret);
+       }
+-      ret = drm_sched_job_init(&submit->base, queue->entity, 1, queue);
++      ret = drm_sched_job_init(&submit->base, queue->entity, 1, queue,
++                               drm_client_id);
+       if (ret) {
+               kfree(submit->hw_fence);
+               kfree(submit);
+@@ -712,7 +713,8 @@ int msm_ioctl_gem_submit(struct drm_devi
+               }
+       }
+-      submit = submit_create(dev, gpu, queue, args->nr_bos, args->nr_cmds);
++      submit = submit_create(dev, gpu, queue, args->nr_bos, args->nr_cmds,
++                             file->client_id);
+       if (IS_ERR(submit)) {
+               ret = PTR_ERR(submit);
+               goto out_post_unlock;
+--- a/drivers/gpu/drm/nouveau/nouveau_sched.c
++++ b/drivers/gpu/drm/nouveau/nouveau_sched.c
+@@ -87,7 +87,8 @@ nouveau_job_init(struct nouveau_job *job
+       }
+       ret = drm_sched_job_init(&job->base, &sched->entity,
+-                               args->credits, NULL);
++                               args->credits, NULL,
++                               job->file_priv->client_id);
+       if (ret)
+               goto err_free_chains;
+--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
++++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
+@@ -273,7 +273,7 @@ static int panfrost_ioctl_submit(struct
+       ret = drm_sched_job_init(&job->base,
+                                &file_priv->sched_entity[slot],
+-                               1, NULL);
++                               1, NULL, file->client_id);
+       if (ret)
+               goto out_put_job;
+--- a/drivers/gpu/drm/panthor/panthor_drv.c
++++ b/drivers/gpu/drm/panthor/panthor_drv.c
+@@ -908,7 +908,8 @@ static int panthor_ioctl_group_submit(st
+               const struct drm_panthor_queue_submit *qsubmit = &jobs_args[i];
+               struct drm_sched_job *job;
+-              job = panthor_job_create(pfile, args->group_handle, qsubmit);
++              job = panthor_job_create(pfile, args->group_handle, qsubmit,
++                                       file->client_id);
+               if (IS_ERR(job)) {
+                       ret = PTR_ERR(job);
+                       goto out_cleanup_submit_ctx;
+--- a/drivers/gpu/drm/panthor/panthor_mmu.c
++++ b/drivers/gpu/drm/panthor/panthor_mmu.c
+@@ -2498,7 +2498,7 @@ panthor_vm_bind_job_create(struct drm_fi
+       kref_init(&job->refcount);
+       job->vm = panthor_vm_get(vm);
+-      ret = drm_sched_job_init(&job->base, &vm->entity, 1, vm);
++      ret = drm_sched_job_init(&job->base, &vm->entity, 1, vm, file->client_id);
+       if (ret)
+               goto err_put_job;
+--- a/drivers/gpu/drm/panthor/panthor_sched.c
++++ b/drivers/gpu/drm/panthor/panthor_sched.c
+@@ -3664,7 +3664,8 @@ struct panthor_vm *panthor_job_vm(struct
+ struct drm_sched_job *
+ panthor_job_create(struct panthor_file *pfile,
+                  u16 group_handle,
+-                 const struct drm_panthor_queue_submit *qsubmit)
++                 const struct drm_panthor_queue_submit *qsubmit,
++                 u64 drm_client_id)
+ {
+       struct panthor_group_pool *gpool = pfile->groups;
+       struct panthor_job *job;
+@@ -3736,7 +3737,7 @@ panthor_job_create(struct panthor_file *
+       ret = drm_sched_job_init(&job->base,
+                                &job->group->queues[job->queue_idx]->entity,
+-                               credits, job->group);
++                               credits, job->group, drm_client_id);
+       if (ret)
+               goto err_put_job;
+--- a/drivers/gpu/drm/panthor/panthor_sched.h
++++ b/drivers/gpu/drm/panthor/panthor_sched.h
+@@ -28,7 +28,8 @@ int panthor_group_get_state(struct panth
+ struct drm_sched_job *
+ panthor_job_create(struct panthor_file *pfile,
+                  u16 group_handle,
+-                 const struct drm_panthor_queue_submit *qsubmit);
++                 const struct drm_panthor_queue_submit *qsubmit,
++                 u64 drm_client_id);
+ struct drm_sched_job *panthor_job_get(struct drm_sched_job *job);
+ struct panthor_vm *panthor_job_vm(struct drm_sched_job *sched_job);
+ void panthor_job_put(struct drm_sched_job *job);
+--- a/drivers/gpu/drm/scheduler/sched_fence.c
++++ b/drivers/gpu/drm/scheduler/sched_fence.c
+@@ -204,7 +204,8 @@ struct drm_sched_fence *to_drm_sched_fen
+ EXPORT_SYMBOL(to_drm_sched_fence);
+ struct drm_sched_fence *drm_sched_fence_alloc(struct drm_sched_entity *entity,
+-                                            void *owner)
++                                            void *owner,
++                                            u64 drm_client_id)
+ {
+       struct drm_sched_fence *fence = NULL;
+@@ -213,6 +214,7 @@ struct drm_sched_fence *drm_sched_fence_
+               return NULL;
+       fence->owner = owner;
++      fence->drm_client_id = drm_client_id;
+       spin_lock_init(&fence->lock);
+       return fence;
+--- a/drivers/gpu/drm/scheduler/sched_main.c
++++ b/drivers/gpu/drm/scheduler/sched_main.c
+@@ -772,6 +772,8 @@ EXPORT_SYMBOL(drm_sched_resubmit_jobs);
+  * @credits: the number of credits this job contributes to the schedulers
+  * credit limit
+  * @owner: job owner for debugging
++ * @drm_client_id: &struct drm_file.client_id of the owner (used by trace
++ * events)
+  *
+  * Refer to drm_sched_entity_push_job() documentation
+  * for locking considerations.
+@@ -788,7 +790,8 @@ EXPORT_SYMBOL(drm_sched_resubmit_jobs);
+  */
+ int drm_sched_job_init(struct drm_sched_job *job,
+                      struct drm_sched_entity *entity,
+-                     u32 credits, void *owner)
++                     u32 credits, void *owner,
++                     uint64_t drm_client_id)
+ {
+       if (!entity->rq) {
+               /* This will most likely be followed by missing frames
+@@ -814,7 +817,7 @@ int drm_sched_job_init(struct drm_sched_
+       job->entity = entity;
+       job->credits = credits;
+-      job->s_fence = drm_sched_fence_alloc(entity, owner);
++      job->s_fence = drm_sched_fence_alloc(entity, owner, drm_client_id);
+       if (!job->s_fence)
+               return -ENOMEM;
+--- a/drivers/gpu/drm/v3d/v3d_submit.c
++++ b/drivers/gpu/drm/v3d/v3d_submit.c
+@@ -186,7 +186,7 @@ v3d_job_init(struct v3d_dev *v3d, struct
+       job->file = file_priv;
+       ret = drm_sched_job_init(&job->base, &v3d_priv->sched_entity[queue],
+-                               1, v3d_priv);
++                               1, v3d_priv, file_priv->client_id);
+       if (ret)
+               return ret;
+--- a/drivers/gpu/drm/xe/xe_sched_job.c
++++ b/drivers/gpu/drm/xe/xe_sched_job.c
+@@ -113,7 +113,8 @@ struct xe_sched_job *xe_sched_job_create
+       kref_init(&job->refcount);
+       xe_exec_queue_get(job->q);
+-      err = drm_sched_job_init(&job->drm, q->entity, 1, NULL);
++      err = drm_sched_job_init(&job->drm, q->entity, 1, NULL,
++                               q->xef ? q->xef->drm->client_id : 0);
+       if (err)
+               goto err_free;
+--- a/include/drm/gpu_scheduler.h
++++ b/include/drm/gpu_scheduler.h
+@@ -309,6 +309,13 @@ struct drm_sched_fence {
+          * @owner: job owner for debugging
+          */
+       void                            *owner;
++
++      /**
++       * @drm_client_id:
++       *
++       * The client_id of the drm_file which owns the job.
++       */
++      uint64_t                        drm_client_id;
+ };
+ struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f);
+@@ -553,7 +560,8 @@ int drm_sched_init(struct drm_gpu_schedu
+ void drm_sched_fini(struct drm_gpu_scheduler *sched);
+ int drm_sched_job_init(struct drm_sched_job *job,
+                      struct drm_sched_entity *entity,
+-                     u32 credits, void *owner);
++                     u32 credits, void *owner,
++                     u64 drm_client_id);
+ void drm_sched_job_arm(struct drm_sched_job *job);
+ int drm_sched_job_add_dependency(struct drm_sched_job *job,
+                                struct dma_fence *fence);
+@@ -613,7 +621,7 @@ bool drm_sched_entity_is_ready(struct dr
+ int drm_sched_entity_error(struct drm_sched_entity *entity);
+ struct drm_sched_fence *drm_sched_fence_alloc(
+-      struct drm_sched_entity *s_entity, void *owner);
++      struct drm_sched_entity *s_entity, void *owner, u64 drm_client_id);
+ void drm_sched_fence_init(struct drm_sched_fence *fence,
+                         struct drm_sched_entity *entity);
+ void drm_sched_fence_free(struct drm_sched_fence *fence);
diff --git a/queue-6.12/drm-tegra-fbdev-remove-offset-into-framebuffer-memory.patch b/queue-6.12/drm-tegra-fbdev-remove-offset-into-framebuffer-memory.patch
new file mode 100644 (file)
index 0000000..0985fde
--- /dev/null
@@ -0,0 +1,61 @@
+From stable+bounces-294035-greg=kroah.com@vger.kernel.org Fri Jul 31 13:23:29 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2026 07:10:52 -0400
+Subject: drm/tegra: fbdev: Remove offset into framebuffer memory
+To: stable@vger.kernel.org
+Cc: Thomas Zimmermann <tzimmermann@suse.de>, dri-devel@lists.freedesktop.org, linux-tegra@vger.kernel.org, Thierry Reding <treding@nvidia.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260731111052.3596094-2-sashal@kernel.org>
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit a18b6e30ecd69096beda4a0c96d2570900c3879a ]
+
+The screen_buffer field in struct fb_info contains the kernel address
+of the first byte of framebuffer memory. Do not add the display offset.
+This offset only describes scrolling during scanout.
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Fixes: de2ba664c30f ("gpu: host1x: drm: Add memory manager and fb")
+Cc: dri-devel@lists.freedesktop.org
+Cc: linux-tegra@vger.kernel.org
+Cc: <stable@vger.kernel.org> # v3.10+
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Link: https://patch.msgid.link/20260421073646.144712-3-tzimmermann@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/tegra/fbdev.c |    8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/drivers/gpu/drm/tegra/fbdev.c
++++ b/drivers/gpu/drm/tegra/fbdev.c
+@@ -75,7 +75,6 @@ static int tegra_fbdev_probe(struct drm_
+       struct fb_info *info = helper->info;
+       unsigned int bytes_per_pixel;
+       struct drm_framebuffer *fb;
+-      unsigned long offset;
+       struct tegra_bo *bo;
+       size_t size;
+       int err;
+@@ -112,9 +111,6 @@ static int tegra_fbdev_probe(struct drm_
+       drm_fb_helper_fill_info(info, helper, sizes);
+-      offset = info->var.xoffset * bytes_per_pixel +
+-               info->var.yoffset * fb->pitches[0];
+-
+       if (bo->pages) {
+               bo->vaddr = vmap(bo->pages, bo->num_pages, VM_MAP,
+                                pgprot_writecombine(PAGE_KERNEL));
+@@ -126,9 +122,9 @@ static int tegra_fbdev_probe(struct drm_
+       }
+       info->flags |= FBINFO_VIRTFB;
+-      info->screen_buffer = bo->vaddr + offset;
++      info->screen_buffer = bo->vaddr;
+       info->screen_size = size;
+-      info->fix.smem_start = (unsigned long)(bo->iova + offset);
++      info->fix.smem_start = (unsigned long)(bo->iova);
+       info->fix.smem_len = size;
+       return 0;
diff --git a/queue-6.12/drm-xe-hold-a-dma-buf-reference-for-imported-bos.patch b/queue-6.12/drm-xe-hold-a-dma-buf-reference-for-imported-bos.patch
new file mode 100644 (file)
index 0000000..c88bc60
--- /dev/null
@@ -0,0 +1,185 @@
+From stable+bounces-294454-greg=kroah.com@vger.kernel.org Sun Aug  2 03:49:43 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat,  1 Aug 2026 21:49:28 -0400
+Subject: drm/xe: Hold a dma-buf reference for imported BOs
+To: stable@vger.kernel.org
+Cc: Nitin Gote <nitin.r.gote@intel.com>, Thomas Hellstrom <thomas.hellstrom@linux.intel.com>, Christian Konig <christian.koenig@amd.com>, Matthew Auld <matthew.auld@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260802014928.509277-2-sashal@kernel.org>
+
+From: Nitin Gote <nitin.r.gote@intel.com>
+
+[ Upstream commit 62775525a27c3b0d56382e08ba81ee2d322058b6 ]
+
+An imported dma-buf BO is created as a ttm_bo_type_sg BO whose
+reservation object is the exporter's dma_buf->resv. The importer,
+however, only takes a dma-buf reference after a successful
+dma_buf_dynamic_attach(). Until then nothing keeps the exporter alive,
+so if the exporter is freed while the BO still references its resv, a
+later access to that resv is a use-after-free:
+
+  Oops: general protection fault, probably for non-canonical address
+        0x6b6b6b6b6b6b6b9c
+  Workqueue: ttm ttm_bo_delayed_delete [ttm]
+  RIP: 0010:mutex_can_spin_on_owner+0x3f/0xc0
+
+This can be reached on two paths:
+
+ - dma_buf_dynamic_attach() fails, or
+ - ttm_bo_init_reserved() fails during BO creation.
+
+In both cases the BO already has bo->base.resv pointing at the exporter
+resv, and sg BOs are always torn down via ttm_bo_delayed_delete(), which
+locks bo->base.resv asynchronously - potentially after the exporter has
+been freed.
+
+Take the dma-buf reference in xe_bo_init_locked(), before
+ttm_bo_init_reserved(), so it also covers a creation failure there, and
+release it in xe_ttm_bo_destroy(). The reference is held for the whole
+BO lifetime, keeping the shared resv alive on every path.
+
+v2:
+  - Reworked the fix to avoid creating the imported sg BO before
+    dma_buf_dynamic_attach() succeeds.
+  - Attach with importer_priv == NULL and make invalidate_mappings ignore
+    incomplete imports.
+
+v3:
+  - Dropped the xe-side reordering approach since importer_priv must be
+    valid when dma_buf_dynamic_attach() publishes the attachment.
+  - Per Christian's suggestion on the v1 thread, keyed the check on
+    import_attach rather than removing the sg guard entirely.
+  - Fixes both xe and amdgpu in a single TTM patch.
+
+v4:
+  - Moved import_attach check to after dma_resv_copy_fences() so fences
+    are copied before returning for successful imports (Thomas).
+  - Removed exporter-alive claim from commit message (Thomas).
+
+v5:
+  - Add drm/xe patch to keep imported sg BOs off the LRU before attach
+    succeeds; the TTM fix alone is not sufficient for xe if the BO is
+    already LRU-visible. (Thomas)
+    v4 patch:
+    https://patchwork.freedesktop.org/patch/736663/?series=169129&rev=2
+  - Patch 1 (drm/ttm) carries Christian's Reviewed-by from v4.
+
+v6:
+  - Reworked the fix based on Thomas' suggestion. Instead of the TTM resv
+    individualization (v1-v5) plus the xe off-LRU/placement handling (v5),
+    just hold a dma-buf reference for the imported BO lifetime so the
+    shared resv can never be freed while the BO still references it.
+    Single xe patch, no TTM change. (Thomas)
+  - Take the reference in xe_bo_init_locked() before ttm_bo_init_reserved()
+    so a TTM creation failure is covered too (Thomas).
+  - Dropped the v5 series (drm/ttm + drm/xe off-LRU); the off-LRU approach
+    also regressed in CI BAT via ttm_bo_pipeline_gutting() creating a ghost
+    BO that outlived the exporter.
+    Link to v5: https://patchwork.freedesktop.org/series/169984/
+
+v7:
+  - Move changelog above --- so it stays in the commit message.
+  - Reorder changelog entries oldest-to-newest. (Thomas)
+
+Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/8023
+Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
+Cc: stable@vger.kernel.org
+Cc: Thomas Hellstrom <thomas.hellstrom@linux.intel.com>
+Cc: Christian Konig <christian.koenig@amd.com>
+Cc: Matthew Auld <matthew.auld@intel.com>
+Suggested-by: Thomas Hellstrom <thomas.hellstrom@linux.intel.com>
+Assisted-by: GitHub_Copilot:claude-sonnet-4.6
+Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Nitin Gote <nitin.r.gote@intel.com>
+Signed-off-by: Matthew Auld <matthew.auld@intel.com>
+Link: https://patch.msgid.link/20260710191027.260160-2-nitin.r.gote@intel.com
+(cherry picked from commit 3516f3fae6be35642f8f06f8a218da6425c0306a)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/xe/xe_bo.c       |   17 +++++++++++++++--
+ drivers/gpu/drm/xe/xe_bo.h       |    2 +-
+ drivers/gpu/drm/xe/xe_bo_types.h |    2 ++
+ drivers/gpu/drm/xe/xe_dma_buf.c  |    2 +-
+ 4 files changed, 19 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/xe/xe_bo.c
++++ b/drivers/gpu/drm/xe/xe_bo.c
+@@ -1131,6 +1131,8 @@ static void xe_ttm_bo_destroy(struct ttm
+       if (bo->ttm.base.import_attach)
+               drm_prime_gem_destroy(&bo->ttm.base, NULL);
++      if (bo->dma_buf)
++              dma_buf_put(bo->dma_buf);
+       drm_gem_object_release(&bo->ttm.base);
+       xe_assert(xe, list_empty(&ttm_bo->base.gpuva.list));
+@@ -1292,7 +1294,7 @@ struct xe_bo *xe_bo_init_locked(struct x
+                               struct xe_tile *tile, struct dma_resv *resv,
+                               struct ttm_lru_bulk_move *bulk, size_t size,
+                               u16 cpu_caching, enum ttm_bo_type type,
+-                              u32 flags)
++                              u32 flags, struct dma_buf *dma_buf)
+ {
+       struct ttm_operation_ctx ctx = {
+               .interruptible = true,
+@@ -1377,6 +1379,17 @@ struct xe_bo *xe_bo_init_locked(struct x
+       placement = (type == ttm_bo_type_sg ||
+                    bo->flags & XE_BO_FLAG_DEFER_BACKING) ? &sys_placement :
+               &bo->placement;
++
++      /*
++       * For imported BOs, keep the exporter dma-buf alive for the BO
++       * lifetime. Taken before ttm_bo_init_reserved() to also cover a
++       * creation failure there. Released in xe_ttm_bo_destroy().
++       */
++      if (dma_buf) {
++              get_dma_buf(dma_buf);
++              bo->dma_buf = dma_buf;
++      }
++
+       err = ttm_bo_init_reserved(&xe->ttm, &bo->ttm, type,
+                                  placement, alignment,
+                                  &ctx, NULL, resv, xe_ttm_bo_destroy);
+@@ -1491,7 +1504,7 @@ __xe_bo_create_locked(struct xe_device *
+                              vm && !xe_vm_in_fault_mode(vm) &&
+                              flags & XE_BO_FLAG_USER ?
+                              &vm->lru_bulk_move : NULL, size,
+-                             cpu_caching, type, flags);
++                             cpu_caching, type, flags, NULL);
+       if (IS_ERR(bo))
+               return bo;
+--- a/drivers/gpu/drm/xe/xe_bo.h
++++ b/drivers/gpu/drm/xe/xe_bo.h
+@@ -84,7 +84,7 @@ struct xe_bo *xe_bo_init_locked(struct x
+                               struct xe_tile *tile, struct dma_resv *resv,
+                               struct ttm_lru_bulk_move *bulk, size_t size,
+                               u16 cpu_caching, enum ttm_bo_type type,
+-                              u32 flags);
++                              u32 flags, struct dma_buf *dma_buf);
+ struct xe_bo *
+ xe_bo_create_locked_range(struct xe_device *xe,
+                         struct xe_tile *tile, struct xe_vm *vm,
+--- a/drivers/gpu/drm/xe/xe_bo_types.h
++++ b/drivers/gpu/drm/xe/xe_bo_types.h
+@@ -30,6 +30,8 @@ struct xe_bo {
+       struct ttm_buffer_object ttm;
+       /** @size: Size of this buffer object */
+       size_t size;
++      /** @dma_buf: Imported dma-buf ref to keep its resv alive. */
++      struct dma_buf *dma_buf;
+       /** @flags: flags for this buffer object */
+       u32 flags;
+       /** @vm: VM this BO is attached to, for extobj this will be NULL */
+--- a/drivers/gpu/drm/xe/xe_dma_buf.c
++++ b/drivers/gpu/drm/xe/xe_dma_buf.c
+@@ -214,7 +214,7 @@ xe_dma_buf_init_obj(struct drm_device *d
+       dma_resv_lock(resv, NULL);
+       bo = xe_bo_init_locked(xe, storage, NULL, resv, NULL, dma_buf->size,
+                              0, /* Will require 1way or 2way for vm_bind */
+-                             ttm_bo_type_sg, XE_BO_FLAG_SYSTEM);
++                             ttm_bo_type_sg, XE_BO_FLAG_SYSTEM, dma_buf);
+       if (IS_ERR(bo)) {
+               ret = PTR_ERR(bo);
+               goto error;
diff --git a/queue-6.12/drm-xe-rename-___xe_bo_create_locked.patch b/queue-6.12/drm-xe-rename-___xe_bo_create_locked.patch
new file mode 100644 (file)
index 0000000..d088027
--- /dev/null
@@ -0,0 +1,97 @@
+From stable+bounces-294453-greg=kroah.com@vger.kernel.org Sun Aug  2 03:49:37 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat,  1 Aug 2026 21:49:27 -0400
+Subject: drm/xe: Rename ___xe_bo_create_locked()
+To: stable@vger.kernel.org
+Cc: "Thomas Hellström" <thomas.hellstrom@linux.intel.com>, "Matthew Brost" <matthew.brost@intel.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260802014928.509277-1-sashal@kernel.org>
+
+From: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+
+[ Upstream commit 550a42a8daee1b056f9b3e6c858e57451a5b315a ]
+
+Don't start external function names with underscores.
+Rename to xe_bo_init_locked().
+
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://lore.kernel.org/r/20250908101246.65025-10-thomas.hellstrom@linux.intel.com
+Stable-dep-of: 62775525a27c ("drm/xe: Hold a dma-buf reference for imported BOs")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/xe/xe_bo.c      |   20 ++++++++++----------
+ drivers/gpu/drm/xe/xe_bo.h      |   10 +++++-----
+ drivers/gpu/drm/xe/xe_dma_buf.c |    6 +++---
+ 3 files changed, 18 insertions(+), 18 deletions(-)
+
+--- a/drivers/gpu/drm/xe/xe_bo.c
++++ b/drivers/gpu/drm/xe/xe_bo.c
+@@ -1288,11 +1288,11 @@ void xe_bo_free(struct xe_bo *bo)
+       kfree(bo);
+ }
+-struct xe_bo *___xe_bo_create_locked(struct xe_device *xe, struct xe_bo *bo,
+-                                   struct xe_tile *tile, struct dma_resv *resv,
+-                                   struct ttm_lru_bulk_move *bulk, size_t size,
+-                                   u16 cpu_caching, enum ttm_bo_type type,
+-                                   u32 flags)
++struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
++                              struct xe_tile *tile, struct dma_resv *resv,
++                              struct ttm_lru_bulk_move *bulk, size_t size,
++                              u16 cpu_caching, enum ttm_bo_type type,
++                              u32 flags)
+ {
+       struct ttm_operation_ctx ctx = {
+               .interruptible = true,
+@@ -1487,11 +1487,11 @@ __xe_bo_create_locked(struct xe_device *
+               }
+       }
+-      bo = ___xe_bo_create_locked(xe, bo, tile, vm ? xe_vm_resv(vm) : NULL,
+-                                  vm && !xe_vm_in_fault_mode(vm) &&
+-                                  flags & XE_BO_FLAG_USER ?
+-                                  &vm->lru_bulk_move : NULL, size,
+-                                  cpu_caching, type, flags);
++      bo = xe_bo_init_locked(xe, bo, tile, vm ? xe_vm_resv(vm) : NULL,
++                             vm && !xe_vm_in_fault_mode(vm) &&
++                             flags & XE_BO_FLAG_USER ?
++                             &vm->lru_bulk_move : NULL, size,
++                             cpu_caching, type, flags);
+       if (IS_ERR(bo))
+               return bo;
+--- a/drivers/gpu/drm/xe/xe_bo.h
++++ b/drivers/gpu/drm/xe/xe_bo.h
+@@ -80,11 +80,11 @@ struct sg_table;
+ struct xe_bo *xe_bo_alloc(void);
+ void xe_bo_free(struct xe_bo *bo);
+-struct xe_bo *___xe_bo_create_locked(struct xe_device *xe, struct xe_bo *bo,
+-                                   struct xe_tile *tile, struct dma_resv *resv,
+-                                   struct ttm_lru_bulk_move *bulk, size_t size,
+-                                   u16 cpu_caching, enum ttm_bo_type type,
+-                                   u32 flags);
++struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
++                              struct xe_tile *tile, struct dma_resv *resv,
++                              struct ttm_lru_bulk_move *bulk, size_t size,
++                              u16 cpu_caching, enum ttm_bo_type type,
++                              u32 flags);
+ struct xe_bo *
+ xe_bo_create_locked_range(struct xe_device *xe,
+                         struct xe_tile *tile, struct xe_vm *vm,
+--- a/drivers/gpu/drm/xe/xe_dma_buf.c
++++ b/drivers/gpu/drm/xe/xe_dma_buf.c
+@@ -212,9 +212,9 @@ xe_dma_buf_init_obj(struct drm_device *d
+       int ret;
+       dma_resv_lock(resv, NULL);
+-      bo = ___xe_bo_create_locked(xe, storage, NULL, resv, NULL, dma_buf->size,
+-                                  0, /* Will require 1way or 2way for vm_bind */
+-                                  ttm_bo_type_sg, XE_BO_FLAG_SYSTEM);
++      bo = xe_bo_init_locked(xe, storage, NULL, resv, NULL, dma_buf->size,
++                             0, /* Will require 1way or 2way for vm_bind */
++                             ttm_bo_type_sg, XE_BO_FLAG_SYSTEM);
+       if (IS_ERR(bo)) {
+               ret = PTR_ERR(bo);
+               goto error;
diff --git a/queue-6.12/drm-xe-wait-on-external-bo-kernel-fences-in-exec-ioctl.patch b/queue-6.12/drm-xe-wait-on-external-bo-kernel-fences-in-exec-ioctl.patch
new file mode 100644 (file)
index 0000000..79072dc
--- /dev/null
@@ -0,0 +1,80 @@
+From stable+bounces-294440-greg=kroah.com@vger.kernel.org Sun Aug  2 01:43:31 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat,  1 Aug 2026 19:43:20 -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@kernel.org>
+Message-ID: <20260801234320.1848118-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@kernel.org>
+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
+@@ -270,13 +270,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++)
index 9a8bbf3aa248d27a748b7ed6b28e53a7252b275b..34e79795c4d12a34870bb5b1a35ecf4a4824f679 100644 (file)
@@ -307,3 +307,18 @@ mptcp-pm-use-addr-entry-for-get_local_id.patch
 mptcp-pm-userspace-fix-use-after-free-in-get_local_id.patch
 kmemleak-iommu-iova-fix-transient-kmemleak-false-positive.patch
 mm-kmemleak-fix-checksum-computation-for-per-cpu-objects.patch
+drm-amdgpu-respect-placement-requirements-in-amdgpu_gtt_mgr-functions.patch
+drm-amdgpu-fix-context-pstate-override-handling.patch
+drm-sched-store-the-drm-client_id-in-drm_sched_fence.patch
+drm-amdgpu-give-each-kernel-job-a-unique-id.patch
+drm-amdgpu-gfx-fix-cleaner-shader-ib-buffer-overflow.patch
+drm-fb-helper-allocate-and-release-fb_info-in-single-place.patch
+drm-tegra-fbdev-remove-offset-into-framebuffer-memory.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
+drm-i915-vrr-check-has_vrr-first-in-intel_vrr_is_capable.patch
+drm-i915-vrr-require-valid-min-max-vfreq-for-vrr.patch
+drm-xe-rename-___xe_bo_create_locked.patch
+drm-xe-hold-a-dma-buf-reference-for-imported-bos.patch
+drm-i915-hdcp-move-to-using-intel_display-in-intel_hdcp.patch
+drm-i915-hdcp-require-monotonically-increasing-seq_num_v.patch