--- /dev/null
+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, ¤t_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, ¤t_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, ¤t_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);
+ }
+
--- /dev/null
+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);
+
--- /dev/null
+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(¶ms, NULL);
++ r = vm->update_funcs->prepare(¶ms, 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(¶ms, sync);
++ r = vm->update_funcs->prepare(¶ms, 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(¶ms, NULL);
++ r = vm->update_funcs->prepare(¶ms, 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;
+
--- /dev/null
+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;
+ }
+
+ /**
--- /dev/null
+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
--- /dev/null
+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)
+ {
+ }
--- /dev/null
+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 ? >->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;
--- /dev/null
+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;
+ }
+
--- /dev/null
+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)
--- /dev/null
+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;
+ }
+
--- /dev/null
+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);
--- /dev/null
+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;
--- /dev/null
+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;
--- /dev/null
+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;
--- /dev/null
+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++)
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