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: 3bb44e8d42 ("drm/i915/cmtg: Modify existing hook to disable CMTG")
Signed-off-by: Animesh Manna <animesh.manna@intel.com>
Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
Link: https://patch.msgid.link/20260629180236.1353704-2-animesh.manna@intel.com
This commit is contained in:
Animesh Manna 2026-06-29 23:32:35 +05:30
parent 6d177908ba
commit 3e64a9e210

View File

@ -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);
}