summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/display
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2024-12-03 18:02:18 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-12-14 19:59:55 +0100
commit396f697500c821892329cfd90e36b7a7edb90474 (patch)
treefde25845cd736a7784d8d32f283e2b2688c5cf64 /drivers/gpu/drm/display
parentc58947a8d4a500902597ee1dbadf0518d7ff8801 (diff)
downloadlinux-396f697500c821892329cfd90e36b7a7edb90474.tar.gz
linux-396f697500c821892329cfd90e36b7a7edb90474.tar.bz2
linux-396f697500c821892329cfd90e36b7a7edb90474.zip
drm/dp_mst: Verify request type in the corresponding down message reply
commit 4d49e77a973d3b5d1881663c3f122906a0702940 upstream. After receiving the response for an MST down request message, the response should be accepted/parsed only if the response type matches that of the request. Ensure this by checking if the request type code stored both in the request and the reply match, dropping the reply in case of a mismatch. This fixes the topology detection for an MST hub, as described in the Closes link below, where the hub sends an incorrect reply message after a CLEAR_PAYLOAD_TABLE -> LINK_ADDRESS down request message sequence. Cc: Lyude Paul <lyude@redhat.com> Cc: <stable@vger.kernel.org> Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12804 Reviewed-by: Lyude Paul <lyude@redhat.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241203160223.2926014-3-imre.deak@intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/gpu/drm/display')
-rw-r--r--drivers/gpu/drm/display/drm_dp_mst_topology.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 0f4a238c6ce7..ec47aab818cd 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -3862,6 +3862,34 @@ drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up,
return true;
}
+static int get_msg_request_type(u8 data)
+{
+ return data & 0x7f;
+}
+
+static bool verify_rx_request_type(struct drm_dp_mst_topology_mgr *mgr,
+ const struct drm_dp_sideband_msg_tx *txmsg,
+ const struct drm_dp_sideband_msg_rx *rxmsg)
+{
+ const struct drm_dp_sideband_msg_hdr *hdr = &rxmsg->initial_hdr;
+ const struct drm_dp_mst_branch *mstb = txmsg->dst;
+ int tx_req_type = get_msg_request_type(txmsg->msg[0]);
+ int rx_req_type = get_msg_request_type(rxmsg->msg[0]);
+ char rad_str[64];
+
+ if (tx_req_type == rx_req_type)
+ return true;
+
+ drm_dp_mst_rad_to_str(mstb->rad, mstb->lct, rad_str, sizeof(rad_str));
+ drm_dbg_kms(mgr->dev,
+ "Got unexpected MST reply, mstb: %p seqno: %d lct: %d rad: %s rx_req_type: %s (%02x) != tx_req_type: %s (%02x)\n",
+ mstb, hdr->seqno, mstb->lct, rad_str,
+ drm_dp_mst_req_type_str(rx_req_type), rx_req_type,
+ drm_dp_mst_req_type_str(tx_req_type), tx_req_type);
+
+ return false;
+}
+
static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
{
struct drm_dp_sideband_msg_tx *txmsg;
@@ -3891,6 +3919,9 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
goto out_clear_reply;
}
+ if (!verify_rx_request_type(mgr, txmsg, msg))
+ goto out_clear_reply;
+
drm_dp_sideband_parse_reply(mgr, msg, &txmsg->reply);
if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {