From 3e64a9e21093942d71a06d44ed93435601c6d4c0 Mon Sep 17 00:00:00 2001 From: Animesh Manna Date: Mon, 29 Jun 2026 23:32:35 +0530 Subject: [PATCH] drm/i915/display: Guard CMTG disable with intel_cmtg_is_allowed() intel_cmtg_disable() maps crtc_state->cpu_transcoder to a CMTG transcoder via to_cmtg_transcoder(), which only returns a valid transcoder for TRANSCODER_A/B. The disable call sites in hsw_crtc_disable() and the fastset/VRR path only check the sticky crtc->cmtg.enabled flag, so during a big-joiner reconfiguration that moves the eDP across pipes intel_cmtg_disable() can be reached with a crtc_state whose cpu_transcoder does not map to a CMTG transcoder. That results in a negative register-array index (trans_offsets[-1]) and a UBSAN array-index-out-of-bounds splat: UBSAN: array-index-out-of-bounds in .../display/intel_cmtg.c:187:24 intel_cmtg_disable+0x395/0x3d0 [xe] intel_old_crtc_state_disables+0xfb/0x1f0 [xe] intel_atomic_commit_tail+0xca6/0x2040 [xe] Gate both call sites with intel_cmtg_is_allowed() so that intel_cmtg_disable() is only invoked for configurations that actually map to a CMTG transcoder. v2: - Guard the intel_cmtg_disable() call sites with intel_cmtg_is_allowed() instead of a silent return (Suraj). Fixes: 3bb44e8d421a ("drm/i915/cmtg: Modify existing hook to disable CMTG") Signed-off-by: Animesh Manna Reviewed-by: Suraj Kandpal Link: https://patch.msgid.link/20260629180236.1353704-2-animesh.manna@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 5bc8e6ea10a5..90c05ad08f86 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1790,7 +1790,7 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, intel_atomic_get_old_crtc_state(state, crtc); struct intel_crtc *pipe_crtc; - if (crtc->cmtg.enabled) { + if (crtc->cmtg.enabled && intel_cmtg_is_allowed(old_crtc_state)) { intel_cmtg_set_clk_select(old_crtc_state); intel_cmtg_disable(old_crtc_state); } @@ -6886,7 +6886,8 @@ static void intel_update_crtc(struct intel_atomic_state *state, old_crtc_state->inherited) intel_crtc_arm_fifo_underrun(crtc, new_crtc_state); - if (crtc->cmtg.enabled && (intel_crtc_vrr_enabling(state, crtc))) { + if (crtc->cmtg.enabled && intel_crtc_vrr_enabling(state, crtc) && + intel_cmtg_is_allowed(new_crtc_state)) { intel_cmtg_set_clk_select(new_crtc_state); intel_cmtg_disable(new_crtc_state); }