]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Jun 2026 16:14:26 +0000 (18:14 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Jun 2026 16:14:26 +0000 (18:14 +0200)
added patches:
drm-amd-display-clamp-hdmi-hdcp2-rx_id_list-read-to-buffer-size.patch
drm-amd-display-clamp-vbios-hdmi-retimer-register-count-to-array-size.patch
drm-amd-display-fix-null-deref-and-buffer-over-read-in-sdp-debugfs.patch
drm-amd-display-use-krealloc_array-in-dal_vector_reserve.patch
drm-amdgpu-restart-the-cs-if-some-parts-of-the-vm-are-still-invalidated.patch
drm-amdkfd-fix-buffer-overflow-in-sdma-queue-checkpoint-restore-on-gfx11.patch
drm-amdkfd-fix-null-dereference-in-get_queue_ids.patch

queue-6.6/drm-amd-display-clamp-hdmi-hdcp2-rx_id_list-read-to-buffer-size.patch [new file with mode: 0644]
queue-6.6/drm-amd-display-clamp-vbios-hdmi-retimer-register-count-to-array-size.patch [new file with mode: 0644]
queue-6.6/drm-amd-display-fix-null-deref-and-buffer-over-read-in-sdp-debugfs.patch [new file with mode: 0644]
queue-6.6/drm-amd-display-use-krealloc_array-in-dal_vector_reserve.patch [new file with mode: 0644]
queue-6.6/drm-amdgpu-restart-the-cs-if-some-parts-of-the-vm-are-still-invalidated.patch [new file with mode: 0644]
queue-6.6/drm-amdkfd-fix-buffer-overflow-in-sdma-queue-checkpoint-restore-on-gfx11.patch [new file with mode: 0644]
queue-6.6/drm-amdkfd-fix-null-dereference-in-get_queue_ids.patch [new file with mode: 0644]
queue-6.6/series

diff --git a/queue-6.6/drm-amd-display-clamp-hdmi-hdcp2-rx_id_list-read-to-buffer-size.patch b/queue-6.6/drm-amd-display-clamp-hdmi-hdcp2-rx_id_list-read-to-buffer-size.patch
new file mode 100644 (file)
index 0000000..4ba247d
--- /dev/null
@@ -0,0 +1,47 @@
+From f0f3981c43b32cadfe373d636d9e9ca522bb3702 Mon Sep 17 00:00:00 2001
+From: Harry Wentland <harry.wentland@amd.com>
+Date: Thu, 7 May 2026 15:38:37 -0400
+Subject: drm/amd/display: Clamp HDMI HDCP2 rx_id_list read to buffer size
+
+From: Harry Wentland <harry.wentland@amd.com>
+
+commit f0f3981c43b32cadfe373d636d9e9ca522bb3702 upstream.
+
+[Why & How]
+During HDCP 2.x repeater authentication over HDMI, the driver reads the
+sink's RxStatus register and extracts a 10-bit message size field (max
+value 1023). This value is used as the read length for the ReceiverID
+list without being clamped to the size of the destination buffer
+rx_id_list[177]. A malicious HDMI repeater could advertise a message
+size larger than the buffer, causing an out-of-bounds write during the
+I2C read.
+
+Clamp the read length in mod_hdcp_read_rx_id_list() to the size of the
+rx_id_list buffer, matching the approach already used in the DP branch.
+
+Fixes: eff682f83c9c ("drm/amd/display: Add DDC handles for HDCP2.2")
+Assisted-by: Copilot:claude-opus-4.6
+Reviewed-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Ray Wu <ray.wu@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 229212219e4247d9486f8ba41ef087358490be09)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c
++++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c
+@@ -533,7 +533,8 @@ enum mod_hdcp_status mod_hdcp_read_rx_id
+       } else {
+               status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,
+                               hdcp->auth.msg.hdcp2.rx_id_list,
+-                              hdcp->auth.msg.hdcp2.rx_id_list_size);
++                              MIN(hdcp->auth.msg.hdcp2.rx_id_list_size,
++                                  sizeof(hdcp->auth.msg.hdcp2.rx_id_list)));
+       }
+       return status;
+ }
diff --git a/queue-6.6/drm-amd-display-clamp-vbios-hdmi-retimer-register-count-to-array-size.patch b/queue-6.6/drm-amd-display-clamp-vbios-hdmi-retimer-register-count-to-array-size.patch
new file mode 100644 (file)
index 0000000..9a92562
--- /dev/null
@@ -0,0 +1,188 @@
+From fb0707ce00eef4e2d60c3020e1c0432739703e4a Mon Sep 17 00:00:00 2001
+From: Harry Wentland <harry.wentland@amd.com>
+Date: Mon, 4 May 2026 15:51:13 -0400
+Subject: drm/amd/display: Clamp VBIOS HDMI retimer register count to array size
+
+From: Harry Wentland <harry.wentland@amd.com>
+
+commit fb0707ce00eef4e2d60c3020e1c0432739703e4a upstream.
+
+[Why & How]
+The VBIOS integrated info tables (v1_11 and v2_1) contain HdmiRegNum and
+Hdmi6GRegNum fields that are used as loop bounds when copying retimer I2C
+register settings into fixed-size arrays (dp*_ext_hdmi_reg_settings[9]
+and dp*_ext_hdmi_6g_reg_settings[3]). These u8 fields are not validated
+before use, so a malformed VBIOS can specify values up to 255, causing an
+out-of-bounds heap write during driver probe.
+
+Clamp each register count to the destination array size using min_t()
+before the copy loops, in both get_integrated_info_v11() and
+get_integrated_info_v2_1().
+
+Assisted-by: GitHub Copilot:claude-opus-4.6
+Reviewed-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Ray Wu <ray.wu@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 5a7f0ef90195940c54b0f5bb85b87da55f038c69)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c |   48 ++++++++++++++-------
+ 1 file changed, 32 insertions(+), 16 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+@@ -2516,14 +2516,16 @@ static enum bp_result get_integrated_inf
+       info_v11->extdispconninfo.checksum;
+       info->dp0_ext_hdmi_slv_addr = info_v11->dp0_retimer_set.HdmiSlvAddr;
+-      info->dp0_ext_hdmi_reg_num = info_v11->dp0_retimer_set.HdmiRegNum;
++      info->dp0_ext_hdmi_reg_num = min_t(u8, info_v11->dp0_retimer_set.HdmiRegNum,
++                                          ARRAY_SIZE(info->dp0_ext_hdmi_reg_settings));
+       for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) {
+               info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index =
+                               info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
+               info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val =
+                               info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
+       }
+-      info->dp0_ext_hdmi_6g_reg_num = info_v11->dp0_retimer_set.Hdmi6GRegNum;
++      info->dp0_ext_hdmi_6g_reg_num = min_t(u8, info_v11->dp0_retimer_set.Hdmi6GRegNum,
++                                             ARRAY_SIZE(info->dp0_ext_hdmi_6g_reg_settings));
+       for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) {
+               info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
+                               info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
+@@ -2532,14 +2534,16 @@ static enum bp_result get_integrated_inf
+       }
+       info->dp1_ext_hdmi_slv_addr = info_v11->dp1_retimer_set.HdmiSlvAddr;
+-      info->dp1_ext_hdmi_reg_num = info_v11->dp1_retimer_set.HdmiRegNum;
++      info->dp1_ext_hdmi_reg_num = min_t(u8, info_v11->dp1_retimer_set.HdmiRegNum,
++                                          ARRAY_SIZE(info->dp1_ext_hdmi_reg_settings));
+       for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) {
+               info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index =
+                               info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
+               info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val =
+                               info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
+       }
+-      info->dp1_ext_hdmi_6g_reg_num = info_v11->dp1_retimer_set.Hdmi6GRegNum;
++      info->dp1_ext_hdmi_6g_reg_num = min_t(u8, info_v11->dp1_retimer_set.Hdmi6GRegNum,
++                                             ARRAY_SIZE(info->dp1_ext_hdmi_6g_reg_settings));
+       for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) {
+               info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
+                               info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
+@@ -2548,14 +2552,16 @@ static enum bp_result get_integrated_inf
+       }
+       info->dp2_ext_hdmi_slv_addr = info_v11->dp2_retimer_set.HdmiSlvAddr;
+-      info->dp2_ext_hdmi_reg_num = info_v11->dp2_retimer_set.HdmiRegNum;
++      info->dp2_ext_hdmi_reg_num = min_t(u8, info_v11->dp2_retimer_set.HdmiRegNum,
++                                          ARRAY_SIZE(info->dp2_ext_hdmi_reg_settings));
+       for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) {
+               info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index =
+                               info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
+               info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val =
+                               info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
+       }
+-      info->dp2_ext_hdmi_6g_reg_num = info_v11->dp2_retimer_set.Hdmi6GRegNum;
++      info->dp2_ext_hdmi_6g_reg_num = min_t(u8, info_v11->dp2_retimer_set.Hdmi6GRegNum,
++                                             ARRAY_SIZE(info->dp2_ext_hdmi_6g_reg_settings));
+       for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) {
+               info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
+                               info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
+@@ -2564,14 +2570,16 @@ static enum bp_result get_integrated_inf
+       }
+       info->dp3_ext_hdmi_slv_addr = info_v11->dp3_retimer_set.HdmiSlvAddr;
+-      info->dp3_ext_hdmi_reg_num = info_v11->dp3_retimer_set.HdmiRegNum;
++      info->dp3_ext_hdmi_reg_num = min_t(u8, info_v11->dp3_retimer_set.HdmiRegNum,
++                                          ARRAY_SIZE(info->dp3_ext_hdmi_reg_settings));
+       for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) {
+               info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index =
+                               info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
+               info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val =
+                               info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
+       }
+-      info->dp3_ext_hdmi_6g_reg_num = info_v11->dp3_retimer_set.Hdmi6GRegNum;
++      info->dp3_ext_hdmi_6g_reg_num = min_t(u8, info_v11->dp3_retimer_set.Hdmi6GRegNum,
++                                             ARRAY_SIZE(info->dp3_ext_hdmi_6g_reg_settings));
+       for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) {
+               info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
+                               info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
+@@ -2721,14 +2729,16 @@ static enum bp_result get_integrated_inf
+       info->ext_disp_conn_info.checksum =
+               info_v2_1->extdispconninfo.checksum;
+       info->dp0_ext_hdmi_slv_addr = info_v2_1->dp0_retimer_set.HdmiSlvAddr;
+-      info->dp0_ext_hdmi_reg_num = info_v2_1->dp0_retimer_set.HdmiRegNum;
++      info->dp0_ext_hdmi_reg_num = min_t(u8, info_v2_1->dp0_retimer_set.HdmiRegNum,
++                                          ARRAY_SIZE(info->dp0_ext_hdmi_reg_settings));
+       for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) {
+               info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index =
+                               info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
+               info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val =
+                               info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
+       }
+-      info->dp0_ext_hdmi_6g_reg_num = info_v2_1->dp0_retimer_set.Hdmi6GRegNum;
++      info->dp0_ext_hdmi_6g_reg_num = min_t(u8, info_v2_1->dp0_retimer_set.Hdmi6GRegNum,
++                                             ARRAY_SIZE(info->dp0_ext_hdmi_6g_reg_settings));
+       for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) {
+               info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
+                               info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
+@@ -2736,14 +2746,16 @@ static enum bp_result get_integrated_inf
+                               info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
+       }
+       info->dp1_ext_hdmi_slv_addr = info_v2_1->dp1_retimer_set.HdmiSlvAddr;
+-      info->dp1_ext_hdmi_reg_num = info_v2_1->dp1_retimer_set.HdmiRegNum;
++      info->dp1_ext_hdmi_reg_num = min_t(u8, info_v2_1->dp1_retimer_set.HdmiRegNum,
++                                          ARRAY_SIZE(info->dp1_ext_hdmi_reg_settings));
+       for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) {
+               info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index =
+                               info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
+               info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val =
+                               info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
+       }
+-      info->dp1_ext_hdmi_6g_reg_num = info_v2_1->dp1_retimer_set.Hdmi6GRegNum;
++      info->dp1_ext_hdmi_6g_reg_num = min_t(u8, info_v2_1->dp1_retimer_set.Hdmi6GRegNum,
++                                             ARRAY_SIZE(info->dp1_ext_hdmi_6g_reg_settings));
+       for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) {
+               info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
+                               info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
+@@ -2751,14 +2763,16 @@ static enum bp_result get_integrated_inf
+                               info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
+       }
+       info->dp2_ext_hdmi_slv_addr = info_v2_1->dp2_retimer_set.HdmiSlvAddr;
+-      info->dp2_ext_hdmi_reg_num = info_v2_1->dp2_retimer_set.HdmiRegNum;
++      info->dp2_ext_hdmi_reg_num = min_t(u8, info_v2_1->dp2_retimer_set.HdmiRegNum,
++                                          ARRAY_SIZE(info->dp2_ext_hdmi_reg_settings));
+       for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) {
+               info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index =
+                               info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
+               info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val =
+                               info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
+       }
+-      info->dp2_ext_hdmi_6g_reg_num = info_v2_1->dp2_retimer_set.Hdmi6GRegNum;
++      info->dp2_ext_hdmi_6g_reg_num = min_t(u8, info_v2_1->dp2_retimer_set.Hdmi6GRegNum,
++                                             ARRAY_SIZE(info->dp2_ext_hdmi_6g_reg_settings));
+       for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) {
+               info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
+                               info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
+@@ -2766,14 +2780,16 @@ static enum bp_result get_integrated_inf
+                               info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
+       }
+       info->dp3_ext_hdmi_slv_addr = info_v2_1->dp3_retimer_set.HdmiSlvAddr;
+-      info->dp3_ext_hdmi_reg_num = info_v2_1->dp3_retimer_set.HdmiRegNum;
++      info->dp3_ext_hdmi_reg_num = min_t(u8, info_v2_1->dp3_retimer_set.HdmiRegNum,
++                                          ARRAY_SIZE(info->dp3_ext_hdmi_reg_settings));
+       for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) {
+               info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index =
+                               info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
+               info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val =
+                               info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
+       }
+-      info->dp3_ext_hdmi_6g_reg_num = info_v2_1->dp3_retimer_set.Hdmi6GRegNum;
++      info->dp3_ext_hdmi_6g_reg_num = min_t(u8, info_v2_1->dp3_retimer_set.Hdmi6GRegNum,
++                                             ARRAY_SIZE(info->dp3_ext_hdmi_6g_reg_settings));
+       for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) {
+               info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
+                               info_v2_1->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
diff --git a/queue-6.6/drm-amd-display-fix-null-deref-and-buffer-over-read-in-sdp-debugfs.patch b/queue-6.6/drm-amd-display-fix-null-deref-and-buffer-over-read-in-sdp-debugfs.patch
new file mode 100644 (file)
index 0000000..038b499
--- /dev/null
@@ -0,0 +1,53 @@
+From adf67034b1f61f7119295208085bfd43f85f56af Mon Sep 17 00:00:00 2001
+From: Harry Wentland <harry.wentland@amd.com>
+Date: Mon, 11 May 2026 16:46:25 -0400
+Subject: drm/amd/display: Fix NULL deref and buffer over-read in SDP debugfs
+
+From: Harry Wentland <harry.wentland@amd.com>
+
+commit adf67034b1f61f7119295208085bfd43f85f56af upstream.
+
+[Why & How]
+dp_sdp_message_debugfs_write() dereferences connector->base.state->crtc
+without checking for NULL. A connector can be connected but not bound to
+any CRTC (e.g. after hot-plug before the next atomic commit), causing a
+kernel crash when writing to the sdp_message debugfs node.
+
+The function also ignores the user-provided size argument and always
+passes 36 bytes to copy_from_user(), reading past the user buffer when
+size < 36.
+
+Fix both issues by:
+- Returning -ENODEV when connector->base.state or state->crtc is NULL
+- Clamping write_size to min(size, sizeof(data))
+
+Fixes: c7ba3653e977 ("drm/amd/display: Generic SDP message access in amdgpu")
+Assisted-by: Copilot:claude-opus-4.6
+Reviewed-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Ray Wu <ray.wu@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 6ab4c36a522842ff70474a1c0af2e40e50fc8300)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+@@ -1230,8 +1230,13 @@ static ssize_t dp_sdp_message_debugfs_wr
+       if (size == 0)
+               return 0;
++      if (!connector->base.state || !connector->base.state->crtc)
++              return -ENODEV;
++
+       acrtc_state = to_dm_crtc_state(connector->base.state->crtc->state);
++      write_size = min_t(size_t, size, sizeof(data));
++
+       r = copy_from_user(data, buf, write_size);
+       write_size -= r;
diff --git a/queue-6.6/drm-amd-display-use-krealloc_array-in-dal_vector_reserve.patch b/queue-6.6/drm-amd-display-use-krealloc_array-in-dal_vector_reserve.patch
new file mode 100644 (file)
index 0000000..74f8fc3
--- /dev/null
@@ -0,0 +1,46 @@
+From da48bc4461b8a5ebfb9264c9b191a701d8e99009 Mon Sep 17 00:00:00 2001
+From: Harry Wentland <harry.wentland@amd.com>
+Date: Tue, 5 May 2026 11:52:15 -0400
+Subject: drm/amd/display: Use krealloc_array() in dal_vector_reserve()
+
+From: Harry Wentland <harry.wentland@amd.com>
+
+commit da48bc4461b8a5ebfb9264c9b191a701d8e99009 upstream.
+
+[Why & How]
+dal_vector_reserve() computes the allocation size as
+"capacity * vector->struct_size" using uint32_t arithmetic, which can
+silently wrap to a small value on overflow. This would cause krealloc to
+return a smaller buffer than expected, leading to heap overflows on
+subsequent vector appends.
+
+Replace krealloc() with krealloc_array() which performs an internal
+overflow check and returns NULL on wrap, preventing the issue.
+
+Fixes: 2004f45ef83f ("drm/amd/display: Use kernel alloc/free")
+Assisted-by: Copilot:claude-opus-4.6
+Reviewed-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Ray Wu <ray.wu@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 37668568641ccc4cc1dbca4923d0a16609dd5707)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/basics/vector.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/dc/basics/vector.c
++++ b/drivers/gpu/drm/amd/display/dc/basics/vector.c
+@@ -288,8 +288,8 @@ bool dal_vector_reserve(struct vector *v
+       if (capacity <= vector->capacity)
+               return true;
+-      new_container = krealloc(vector->container,
+-                               capacity * vector->struct_size, GFP_KERNEL);
++      new_container = krealloc_array(vector->container,
++                                     capacity, vector->struct_size, GFP_KERNEL);
+       if (new_container) {
+               vector->container = new_container;
diff --git a/queue-6.6/drm-amdgpu-restart-the-cs-if-some-parts-of-the-vm-are-still-invalidated.patch b/queue-6.6/drm-amdgpu-restart-the-cs-if-some-parts-of-the-vm-are-still-invalidated.patch
new file mode 100644 (file)
index 0000000..99804c8
--- /dev/null
@@ -0,0 +1,48 @@
+From 40396ffdf6120e2380706c59e1a84d7e765a37b6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Wed, 25 Feb 2026 15:12:02 +0100
+Subject: drm/amdgpu: restart the CS if some parts of the VM are still invalidated
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christian König <christian.koenig@amd.com>
+
+commit 40396ffdf6120e2380706c59e1a84d7e765a37b6 upstream.
+
+Make sure that we only submit work with full up to date VM page tables.
+
+Backport to 7.1 and older.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
+Tested-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 59720bfd8c6dbebeb8d5a7ab64241b007efd9213)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+@@ -1272,6 +1272,7 @@ static int amdgpu_cs_submit(struct amdgp
+ {
+       struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
+       struct amdgpu_job *leader = p->gang_leader;
++      struct amdgpu_vm *vm = &fpriv->vm;
+       struct amdgpu_bo_list_entry *e;
+       struct drm_gem_object *gobj;
+       unsigned long index;
+@@ -1317,7 +1318,8 @@ static int amdgpu_cs_submit(struct amdgp
+                                                       e->range);
+               e->range = NULL;
+       }
+-      if (r) {
++
++      if (r || !list_empty(&vm->invalidated)) {
+               r = -EAGAIN;
+               mutex_unlock(&p->adev->notifier_lock);
+               return r;
diff --git a/queue-6.6/drm-amdkfd-fix-buffer-overflow-in-sdma-queue-checkpoint-restore-on-gfx11.patch b/queue-6.6/drm-amdkfd-fix-buffer-overflow-in-sdma-queue-checkpoint-restore-on-gfx11.patch
new file mode 100644 (file)
index 0000000..838194b
--- /dev/null
@@ -0,0 +1,118 @@
+From 352ea59028ea48a6fff77f19ae28f98f71946a80 Mon Sep 17 00:00:00 2001
+From: Andrew Martin <andrew.martin@amd.com>
+Date: Thu, 28 May 2026 12:54:39 -0400
+Subject: drm/amdkfd: Fix buffer overflow in SDMA queue checkpoint/restore on GFX11
+
+From: Andrew Martin <andrew.martin@amd.com>
+
+commit 352ea59028ea48a6fff77f19ae28f98f71946a80 upstream.
+
+The v11 MQD manager incorrectly assigned the CP-compute variants of
+checkpoint_mqd/restore_mqd for KFD_MQD_TYPE_SDMA queues. These functions
+use sizeof(struct v11_compute_mqd) (2048 bytes) instead of sizeof(struct
+v11_sdma_mqd) (512 bytes), causing a 1536-byte overflow.
+
+During CRIU checkpoint of an SDMA queue on Navi3x:
+- checkpoint_mqd() reads 2048 bytes from a 512-byte SDMA MQD buffer,
+  leaking 1536 bytes of adjacent GTT memory to userspace
+
+During CRIU restore:
+- restore_mqd() writes 2048 bytes into a 512-byte SDMA MQD buffer,
+  corrupting 1536 bytes of adjacent GTT memory (often the ring buffer
+  or neighboring MQDs)
+
+This is a copy-paste regression unique to v11. All other ASIC backends
+(cik, vi, v9, v10, v12) correctly use the SDMA-specific variants.
+
+Add checkpoint_mqd_sdma() and restore_mqd_sdma() functions that properly
+handle the smaller v11_sdma_mqd structure, matching the pattern used in
+other MQD managers.
+
+Fixes: cc009e613de6 ("drm/amdkfd: Add KFD support for soc21 v3")
+Assisted-by: Claude:Sonnet 4-5
+Signed-off-by: Andrew Martin <andrew.martin@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 6fa41db7ffdec97d62433adf03b7b9b759af8c2c)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c |   49 +++++++++++++++++++----
+ 1 file changed, 41 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
+@@ -333,8 +333,7 @@ static void checkpoint_mqd(struct mqd_ma
+ static void restore_mqd(struct mqd_manager *mm, void **mqd,
+                       struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
+-                      struct queue_properties *qp,
+-                      const void *mqd_src,
++                      struct queue_properties *qp, const void *mqd_src,
+                       const void *ctl_stack_src, const u32 ctl_stack_size)
+ {
+       uint64_t addr;
+@@ -350,14 +349,48 @@ static void restore_mqd(struct mqd_manag
+               *gart_addr = addr;
+       m->cp_hqd_pq_doorbell_control =
+-              qp->doorbell_off <<
+-                      CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT;
+-      pr_debug("cp_hqd_pq_doorbell_control 0x%x\n",
+-                      m->cp_hqd_pq_doorbell_control);
++              qp->doorbell_off << CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT;
++      pr_debug("cp_hqd_pq_doorbell_control 0x%x\n", m->cp_hqd_pq_doorbell_control);
+       qp->is_active = 0;
+ }
++static void checkpoint_mqd_sdma(struct mqd_manager *mm,
++                              void *mqd,
++                              void *mqd_dst,
++                              void *ctl_stack_dst)
++{
++      struct v11_sdma_mqd *m;
++
++      m = get_sdma_mqd(mqd);
++
++      memcpy(mqd_dst, m, sizeof(struct v11_sdma_mqd));
++}
++
++static void restore_mqd_sdma(struct mqd_manager *mm, void **mqd,
++                           struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
++                           struct queue_properties *qp,
++                           const void *mqd_src,
++                           const void *ctl_stack_src,
++                           const u32 ctl_stack_size)
++{
++      uint64_t addr;
++      struct v11_sdma_mqd *m;
++
++      m = (struct v11_sdma_mqd *) mqd_mem_obj->cpu_ptr;
++      addr = mqd_mem_obj->gpu_addr;
++
++      memcpy(m, mqd_src, sizeof(*m));
++
++      m->sdmax_rlcx_doorbell_offset =
++              qp->doorbell_off << SDMA0_QUEUE0_DOORBELL_OFFSET__OFFSET__SHIFT;
++
++      *mqd = m;
++      if (gart_addr)
++              *gart_addr = addr;
++
++      qp->is_active = 0;
++}
+ static void init_mqd_hiq(struct mqd_manager *mm, void **mqd,
+                       struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
+@@ -542,8 +575,8 @@ struct mqd_manager *mqd_manager_init_v11
+               mqd->update_mqd = update_mqd_sdma;
+               mqd->destroy_mqd = kfd_destroy_mqd_sdma;
+               mqd->is_occupied = kfd_is_occupied_sdma;
+-              mqd->checkpoint_mqd = checkpoint_mqd;
+-              mqd->restore_mqd = restore_mqd;
++              mqd->checkpoint_mqd = checkpoint_mqd_sdma;
++              mqd->restore_mqd = restore_mqd_sdma;
+               mqd->mqd_size = sizeof(struct v11_sdma_mqd);
+               mqd->mqd_stride = kfd_mqd_stride;
+ #if defined(CONFIG_DEBUG_FS)
diff --git a/queue-6.6/drm-amdkfd-fix-null-dereference-in-get_queue_ids.patch b/queue-6.6/drm-amdkfd-fix-null-dereference-in-get_queue_ids.patch
new file mode 100644 (file)
index 0000000..4ef64a6
--- /dev/null
@@ -0,0 +1,45 @@
+From 2bd550b547deabef98bd3b017ff743b7c34d3a6d Mon Sep 17 00:00:00 2001
+From: Muhammad Bilal <meatuni001@gmail.com>
+Date: Sat, 23 May 2026 16:56:46 +0000
+Subject: drm/amdkfd: fix NULL dereference in get_queue_ids()
+
+From: Muhammad Bilal <meatuni001@gmail.com>
+
+commit 2bd550b547deabef98bd3b017ff743b7c34d3a6d upstream.
+
+When usr_queue_id_array is NULL and num_queues is non-zero,
+get_queue_ids() returns NULL. The callers check only IS_ERR() on the
+return value; since IS_ERR(NULL) == false the check passes, and
+suspend_queues() calls q_array_invalidate() which immediately
+dereferences NULL while iterating num_queues times.
+
+Userspace can trigger this via kfd_ioctl_set_debug_trap() by supplying
+num_queues > 0 with a zero queue_array_ptr, causing a kernel panic.
+
+A NULL usr_queue_id_array with num_queues == 0 is a legitimate no-op
+(q_array_invalidate never executes, and resume_queues already guards
+all queue_ids dereferences behind a NULL check). Return ERR_PTR(-EINVAL)
+only when num_queues is non-zero and the pointer is absent; both callers
+already propagate IS_ERR() returns correctly to userspace.
+
+Fixes: a70a93fa568b ("drm/amdkfd: add debug suspend and resume process queues operation")
+Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit f165a82cdf503884bb1797771c61b2fcc72113d4)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+@@ -2787,7 +2787,7 @@ static void copy_context_work_handler (s
+ static uint32_t *get_queue_ids(uint32_t num_queues, uint32_t *usr_queue_id_array)
+ {
+       if (!usr_queue_id_array)
+-              return NULL;
++              return num_queues ? ERR_PTR(-EINVAL) : NULL;
+       if (num_queues > KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)
+               return ERR_PTR(-EINVAL);
index 608386ce759dc7d39faf3f51a0bb844d0048bbff..01565b83d8653a79dc5eb410d5df50163e119710 100644 (file)
@@ -358,3 +358,10 @@ thunderbolt-validate-xdomain-request-packet-size-before-type-cast.patch
 thunderbolt-limit-xdomain-response-copy-to-actual-frame-size.patch
 slimbus-qcom-ngd-ctrl-fix-of-node-refcount.patch
 slimbus-qcom-ngd-ctrl-avoid-abba-on-tx_lock-ctrl-lock.patch
+drm-amdkfd-fix-null-dereference-in-get_queue_ids.patch
+drm-amdkfd-fix-buffer-overflow-in-sdma-queue-checkpoint-restore-on-gfx11.patch
+drm-amdgpu-restart-the-cs-if-some-parts-of-the-vm-are-still-invalidated.patch
+drm-amd-display-clamp-hdmi-hdcp2-rx_id_list-read-to-buffer-size.patch
+drm-amd-display-clamp-vbios-hdmi-retimer-register-count-to-array-size.patch
+drm-amd-display-fix-null-deref-and-buffer-over-read-in-sdp-debugfs.patch
+drm-amd-display-use-krealloc_array-in-dal_vector_reserve.patch