From: Greg Kroah-Hartman Date: Fri, 7 Aug 2026 13:05:37 +0000 (+0200) Subject: 6.12-stable patches X-Git-Tag: v6.6.151~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9ccebd32953d1f7a136f2690e52a88fd98aa1358;p=thirdparty%2Fkernel%2Fstable-queue.git 6.12-stable patches added patches: drm-amdgpu-fix-context-pstate-override-handling.patch drm-amdgpu-gfx-fix-cleaner-shader-ib-buffer-overflow.patch drm-amdgpu-give-each-kernel-job-a-unique-id.patch drm-amdgpu-respect-placement-requirements-in-amdgpu_gtt_mgr-functions.patch drm-exec-remove-the-index-parameter-from-drm_exec_for_each_locked_obj.patch drm-fb-helper-allocate-and-release-fb_info-in-single-place.patch drm-i915-hdcp-move-to-using-intel_display-in-intel_hdcp.patch drm-i915-hdcp-require-monotonically-increasing-seq_num_v.patch drm-i915-vrr-check-has_vrr-first-in-intel_vrr_is_capable.patch drm-i915-vrr-require-valid-min-max-vfreq-for-vrr.patch drm-sched-store-the-drm-client_id-in-drm_sched_fence.patch drm-tegra-fbdev-remove-offset-into-framebuffer-memory.patch drm-xe-hold-a-dma-buf-reference-for-imported-bos.patch drm-xe-rename-___xe_bo_create_locked.patch drm-xe-wait-on-external-bo-kernel-fences-in-exec-ioctl.patch --- diff --git a/queue-6.12/drm-amdgpu-fix-context-pstate-override-handling.patch b/queue-6.12/drm-amdgpu-fix-context-pstate-override-handling.patch new file mode 100644 index 0000000000..48070e4bb9 --- /dev/null +++ b/queue-6.12/drm-amdgpu-fix-context-pstate-override-handling.patch @@ -0,0 +1,165 @@ +From stable+bounces-294146-greg=kroah.com@vger.kernel.org Fri Jul 31 18:47:58 2026 +From: Sasha Levin +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" , "Chengming Gui" , "Alex Deucher" , "Christian König" , "Sasha Levin" +Message-ID: <20260731162530.789974-1-sashal@kernel.org> + +From: Tvrtko Ursulin + +[ 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 +Fixes: 79610d304133 ("drm/amdgpu: fix pstate setting issue") +Cc: Chengming Gui +Cc: Alex Deucher +Cc: "Christian König" +Signed-off-by: Alex Deucher +(cherry picked from commit 1b5e413713c0a93bc1818394d0ce49aaad21bd27) +Cc: # v6.1+ +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + 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); + } + diff --git a/queue-6.12/drm-amdgpu-gfx-fix-cleaner-shader-ib-buffer-overflow.patch b/queue-6.12/drm-amdgpu-gfx-fix-cleaner-shader-ib-buffer-overflow.patch new file mode 100644 index 0000000000..086286dad9 --- /dev/null +++ b/queue-6.12/drm-amdgpu-gfx-fix-cleaner-shader-ib-buffer-overflow.patch @@ -0,0 +1,74 @@ +From stable+bounces-294122-greg=kroah.com@vger.kernel.org Fri Jul 31 17:54:19 2026 +From: Sasha Levin +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 , Lijo Lazar , Alex Deucher , Sasha Levin +Message-ID: <20260731154959.602805-3-sashal@kernel.org> + +From: Asad Kamal + +[ 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 +Signed-off-by: Asad Kamal +Reviewed-by: Lijo Lazar +Signed-off-by: Alex Deucher +(cherry picked from commit bf21af331ebf72d0935fd70c73192414a422c03a) +CC: stable@vger.kernel.org +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +@@ -1426,12 +1426,13 @@ static int amdgpu_gfx_run_cleaner_shader + struct amdgpu_device *adev = ring->adev; + struct drm_gpu_scheduler *sched = &ring->sched; + struct drm_sched_entity entity; ++ unsigned int ib_size_dw = 16; + static atomic_t counter; + struct dma_fence *f; + struct amdgpu_job *job; + struct amdgpu_ib *ib; + void *owner; +- int i, r; ++ int r; + + /* Initialize the scheduler entity */ + r = drm_sched_entity_init(&entity, DRM_SCHED_PRIORITY_NORMAL, +@@ -1449,7 +1450,7 @@ static int amdgpu_gfx_run_cleaner_shader + owner = (void *)(unsigned long)atomic_inc_return(&counter); + + r = amdgpu_job_alloc_with_ib(ring->adev, &entity, owner, +- 64, 0, &job, ++ ib_size_dw * sizeof(uint32_t), 0, &job, + AMDGPU_KERNEL_JOB_ID_CLEANER_SHADER); + if (r) + goto err; +@@ -1457,9 +1458,8 @@ static int amdgpu_gfx_run_cleaner_shader + job->enforce_isolation = true; + + ib = &job->ibs[0]; +- for (i = 0; i <= ring->funcs->align_mask; ++i) +- ib->ptr[i] = ring->funcs->nop; +- ib->length_dw = ring->funcs->align_mask + 1; ++ memset32(ib->ptr, ring->funcs->nop, ib_size_dw); ++ ib->length_dw = ib_size_dw; + + f = amdgpu_job_submit(job); + diff --git a/queue-6.12/drm-amdgpu-give-each-kernel-job-a-unique-id.patch b/queue-6.12/drm-amdgpu-give-each-kernel-job-a-unique-id.patch new file mode 100644 index 0000000000..54356857b3 --- /dev/null +++ b/queue-6.12/drm-amdgpu-give-each-kernel-job-a-unique-id.patch @@ -0,0 +1,520 @@ +From stable+bounces-294123-greg=kroah.com@vger.kernel.org Fri Jul 31 18:01:33 2026 +From: Sasha Levin +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 , Alex Deucher , Arunpravin Paneer Selvam , Sasha Levin +Message-ID: <20260731154959.602805-2-sashal@kernel.org> + +From: Pierre-Eric Pelloux-Prayer + +[ 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 +Acked-by: Alex Deucher +Signed-off-by: Arunpravin Paneer Selvam +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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; + diff --git a/queue-6.12/drm-amdgpu-respect-placement-requirements-in-amdgpu_gtt_mgr-functions.patch b/queue-6.12/drm-amdgpu-respect-placement-requirements-in-amdgpu_gtt_mgr-functions.patch new file mode 100644 index 0000000000..bd1d26e2b5 --- /dev/null +++ b/queue-6.12/drm-amdgpu-respect-placement-requirements-in-amdgpu_gtt_mgr-functions.patch @@ -0,0 +1,75 @@ +From stable+bounces-294155-greg=kroah.com@vger.kernel.org Fri Jul 31 19:25:03 2026 +From: Sasha Levin +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" , "Christian König" , "Alex Deucher" , "Sasha Levin" +Message-ID: <20260731163901.838294-1-sashal@kernel.org> + +From: Timur Kristóf + +[ 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 +Signed-off-by: Timur Kristóf +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +(cherry picked from commit bc06579ca29dee9c245a41b12e39c7bb6938af5d) +Cc: stable@vger.kernel.org +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c | 30 ++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c +@@ -217,7 +217,20 @@ static bool amdgpu_gtt_mgr_intersects(st + const struct ttm_place *place, + size_t size) + { +- return !place->lpfn || amdgpu_gtt_mgr_has_gart_addr(res); ++ const struct drm_mm_node *const node = &to_ttm_range_mgr_node(res)->mm_nodes[0]; ++ const u32 num_pages = PFN_UP(size); ++ ++ if (!place->lpfn) ++ return true; ++ ++ if (!amdgpu_gtt_mgr_has_gart_addr(res)) ++ return false; ++ ++ if (place->fpfn >= (node->start + num_pages) || ++ (place->lpfn && place->lpfn <= node->start)) ++ return false; ++ ++ return true; + } + + /** +@@ -235,7 +248,20 @@ static bool amdgpu_gtt_mgr_compatible(st + const struct ttm_place *place, + size_t size) + { +- return !place->lpfn || amdgpu_gtt_mgr_has_gart_addr(res); ++ const struct drm_mm_node *const node = &to_ttm_range_mgr_node(res)->mm_nodes[0]; ++ const u32 num_pages = PFN_UP(size); ++ ++ if (!place->lpfn) ++ return true; ++ ++ if (!amdgpu_gtt_mgr_has_gart_addr(res)) ++ return false; ++ ++ if (node->start < place->fpfn || ++ (place->lpfn && (node->start + num_pages) > place->lpfn)) ++ return false; ++ ++ return true; + } + + /** diff --git a/queue-6.12/drm-exec-remove-the-index-parameter-from-drm_exec_for_each_locked_obj.patch b/queue-6.12/drm-exec-remove-the-index-parameter-from-drm_exec_for_each_locked_obj.patch new file mode 100644 index 0000000000..4f7505c2e1 --- /dev/null +++ b/queue-6.12/drm-exec-remove-the-index-parameter-from-drm_exec_for_each_locked_obj.patch @@ -0,0 +1,195 @@ +From stable+bounces-294439-greg=kroah.com@vger.kernel.org Sun Aug 2 01:43:31 2026 +From: Sasha Levin +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" , "Christian König" , "Sasha Levin" +Message-ID: <20260801234320.1848118-1-sashal@kernel.org> + +From: Thomas Hellström + +[ Upstream commit ce44b78512e9102aea54ff6b6e521d6c8de9f31c ] + +Nobody makes any use of it. Possible internal future users can +instead use the _index variable. External users shouldn't use +it since the array it's pointing into is internal drm_exec state. + +v2: +- Use a unique id for the loop variable (Christian) + +Assisted-by: GitHub Copilot:claude-sonnet-4.6 +Signed-off-by: Thomas Hellström +Reviewed-by: Christian König +Link: https://patch.msgid.link/20260520101616.41284-2-thomas.hellstrom@linux.intel.com +Stable-dep-of: af80e2bfde93 ("drm/xe: Wait on external BO kernel fences in exec IOCTL") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 9 +++------ + drivers/gpu/drm/drm_exec.c | 6 ++---- + drivers/gpu/drm/drm_gpuvm.c | 3 +-- + drivers/gpu/drm/xe/xe_vm.c | 3 +-- + include/drm/drm_exec.h | 20 ++++++++++++-------- + 5 files changed, 19 insertions(+), 22 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +@@ -848,7 +848,6 @@ static int amdgpu_cs_parser_bos(struct a + struct amdgpu_vm *vm = &fpriv->vm; + struct amdgpu_bo_list_entry *e; + struct drm_gem_object *obj; +- unsigned long index; + unsigned int i; + int r; + +@@ -969,7 +968,7 @@ static int amdgpu_cs_parser_bos(struct a + goto out_free_user_pages; + } + +- drm_exec_for_each_locked_object(&p->exec, index, obj) { ++ drm_exec_for_each_locked_object(&p->exec, obj) { + r = amdgpu_cs_bo_validate(p, gem_to_amdgpu_bo(obj)); + if (unlikely(r)) + goto out_free_user_pages; +@@ -1207,7 +1206,6 @@ static int amdgpu_cs_sync_rings(struct a + struct drm_gpu_scheduler *sched; + struct drm_gem_object *obj; + struct dma_fence *fence; +- unsigned long index; + unsigned int i; + int r; + +@@ -1218,7 +1216,7 @@ static int amdgpu_cs_sync_rings(struct a + return r; + } + +- drm_exec_for_each_locked_object(&p->exec, index, obj) { ++ drm_exec_for_each_locked_object(&p->exec, obj) { + struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); + + struct dma_resv *resv = bo->tbo.base.resv; +@@ -1286,7 +1284,6 @@ static int amdgpu_cs_submit(struct amdgp + struct amdgpu_vm *vm = &fpriv->vm; + struct amdgpu_bo_list_entry *e; + struct drm_gem_object *gobj; +- unsigned long index; + unsigned int i; + uint64_t seq; + int r; +@@ -1337,7 +1334,7 @@ static int amdgpu_cs_submit(struct amdgp + } + + p->fence = dma_fence_get(&leader->base.s_fence->finished); +- drm_exec_for_each_locked_object(&p->exec, index, gobj) { ++ drm_exec_for_each_locked_object(&p->exec, gobj) { + + ttm_bo_move_to_lru_tail_unlocked(&gem_to_amdgpu_bo(gobj)->tbo); + +--- a/drivers/gpu/drm/drm_exec.c ++++ b/drivers/gpu/drm/drm_exec.c +@@ -22,7 +22,6 @@ + * + * struct drm_gem_object *obj; + * struct drm_exec exec; +- * unsigned long index; + * int ret; + * + * drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); +@@ -38,7 +37,7 @@ + * goto error; + * } + * +- * drm_exec_for_each_locked_object(&exec, index, obj) { ++ * drm_exec_for_each_locked_object(&exec, obj) { + * dma_resv_add_fence(obj->resv, fence, DMA_RESV_USAGE_READ); + * ... + * } +@@ -54,9 +53,8 @@ + static void drm_exec_unlock_all(struct drm_exec *exec) + { + struct drm_gem_object *obj; +- unsigned long index; + +- drm_exec_for_each_locked_object_reverse(exec, index, obj) { ++ drm_exec_for_each_locked_object_reverse(exec, obj) { + dma_resv_unlock(obj->resv); + drm_gem_object_put(obj); + } +--- a/drivers/gpu/drm/drm_gpuvm.c ++++ b/drivers/gpu/drm/drm_gpuvm.c +@@ -1451,9 +1451,8 @@ drm_gpuvm_resv_add_fence(struct drm_gpuv + enum dma_resv_usage extobj_usage) + { + struct drm_gem_object *obj; +- unsigned long index; + +- drm_exec_for_each_locked_object(exec, index, obj) { ++ drm_exec_for_each_locked_object(exec, obj) { + dma_resv_assert_held(obj->resv); + dma_resv_add_fence(obj->resv, fence, + drm_gpuvm_is_extobj(gpuvm, obj) ? +--- a/drivers/gpu/drm/xe/xe_vm.c ++++ b/drivers/gpu/drm/xe/xe_vm.c +@@ -418,7 +418,6 @@ int xe_vm_validate_rebind(struct xe_vm * + unsigned int num_fences) + { + struct drm_gem_object *obj; +- unsigned long index; + int ret; + + do { +@@ -431,7 +430,7 @@ int xe_vm_validate_rebind(struct xe_vm * + return ret; + } while (!list_empty(&vm->gpuvm.evict.list)); + +- drm_exec_for_each_locked_object(exec, index, obj) { ++ drm_exec_for_each_locked_object(exec, obj) { + ret = dma_resv_reserve_fences(obj->resv, num_fences); + if (ret) + return ret; +--- a/include/drm/drm_exec.h ++++ b/include/drm/drm_exec.h +@@ -65,31 +65,35 @@ drm_exec_obj(struct drm_exec *exec, unsi + return index < exec->num_objects ? exec->objects[index] : NULL; + } + ++/* Helper for drm_exec_for_each_locked_object(). Internal use only. */ ++#define __drm_exec_for_each_locked_object(exec, obj, __index) \ ++ for (unsigned long __index = 0; ((obj) = drm_exec_obj(exec, __index)); ++__index) + /** + * drm_exec_for_each_locked_object - iterate over all the locked objects + * @exec: drm_exec object +- * @index: unsigned long index for the iteration + * @obj: the current GEM object + * + * Iterate over all the locked GEM objects inside the drm_exec object. + */ +-#define drm_exec_for_each_locked_object(exec, index, obj) \ +- for ((index) = 0; ((obj) = drm_exec_obj(exec, index)); ++(index)) ++#define drm_exec_for_each_locked_object(exec, obj) \ ++ __drm_exec_for_each_locked_object(exec, obj, __UNIQUE_ID(drm_exec)) + ++/* Helper for drm_exec_for_each_locked_object_reverse(). Internal use only. */ ++#define __drm_exec_for_each_locked_object_reverse(exec, obj, __index) \ ++ for (unsigned long __index = (exec)->num_objects - 1; \ ++ ((obj) = drm_exec_obj(exec, __index)); --__index) + /** + * drm_exec_for_each_locked_object_reverse - iterate over all the locked + * objects in reverse locking order + * @exec: drm_exec object +- * @index: unsigned long index for the iteration + * @obj: the current GEM object + * + * Iterate over all the locked GEM objects inside the drm_exec object in +- * reverse locking order. Note that @index may go below zero and wrap, ++ * reverse locking order. Note that the internal index may wrap around, + * but that will be caught by drm_exec_obj(), returning a NULL object. + */ +-#define drm_exec_for_each_locked_object_reverse(exec, index, obj) \ +- for ((index) = (exec)->num_objects - 1; \ +- ((obj) = drm_exec_obj(exec, index)); --(index)) ++#define drm_exec_for_each_locked_object_reverse(exec, obj) \ ++ __drm_exec_for_each_locked_object_reverse(exec, obj, __UNIQUE_ID(drm_exec)) + + /** + * drm_exec_until_all_locked - loop until all GEM objects are locked diff --git a/queue-6.12/drm-fb-helper-allocate-and-release-fb_info-in-single-place.patch b/queue-6.12/drm-fb-helper-allocate-and-release-fb_info-in-single-place.patch new file mode 100644 index 0000000000..992553eee2 --- /dev/null +++ b/queue-6.12/drm-fb-helper-allocate-and-release-fb_info-in-single-place.patch @@ -0,0 +1,528 @@ +From stable+bounces-294034-greg=kroah.com@vger.kernel.org Fri Jul 31 13:13:59 2026 +From: Sasha Levin +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" , "Christian König" , "Dmitry Baryshkov" , "Javier Martinez Canillas" , "Sasha Levin" +Message-ID: <20260731111052.3596094-1-sashal@kernel.org> + +From: Thomas Zimmermann + +[ 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 +Acked-by: Christian König # radeon +Acked-by: Dmitry Baryshkov # msm +Acked-by: Javier Martinez Canillas +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 +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/armada/armada_fbdev.c | 12 -------- + drivers/gpu/drm/drm_fb_helper.c | 39 ++++++++--------------------- + drivers/gpu/drm/drm_fbdev_dma.c | 12 +------- + drivers/gpu/drm/drm_fbdev_shmem.c | 12 +------- + drivers/gpu/drm/drm_fbdev_ttm.c | 12 +------- + drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 9 ------ + drivers/gpu/drm/gma500/fbdev.c | 13 --------- + drivers/gpu/drm/i915/display/intel_fbdev.c | 9 ------ + drivers/gpu/drm/msm/msm_fbdev.c | 9 ------ + drivers/gpu/drm/omapdrm/omap_fbdev.c | 9 ------ + drivers/gpu/drm/radeon/radeon_fbdev.c | 13 --------- + drivers/gpu/drm/tegra/fbdev.c | 9 ------ + include/drm/drm_fb_helper.h | 12 -------- + 13 files changed, 26 insertions(+), 144 deletions(-) + +--- a/drivers/gpu/drm/armada/armada_fbdev.c ++++ b/drivers/gpu/drm/armada/armada_fbdev.c +@@ -43,10 +43,10 @@ static int armada_fbdev_create(struct dr + struct drm_fb_helper_surface_size *sizes) + { + struct drm_device *dev = fbh->dev; ++ struct fb_info *info = fbh->info; + struct drm_mode_fb_cmd2 mode; + struct armada_framebuffer *dfb; + struct armada_gem_object *obj; +- struct fb_info *info; + int size, ret; + void *ptr; + +@@ -87,12 +87,6 @@ static int armada_fbdev_create(struct dr + if (IS_ERR(dfb)) + return PTR_ERR(dfb); + +- info = drm_fb_helper_alloc_info(fbh); +- if (IS_ERR(info)) { +- ret = PTR_ERR(info); +- goto err_fballoc; +- } +- + info->fbops = &armada_fb_ops; + info->fix.smem_start = obj->phys_addr; + info->fix.smem_len = obj->obj.size; +@@ -107,10 +101,6 @@ static int armada_fbdev_create(struct dr + (unsigned long long)obj->phys_addr); + + return 0; +- +- err_fballoc: +- dfb->fb.funcs->destroy(&dfb->fb); +- return ret; + } + + static int armada_fb_probe(struct drm_fb_helper *fbh, +--- a/drivers/gpu/drm/drm_fb_helper.c ++++ b/drivers/gpu/drm/drm_fb_helper.c +@@ -485,20 +485,7 @@ int drm_fb_helper_init(struct drm_device + } + EXPORT_SYMBOL(drm_fb_helper_init); + +-/** +- * drm_fb_helper_alloc_info - allocate fb_info and some of its members +- * @fb_helper: driver-allocated fbdev helper +- * +- * A helper to alloc fb_info and the member cmap. Called by the driver +- * within the struct &drm_driver.fbdev_probe callback function. Drivers do +- * not need to release the allocated fb_info structure themselves, this is +- * automatically done when calling drm_fb_helper_fini(). +- * +- * RETURNS: +- * fb_info pointer if things went okay, pointer containing error code +- * otherwise +- */ +-struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper) ++static struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper) + { + struct device *dev = fb_helper->dev->dev; + struct fb_info *info; +@@ -525,17 +512,8 @@ err_release: + framebuffer_release(info); + return ERR_PTR(ret); + } +-EXPORT_SYMBOL(drm_fb_helper_alloc_info); + +-/** +- * drm_fb_helper_release_info - release fb_info and its members +- * @fb_helper: driver-allocated fbdev helper +- * +- * A helper to release fb_info and the member cmap. Drivers do not +- * need to release the allocated fb_info structure themselves, this is +- * automatically done when calling drm_fb_helper_fini(). +- */ +-void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper) ++static void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper) + { + struct fb_info *info = fb_helper->info; + +@@ -548,7 +526,6 @@ void drm_fb_helper_release_info(struct d + fb_dealloc_cmap(&info->cmap); + framebuffer_release(info); + } +-EXPORT_SYMBOL(drm_fb_helper_release_info); + + /** + * drm_fb_helper_unregister_info - unregister fb_info framebuffer device +@@ -1803,6 +1780,11 @@ __drm_fb_helper_initial_config_and_unloc + height = dev->mode_config.max_height; + + drm_client_modeset_probe(&fb_helper->client, width, height); ++ ++ info = drm_fb_helper_alloc_info(fb_helper); ++ if (IS_ERR(info)) ++ return PTR_ERR(info); ++ + ret = drm_fb_helper_single_fb_probe(fb_helper); + if (ret < 0) { + if (ret == -EAGAIN) { +@@ -1811,13 +1793,12 @@ __drm_fb_helper_initial_config_and_unloc + } + mutex_unlock(&fb_helper->lock); + +- return ret; ++ goto err_drm_fb_helper_release_info; + } + drm_setup_crtcs_fb(fb_helper); + + fb_helper->deferred_setup = false; + +- info = fb_helper->info; + info->var.pixclock = 0; + + /* Need to drop locks to avoid recursive deadlock in +@@ -1840,6 +1821,10 @@ __drm_fb_helper_initial_config_and_unloc + mutex_unlock(&kernel_fb_helper_lock); + + return 0; ++ ++err_drm_fb_helper_release_info: ++ drm_fb_helper_release_info(fb_helper); ++ return ret; + } + + /** +--- a/drivers/gpu/drm/drm_fbdev_dma.c ++++ b/drivers/gpu/drm/drm_fbdev_dma.c +@@ -280,9 +280,9 @@ int drm_fbdev_dma_driver_fbdev_probe(str + { + struct drm_client_dev *client = &fb_helper->client; + struct drm_device *dev = fb_helper->dev; ++ struct fb_info *info = fb_helper->info; + struct drm_client_buffer *buffer; + struct drm_framebuffer *fb; +- struct fb_info *info; + u32 format; + struct iosys_map map; + int ret; +@@ -312,12 +312,6 @@ int drm_fbdev_dma_driver_fbdev_probe(str + fb_helper->buffer = buffer; + fb_helper->fb = fb; + +- info = drm_fb_helper_alloc_info(fb_helper); +- if (IS_ERR(info)) { +- ret = PTR_ERR(info); +- goto err_drm_client_buffer_vunmap; +- } +- + drm_fb_helper_fill_info(info, fb_helper, sizes); + + if (fb->funcs->dirty) +@@ -325,12 +319,10 @@ int drm_fbdev_dma_driver_fbdev_probe(str + else + ret = drm_fbdev_dma_driver_fbdev_probe_tail(fb_helper, sizes); + if (ret) +- goto err_drm_fb_helper_release_info; ++ goto err_drm_client_buffer_vunmap; + + return 0; + +-err_drm_fb_helper_release_info: +- drm_fb_helper_release_info(fb_helper); + err_drm_client_buffer_vunmap: + fb_helper->fb = NULL; + fb_helper->buffer = NULL; +--- a/drivers/gpu/drm/drm_fbdev_shmem.c ++++ b/drivers/gpu/drm/drm_fbdev_shmem.c +@@ -110,10 +110,10 @@ static int drm_fbdev_shmem_helper_fb_pro + { + struct drm_client_dev *client = &fb_helper->client; + struct drm_device *dev = fb_helper->dev; ++ struct fb_info *info = fb_helper->info; + struct drm_client_buffer *buffer; + struct drm_gem_shmem_object *shmem; + struct drm_framebuffer *fb; +- struct fb_info *info; + u32 format; + struct iosys_map map; + int ret; +@@ -142,12 +142,6 @@ static int drm_fbdev_shmem_helper_fb_pro + fb_helper->buffer = buffer; + fb_helper->fb = fb; + +- info = drm_fb_helper_alloc_info(fb_helper); +- if (IS_ERR(info)) { +- ret = PTR_ERR(info); +- goto err_drm_client_buffer_vunmap; +- } +- + drm_fb_helper_fill_info(info, fb_helper, sizes); + + info->fbops = &drm_fbdev_shmem_fb_ops; +@@ -168,12 +162,10 @@ static int drm_fbdev_shmem_helper_fb_pro + info->fbdefio = &fb_helper->fbdefio; + ret = fb_deferred_io_init(info); + if (ret) +- goto err_drm_fb_helper_release_info; ++ goto err_drm_client_buffer_vunmap; + + return 0; + +-err_drm_fb_helper_release_info: +- drm_fb_helper_release_info(fb_helper); + err_drm_client_buffer_vunmap: + fb_helper->fb = NULL; + fb_helper->buffer = NULL; +--- a/drivers/gpu/drm/drm_fbdev_ttm.c ++++ b/drivers/gpu/drm/drm_fbdev_ttm.c +@@ -185,8 +185,8 @@ int drm_fbdev_ttm_driver_fbdev_probe(str + { + struct drm_client_dev *client = &fb_helper->client; + struct drm_device *dev = fb_helper->dev; ++ struct fb_info *info = fb_helper->info; + struct drm_client_buffer *buffer; +- struct fb_info *info; + size_t screen_size; + void *screen_buffer; + u32 format; +@@ -214,12 +214,6 @@ int drm_fbdev_ttm_driver_fbdev_probe(str + goto err_drm_client_framebuffer_delete; + } + +- info = drm_fb_helper_alloc_info(fb_helper); +- if (IS_ERR(info)) { +- ret = PTR_ERR(info); +- goto err_vfree; +- } +- + drm_fb_helper_fill_info(info, fb_helper, sizes); + + info->fbops = &drm_fbdev_ttm_fb_ops; +@@ -236,12 +230,10 @@ int drm_fbdev_ttm_driver_fbdev_probe(str + info->fbdefio = &fb_helper->fbdefio; + ret = fb_deferred_io_init(info); + if (ret) +- goto err_drm_fb_helper_release_info; ++ goto err_vfree; + + return 0; + +-err_drm_fb_helper_release_info: +- drm_fb_helper_release_info(fb_helper); + err_vfree: + vfree(screen_buffer); + err_drm_client_framebuffer_delete: +--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c ++++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +@@ -60,18 +60,11 @@ static int exynos_drm_fbdev_update(struc + struct drm_fb_helper_surface_size *sizes, + struct exynos_drm_gem *exynos_gem) + { +- struct fb_info *fbi; ++ struct fb_info *fbi = helper->info; + struct drm_framebuffer *fb = helper->fb; + unsigned int size = fb->width * fb->height * fb->format->cpp[0]; + unsigned long offset; + +- fbi = drm_fb_helper_alloc_info(helper); +- if (IS_ERR(fbi)) { +- DRM_DEV_ERROR(to_dma_dev(helper->dev), +- "failed to allocate fb info.\n"); +- return PTR_ERR(fbi); +- } +- + fbi->fbops = &exynos_drm_fb_ops; + + drm_fb_helper_fill_info(fbi, helper, sizes); +--- a/drivers/gpu/drm/gma500/fbdev.c ++++ b/drivers/gpu/drm/gma500/fbdev.c +@@ -110,7 +110,7 @@ static int psb_fbdev_fb_probe(struct drm + struct drm_device *dev = fb_helper->dev; + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); + struct pci_dev *pdev = to_pci_dev(dev->dev); +- struct fb_info *info; ++ struct fb_info *info = fb_helper->info; + struct drm_framebuffer *fb; + struct drm_mode_fb_cmd2 mode_cmd = { }; + int size; +@@ -165,12 +165,6 @@ static int psb_fbdev_fb_probe(struct drm + + fb_helper->fb = fb; + +- info = drm_fb_helper_alloc_info(fb_helper); +- if (IS_ERR(info)) { +- ret = PTR_ERR(info); +- goto err_drm_framebuffer_unregister_private; +- } +- + info->fbops = &psb_fbdev_fb_ops; + + /* Accessed stolen memory directly */ +@@ -194,11 +188,6 @@ static int psb_fbdev_fb_probe(struct drm + + return 0; + +-err_drm_framebuffer_unregister_private: +- drm_framebuffer_unregister_private(fb); +- fb->obj[0] = NULL; +- drm_framebuffer_cleanup(fb); +- kfree(fb); + err_drm_gem_object_put: + drm_gem_object_put(obj); + return ret; +--- a/drivers/gpu/drm/i915/display/intel_fbdev.c ++++ b/drivers/gpu/drm/i915/display/intel_fbdev.c +@@ -183,7 +183,7 @@ static int intelfb_create(struct drm_fb_ + .type = I915_GTT_VIEW_NORMAL, + }; + intel_wakeref_t wakeref; +- struct fb_info *info; ++ struct fb_info *info = helper->info; + struct i915_vma *vma; + unsigned long flags = 0; + bool prealloc = false; +@@ -236,13 +236,6 @@ static int intelfb_create(struct drm_fb_ + goto out_unlock; + } + +- info = drm_fb_helper_alloc_info(helper); +- if (IS_ERR(info)) { +- drm_err(&dev_priv->drm, "Failed to allocate fb_info (%pe)\n", info); +- ret = PTR_ERR(info); +- goto out_unpin; +- } +- + ifbdev->helper.fb = &fb->base; + + info->fbops = &intelfb_ops; +--- a/drivers/gpu/drm/msm/msm_fbdev.c ++++ b/drivers/gpu/drm/msm/msm_fbdev.c +@@ -70,9 +70,9 @@ static int msm_fbdev_create(struct drm_f + { + struct drm_device *dev = helper->dev; + struct msm_drm_private *priv = dev->dev_private; ++ struct fb_info *fbi = helper->info; + struct drm_framebuffer *fb = NULL; + struct drm_gem_object *bo; +- struct fb_info *fbi = NULL; + uint64_t paddr; + uint32_t format; + int ret, pitch; +@@ -105,13 +105,6 @@ static int msm_fbdev_create(struct drm_f + goto fail; + } + +- fbi = drm_fb_helper_alloc_info(helper); +- if (IS_ERR(fbi)) { +- DRM_DEV_ERROR(dev->dev, "failed to allocate fb info\n"); +- ret = PTR_ERR(fbi); +- goto fail; +- } +- + DBG("fbi=%p, dev=%p", fbi, dev); + + helper->fb = fb; +--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c ++++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c +@@ -131,9 +131,9 @@ static int omap_fbdev_create(struct drm_ + struct omap_fbdev *fbdev = to_omap_fbdev(helper); + struct drm_device *dev = helper->dev; + struct omap_drm_private *priv = dev->dev_private; ++ struct fb_info *fbi = helper->info; + struct drm_framebuffer *fb = NULL; + union omap_gem_size gsize; +- struct fb_info *fbi = NULL; + struct drm_mode_fb_cmd2 mode_cmd = {0}; + struct drm_gem_object *bo; + dma_addr_t dma_addr; +@@ -199,13 +199,6 @@ static int omap_fbdev_create(struct drm_ + goto fail; + } + +- fbi = drm_fb_helper_alloc_info(helper); +- if (IS_ERR(fbi)) { +- dev_err(dev->dev, "failed to allocate fb info\n"); +- ret = PTR_ERR(fbi); +- goto fail; +- } +- + DBG("fbi=%p, dev=%p", fbi, dev); + + helper->fb = fb; +--- a/drivers/gpu/drm/radeon/radeon_fbdev.c ++++ b/drivers/gpu/drm/radeon/radeon_fbdev.c +@@ -207,7 +207,7 @@ static int radeon_fbdev_fb_helper_fb_pro + { + struct radeon_device *rdev = fb_helper->dev->dev_private; + struct drm_mode_fb_cmd2 mode_cmd = { }; +- struct fb_info *info; ++ struct fb_info *info = fb_helper->info; + struct drm_gem_object *gobj; + struct radeon_bo *rbo; + struct drm_framebuffer *fb; +@@ -245,13 +245,6 @@ static int radeon_fbdev_fb_helper_fb_pro + /* setup helper */ + fb_helper->fb = fb; + +- /* okay we have an object now allocate the framebuffer */ +- info = drm_fb_helper_alloc_info(fb_helper); +- if (IS_ERR(info)) { +- ret = PTR_ERR(info); +- goto err_drm_framebuffer_unregister_private; +- } +- + info->fbops = &radeon_fbdev_fb_ops; + + /* radeon resume is fragile and needs a vt switch to help it along */ +@@ -277,10 +270,6 @@ static int radeon_fbdev_fb_helper_fb_pro + + return 0; + +-err_drm_framebuffer_unregister_private: +- fb_helper->fb = NULL; +- drm_framebuffer_unregister_private(fb); +- drm_framebuffer_cleanup(fb); + err_kfree: + kfree(fb); + err_radeon_fbdev_destroy_pinned_object: +--- a/drivers/gpu/drm/tegra/fbdev.c ++++ b/drivers/gpu/drm/tegra/fbdev.c +@@ -72,10 +72,10 @@ static int tegra_fbdev_probe(struct drm_ + struct tegra_drm *tegra = helper->dev->dev_private; + struct drm_device *drm = helper->dev; + struct drm_mode_fb_cmd2 cmd = { 0 }; ++ struct fb_info *info = helper->info; + unsigned int bytes_per_pixel; + struct drm_framebuffer *fb; + unsigned long offset; +- struct fb_info *info; + struct tegra_bo *bo; + size_t size; + int err; +@@ -96,13 +96,6 @@ static int tegra_fbdev_probe(struct drm_ + if (IS_ERR(bo)) + return PTR_ERR(bo); + +- info = drm_fb_helper_alloc_info(helper); +- if (IS_ERR(info)) { +- dev_err(drm->dev, "failed to allocate framebuffer info\n"); +- drm_gem_object_put(&bo->gem); +- return PTR_ERR(info); +- } +- + fb = tegra_fb_alloc(drm, &cmd, &bo, 1); + if (IS_ERR(fb)) { + err = PTR_ERR(fb); +--- a/include/drm/drm_fb_helper.h ++++ b/include/drm/drm_fb_helper.h +@@ -246,8 +246,6 @@ int drm_fb_helper_check_var(struct fb_va + + int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper); + +-struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper); +-void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper); + void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper); + void drm_fb_helper_fill_info(struct fb_info *info, + struct drm_fb_helper *fb_helper, +@@ -328,16 +326,6 @@ drm_fb_helper_restore_fbdev_mode_unlocke + return 0; + } + +-static inline struct fb_info * +-drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper) +-{ +- return NULL; +-} +- +-static inline void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper) +-{ +-} +- + static inline void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper) + { + } diff --git a/queue-6.12/drm-i915-hdcp-move-to-using-intel_display-in-intel_hdcp.patch b/queue-6.12/drm-i915-hdcp-move-to-using-intel_display-in-intel_hdcp.patch new file mode 100644 index 0000000000..bcafffc26c --- /dev/null +++ b/queue-6.12/drm-i915-hdcp-move-to-using-intel_display-in-intel_hdcp.patch @@ -0,0 +1,2068 @@ +From stable+bounces-294456-greg=kroah.com@vger.kernel.org Sun Aug 2 03:50:28 2026 +From: Sasha Levin +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 , Jani Nikula , Sasha Levin +Message-ID: <20260802014934.510825-1-sashal@kernel.org> + +From: Suraj Kandpal + +[ 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 +Reviewed-by: Jani Nikula +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 + + struct drm_i915_private; ++struct intel_display; + struct intel_hdcp_gsc_message; + +-bool intel_hdcp_gsc_cs_required(struct drm_i915_private *i915); ++bool intel_hdcp_gsc_cs_required(struct intel_display *display); + ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in, + size_t msg_in_len, u8 *msg_out, + size_t msg_out_len); + int intel_hdcp_gsc_init(struct drm_i915_private *i915); + void intel_hdcp_gsc_fini(struct drm_i915_private *i915); +-bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915); ++bool intel_hdcp_gsc_check_status(struct intel_display *display); + + #endif /* __INTEL_HDCP_GCS_H__ */ +--- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h ++++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h +@@ -22,11 +22,12 @@ struct hdcp2_ske_send_eks; + struct hdcp2_rep_send_receiverid_list; + struct hdcp2_rep_send_ack; + struct hdcp2_rep_stream_ready; ++struct intel_display; + + ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in, + size_t msg_in_len, u8 *msg_out, + size_t msg_out_len); +-bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915); ++bool intel_hdcp_gsc_check_status(struct intel_display *display); + int + intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data, + struct hdcp2_ake_init *ake_data); +--- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c ++++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c +@@ -30,13 +30,14 @@ struct intel_hdcp_gsc_message { + + #define HDCP_GSC_HEADER_SIZE sizeof(struct intel_gsc_mtl_header) + +-bool intel_hdcp_gsc_cs_required(struct xe_device *xe) ++bool intel_hdcp_gsc_cs_required(struct intel_display *display) + { +- return DISPLAY_VER(xe) >= 14; ++ return DISPLAY_VER(display) >= 14; + } + +-bool intel_hdcp_gsc_check_status(struct xe_device *xe) ++bool intel_hdcp_gsc_check_status(struct intel_display *display) + { ++ struct xe_device *xe = to_xe_device(display->drm); + struct xe_tile *tile = xe_device_get_root_tile(xe); + struct xe_gt *gt = tile->media_gt; + struct xe_gsc *gsc; diff --git a/queue-6.12/drm-i915-hdcp-require-monotonically-increasing-seq_num_v.patch b/queue-6.12/drm-i915-hdcp-require-monotonically-increasing-seq_num_v.patch new file mode 100644 index 0000000000..482ceba6e9 --- /dev/null +++ b/queue-6.12/drm-i915-hdcp-require-monotonically-increasing-seq_num_v.patch @@ -0,0 +1,54 @@ +From stable+bounces-294455-greg=kroah.com@vger.kernel.org Sun Aug 2 03:50:18 2026 +From: Sasha Levin +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 , Martin Hodo , Suraj Kandpal , Joonas Lahtinen , Sasha Levin +Message-ID: <20260802014934.510825-2-sashal@kernel.org> + +From: Jani Nikula + +[ 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 +Fixes: d849178e2c9e ("drm/i915: Implement HDCP2.2 repeater authentication") +Cc: stable@vger.kernel.org # v5.2+ +Cc: Suraj Kandpal +Reviewed-by: Suraj Kandpal +Link: https://patch.msgid.link/20260625104407.1025614-1-jani.nikula@intel.com +Signed-off-by: Jani Nikula +(cherry picked from commit 58a224375c81179b52558c53d8857b93196d2687) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/i915/display/intel_hdcp.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/i915/display/intel_hdcp.c ++++ b/drivers/gpu/drm/i915/display/intel_hdcp.c +@@ -1742,9 +1742,10 @@ int hdcp2_authenticate_repeater_topology + return -EINVAL; + } + +- if (seq_num_v < hdcp->seq_num_v) { +- /* Roll over of the seq_num_v from repeater. Reauthenticate. */ +- drm_dbg_kms(display->drm, "Seq_num_v roll over.\n"); ++ if (hdcp->hdcp2_encrypted && seq_num_v <= hdcp->seq_num_v) { ++ /* Reauthenticate on Seq_num_v repeat or rollover */ ++ drm_dbg_kms(display->drm, "Seq_num_v %s\n", ++ seq_num_v == hdcp->seq_num_v ? "repeat" : "rollover"); + return -EINVAL; + } + diff --git a/queue-6.12/drm-i915-vrr-check-has_vrr-first-in-intel_vrr_is_capable.patch b/queue-6.12/drm-i915-vrr-check-has_vrr-first-in-intel_vrr_is_capable.patch new file mode 100644 index 0000000000..a963acdb1e --- /dev/null +++ b/queue-6.12/drm-i915-vrr-check-has_vrr-first-in-intel_vrr_is_capable.patch @@ -0,0 +1,48 @@ +From stable+bounces-294451-greg=kroah.com@vger.kernel.org Sun Aug 2 03:49:36 2026 +From: Sasha Levin +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ä" , "Ankit Nautiyal" , "Sasha Levin" +Message-ID: <20260802014920.506109-1-sashal@kernel.org> + +From: Ville Syrjälä + +[ 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ä +Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-23-ville.syrjala@linux.intel.com +Reviewed-by: Ankit Nautiyal +Stable-dep-of: f8a9262c7a6f ("drm/i915/vrr: require valid min/max vfreq for VRR") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/i915/display/intel_vrr.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/i915/display/intel_vrr.c ++++ b/drivers/gpu/drm/i915/display/intel_vrr.c +@@ -21,6 +21,9 @@ bool intel_vrr_is_capable(struct intel_c + const struct drm_display_info *info = &connector->base.display_info; + struct intel_dp *intel_dp; + ++ if (!HAS_VRR(display)) ++ return false; ++ + /* + * DP Sink is capable of VRR video timings if + * Ignore MSA bit is set in DPCD. +@@ -43,8 +46,7 @@ bool intel_vrr_is_capable(struct intel_c + return false; + } + +- return HAS_VRR(display) && +- info->monitor_range.max_vfreq - info->monitor_range.min_vfreq > 10; ++ return info->monitor_range.max_vfreq - info->monitor_range.min_vfreq > 10; + } + + bool intel_vrr_is_in_range(struct intel_connector *connector, int vrefresh) diff --git a/queue-6.12/drm-i915-vrr-require-valid-min-max-vfreq-for-vrr.patch b/queue-6.12/drm-i915-vrr-require-valid-min-max-vfreq-for-vrr.patch new file mode 100644 index 0000000000..7a8498d361 --- /dev/null +++ b/queue-6.12/drm-i915-vrr-require-valid-min-max-vfreq-for-vrr.patch @@ -0,0 +1,49 @@ +From stable+bounces-294452-greg=kroah.com@vger.kernel.org Sun Aug 2 03:49:38 2026 +From: Sasha Levin +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 , Martin Hodo , Ankit Nautiyal , Joonas Lahtinen , Sasha Levin +Message-ID: <20260802014920.506109-2-sashal@kernel.org> + +From: Jani Nikula + +[ 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 +Fixes: 117cd09ba528 ("drm/i915/display/dp: Compute VRR state in atomic_check") +Cc: stable@vger.kernel.org # v5.12+ +Cc: Ankit Nautiyal +Reviewed-by: Ankit Nautiyal +Link: https://patch.msgid.link/20260625131040.1051272-1-jani.nikula@intel.com +Signed-off-by: Jani Nikula +(cherry picked from commit 1765cf59f517b02f3b0591fe5120930d08bddeb6) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/i915/display/intel_vrr.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/gpu/drm/i915/display/intel_vrr.c ++++ b/drivers/gpu/drm/i915/display/intel_vrr.c +@@ -46,6 +46,10 @@ bool intel_vrr_is_capable(struct intel_c + return false; + } + ++ if (!info->monitor_range.min_vfreq || !info->monitor_range.max_vfreq || ++ info->monitor_range.min_vfreq > info->monitor_range.max_vfreq) ++ return false; ++ + return info->monitor_range.max_vfreq - info->monitor_range.min_vfreq > 10; + } + diff --git a/queue-6.12/drm-sched-store-the-drm-client_id-in-drm_sched_fence.patch b/queue-6.12/drm-sched-store-the-drm-client_id-in-drm_sched_fence.patch new file mode 100644 index 0000000000..2e1ea55233 --- /dev/null +++ b/queue-6.12/drm-sched-store-the-drm-client_id-in-drm_sched_fence.patch @@ -0,0 +1,449 @@ +From stable+bounces-294121-greg=kroah.com@vger.kernel.org Fri Jul 31 17:58:27 2026 +From: Sasha Levin +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" , "Christian König" , "Philipp Stanner" , "Sasha Levin" +Message-ID: <20260731154959.602805-1-sashal@kernel.org> + +From: Pierre-Eric Pelloux-Prayer + +[ 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 +Signed-off-by: Pierre-Eric Pelloux-Prayer +Signed-off-by: Philipp Stanner +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 +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 2 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 3 ++- + drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 8 +++++--- + drivers/gpu/drm/amd/amdgpu/amdgpu_job.h | 3 ++- + drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 2 +- + drivers/gpu/drm/imagination/pvr_job.c | 2 +- + drivers/gpu/drm/imagination/pvr_queue.c | 5 +++-- + drivers/gpu/drm/imagination/pvr_queue.h | 2 +- + drivers/gpu/drm/lima/lima_gem.c | 2 +- + drivers/gpu/drm/lima/lima_sched.c | 6 ++++-- + drivers/gpu/drm/lima/lima_sched.h | 3 ++- + drivers/gpu/drm/msm/msm_gem_submit.c | 8 +++++--- + drivers/gpu/drm/nouveau/nouveau_sched.c | 3 ++- + drivers/gpu/drm/panfrost/panfrost_drv.c | 2 +- + drivers/gpu/drm/panthor/panthor_drv.c | 3 ++- + drivers/gpu/drm/panthor/panthor_mmu.c | 2 +- + drivers/gpu/drm/panthor/panthor_sched.c | 5 +++-- + drivers/gpu/drm/panthor/panthor_sched.h | 3 ++- + drivers/gpu/drm/scheduler/sched_fence.c | 4 +++- + drivers/gpu/drm/scheduler/sched_main.c | 7 +++++-- + drivers/gpu/drm/v3d/v3d_submit.c | 2 +- + drivers/gpu/drm/xe/xe_sched_job.c | 3 ++- + include/drm/gpu_scheduler.h | 12 ++++++++++-- + 23 files changed, 60 insertions(+), 32 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +@@ -681,7 +681,7 @@ int amdgpu_amdkfd_submit_ib(struct amdgp + goto err; + } + +- ret = amdgpu_job_alloc(adev, NULL, NULL, NULL, 1, &job); ++ ret = amdgpu_job_alloc(adev, NULL, NULL, NULL, 1, &job, 0); + if (ret) + goto err; + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +@@ -297,7 +297,8 @@ static int amdgpu_cs_pass1(struct amdgpu + + for (i = 0; i < p->gang_size; ++i) { + ret = amdgpu_job_alloc(p->adev, vm, p->entities[i], vm, +- num_ibs[i], &p->jobs[i]); ++ num_ibs[i], &p->jobs[i], ++ p->filp->client_id); + if (ret) + goto free_all_kdata; + p->jobs[i]->enforce_isolation = p->adev->enforce_isolation[fpriv->xcp_id]; +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +@@ -187,7 +187,8 @@ exit: + + int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm, + struct drm_sched_entity *entity, void *owner, +- unsigned int num_ibs, struct amdgpu_job **job) ++ unsigned int num_ibs, struct amdgpu_job **job, ++ u64 drm_client_id) + { + if (num_ibs == 0) + return -EINVAL; +@@ -210,7 +211,8 @@ int amdgpu_job_alloc(struct amdgpu_devic + if (!entity) + return 0; + +- return drm_sched_job_init(&(*job)->base, entity, 1, owner); ++ return drm_sched_job_init(&(*job)->base, entity, 1, owner, ++ drm_client_id); + } + + int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, +@@ -220,7 +222,7 @@ int amdgpu_job_alloc_with_ib(struct amdg + { + int r; + +- r = amdgpu_job_alloc(adev, NULL, entity, owner, 1, job); ++ r = amdgpu_job_alloc(adev, NULL, entity, owner, 1, job, 0); + if (r) + return r; + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h +@@ -90,7 +90,8 @@ static inline struct amdgpu_ring *amdgpu + + int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm, + struct drm_sched_entity *entity, void *owner, +- unsigned int num_ibs, struct amdgpu_job **job); ++ unsigned int num_ibs, struct amdgpu_job **job, ++ u64 drm_client_id); + int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, + struct drm_sched_entity *entity, void *owner, + size_t size, enum amdgpu_ib_pool_type pool_type, +--- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c +@@ -535,7 +535,7 @@ int etnaviv_ioctl_gem_submit(struct drm_ + + ret = drm_sched_job_init(&submit->sched_job, + &ctx->sched_entity[args->pipe], +- 1, submit->ctx); ++ 1, submit->ctx, file->client_id); + if (ret) + goto err_submit_put; + +--- a/drivers/gpu/drm/imagination/pvr_job.c ++++ b/drivers/gpu/drm/imagination/pvr_job.c +@@ -453,7 +453,7 @@ create_job(struct pvr_device *pvr_dev, + if (err) + goto err_put_job; + +- err = pvr_queue_job_init(job); ++ err = pvr_queue_job_init(job, pvr_file->file->client_id); + if (err) + goto err_put_job; + +--- a/drivers/gpu/drm/imagination/pvr_queue.c ++++ b/drivers/gpu/drm/imagination/pvr_queue.c +@@ -1088,6 +1088,7 @@ static int pvr_queue_cleanup_fw_context( + /** + * pvr_queue_job_init() - Initialize queue related fields in a pvr_job object. + * @job: The job to initialize. ++ * @drm_client_id: drm_file.client_id submitting the job + * + * Bind the job to a queue and allocate memory to guarantee pvr_queue_job_arm() + * and pvr_queue_job_push() can't fail. We also make sure the context type is +@@ -1097,7 +1098,7 @@ static int pvr_queue_cleanup_fw_context( + * * 0 on success, or + * * An error code if something failed. + */ +-int pvr_queue_job_init(struct pvr_job *job) ++int pvr_queue_job_init(struct pvr_job *job, u64 drm_client_id) + { + /* Fragment jobs need at least one native fence wait on the geometry job fence. */ + u32 min_native_dep_count = job->type == DRM_PVR_JOB_TYPE_FRAGMENT ? 1 : 0; +@@ -1114,7 +1115,7 @@ int pvr_queue_job_init(struct pvr_job *j + if (!pvr_cccb_cmdseq_can_fit(&queue->cccb, job_cmds_size(job, min_native_dep_count))) + return -E2BIG; + +- err = drm_sched_job_init(&job->base, &queue->entity, 1, THIS_MODULE); ++ err = drm_sched_job_init(&job->base, &queue->entity, 1, THIS_MODULE, drm_client_id); + if (err) + return err; + +--- a/drivers/gpu/drm/imagination/pvr_queue.h ++++ b/drivers/gpu/drm/imagination/pvr_queue.h +@@ -143,7 +143,7 @@ struct pvr_queue { + + bool pvr_queue_fence_is_ufo_backed(struct dma_fence *f); + +-int pvr_queue_job_init(struct pvr_job *job); ++int pvr_queue_job_init(struct pvr_job *job, u64 drm_client_id); + + void pvr_queue_job_cleanup(struct pvr_job *job); + +--- a/drivers/gpu/drm/lima/lima_gem.c ++++ b/drivers/gpu/drm/lima/lima_gem.c +@@ -341,7 +341,7 @@ int lima_gem_submit(struct drm_file *fil + + err = lima_sched_task_init( + submit->task, submit->ctx->context + submit->pipe, +- bos, submit->nr_bos, vm); ++ bos, submit->nr_bos, vm, file->client_id); + if (err) + goto err_out1; + +--- a/drivers/gpu/drm/lima/lima_sched.c ++++ b/drivers/gpu/drm/lima/lima_sched.c +@@ -113,7 +113,8 @@ static inline struct lima_sched_pipe *to + int lima_sched_task_init(struct lima_sched_task *task, + struct lima_sched_context *context, + struct lima_bo **bos, int num_bos, +- struct lima_vm *vm) ++ struct lima_vm *vm, ++ u64 drm_client_id) + { + int err, i; + +@@ -124,7 +125,8 @@ int lima_sched_task_init(struct lima_sch + for (i = 0; i < num_bos; i++) + drm_gem_object_get(&bos[i]->base.base); + +- err = drm_sched_job_init(&task->base, &context->base, 1, vm); ++ err = drm_sched_job_init(&task->base, &context->base, 1, vm, ++ drm_client_id); + if (err) { + kfree(task->bos); + return err; +--- a/drivers/gpu/drm/lima/lima_sched.h ++++ b/drivers/gpu/drm/lima/lima_sched.h +@@ -88,7 +88,8 @@ struct lima_sched_pipe { + int lima_sched_task_init(struct lima_sched_task *task, + struct lima_sched_context *context, + struct lima_bo **bos, int num_bos, +- struct lima_vm *vm); ++ struct lima_vm *vm, ++ u64 drm_client_id); + void lima_sched_task_fini(struct lima_sched_task *task); + + int lima_sched_context_init(struct lima_sched_pipe *pipe, +--- a/drivers/gpu/drm/msm/msm_gem_submit.c ++++ b/drivers/gpu/drm/msm/msm_gem_submit.c +@@ -30,7 +30,7 @@ + static struct msm_gem_submit *submit_create(struct drm_device *dev, + struct msm_gpu *gpu, + struct msm_gpu_submitqueue *queue, uint32_t nr_bos, +- uint32_t nr_cmds) ++ uint32_t nr_cmds, u64 drm_client_id) + { + static atomic_t ident = ATOMIC_INIT(0); + struct msm_gem_submit *submit; +@@ -54,7 +54,8 @@ static struct msm_gem_submit *submit_cre + return ERR_PTR(ret); + } + +- ret = drm_sched_job_init(&submit->base, queue->entity, 1, queue); ++ ret = drm_sched_job_init(&submit->base, queue->entity, 1, queue, ++ drm_client_id); + if (ret) { + kfree(submit->hw_fence); + kfree(submit); +@@ -712,7 +713,8 @@ int msm_ioctl_gem_submit(struct drm_devi + } + } + +- submit = submit_create(dev, gpu, queue, args->nr_bos, args->nr_cmds); ++ submit = submit_create(dev, gpu, queue, args->nr_bos, args->nr_cmds, ++ file->client_id); + if (IS_ERR(submit)) { + ret = PTR_ERR(submit); + goto out_post_unlock; +--- a/drivers/gpu/drm/nouveau/nouveau_sched.c ++++ b/drivers/gpu/drm/nouveau/nouveau_sched.c +@@ -87,7 +87,8 @@ nouveau_job_init(struct nouveau_job *job + } + + ret = drm_sched_job_init(&job->base, &sched->entity, +- args->credits, NULL); ++ args->credits, NULL, ++ job->file_priv->client_id); + if (ret) + goto err_free_chains; + +--- a/drivers/gpu/drm/panfrost/panfrost_drv.c ++++ b/drivers/gpu/drm/panfrost/panfrost_drv.c +@@ -273,7 +273,7 @@ static int panfrost_ioctl_submit(struct + + ret = drm_sched_job_init(&job->base, + &file_priv->sched_entity[slot], +- 1, NULL); ++ 1, NULL, file->client_id); + if (ret) + goto out_put_job; + +--- a/drivers/gpu/drm/panthor/panthor_drv.c ++++ b/drivers/gpu/drm/panthor/panthor_drv.c +@@ -908,7 +908,8 @@ static int panthor_ioctl_group_submit(st + const struct drm_panthor_queue_submit *qsubmit = &jobs_args[i]; + struct drm_sched_job *job; + +- job = panthor_job_create(pfile, args->group_handle, qsubmit); ++ job = panthor_job_create(pfile, args->group_handle, qsubmit, ++ file->client_id); + if (IS_ERR(job)) { + ret = PTR_ERR(job); + goto out_cleanup_submit_ctx; +--- a/drivers/gpu/drm/panthor/panthor_mmu.c ++++ b/drivers/gpu/drm/panthor/panthor_mmu.c +@@ -2498,7 +2498,7 @@ panthor_vm_bind_job_create(struct drm_fi + kref_init(&job->refcount); + job->vm = panthor_vm_get(vm); + +- ret = drm_sched_job_init(&job->base, &vm->entity, 1, vm); ++ ret = drm_sched_job_init(&job->base, &vm->entity, 1, vm, file->client_id); + if (ret) + goto err_put_job; + +--- a/drivers/gpu/drm/panthor/panthor_sched.c ++++ b/drivers/gpu/drm/panthor/panthor_sched.c +@@ -3664,7 +3664,8 @@ struct panthor_vm *panthor_job_vm(struct + struct drm_sched_job * + panthor_job_create(struct panthor_file *pfile, + u16 group_handle, +- const struct drm_panthor_queue_submit *qsubmit) ++ const struct drm_panthor_queue_submit *qsubmit, ++ u64 drm_client_id) + { + struct panthor_group_pool *gpool = pfile->groups; + struct panthor_job *job; +@@ -3736,7 +3737,7 @@ panthor_job_create(struct panthor_file * + + ret = drm_sched_job_init(&job->base, + &job->group->queues[job->queue_idx]->entity, +- credits, job->group); ++ credits, job->group, drm_client_id); + if (ret) + goto err_put_job; + +--- a/drivers/gpu/drm/panthor/panthor_sched.h ++++ b/drivers/gpu/drm/panthor/panthor_sched.h +@@ -28,7 +28,8 @@ int panthor_group_get_state(struct panth + struct drm_sched_job * + panthor_job_create(struct panthor_file *pfile, + u16 group_handle, +- const struct drm_panthor_queue_submit *qsubmit); ++ const struct drm_panthor_queue_submit *qsubmit, ++ u64 drm_client_id); + struct drm_sched_job *panthor_job_get(struct drm_sched_job *job); + struct panthor_vm *panthor_job_vm(struct drm_sched_job *sched_job); + void panthor_job_put(struct drm_sched_job *job); +--- a/drivers/gpu/drm/scheduler/sched_fence.c ++++ b/drivers/gpu/drm/scheduler/sched_fence.c +@@ -204,7 +204,8 @@ struct drm_sched_fence *to_drm_sched_fen + EXPORT_SYMBOL(to_drm_sched_fence); + + struct drm_sched_fence *drm_sched_fence_alloc(struct drm_sched_entity *entity, +- void *owner) ++ void *owner, ++ u64 drm_client_id) + { + struct drm_sched_fence *fence = NULL; + +@@ -213,6 +214,7 @@ struct drm_sched_fence *drm_sched_fence_ + return NULL; + + fence->owner = owner; ++ fence->drm_client_id = drm_client_id; + spin_lock_init(&fence->lock); + + return fence; +--- a/drivers/gpu/drm/scheduler/sched_main.c ++++ b/drivers/gpu/drm/scheduler/sched_main.c +@@ -772,6 +772,8 @@ EXPORT_SYMBOL(drm_sched_resubmit_jobs); + * @credits: the number of credits this job contributes to the schedulers + * credit limit + * @owner: job owner for debugging ++ * @drm_client_id: &struct drm_file.client_id of the owner (used by trace ++ * events) + * + * Refer to drm_sched_entity_push_job() documentation + * for locking considerations. +@@ -788,7 +790,8 @@ EXPORT_SYMBOL(drm_sched_resubmit_jobs); + */ + int drm_sched_job_init(struct drm_sched_job *job, + struct drm_sched_entity *entity, +- u32 credits, void *owner) ++ u32 credits, void *owner, ++ uint64_t drm_client_id) + { + if (!entity->rq) { + /* This will most likely be followed by missing frames +@@ -814,7 +817,7 @@ int drm_sched_job_init(struct drm_sched_ + + job->entity = entity; + job->credits = credits; +- job->s_fence = drm_sched_fence_alloc(entity, owner); ++ job->s_fence = drm_sched_fence_alloc(entity, owner, drm_client_id); + if (!job->s_fence) + return -ENOMEM; + +--- a/drivers/gpu/drm/v3d/v3d_submit.c ++++ b/drivers/gpu/drm/v3d/v3d_submit.c +@@ -186,7 +186,7 @@ v3d_job_init(struct v3d_dev *v3d, struct + job->file = file_priv; + + ret = drm_sched_job_init(&job->base, &v3d_priv->sched_entity[queue], +- 1, v3d_priv); ++ 1, v3d_priv, file_priv->client_id); + if (ret) + return ret; + +--- a/drivers/gpu/drm/xe/xe_sched_job.c ++++ b/drivers/gpu/drm/xe/xe_sched_job.c +@@ -113,7 +113,8 @@ struct xe_sched_job *xe_sched_job_create + kref_init(&job->refcount); + xe_exec_queue_get(job->q); + +- err = drm_sched_job_init(&job->drm, q->entity, 1, NULL); ++ err = drm_sched_job_init(&job->drm, q->entity, 1, NULL, ++ q->xef ? q->xef->drm->client_id : 0); + if (err) + goto err_free; + +--- a/include/drm/gpu_scheduler.h ++++ b/include/drm/gpu_scheduler.h +@@ -309,6 +309,13 @@ struct drm_sched_fence { + * @owner: job owner for debugging + */ + void *owner; ++ ++ /** ++ * @drm_client_id: ++ * ++ * The client_id of the drm_file which owns the job. ++ */ ++ uint64_t drm_client_id; + }; + + struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f); +@@ -553,7 +560,8 @@ int drm_sched_init(struct drm_gpu_schedu + void drm_sched_fini(struct drm_gpu_scheduler *sched); + int drm_sched_job_init(struct drm_sched_job *job, + struct drm_sched_entity *entity, +- u32 credits, void *owner); ++ u32 credits, void *owner, ++ u64 drm_client_id); + void drm_sched_job_arm(struct drm_sched_job *job); + int drm_sched_job_add_dependency(struct drm_sched_job *job, + struct dma_fence *fence); +@@ -613,7 +621,7 @@ bool drm_sched_entity_is_ready(struct dr + int drm_sched_entity_error(struct drm_sched_entity *entity); + + struct drm_sched_fence *drm_sched_fence_alloc( +- struct drm_sched_entity *s_entity, void *owner); ++ struct drm_sched_entity *s_entity, void *owner, u64 drm_client_id); + void drm_sched_fence_init(struct drm_sched_fence *fence, + struct drm_sched_entity *entity); + void drm_sched_fence_free(struct drm_sched_fence *fence); diff --git a/queue-6.12/drm-tegra-fbdev-remove-offset-into-framebuffer-memory.patch b/queue-6.12/drm-tegra-fbdev-remove-offset-into-framebuffer-memory.patch new file mode 100644 index 0000000000..0985fde02d --- /dev/null +++ b/queue-6.12/drm-tegra-fbdev-remove-offset-into-framebuffer-memory.patch @@ -0,0 +1,61 @@ +From stable+bounces-294035-greg=kroah.com@vger.kernel.org Fri Jul 31 13:23:29 2026 +From: Sasha Levin +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 , dri-devel@lists.freedesktop.org, linux-tegra@vger.kernel.org, Thierry Reding , Sasha Levin +Message-ID: <20260731111052.3596094-2-sashal@kernel.org> + +From: Thomas Zimmermann + +[ 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 +Fixes: de2ba664c30f ("gpu: host1x: drm: Add memory manager and fb") +Cc: dri-devel@lists.freedesktop.org +Cc: linux-tegra@vger.kernel.org +Cc: # v3.10+ +Signed-off-by: Thierry Reding +Link: https://patch.msgid.link/20260421073646.144712-3-tzimmermann@suse.de +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/tegra/fbdev.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/tegra/fbdev.c ++++ b/drivers/gpu/drm/tegra/fbdev.c +@@ -75,7 +75,6 @@ static int tegra_fbdev_probe(struct drm_ + struct fb_info *info = helper->info; + unsigned int bytes_per_pixel; + struct drm_framebuffer *fb; +- unsigned long offset; + struct tegra_bo *bo; + size_t size; + int err; +@@ -112,9 +111,6 @@ static int tegra_fbdev_probe(struct drm_ + + drm_fb_helper_fill_info(info, helper, sizes); + +- offset = info->var.xoffset * bytes_per_pixel + +- info->var.yoffset * fb->pitches[0]; +- + if (bo->pages) { + bo->vaddr = vmap(bo->pages, bo->num_pages, VM_MAP, + pgprot_writecombine(PAGE_KERNEL)); +@@ -126,9 +122,9 @@ static int tegra_fbdev_probe(struct drm_ + } + + info->flags |= FBINFO_VIRTFB; +- info->screen_buffer = bo->vaddr + offset; ++ info->screen_buffer = bo->vaddr; + info->screen_size = size; +- info->fix.smem_start = (unsigned long)(bo->iova + offset); ++ info->fix.smem_start = (unsigned long)(bo->iova); + info->fix.smem_len = size; + + return 0; diff --git a/queue-6.12/drm-xe-hold-a-dma-buf-reference-for-imported-bos.patch b/queue-6.12/drm-xe-hold-a-dma-buf-reference-for-imported-bos.patch new file mode 100644 index 0000000000..c88bc60c42 --- /dev/null +++ b/queue-6.12/drm-xe-hold-a-dma-buf-reference-for-imported-bos.patch @@ -0,0 +1,185 @@ +From stable+bounces-294454-greg=kroah.com@vger.kernel.org Sun Aug 2 03:49:43 2026 +From: Sasha Levin +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 , Thomas Hellstrom , Christian Konig , Matthew Auld , Sasha Levin +Message-ID: <20260802014928.509277-2-sashal@kernel.org> + +From: Nitin Gote + +[ 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 +Cc: Christian Konig +Cc: Matthew Auld +Suggested-by: Thomas Hellstrom +Assisted-by: GitHub_Copilot:claude-sonnet-4.6 +Reviewed-by: Thomas Hellström +Signed-off-by: Nitin Gote +Signed-off-by: Matthew Auld +Link: https://patch.msgid.link/20260710191027.260160-2-nitin.r.gote@intel.com +(cherry picked from commit 3516f3fae6be35642f8f06f8a218da6425c0306a) +Signed-off-by: Thomas Hellström +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/xe/xe_bo.c | 17 +++++++++++++++-- + drivers/gpu/drm/xe/xe_bo.h | 2 +- + drivers/gpu/drm/xe/xe_bo_types.h | 2 ++ + drivers/gpu/drm/xe/xe_dma_buf.c | 2 +- + 4 files changed, 19 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/xe/xe_bo.c ++++ b/drivers/gpu/drm/xe/xe_bo.c +@@ -1131,6 +1131,8 @@ static void xe_ttm_bo_destroy(struct ttm + + if (bo->ttm.base.import_attach) + drm_prime_gem_destroy(&bo->ttm.base, NULL); ++ if (bo->dma_buf) ++ dma_buf_put(bo->dma_buf); + drm_gem_object_release(&bo->ttm.base); + + xe_assert(xe, list_empty(&ttm_bo->base.gpuva.list)); +@@ -1292,7 +1294,7 @@ struct xe_bo *xe_bo_init_locked(struct x + struct xe_tile *tile, struct dma_resv *resv, + struct ttm_lru_bulk_move *bulk, size_t size, + u16 cpu_caching, enum ttm_bo_type type, +- u32 flags) ++ u32 flags, struct dma_buf *dma_buf) + { + struct ttm_operation_ctx ctx = { + .interruptible = true, +@@ -1377,6 +1379,17 @@ struct xe_bo *xe_bo_init_locked(struct x + placement = (type == ttm_bo_type_sg || + bo->flags & XE_BO_FLAG_DEFER_BACKING) ? &sys_placement : + &bo->placement; ++ ++ /* ++ * For imported BOs, keep the exporter dma-buf alive for the BO ++ * lifetime. Taken before ttm_bo_init_reserved() to also cover a ++ * creation failure there. Released in xe_ttm_bo_destroy(). ++ */ ++ if (dma_buf) { ++ get_dma_buf(dma_buf); ++ bo->dma_buf = dma_buf; ++ } ++ + err = ttm_bo_init_reserved(&xe->ttm, &bo->ttm, type, + placement, alignment, + &ctx, NULL, resv, xe_ttm_bo_destroy); +@@ -1491,7 +1504,7 @@ __xe_bo_create_locked(struct xe_device * + vm && !xe_vm_in_fault_mode(vm) && + flags & XE_BO_FLAG_USER ? + &vm->lru_bulk_move : NULL, size, +- cpu_caching, type, flags); ++ cpu_caching, type, flags, NULL); + if (IS_ERR(bo)) + return bo; + +--- a/drivers/gpu/drm/xe/xe_bo.h ++++ b/drivers/gpu/drm/xe/xe_bo.h +@@ -84,7 +84,7 @@ struct xe_bo *xe_bo_init_locked(struct x + struct xe_tile *tile, struct dma_resv *resv, + struct ttm_lru_bulk_move *bulk, size_t size, + u16 cpu_caching, enum ttm_bo_type type, +- u32 flags); ++ u32 flags, struct dma_buf *dma_buf); + struct xe_bo * + xe_bo_create_locked_range(struct xe_device *xe, + struct xe_tile *tile, struct xe_vm *vm, +--- a/drivers/gpu/drm/xe/xe_bo_types.h ++++ b/drivers/gpu/drm/xe/xe_bo_types.h +@@ -30,6 +30,8 @@ struct xe_bo { + struct ttm_buffer_object ttm; + /** @size: Size of this buffer object */ + size_t size; ++ /** @dma_buf: Imported dma-buf ref to keep its resv alive. */ ++ struct dma_buf *dma_buf; + /** @flags: flags for this buffer object */ + u32 flags; + /** @vm: VM this BO is attached to, for extobj this will be NULL */ +--- a/drivers/gpu/drm/xe/xe_dma_buf.c ++++ b/drivers/gpu/drm/xe/xe_dma_buf.c +@@ -214,7 +214,7 @@ xe_dma_buf_init_obj(struct drm_device *d + dma_resv_lock(resv, NULL); + bo = xe_bo_init_locked(xe, storage, NULL, resv, NULL, dma_buf->size, + 0, /* Will require 1way or 2way for vm_bind */ +- ttm_bo_type_sg, XE_BO_FLAG_SYSTEM); ++ ttm_bo_type_sg, XE_BO_FLAG_SYSTEM, dma_buf); + if (IS_ERR(bo)) { + ret = PTR_ERR(bo); + goto error; diff --git a/queue-6.12/drm-xe-rename-___xe_bo_create_locked.patch b/queue-6.12/drm-xe-rename-___xe_bo_create_locked.patch new file mode 100644 index 0000000000..d088027787 --- /dev/null +++ b/queue-6.12/drm-xe-rename-___xe_bo_create_locked.patch @@ -0,0 +1,97 @@ +From stable+bounces-294453-greg=kroah.com@vger.kernel.org Sun Aug 2 03:49:37 2026 +From: Sasha Levin +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" , "Matthew Brost" , "Sasha Levin" +Message-ID: <20260802014928.509277-1-sashal@kernel.org> + +From: Thomas Hellström + +[ Upstream commit 550a42a8daee1b056f9b3e6c858e57451a5b315a ] + +Don't start external function names with underscores. +Rename to xe_bo_init_locked(). + +Signed-off-by: Thomas Hellström +Reviewed-by: Matthew Brost +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 +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/xe/xe_bo.c | 20 ++++++++++---------- + drivers/gpu/drm/xe/xe_bo.h | 10 +++++----- + drivers/gpu/drm/xe/xe_dma_buf.c | 6 +++--- + 3 files changed, 18 insertions(+), 18 deletions(-) + +--- a/drivers/gpu/drm/xe/xe_bo.c ++++ b/drivers/gpu/drm/xe/xe_bo.c +@@ -1288,11 +1288,11 @@ void xe_bo_free(struct xe_bo *bo) + kfree(bo); + } + +-struct xe_bo *___xe_bo_create_locked(struct xe_device *xe, struct xe_bo *bo, +- struct xe_tile *tile, struct dma_resv *resv, +- struct ttm_lru_bulk_move *bulk, size_t size, +- u16 cpu_caching, enum ttm_bo_type type, +- u32 flags) ++struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo, ++ struct xe_tile *tile, struct dma_resv *resv, ++ struct ttm_lru_bulk_move *bulk, size_t size, ++ u16 cpu_caching, enum ttm_bo_type type, ++ u32 flags) + { + struct ttm_operation_ctx ctx = { + .interruptible = true, +@@ -1487,11 +1487,11 @@ __xe_bo_create_locked(struct xe_device * + } + } + +- bo = ___xe_bo_create_locked(xe, bo, tile, vm ? xe_vm_resv(vm) : NULL, +- vm && !xe_vm_in_fault_mode(vm) && +- flags & XE_BO_FLAG_USER ? +- &vm->lru_bulk_move : NULL, size, +- cpu_caching, type, flags); ++ bo = xe_bo_init_locked(xe, bo, tile, vm ? xe_vm_resv(vm) : NULL, ++ vm && !xe_vm_in_fault_mode(vm) && ++ flags & XE_BO_FLAG_USER ? ++ &vm->lru_bulk_move : NULL, size, ++ cpu_caching, type, flags); + if (IS_ERR(bo)) + return bo; + +--- a/drivers/gpu/drm/xe/xe_bo.h ++++ b/drivers/gpu/drm/xe/xe_bo.h +@@ -80,11 +80,11 @@ struct sg_table; + struct xe_bo *xe_bo_alloc(void); + void xe_bo_free(struct xe_bo *bo); + +-struct xe_bo *___xe_bo_create_locked(struct xe_device *xe, struct xe_bo *bo, +- struct xe_tile *tile, struct dma_resv *resv, +- struct ttm_lru_bulk_move *bulk, size_t size, +- u16 cpu_caching, enum ttm_bo_type type, +- u32 flags); ++struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo, ++ struct xe_tile *tile, struct dma_resv *resv, ++ struct ttm_lru_bulk_move *bulk, size_t size, ++ u16 cpu_caching, enum ttm_bo_type type, ++ u32 flags); + struct xe_bo * + xe_bo_create_locked_range(struct xe_device *xe, + struct xe_tile *tile, struct xe_vm *vm, +--- a/drivers/gpu/drm/xe/xe_dma_buf.c ++++ b/drivers/gpu/drm/xe/xe_dma_buf.c +@@ -212,9 +212,9 @@ xe_dma_buf_init_obj(struct drm_device *d + int ret; + + dma_resv_lock(resv, NULL); +- bo = ___xe_bo_create_locked(xe, storage, NULL, resv, NULL, dma_buf->size, +- 0, /* Will require 1way or 2way for vm_bind */ +- ttm_bo_type_sg, XE_BO_FLAG_SYSTEM); ++ bo = xe_bo_init_locked(xe, storage, NULL, resv, NULL, dma_buf->size, ++ 0, /* Will require 1way or 2way for vm_bind */ ++ ttm_bo_type_sg, XE_BO_FLAG_SYSTEM); + if (IS_ERR(bo)) { + ret = PTR_ERR(bo); + goto error; diff --git a/queue-6.12/drm-xe-wait-on-external-bo-kernel-fences-in-exec-ioctl.patch b/queue-6.12/drm-xe-wait-on-external-bo-kernel-fences-in-exec-ioctl.patch new file mode 100644 index 0000000000..79072dc866 --- /dev/null +++ b/queue-6.12/drm-xe-wait-on-external-bo-kernel-fences-in-exec-ioctl.patch @@ -0,0 +1,80 @@ +From stable+bounces-294440-greg=kroah.com@vger.kernel.org Sun Aug 2 01:43:31 2026 +From: Sasha Levin +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 Auld" , "Thomas Hellström" , "Sasha Levin" +Message-ID: <20260801234320.1848118-2-sashal@kernel.org> + +From: Matthew Brost + +[ Upstream commit af80e2bfde9312c76b60cf9274248dce0410b30d ] + +Before arming a user job, xe_exec_ioctl() only added the VM's +dma-resv KERNEL slot as a dependency. That slot covers rebinds and +the kernel operations of the VM's private BOs, but not external BOs +(bo->vm == NULL), which carry their kernel operations (evictions, +moves, ...) in their own dma-resv KERNEL slot. + +The DMA_RESV_USAGE_KERNEL slot is the cross-driver contract for +memory management operations that must complete before the BO or its +backing store may be used: any accessor is required to wait on the +KERNEL fences before touching the resv. By skipping the external BOs' +KERNEL slots, the exec path violated that contract and could schedule +a user job while a kernel operation on an external BO mapped by the VM +was still in flight, racing against it and potentially reading or +writing memory that was being moved. + +Replace the VM-only dependency with an iteration over every object +locked by the exec, adding each object's KERNEL slot as a job +dependency. This covers the VM resv (rebinds and private BOs) as well +as every external BO, mirroring the drm_gpuvm_resv_add_fence() call +that later publishes the job fence to the same set of objects. +Long-running mode continues to skip this, as before. + +Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") +Cc: stable@vger.kernel.org +Assisted-by: GitHub_Copilot:claude-opus-4.8 +Signed-off-by: Matthew Brost +Reviewed-by: Matthew Auld +Link: https://patch.msgid.link/20260702215805.4011228-1-matthew.brost@intel.com +(cherry picked from commit a6b842acf3ddd1efc53a56de9260cfa718fb35e7) +Signed-off-by: Thomas Hellström +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/xe/xe_exec.c | 22 ++++++++++++++++------ + 1 file changed, 16 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/xe/xe_exec.c ++++ b/drivers/gpu/drm/xe/xe_exec.c +@@ -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++) diff --git a/queue-6.12/series b/queue-6.12/series index 9a8bbf3aa2..34e79795c4 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -307,3 +307,18 @@ mptcp-pm-use-addr-entry-for-get_local_id.patch mptcp-pm-userspace-fix-use-after-free-in-get_local_id.patch kmemleak-iommu-iova-fix-transient-kmemleak-false-positive.patch mm-kmemleak-fix-checksum-computation-for-per-cpu-objects.patch +drm-amdgpu-respect-placement-requirements-in-amdgpu_gtt_mgr-functions.patch +drm-amdgpu-fix-context-pstate-override-handling.patch +drm-sched-store-the-drm-client_id-in-drm_sched_fence.patch +drm-amdgpu-give-each-kernel-job-a-unique-id.patch +drm-amdgpu-gfx-fix-cleaner-shader-ib-buffer-overflow.patch +drm-fb-helper-allocate-and-release-fb_info-in-single-place.patch +drm-tegra-fbdev-remove-offset-into-framebuffer-memory.patch +drm-exec-remove-the-index-parameter-from-drm_exec_for_each_locked_obj.patch +drm-xe-wait-on-external-bo-kernel-fences-in-exec-ioctl.patch +drm-i915-vrr-check-has_vrr-first-in-intel_vrr_is_capable.patch +drm-i915-vrr-require-valid-min-max-vfreq-for-vrr.patch +drm-xe-rename-___xe_bo_create_locked.patch +drm-xe-hold-a-dma-buf-reference-for-imported-bos.patch +drm-i915-hdcp-move-to-using-intel_display-in-intel_hdcp.patch +drm-i915-hdcp-require-monotonically-increasing-seq_num_v.patch