Commit d340cba0df4c for kernel

commit d340cba0df4cf327c7e89c7c1a4e79d4771d7dd5
Author: Andriy Korud <a.korud@gmail.com>
Date:   Fri Jul 10 12:52:26 2026 +0200

    drm/amd/display: dce100: skip non-DP stream encoders for DP MST

    On DCE8-class ASICs (e.g. Bonaire), the resource pool contains digital
    DIG stream encoders plus one analog DAC encoder. When assigning a stream
    encoder for a second DisplayPort MST stream, if the preferred digital
    encoder is already acquired, dce100_find_first_free_match_stream_enc_for_link()
    falls back to the first free pool entry. That entry may be the analog
    encoder, whose funcs table lacks DP hooks such as dp_set_stream_attribute.
    The subsequent atomic commit then dereferences NULL function pointers in
    link_set_dpms_on() and crashes.

    Skip encoders without dp_set_stream_attribute when the stream uses a DP
    signal (including MST). Use dc_is_dp_signal(stream->signal) for the MST
    fallback path instead of checking only the link connector signal.

    Tested on:
    - GPU: AMD Radeon R7 260X (Bonaire / DCE8)
    - Board: Supermicro C9X299-PG300
    - Setup: DP MST daisy chain, hotplug second monitor or have it connected on boot
    - Kernel: 7.1.3 (issue observed since 6.19)
    - Result: kernel oops without patch; dual monitors stable with patch

    Signed-off-by: Andriy Korud <a.korud@gmail.com>
    Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/5162
    Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
    (cherry picked from commit 28ec64943e3ee4d9b8d30cea61e380f1429953a8)
    Cc: stable@vger.kernel.org

diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
index b92d4f378d60..97ea22af5d2b 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
@@ -992,6 +992,11 @@ struct stream_encoder *dce100_find_first_free_match_stream_enc_for_link(
 	for (i = 0; i < pool->stream_enc_count; i++) {
 		if (!res_ctx->is_stream_enc_acquired[i] &&
 				pool->stream_enc[i]) {
+			/* DP/MST needs a digital encoder; skip analog/no-DP encoders */
+			if (dc_is_dp_signal(stream->signal) &&
+			    (!pool->stream_enc[i]->funcs ||
+			     !pool->stream_enc[i]->funcs->dp_set_stream_attribute))
+				continue;
 			/* Store first available for MST second display
 			 * in daisy chain use case
 			 */
@@ -1014,7 +1019,7 @@ struct stream_encoder *dce100_find_first_free_match_stream_enc_for_link(
 	 * required for non DP connectors.
 	 */

-	if (j >= 0 && link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT)
+	if (j >= 0 && dc_is_dp_signal(stream->signal))
 		return pool->stream_enc[j];

 	return NULL;