]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/mst: limit DP MST ESI service loop
authorJani Nikula <jani.nikula@intel.com>
Thu, 25 Jun 2026 14:22:04 +0000 (17:22 +0300)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Mon, 6 Jul 2026 14:26:00 +0000 (10:26 -0400)
The loop in intel_dp_check_mst_status() keeps servicing interrupts
originating from the sink without bound. Add an upper bound to the new
interrupts occurring during interrupt processing to not get stuck on
potentially stuck sink devices. Use arbitrary 32 tries to clear incoming
interrupts in one go.

Discovered using AI-assisted static analysis confirmed by Intel Product
Security.

Note: The condition likely pre-dates the commit in the Fixes: tag, but
this is about as far back as a backport has any chance of
succeeding. Before that, the retry had a goto.

Reported-by: Martin Hodo <martin.hodo@intel.com>
Fixes: 3c0ec2c2d594 ("drm/i915: Flatten intel_dp_check_mst_status() a bit")
Cc: stable@vger.kernel.org # v5.8+
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Link: https://patch.msgid.link/20260625142204.1078287-1-jani.nikula@intel.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
(cherry picked from commit b4ea5272133059acb493cc36599071a9e852ec2e)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/i915/display/intel_dp.c

index 85d3aa3b9894c096d2a8aa6c1e8ccd8ec52e521b..7ff5712f8b1990bc7ba3b5490abf4d58ff0eea3a 100644 (file)
@@ -5737,8 +5737,9 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
        struct intel_display *display = to_intel_display(intel_dp);
        bool force_retrain = intel_dp->link.force_retrain;
        bool reprobe_needed = false;
+       int tries = 33;
 
-       for (;;) {
+       while (--tries) {
                u8 esi[4] = {};
                u8 ack[4] = {};
                bool new_irqs;
@@ -5781,6 +5782,11 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
                        break;
        }
 
+       if (!tries) {
+               drm_dbg_kms(display->drm, "DPRX ESI not clearing, device may be stuck\n");
+               reprobe_needed = true;
+       }
+
        return !reprobe_needed;
 }