]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
7.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Jun 2026 16:09:37 +0000 (18:09 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Jun 2026 16:09:37 +0000 (18:09 +0200)
added patches:
drm-amd-display-add-missing-csc-entries-for-bt.2020-for-dce-ips.patch
drm-amd-display-bound-vbios-record-chain-walk-loops.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-fix-out-of-bounds-read-in-dp_get_eq_aux_rd_interval.patch
drm-amd-display-use-krealloc_array-in-dal_vector_reserve.patch
drm-amd-pm-apply-smu-13.0.10-workaround-during-mp1-unload.patch
drm-amd-pm-fix-smu13-power-limit-default-cap-calculation.patch
drm-amd-pm-mark-metrics.energy_accumulator-is-invalid-for-smu-14.0.2.patch
drm-amd-pm-smu_v14_0_0-use-softmin-for-gfxclk-in-set_soft_freq_limited_range.patch
drm-amdgpu-fix-incorrect-vram-gart-mappings-on-non-4k-page-size-systems.patch
drm-amdgpu-fix-waiting-for-all-submissions-for-userptrs.patch
drm-amdgpu-restart-the-cs-if-some-parts-of-the-vm-are-still-invalidated.patch
drm-amdgpu-set-noretry-1-as-default-for-gfx-10.1.x-navi10-12-14.patch
drm-amdkfd-fix-buffer-overflow-in-sdma-queue-checkpoint-restore-on-gfx11.patch
drm-amdkfd-fix-null-dereference-in-get_queue_ids.patch
drm-v3d-fix-global-performance-monitor-reference-counting.patch
drm-v3d-fix-vaddr-leak-when-indirect-csd-has-zeroed-workgroups.patch
drm-v3d-skip-csd-when-it-has-zeroed-workgroups.patch
drm-v3d-wait-for-pending-l2t-flush-before-cleaning-caches.patch
drm-xe-clear-pending_disable-before-signaling-suspend-fence.patch
drm-xe-display-fix-oops-in-suspend-shutdown-without-display.patch
drm-xe-multi_queue-skip-submit-when-primary-queue-is-suspended.patch

25 files changed:
queue-7.0/drm-amd-display-add-missing-csc-entries-for-bt.2020-for-dce-ips.patch [new file with mode: 0644]
queue-7.0/drm-amd-display-bound-vbios-record-chain-walk-loops.patch [new file with mode: 0644]
queue-7.0/drm-amd-display-clamp-hdmi-hdcp2-rx_id_list-read-to-buffer-size.patch [new file with mode: 0644]
queue-7.0/drm-amd-display-clamp-vbios-hdmi-retimer-register-count-to-array-size.patch [new file with mode: 0644]
queue-7.0/drm-amd-display-fix-null-deref-and-buffer-over-read-in-sdp-debugfs.patch [new file with mode: 0644]
queue-7.0/drm-amd-display-fix-out-of-bounds-read-in-dp_get_eq_aux_rd_interval.patch [new file with mode: 0644]
queue-7.0/drm-amd-display-use-krealloc_array-in-dal_vector_reserve.patch [new file with mode: 0644]
queue-7.0/drm-amd-pm-apply-smu-13.0.10-workaround-during-mp1-unload.patch [new file with mode: 0644]
queue-7.0/drm-amd-pm-fix-smu13-power-limit-default-cap-calculation.patch [new file with mode: 0644]
queue-7.0/drm-amd-pm-mark-metrics.energy_accumulator-is-invalid-for-smu-14.0.2.patch [new file with mode: 0644]
queue-7.0/drm-amd-pm-smu_v14_0_0-use-softmin-for-gfxclk-in-set_soft_freq_limited_range.patch [new file with mode: 0644]
queue-7.0/drm-amdgpu-fix-incorrect-vram-gart-mappings-on-non-4k-page-size-systems.patch [new file with mode: 0644]
queue-7.0/drm-amdgpu-fix-waiting-for-all-submissions-for-userptrs.patch [new file with mode: 0644]
queue-7.0/drm-amdgpu-restart-the-cs-if-some-parts-of-the-vm-are-still-invalidated.patch [new file with mode: 0644]
queue-7.0/drm-amdgpu-set-noretry-1-as-default-for-gfx-10.1.x-navi10-12-14.patch [new file with mode: 0644]
queue-7.0/drm-amdkfd-fix-buffer-overflow-in-sdma-queue-checkpoint-restore-on-gfx11.patch [new file with mode: 0644]
queue-7.0/drm-amdkfd-fix-null-dereference-in-get_queue_ids.patch [new file with mode: 0644]
queue-7.0/drm-v3d-fix-global-performance-monitor-reference-counting.patch [new file with mode: 0644]
queue-7.0/drm-v3d-fix-vaddr-leak-when-indirect-csd-has-zeroed-workgroups.patch [new file with mode: 0644]
queue-7.0/drm-v3d-skip-csd-when-it-has-zeroed-workgroups.patch [new file with mode: 0644]
queue-7.0/drm-v3d-wait-for-pending-l2t-flush-before-cleaning-caches.patch [new file with mode: 0644]
queue-7.0/drm-xe-clear-pending_disable-before-signaling-suspend-fence.patch [new file with mode: 0644]
queue-7.0/drm-xe-display-fix-oops-in-suspend-shutdown-without-display.patch [new file with mode: 0644]
queue-7.0/drm-xe-multi_queue-skip-submit-when-primary-queue-is-suspended.patch [new file with mode: 0644]
queue-7.0/series

diff --git a/queue-7.0/drm-amd-display-add-missing-csc-entries-for-bt.2020-for-dce-ips.patch b/queue-7.0/drm-amd-display-add-missing-csc-entries-for-bt.2020-for-dce-ips.patch
new file mode 100644 (file)
index 0000000..1e5f862
--- /dev/null
@@ -0,0 +1,69 @@
+From 6590fe323ce2807f5d9454e7fccf3fab875d4352 Mon Sep 17 00:00:00 2001
+From: Leorize <leorize+oss@disroot.org>
+Date: Wed, 27 May 2026 23:58:54 -0700
+Subject: drm/amd/display: add missing CSC entries for BT.2020 for DCE IPs
+
+From: Leorize <leorize+oss@disroot.org>
+
+commit 6590fe323ce2807f5d9454e7fccf3fab875d4352 upstream.
+
+DCE-based hardware does not have the CSC matrices for BT.2020, which
+causes the driver to fallback to the GPU built-in matrices. This does
+not appear to cause any issues for RGB sinks, but causes major color
+artifacts for YCbCr ones (e.g. black becomes green).
+
+This commit adds the missing CSC matrices (taken from DC common) to DCE
+CSC tables, resolving the issue.
+
+Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/3358
+Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/5333
+Assisted-by: oh-my-pi:GPT-5.5
+Signed-off-by: Leorize <leorize+oss@disroot.org>
+Reviewed-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 51e6668ab4baf55b082c376318d51ef965757196)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/dce/dce_transform.c       |   10 +++++++++-
+ drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_csc_v.c |   10 +++++++++-
+ 2 files changed, 18 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c
+@@ -110,7 +110,15 @@ static const struct out_csc_color_matrix
+ { COLOR_SPACE_YCBCR601_LIMITED, { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991,
+       0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} },
+ { COLOR_SPACE_YCBCR709_LIMITED, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
+-      0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }
++      0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
++{ COLOR_SPACE_2020_RGB_FULLRANGE,
++      { 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
++{ COLOR_SPACE_2020_RGB_LIMITEDRANGE,
++      { 0x1B67, 0, 0, 0x201, 0, 0x1B67, 0, 0x201, 0, 0, 0x1B67, 0x201} },
++{ COLOR_SPACE_2020_YCBCR_LIMITED, { 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868,
++      0x15B2, 0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} },
++{ COLOR_SPACE_2020_YCBCR_FULL, { 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868, 0x15B2,
++      0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} }
+ };
+ static bool setup_scaling_configuration(
+--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_csc_v.c
++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_csc_v.c
+@@ -88,7 +88,15 @@ static const struct out_csc_color_matrix
+ { COLOR_SPACE_YCBCR601_LIMITED, { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991,
+       0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} },
+ { COLOR_SPACE_YCBCR709_LIMITED, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
+-      0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }
++      0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
++{ COLOR_SPACE_2020_RGB_FULLRANGE,
++      { 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
++{ COLOR_SPACE_2020_RGB_LIMITEDRANGE,
++      { 0x1B67, 0, 0, 0x201, 0, 0x1B67, 0, 0x201, 0, 0, 0x1B67, 0x201} },
++{ COLOR_SPACE_2020_YCBCR_LIMITED, { 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868,
++      0x15B2, 0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} },
++{ COLOR_SPACE_2020_YCBCR_FULL, { 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868, 0x15B2,
++      0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} }
+ };
+ enum csc_color_mode {
diff --git a/queue-7.0/drm-amd-display-bound-vbios-record-chain-walk-loops.patch b/queue-7.0/drm-amd-display-bound-vbios-record-chain-walk-loops.patch
new file mode 100644 (file)
index 0000000..d1da8ad
--- /dev/null
@@ -0,0 +1,291 @@
+From ff287df16a1a58aca78b08d1f3ee09fc44da0351 Mon Sep 17 00:00:00 2001
+From: Harry Wentland <harry.wentland@amd.com>
+Date: Tue, 12 May 2026 15:24:22 -0400
+Subject: drm/amd/display: Bound VBIOS record-chain walk loops
+
+From: Harry Wentland <harry.wentland@amd.com>
+
+commit ff287df16a1a58aca78b08d1f3ee09fc44da0351 upstream.
+
+[Why & How]
+All record-chain walk loops in bios_parser.c and bios_parser2.c use
+for(;;) and only terminate on a 0xFF record_type sentinel or zero
+record_size. A malformed VBIOS image missing the terminator record
+causes unbounded iteration at probe time, potentially hundreds of
+thousands of iterations with record_size=1. In the final iterations
+near the BIOS image boundary, struct casts beyond the 2-byte header
+validated by GET_IMAGE can also read out of bounds.
+
+Cap all 14 record-chain walk loops to BIOS_MAX_NUM_RECORD (256)
+iterations. The atombios.h defines up to 22 distinct record types
+and atomfirmware.h has 13. Assuming an average of less than 10
+records per type (which is reasonable since most are connector-
+based) 256 is a generous upper bound.
+
+Fixes: 4562236b3bc0 ("drm/amd/dc: Add dc display driver (v2)")
+Assisted-by: Copilot:claude-opus-4.6 Mythos
+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 95700a3d660287ed657d6892f7be9ffc0e294a93)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/bios/bios_parser.c        |   15 +++++---
+ drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c       |   27 ++++++++++-----
+ drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h |    5 ++
+ 3 files changed, 33 insertions(+), 14 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
+@@ -222,6 +222,7 @@ static enum bp_result bios_parser_get_i2
+       ATOM_COMMON_RECORD_HEADER *header;
+       ATOM_I2C_RECORD *record;
+       struct bios_parser *bp = BP_FROM_DCB(dcb);
++      int i;
+       if (!info)
+               return BP_RESULT_BADINPUT;
+@@ -234,7 +235,7 @@ static enum bp_result bios_parser_get_i2
+       offset = le16_to_cpu(object->usRecordOffset)
+                       + bp->object_info_tbl_offset;
+-      for (;;) {
++      for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
+               header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
+               if (!header)
+@@ -293,11 +294,12 @@ static enum bp_result bios_parser_get_de
+ {
+       ATOM_COMMON_RECORD_HEADER *header;
+       uint32_t offset;
++      int i;
+       offset = le16_to_cpu(object->usRecordOffset)
+                       + bp->object_info_tbl_offset;
+-      for (;;) {
++      for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
+               header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
+               if (!header)
+@@ -948,6 +950,7 @@ static ATOM_HPD_INT_RECORD *get_hpd_reco
+ {
+       ATOM_COMMON_RECORD_HEADER *header;
+       uint32_t offset;
++      int i;
+       if (!object) {
+               BREAK_TO_DEBUGGER(); /* Invalid object */
+@@ -957,7 +960,7 @@ static ATOM_HPD_INT_RECORD *get_hpd_reco
+       offset = le16_to_cpu(object->usRecordOffset)
+                       + bp->object_info_tbl_offset;
+-      for (;;) {
++      for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
+               header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
+               if (!header)
+@@ -1652,6 +1655,7 @@ static ATOM_ENCODER_CAP_RECORD_V2 *get_e
+ {
+       ATOM_COMMON_RECORD_HEADER *header;
+       uint32_t offset;
++      int i;
+       if (!object) {
+               BREAK_TO_DEBUGGER(); /* Invalid object */
+@@ -1661,7 +1665,7 @@ static ATOM_ENCODER_CAP_RECORD_V2 *get_e
+       offset = le16_to_cpu(object->usRecordOffset)
+                                       + bp->object_info_tbl_offset;
+-      for (;;) {
++      for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
+               header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
+               if (!header)
+@@ -2750,6 +2754,7 @@ static enum bp_result update_slot_layout
+                                             unsigned int record_offset)
+ {
+       unsigned int j;
++      unsigned int n;
+       struct bios_parser *bp;
+       ATOM_BRACKET_LAYOUT_RECORD *record;
+       ATOM_COMMON_RECORD_HEADER *record_header;
+@@ -2759,7 +2764,7 @@ static enum bp_result update_slot_layout
+       record = NULL;
+       record_header = NULL;
+-      for (;;) {
++      for (n = 0; n < BIOS_MAX_NUM_RECORD; n++) {
+               record_header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, record_offset);
+               if (record_header == NULL) {
+--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+@@ -395,6 +395,7 @@ static enum bp_result bios_parser_get_i2
+       struct atom_i2c_record *record;
+       struct atom_i2c_record dummy_record = {0};
+       struct bios_parser *bp = BP_FROM_DCB(dcb);
++      int i;
+       if (!info)
+               return BP_RESULT_BADINPUT;
+@@ -428,7 +429,7 @@ static enum bp_result bios_parser_get_i2
+               break;
+       }
+-      for (;;) {
++      for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
+               header = GET_IMAGE(struct atom_common_record_header, offset);
+               if (!header)
+@@ -533,6 +534,7 @@ static struct atom_hpd_int_record *get_h
+ {
+       struct atom_common_record_header *header;
+       uint32_t offset;
++      int i;
+       if (!object) {
+               BREAK_TO_DEBUGGER(); /* Invalid object */
+@@ -541,7 +543,7 @@ static struct atom_hpd_int_record *get_h
+       offset = object->disp_recordoffset + bp->object_info_tbl_offset;
+-      for (;;) {
++      for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
+               header = GET_IMAGE(struct atom_common_record_header, offset);
+               if (!header)
+@@ -610,6 +612,7 @@ static struct atom_hpd_int_record *get_h
+ {
+       struct atom_common_record_header *header;
+       uint32_t offset;
++      int i;
+       if (!object) {
+               BREAK_TO_DEBUGGER(); /* Invalid object */
+@@ -619,7 +622,7 @@ static struct atom_hpd_int_record *get_h
+       offset = le16_to_cpu(object->disp_recordoffset)
+                       + bp->object_info_tbl_offset;
+-      for (;;) {
++      for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
+               header = GET_IMAGE(struct atom_common_record_header, offset);
+               if (!header)
+@@ -2188,6 +2191,7 @@ static struct atom_encoder_caps_record *
+ {
+       struct atom_common_record_header *header;
+       uint32_t offset;
++      int i;
+       if (!object) {
+               BREAK_TO_DEBUGGER(); /* Invalid object */
+@@ -2196,7 +2200,7 @@ static struct atom_encoder_caps_record *
+       offset = object->encoder_recordoffset + bp->object_info_tbl_offset;
+-      for (;;) {
++      for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
+               header = GET_IMAGE(struct atom_common_record_header, offset);
+               if (!header)
+@@ -2225,6 +2229,7 @@ static struct atom_disp_connector_caps_r
+ {
+       struct atom_common_record_header *header;
+       uint32_t offset;
++      int i;
+       if (!object) {
+               BREAK_TO_DEBUGGER(); /* Invalid object */
+@@ -2233,7 +2238,7 @@ static struct atom_disp_connector_caps_r
+       offset = object->disp_recordoffset + bp->object_info_tbl_offset;
+-      for (;;) {
++      for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
+               header = GET_IMAGE(struct atom_common_record_header, offset);
+               if (!header)
+@@ -2261,6 +2266,7 @@ static struct atom_connector_caps_record
+ {
+       struct atom_common_record_header *header;
+       uint32_t offset;
++      int i;
+       if (!object) {
+               BREAK_TO_DEBUGGER(); /* Invalid object */
+@@ -2269,7 +2275,7 @@ static struct atom_connector_caps_record
+       offset = object->disp_recordoffset + bp->object_info_tbl_offset;
+-      for (;;) {
++      for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
+               header = GET_IMAGE(struct atom_common_record_header, offset);
+               if (!header)
+@@ -2347,6 +2353,7 @@ static struct atom_connector_speed_recor
+ {
+       struct atom_common_record_header *header;
+       uint32_t offset;
++      int i;
+       if (!object) {
+               BREAK_TO_DEBUGGER(); /* Invalid object */
+@@ -2355,7 +2362,7 @@ static struct atom_connector_speed_recor
+       offset = object->disp_recordoffset + bp->object_info_tbl_offset;
+-      for (;;) {
++      for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
+               header = GET_IMAGE(struct atom_common_record_header, offset);
+               if (!header)
+@@ -3240,6 +3247,7 @@ static enum bp_result update_slot_layout
+ {
+       unsigned int record_offset;
+       unsigned int j;
++      unsigned int n;
+       struct atom_display_object_path_v2 *object;
+       struct atom_bracket_layout_record *record;
+       struct atom_common_record_header *record_header;
+@@ -3261,7 +3269,7 @@ static enum bp_result update_slot_layout
+               (object->disp_recordoffset) +
+               (unsigned int)(bp->object_info_tbl_offset);
+-      for (;;) {
++      for (n = 0; n < BIOS_MAX_NUM_RECORD; n++) {
+               record_header = (struct atom_common_record_header *)
+                       GET_IMAGE(struct atom_common_record_header,
+@@ -3355,6 +3363,7 @@ static enum bp_result update_slot_layout
+       struct slot_layout_info *slot_layout_info)
+ {
+       unsigned int record_offset;
++      unsigned int n;
+       struct atom_display_object_path_v3 *object;
+       struct atom_bracket_layout_record_v2 *record;
+       struct atom_common_record_header *record_header;
+@@ -3377,7 +3386,7 @@ static enum bp_result update_slot_layout
+               (object->disp_recordoffset) +
+               (unsigned int)(bp->object_info_tbl_offset);
+-      for (;;) {
++      for (n = 0; n < BIOS_MAX_NUM_RECORD; n++) {
+               record_header = (struct atom_common_record_header *)
+                       GET_IMAGE(struct atom_common_record_header,
+--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h
++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h
+@@ -37,4 +37,9 @@ void bios_set_scratch_critical_state(str
+ #define GET_IMAGE(type, offset) ((type *) bios_get_image(&bp->base, offset, sizeof(type)))
++/* Upper bound on the number of records in a VBIOS record chain. Prevents
++ * unbounded looping if the VBIOS image is malformed and lacks a terminator.
++ */
++#define BIOS_MAX_NUM_RECORD 256
++
+ #endif
diff --git a/queue-7.0/drm-amd-display-clamp-hdmi-hdcp2-rx_id_list-read-to-buffer-size.patch b/queue-7.0/drm-amd-display-clamp-hdmi-hdcp2-rx_id_list-read-to-buffer-size.patch
new file mode 100644 (file)
index 0000000..69d5ce3
--- /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
+@@ -529,7 +529,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-7.0/drm-amd-display-clamp-vbios-hdmi-retimer-register-count-to-array-size.patch b/queue-7.0/drm-amd-display-clamp-vbios-hdmi-retimer-register-count-to-array-size.patch
new file mode 100644 (file)
index 0000000..9fbff5b
--- /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
+@@ -2602,14 +2602,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;
+@@ -2618,14 +2620,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;
+@@ -2634,14 +2638,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;
+@@ -2650,14 +2656,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;
+@@ -2807,14 +2815,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;
+@@ -2822,14 +2832,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;
+@@ -2837,14 +2849,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;
+@@ -2852,14 +2866,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-7.0/drm-amd-display-fix-null-deref-and-buffer-over-read-in-sdp-debugfs.patch b/queue-7.0/drm-amd-display-fix-null-deref-and-buffer-over-read-in-sdp-debugfs.patch
new file mode 100644 (file)
index 0000000..b8a73be
--- /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
+@@ -1344,8 +1344,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-7.0/drm-amd-display-fix-out-of-bounds-read-in-dp_get_eq_aux_rd_interval.patch b/queue-7.0/drm-amd-display-fix-out-of-bounds-read-in-dp_get_eq_aux_rd_interval.patch
new file mode 100644 (file)
index 0000000..c438266
--- /dev/null
@@ -0,0 +1,44 @@
+From e8b4d37eba05141ee01794fc6b7f2da808cee83b Mon Sep 17 00:00:00 2001
+From: Harry Wentland <harry.wentland@amd.com>
+Date: Tue, 5 May 2026 11:44:15 -0400
+Subject: drm/amd/display: Fix out-of-bounds read in dp_get_eq_aux_rd_interval()
+
+From: Harry Wentland <harry.wentland@amd.com>
+
+commit e8b4d37eba05141ee01794fc6b7f2da808cee83b upstream.
+
+[Why & How]
+The aux_rd_interval array in struct dc_lttpr_caps is declared with
+MAX_REPEATER_CNT - 1 (7) elements, indexed 0..6. However, the offset
+parameter passed to dp_get_eq_aux_rd_interval() can be as large as
+MAX_REPEATER_CNT (8) when a sink reports 8 LTTPR repeaters via DPCD.
+This leads to an out-of-bounds read of aux_rd_interval[7] when offset
+is 8.
+
+Fix this by growing aux_rd_interval to MAX_REPEATER_CNT elements to
+accommodate the full range of valid repeater counts defined by the DP
+spec.
+
+Assisted-by: GitHub Copilot:Claude claude-4-opus
+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 a55a458a8df37a65ffda5cf721d554a8f74f6b04)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/dc_dp_types.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
++++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
+@@ -1217,7 +1217,7 @@ struct dc_lttpr_caps {
+       union dp_main_link_channel_coding_lttpr_cap main_link_channel_coding;
+       union dp_128b_132b_supported_lttpr_link_rates supported_128b_132b_rates;
+       union dp_alpm_lttpr_cap alpm;
+-      uint8_t aux_rd_interval[MAX_REPEATER_CNT - 1];
++      uint8_t aux_rd_interval[MAX_REPEATER_CNT];
+       uint8_t lttpr_ieee_oui[3]; // Always read from closest LTTPR to host
+       uint8_t lttpr_device_id[6]; // Always read from closest LTTPR to host
+ };
diff --git a/queue-7.0/drm-amd-display-use-krealloc_array-in-dal_vector_reserve.patch b/queue-7.0/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-7.0/drm-amd-pm-apply-smu-13.0.10-workaround-during-mp1-unload.patch b/queue-7.0/drm-amd-pm-apply-smu-13.0.10-workaround-during-mp1-unload.patch
new file mode 100644 (file)
index 0000000..be8ae47
--- /dev/null
@@ -0,0 +1,52 @@
+From 2493d87bb4c31ec9ca7f0ef7257e33b8b175f913 Mon Sep 17 00:00:00 2001
+From: Yang Wang <kevinyang.wang@amd.com>
+Date: Thu, 21 May 2026 22:36:37 +0800
+Subject: drm/amd/pm: apply SMU 13.0.10 workaround during MP1 unload
+
+From: Yang Wang <kevinyang.wang@amd.com>
+
+commit 2493d87bb4c31ec9ca7f0ef7257e33b8b175f913 upstream.
+
+On SMU v13.0.10, sending PrepareMp1ForUnload with the default
+parameter may leave the device in an inaccessible state. This can
+affect runtime power management and partial PnP flows.
+e.g: kexec, driver unload, boco/d3cold.
+
+Pass the required workaround parameter 0x55, when preparing MP1 for
+unload on SMU v13.0.10, keep the existing behavior for other SMU
+versions.
+
+Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/5133
+Signed-off-by: Yang Wang <kevinyang.wang@amd.com>
+Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 4e8ee1afeedb8d24dd22cdd5ae9f98a6d76ebe4b)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+@@ -2801,11 +2801,19 @@ static void smu_v13_0_0_i2c_control_fini
+ static int smu_v13_0_0_set_mp1_state(struct smu_context *smu,
+                                    enum pp_mp1_state mp1_state)
+ {
++      uint32_t param;
+       int ret;
+       switch (mp1_state) {
+       case PP_MP1_STATE_UNLOAD:
+-              ret = smu_cmn_set_mp1_state(smu, mp1_state);
++              /*
++               * NOTE: Param 0x55 comes from PMFW 80.31.0, ignored in older versions.
++               * No PMFW version check required.
++               */
++              param = amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) ?
++                      0x55 : 0x00;
++              ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PrepareMp1ForUnload,
++                                                    param, NULL);
+               break;
+       default:
+               /* Ignore others */
diff --git a/queue-7.0/drm-amd-pm-fix-smu13-power-limit-default-cap-calculation.patch b/queue-7.0/drm-amd-pm-fix-smu13-power-limit-default-cap-calculation.patch
new file mode 100644 (file)
index 0000000..e4a83bf
--- /dev/null
@@ -0,0 +1,162 @@
+From bb204f19e4a115f094a6a3c4d82fcf48862d0766 Mon Sep 17 00:00:00 2001
+From: Yang Wang <kevinyang.wang@amd.com>
+Date: Tue, 19 May 2026 11:18:12 +0800
+Subject: drm/amd/pm: fix smu13 power limit default/cap calculation
+
+From: Yang Wang <kevinyang.wang@amd.com>
+
+commit bb204f19e4a115f094a6a3c4d82fcf48862d0766 upstream.
+
+smu_v13_0_0_get_power_limit() and smu_v13_0_7_get_power_limit() mix
+runtime power_limit with PP table limits when reporting default/min/max.
+
+When current power limit query succeeds, default_power_limit was set to the
+runtime value instead of the PP table default, and min/max could be derived
+from inconsistent bases (MsgLimits/runtime), leading to incorrect cap info.
+
+Use SocketPowerLimitAc/Dc as the PP default base (pp_limit), keep
+current_power_limit as runtime value, and derive min/max from pp_limit with
+OD percentages.
+
+Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/5227
+Signed-off-by: Yang Wang <kevinyang.wang@amd.com>
+Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
+Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 1eaf26db95901ca70737503a89b831dd763c8453)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c |   32 ++++++++++---------
+ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c |   32 ++++++++++---------
+ 2 files changed, 35 insertions(+), 29 deletions(-)
+
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+@@ -2390,28 +2390,30 @@ static int smu_v13_0_0_enable_mgpu_fan_b
+ }
+ static int smu_v13_0_0_get_power_limit(struct smu_context *smu,
+-                                              uint32_t *current_power_limit,
+-                                              uint32_t *default_power_limit,
+-                                              uint32_t *max_power_limit,
+-                                              uint32_t *min_power_limit)
++                                     uint32_t *current_power_limit,
++                                     uint32_t *default_power_limit,
++                                     uint32_t *max_power_limit,
++                                     uint32_t *min_power_limit)
+ {
+       struct smu_table_context *table_context = &smu->smu_table;
+       struct smu_13_0_0_powerplay_table *powerplay_table =
+               (struct smu_13_0_0_powerplay_table *)table_context->power_play_table;
+       PPTable_t *pptable = table_context->driver_pptable;
+       SkuTable_t *skutable = &pptable->SkuTable;
+-      uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0;
+-      uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC];
+-
+-      if (smu_v13_0_get_current_power_limit(smu, &power_limit))
+-              power_limit = smu->adev->pm.ac_power ?
++      uint32_t pp_limit = smu->adev->pm.ac_power ?
+                             skutable->SocketPowerLimitAc[PPT_THROTTLER_PPT0] :
+                             skutable->SocketPowerLimitDc[PPT_THROTTLER_PPT0];
++      uint32_t power_limit = 0, od_percent_upper = 0, od_percent_lower = 0;
++      int ret;
++
++      if (current_power_limit) {
++              ret = smu_v13_0_get_current_power_limit(smu, &power_limit);
++              if (ret)
++                      *current_power_limit = pp_limit;
++      }
+-      if (current_power_limit)
+-              *current_power_limit = power_limit;
+       if (default_power_limit)
+-              *default_power_limit = power_limit;
++              *default_power_limit = pp_limit;
+       if (powerplay_table) {
+               if (smu->od_enabled &&
+@@ -2425,15 +2427,15 @@ static int smu_v13_0_0_get_power_limit(s
+       }
+       dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
+-                                      od_percent_upper, od_percent_lower, power_limit);
++              od_percent_upper, od_percent_lower, pp_limit);
+       if (max_power_limit) {
+-              *max_power_limit = msg_limit * (100 + od_percent_upper);
++              *max_power_limit = pp_limit * (100 + od_percent_upper);
+               *max_power_limit /= 100;
+       }
+       if (min_power_limit) {
+-              *min_power_limit = power_limit * (100 - od_percent_lower);
++              *min_power_limit = pp_limit * (100 - od_percent_lower);
+               *min_power_limit /= 100;
+       }
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+@@ -2372,28 +2372,32 @@ static int smu_v13_0_7_enable_mgpu_fan_b
+ }
+ static int smu_v13_0_7_get_power_limit(struct smu_context *smu,
+-                                              uint32_t *current_power_limit,
+-                                              uint32_t *default_power_limit,
+-                                              uint32_t *max_power_limit,
+-                                              uint32_t *min_power_limit)
++                                     uint32_t *current_power_limit,
++                                     uint32_t *default_power_limit,
++                                     uint32_t *max_power_limit,
++                                     uint32_t *min_power_limit)
+ {
+       struct smu_table_context *table_context = &smu->smu_table;
+       struct smu_13_0_7_powerplay_table *powerplay_table =
+               (struct smu_13_0_7_powerplay_table *)table_context->power_play_table;
+       PPTable_t *pptable = table_context->driver_pptable;
+       SkuTable_t *skutable = &pptable->SkuTable;
+-      uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0;
+-      uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC];
+-
+-      if (smu_v13_0_get_current_power_limit(smu, &power_limit))
+-              power_limit = smu->adev->pm.ac_power ?
++      uint32_t pp_limit = smu->adev->pm.ac_power ?
+                             skutable->SocketPowerLimitAc[PPT_THROTTLER_PPT0] :
+                             skutable->SocketPowerLimitDc[PPT_THROTTLER_PPT0];
++      uint32_t power_limit = 0, od_percent_upper = 0, od_percent_lower = 0;
++      int ret;
++
++      if (current_power_limit) {
++              ret = smu_v13_0_get_current_power_limit(smu, &power_limit);
++              if (ret)
++                      power_limit = pp_limit;
+-      if (current_power_limit)
+               *current_power_limit = power_limit;
++      }
++
+       if (default_power_limit)
+-              *default_power_limit = power_limit;
++              *default_power_limit = pp_limit;
+       if (powerplay_table) {
+               if (smu->od_enabled &&
+@@ -2407,15 +2411,15 @@ static int smu_v13_0_7_get_power_limit(s
+       }
+       dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
+-                                      od_percent_upper, od_percent_lower, power_limit);
++              od_percent_upper, od_percent_lower, pp_limit);
+       if (max_power_limit) {
+-              *max_power_limit = msg_limit * (100 + od_percent_upper);
++              *max_power_limit = pp_limit * (100 + od_percent_upper);
+               *max_power_limit /= 100;
+       }
+       if (min_power_limit) {
+-              *min_power_limit = power_limit * (100 - od_percent_lower);
++              *min_power_limit = pp_limit * (100 - od_percent_lower);
+               *min_power_limit /= 100;
+       }
diff --git a/queue-7.0/drm-amd-pm-mark-metrics.energy_accumulator-is-invalid-for-smu-14.0.2.patch b/queue-7.0/drm-amd-pm-mark-metrics.energy_accumulator-is-invalid-for-smu-14.0.2.patch
new file mode 100644 (file)
index 0000000..c80ef8b
--- /dev/null
@@ -0,0 +1,31 @@
+From ee193c5bbd5e2b56bbeb54ef554414b43a6fc896 Mon Sep 17 00:00:00 2001
+From: Yang Wang <kevinyang.wang@amd.com>
+Date: Fri, 29 May 2026 11:47:31 +0800
+Subject: drm/amd/pm: mark metrics.energy_accumulator is invalid for smu 14.0.2
+
+From: Yang Wang <kevinyang.wang@amd.com>
+
+commit ee193c5bbd5e2b56bbeb54ef554414b43a6fc896 upstream.
+
+EnergyAccumulator is unsupported on SMU 14.0.2, mark it invalid.
+
+Signed-off-by: Yang Wang <kevinyang.wang@amd.com>
+Reviewed-by: Asad Kamal <asad.kamal@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 646b05043eeed04b51c14aad22a400a8250af4b7)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
+@@ -2150,7 +2150,6 @@ static ssize_t smu_v14_0_2_get_gpu_metri
+                                              metrics->Vcn1ActivityPercentage);
+       gpu_metrics->average_socket_power = metrics->AverageSocketPower;
+-      gpu_metrics->energy_accumulator = metrics->EnergyAccumulator;
+       if (metrics->AverageGfxActivity <= SMU_14_0_2_BUSY_THRESHOLD)
+               gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPostDs;
diff --git a/queue-7.0/drm-amd-pm-smu_v14_0_0-use-softmin-for-gfxclk-in-set_soft_freq_limited_range.patch b/queue-7.0/drm-amd-pm-smu_v14_0_0-use-softmin-for-gfxclk-in-set_soft_freq_limited_range.patch
new file mode 100644 (file)
index 0000000..2d0342a
--- /dev/null
@@ -0,0 +1,43 @@
+From 03b70e0d8aa26bab89a0f1394c1c80a871925e42 Mon Sep 17 00:00:00 2001
+From: Priya Hosur <Priya.Hosur@amd.com>
+Date: Thu, 7 May 2026 13:31:37 +0530
+Subject: drm/amd/pm: smu_v14_0_0: use SoftMin for gfxclk in set_soft_freq_limited_range
+
+From: Priya Hosur <Priya.Hosur@amd.com>
+
+commit 03b70e0d8aa26bab89a0f1394c1c80a871925e42 upstream.
+
+In smu_v14_0_0_set_soft_freq_limited_range(), the gfxclk floor is
+programmed via SetHardMinGfxClk together with SetSoftMaxGfxClk. Under
+power_dpm_force_performance_level=high this pins HardMin to peak gfxclk.
+
+In PMFW arbitration HardMin has higher priority than SoftMax, so the
+firmware thermal/PPT throttler cannot clamp gfxclk via SoftMax once
+HardMin is set to peak. Replace SetHardMinGfxClk with SetSoftMinGfxclk
+so the driver still requests peak performance but the firmware
+throttler retains the ability to clamp gfxclk under thermal/PPT
+pressure. SoftMax handling is unchanged and no other clock domains
+are affected.
+
+Signed-off-by: Priya Hosur <Priya.Hosur@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 3ea273267fd29cbf6d83ee72329f59eb5042605b)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
+@@ -1228,7 +1228,8 @@ static int smu_v14_0_0_set_soft_freq_lim
+       switch (clk_type) {
+       case SMU_GFXCLK:
+       case SMU_SCLK:
+-              msg_set_min = SMU_MSG_SetHardMinGfxClk;
++              /* SoftMin lets PMFW throttle gfxclk; HardMin would override SoftMax. */
++              msg_set_min = SMU_MSG_SetSoftMinGfxclk;
+               msg_set_max = SMU_MSG_SetSoftMaxGfxClk;
+               break;
+       case SMU_FCLK:
diff --git a/queue-7.0/drm-amdgpu-fix-incorrect-vram-gart-mappings-on-non-4k-page-size-systems.patch b/queue-7.0/drm-amdgpu-fix-incorrect-vram-gart-mappings-on-non-4k-page-size-systems.patch
new file mode 100644 (file)
index 0000000..fa38e3f
--- /dev/null
@@ -0,0 +1,63 @@
+From ec4c462e2d8161b32038e21e7187f4a15fe1661d Mon Sep 17 00:00:00 2001
+From: Donet Tom <donettom@linux.ibm.com>
+Date: Wed, 27 May 2026 18:49:31 +0530
+Subject: drm/amdgpu: Fix incorrect VRAM GART mappings on non-4K page size systems
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Donet Tom <donettom@linux.ibm.com>
+
+commit ec4c462e2d8161b32038e21e7187f4a15fe1661d upstream.
+
+When mapping VRAM pages into the GART page table,
+amdgpu_gart_map_vram_range() assumes that the system page size is the
+same as the GPU page size.
+
+On systems with non-4K page sizes, multiple GPU pages can exist within
+a single CPU page. As a result, the mappings are created incorrectly
+because fewer page table entries are programmed than required.
+
+Fix this by programming the mappings correctly for non-4K page size
+systems.
+
+Fixes: 237d623ae659 ("drm/amdgpu/gart: Add helper to bind VRAM pages (v2)")
+Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Donet Tom <donettom@linux.ibm.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit a8f0bc22388f74e0cf4ed8b7d1846c580eaf44cc)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
+@@ -394,7 +394,8 @@ void amdgpu_gart_map_vram_range(struct a
+                               uint64_t start_page, uint64_t num_pages,
+                               uint64_t flags, void *dst)
+ {
+-      u32 i, idx;
++      u32 i, j, t, idx;
++      u64 page_base;
+       /* The SYSTEM flag indicates the pages aren't in VRAM. */
+       WARN_ON_ONCE(flags & AMDGPU_PTE_SYSTEM);
+@@ -402,9 +403,12 @@ void amdgpu_gart_map_vram_range(struct a
+       if (!drm_dev_enter(adev_to_drm(adev), &idx))
+               return;
+-      for (i = 0; i < num_pages; ++i) {
+-              amdgpu_gmc_set_pte_pde(adev, dst,
+-                      start_page + i, pa + AMDGPU_GPU_PAGE_SIZE * i, flags);
++      page_base = pa;
++      for (i = 0, t = 0; i < num_pages; i++) {
++              for (j = 0; j < AMDGPU_GPU_PAGES_IN_CPU_PAGE; j++, t++) {
++                      amdgpu_gmc_set_pte_pde(adev, dst, start_page + t, page_base, flags);
++                      page_base += AMDGPU_GPU_PAGE_SIZE;
++              }
+       }
+       drm_dev_exit(idx);
diff --git a/queue-7.0/drm-amdgpu-fix-waiting-for-all-submissions-for-userptrs.patch b/queue-7.0/drm-amdgpu-fix-waiting-for-all-submissions-for-userptrs.patch
new file mode 100644 (file)
index 0000000..6d80b91
--- /dev/null
@@ -0,0 +1,49 @@
+From 58bafc666c484b21839a2d27e923ae1b2727a1df Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Wed, 18 Feb 2026 13:05:46 +0100
+Subject: drm/amdgpu: fix waiting for all submissions for userptrs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christian König <christian.koenig@amd.com>
+
+commit 58bafc666c484b21839a2d27e923ae1b2727a1df upstream.
+
+Wait for all submissions when userptrs need to be invalidated by the MMU
+notifier, not just the one the userptr was involved into.
+
+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 91250893cbaa25c86872deca95a540d08de1f91e)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c
+@@ -67,6 +67,7 @@ static bool amdgpu_hmm_invalidate_gfx(st
+ {
+       struct amdgpu_bo *bo = container_of(mni, struct amdgpu_bo, notifier);
+       struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
++      struct amdgpu_bo *vm_root = bo->vm_bo->vm->root.bo;
+       long r;
+       if (!mmu_notifier_range_blockable(range))
+@@ -77,8 +78,9 @@ static bool amdgpu_hmm_invalidate_gfx(st
+       mmu_interval_set_seq(mni, cur_seq);
+       amdgpu_vm_bo_invalidate(bo, false);
+-      r = dma_resv_wait_timeout(bo->tbo.base.resv, DMA_RESV_USAGE_BOOKKEEP,
+-                                false, MAX_SCHEDULE_TIMEOUT);
++      r = dma_resv_wait_timeout(vm_root->tbo.base.resv,
++                                DMA_RESV_USAGE_BOOKKEEP, false,
++                                MAX_SCHEDULE_TIMEOUT);
+       mutex_unlock(&adev->notifier_lock);
+       if (r <= 0)
+               DRM_ERROR("(%ld) failed to wait for user bo\n", r);
diff --git a/queue-7.0/drm-amdgpu-restart-the-cs-if-some-parts-of-the-vm-are-still-invalidated.patch b/queue-7.0/drm-amdgpu-restart-the-cs-if-some-parts-of-the-vm-are-still-invalidated.patch
new file mode 100644 (file)
index 0000000..41e00c9
--- /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
+@@ -1285,6 +1285,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;
+@@ -1330,7 +1331,8 @@ static int amdgpu_cs_submit(struct amdgp
+               amdgpu_hmm_range_free(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-7.0/drm-amdgpu-set-noretry-1-as-default-for-gfx-10.1.x-navi10-12-14.patch b/queue-7.0/drm-amdgpu-set-noretry-1-as-default-for-gfx-10.1.x-navi10-12-14.patch
new file mode 100644 (file)
index 0000000..d75fbe8
--- /dev/null
@@ -0,0 +1,89 @@
+From e47b0056a08dc70430ffc44bbf62197e7d1ff8ea Mon Sep 17 00:00:00 2001
+From: Vitaly Prosyak <vitaly.prosyak@amd.com>
+Date: Fri, 29 May 2026 13:50:38 -0400
+Subject: drm/amdgpu: set noretry=1 as default for GFX 10.1.x (Navi10/12/14)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Vitaly Prosyak <vitaly.prosyak@amd.com>
+
+commit e47b0056a08dc70430ffc44bbf62197e7d1ff8ea upstream.
+
+Problem:
+While developing the amd_close_race IGT test (which intentionally triggers
+execute permission faults by removing VM_PAGE_EXECUTABLE from GPU page table
+entries), we discovered that on Navi10 (GFX 10.1.x) these faults produce
+zero diagnostic output. The GPU simply hangs silently for ~10s until the
+scheduler timeout fires. There is no way to distinguish an execute
+permission fault from any other type of GPU hang.
+
+Root cause:
+GFX 10.1.x defaults to noretry=0, which sets
+RETRY_PERMISSION_OR_INVALID_PAGE_FAULT=1 in the GFXHUB UTCL2 registers
+(gfxhub_v2_0.c line 313). With this bit set, permission faults (valid PTE,
+wrong R/W/X bits) are handled entirely within the UTCL1/UTCL2 hardware
+loop: UTCL2 returns an XNACK to UTCL1, and UTCL1 re-requests the
+translation indefinitely, expecting software to eventually fix the
+permission bits (as happens in SVM/HMM recovery). No interrupt of any kind
+reaches the IH ring.
+
+This is different from invalid-page faults (V=0) which DO generate a retry
+fault interrupt that the driver can escalate to a no-retry fault. Permission
+faults with valid PTEs loop silently forever in hardware.
+
+GFX 10.3+ already defaults to noretry=1, which makes permission faults
+generate immediate L2 protection fault interrupts. GFX 10.1.x was
+inadvertently left out of this default.
+
+Fix:
+Change the noretry=1 threshold from IP_VERSION(10, 3, 0) to
+IP_VERSION(10, 1, 0) in amdgpu_gmc_noretry_set(). This is a one-line
+change that aligns GFX 10.1.x behavior with GFX 10.3+ and all newer
+generations.
+
+With noretry=1, the existing non-retry fault handler
+(gmc_v10_0_process_interrupt) already decodes and prints the full
+GCVM_L2_PROTECTION_FAULT_STATUS register including PERMISSION_FAULTS,
+faulting address, VMID, PASID, and process name. No additional logging
+code is needed — the fix is purely routing permission faults to the
+existing, fully-capable non-retry interrupt handler.
+
+v2: Dropped GFX10-specific logging from gmc_v10_0.c and
+kfd_int_process_v10.c (Felix Kuehling). v1 added logging in the retry
+fault handler, but with noretry=1 permission faults take the non-retry
+path — the v1 retry handler code was dead and would never execute.
+
+Tested on Navi10 (GFX 10.1.10):
+- Execute permission faults now produce immediate, clear output:
+    [gfxhub] page fault (src_id:0 ring:64 vmid:4 pasid:592)
+     Process amd_close_race pid 13380 thread amd_close_race pid 13384
+      in page at address 0x40001000 from client 0x1b (UTCL2)
+    GCVM_L2_PROTECTION_FAULT_STATUS:0x00700881
+         PERMISSION_FAULTS: 0x8
+- No regressions with properly-mapped GPU workloads
+
+Cc: Christian Koenig <christian.koenig@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: Felix Kuehling <felix.kuehling@amd.com>
+Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit eb21edd24c40d81066753f8ac6f23bce15745395)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+@@ -1002,7 +1002,7 @@ void amdgpu_gmc_noretry_set(struct amdgp
+                               gc_ver == IP_VERSION(9, 4, 3) ||
+                               gc_ver == IP_VERSION(9, 4, 4) ||
+                               gc_ver == IP_VERSION(9, 5, 0) ||
+-                              gc_ver >= IP_VERSION(10, 3, 0));
++                              gc_ver >= IP_VERSION(10, 1, 0));
+       if (!amdgpu_sriov_xnack_support(adev))
+               gmc->noretry = 1;
diff --git a/queue-7.0/drm-amdkfd-fix-buffer-overflow-in-sdma-queue-checkpoint-restore-on-gfx11.patch b/queue-7.0/drm-amdkfd-fix-buffer-overflow-in-sdma-queue-checkpoint-restore-on-gfx11.patch
new file mode 100644 (file)
index 0000000..d57b02a
--- /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
+@@ -320,8 +320,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;
+@@ -337,14 +336,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,
+@@ -529,8 +562,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-7.0/drm-amdkfd-fix-null-dereference-in-get_queue_ids.patch b/queue-7.0/drm-amdkfd-fix-null-dereference-in-get_queue_ids.patch
new file mode 100644 (file)
index 0000000..193eba6
--- /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
+@@ -3297,7 +3297,7 @@ static void copy_context_work_handler(st
+ 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);
diff --git a/queue-7.0/drm-v3d-fix-global-performance-monitor-reference-counting.patch b/queue-7.0/drm-v3d-fix-global-performance-monitor-reference-counting.patch
new file mode 100644 (file)
index 0000000..466de3c
--- /dev/null
@@ -0,0 +1,85 @@
+From 6bf7e2affc6e62da7add393d7f352d4040f5bc27 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com>
+Date: Sun, 31 May 2026 17:18:55 -0300
+Subject: drm/v3d: Fix global performance monitor reference counting
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maíra Canal <mcanal@igalia.com>
+
+commit 6bf7e2affc6e62da7add393d7f352d4040f5bc27 upstream.
+
+In the SET_GLOBAL ioctl, v3d_perfmon_find() bumps the reference count on
+the perfmon it returns, but v3d_perfmon_set_global_ioctl() and
+v3d_perfmon_delete() fail to release that reference on several paths:
+
+  1. v3d_perfmon_set_global_ioctl() leaks the reference on its error
+     paths.
+
+  2. CLEAR_GLOBAL leaks both the find reference and the reference
+     previously stashed in v3d->global_perfmon by the SET_GLOBAL ioctl
+     that configured it.
+
+  3. Destroying a perfmon that is the current global perfmon leaks the
+     reference stashed by the SET_GLOBAL ioctl.
+
+Release each of these references explicitly.
+
+Cc: stable@vger.kernel.org
+Fixes: c6eabbab359c ("drm/v3d: Add DRM_IOCTL_V3D_PERFMON_SET_GLOBAL")
+Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
+Link: https://patch.msgid.link/20260531-v3d-perfmon-lifetime-v2-1-60ed4485a203@igalia.com
+Signed-off-by: Maíra Canal <mcanal@igalia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/v3d/v3d_perfmon.c |   24 +++++++++++++++++++-----
+ 1 file changed, 19 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/v3d/v3d_perfmon.c
++++ b/drivers/gpu/drm/v3d/v3d_perfmon.c
+@@ -313,8 +313,11 @@ static int v3d_perfmon_idr_del(int id, v
+       if (perfmon == v3d->active_perfmon)
+               v3d_perfmon_stop(v3d, perfmon, false);
+-      /* If the global perfmon is being destroyed, set it to NULL */
+-      cmpxchg(&v3d->global_perfmon, perfmon, NULL);
++      /* If the global perfmon is being destroyed, clean it and release
++       * the reference stashed in v3d_perfmon_set_global_ioctl().
++       */
++      if (cmpxchg(&v3d->global_perfmon, perfmon, NULL) == perfmon)
++              v3d_perfmon_put(perfmon);
+       v3d_perfmon_put(perfmon);
+@@ -480,16 +483,27 @@ int v3d_perfmon_set_global_ioctl(struct
+       /* If the request is to clear the global performance monitor */
+       if (req->flags & DRM_V3D_PERFMON_CLEAR_GLOBAL) {
+-              if (!v3d->global_perfmon)
++              struct v3d_perfmon *old;
++
++              /* DRM_V3D_PERFMON_CLEAR_GLOBAL doesn't check if
++               * v3d->global_perfmon == perfmon. Therefore, there
++               * is no need to keep perfmon's reference.
++               */
++              v3d_perfmon_put(perfmon);
++
++              old = xchg(&v3d->global_perfmon, NULL);
++              if (!old)
+                       return -EINVAL;
+-              xchg(&v3d->global_perfmon, NULL);
++              v3d_perfmon_put(old);
+               return 0;
+       }
+-      if (cmpxchg(&v3d->global_perfmon, NULL, perfmon))
++      if (cmpxchg(&v3d->global_perfmon, NULL, perfmon)) {
++              v3d_perfmon_put(perfmon);
+               return -EBUSY;
++      }
+       return 0;
+ }
diff --git a/queue-7.0/drm-v3d-fix-vaddr-leak-when-indirect-csd-has-zeroed-workgroups.patch b/queue-7.0/drm-v3d-fix-vaddr-leak-when-indirect-csd-has-zeroed-workgroups.patch
new file mode 100644 (file)
index 0000000..9777f8c
--- /dev/null
@@ -0,0 +1,51 @@
+From ae7676952790f421c40918e2586a2c9f12a682b6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com>
+Date: Tue, 2 Jun 2026 14:50:14 -0300
+Subject: drm/v3d: Fix vaddr leak when indirect CSD has zeroed workgroups
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maíra Canal <mcanal@igalia.com>
+
+commit ae7676952790f421c40918e2586a2c9f12a682b6 upstream.
+
+v3d_rewrite_csd_job_wg_counts_from_indirect() maps both the indirect
+buffer and the workgroup buffer and is expected to release them before
+returning. When any of the workgroup counts read from the buffer is zero,
+the function bailed out early and skipped the cleanup, leaking the vaddr
+mappings of both BOs.
+
+Jump to the cleanup path instead of returning directly, so the mappings
+are always dropped.
+
+Cc: stable@vger.kernel.org
+Fixes: 18b8413b25b7 ("drm/v3d: Create a CPU job extension for a indirect CSD job")
+Suggested-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
+Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
+Link: https://patch.msgid.link/20260602-v3d-fix-indirect-csd-v4-1-654309e32bc0@igalia.com
+Signed-off-by: Maíra Canal <mcanal@igalia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/v3d/v3d_sched.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/v3d/v3d_sched.c
++++ b/drivers/gpu/drm/v3d/v3d_sched.c
+@@ -429,7 +429,7 @@ v3d_rewrite_csd_job_wg_counts_from_indir
+       wg_counts = (uint32_t *)(bo->vaddr + indirect_csd->offset);
+       if (wg_counts[0] == 0 || wg_counts[1] == 0 || wg_counts[2] == 0)
+-              return;
++              goto unmap_bo;
+       args->cfg[0] = wg_counts[0] << V3D_CSD_CFG012_WG_COUNT_SHIFT;
+       args->cfg[1] = wg_counts[1] << V3D_CSD_CFG012_WG_COUNT_SHIFT;
+@@ -454,6 +454,7 @@ v3d_rewrite_csd_job_wg_counts_from_indir
+               }
+       }
++unmap_bo:
+       v3d_put_bo_vaddr(indirect);
+       v3d_put_bo_vaddr(bo);
+ }
diff --git a/queue-7.0/drm-v3d-skip-csd-when-it-has-zeroed-workgroups.patch b/queue-7.0/drm-v3d-skip-csd-when-it-has-zeroed-workgroups.patch
new file mode 100644 (file)
index 0000000..7978d1c
--- /dev/null
@@ -0,0 +1,75 @@
+From 7f93fad5ea0affc9e1505dd0f7596c0fdb496213 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com>
+Date: Tue, 2 Jun 2026 14:50:15 -0300
+Subject: drm/v3d: Skip CSD when it has zeroed workgroups
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maíra Canal <mcanal@igalia.com>
+
+commit 7f93fad5ea0affc9e1505dd0f7596c0fdb496213 upstream.
+
+A compute shader dispatch encodes its workgroup counts in the CFG0..CFG2
+registers. Kicking off a dispatch with a zero count in any of the three
+dimensions is invalid. First, the hardware will process 0 as 65536,
+while the user-space driver exposes a maximum of 65535. Over that, a
+submission with a zeroed workgroup dimension should be a no-op.
+
+These zeroed counts can reach the dispatch path through an indirect CSD
+job, whose workgroup counts are only known once the indirect buffer is
+read and may legitimately be zero, but such scenario should only result in
+a no-op.
+
+Overwrite the indirect CSD job workgroup counts with the indirect BO
+ones, even if they are zeroed, and don't submit the job to the hardware
+when any of the workgroup counts is zero, so the job completes immediately
+instead of running the shader.
+
+Cc: stable@vger.kernel.org
+Fixes: d223f98f0209 ("drm/v3d: Add support for compute shader dispatch.")
+Suggested-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
+Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
+Link: https://patch.msgid.link/20260602-v3d-fix-indirect-csd-v4-2-654309e32bc0@igalia.com
+Signed-off-by: Maíra Canal <mcanal@igalia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/v3d/v3d_sched.c |   16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/v3d/v3d_sched.c
++++ b/drivers/gpu/drm/v3d/v3d_sched.c
+@@ -378,6 +378,16 @@ v3d_csd_job_run(struct drm_sched_job *sc
+               return NULL;
+       }
++      /* The HW interprets a workgroup size of 0 as 65536; however, the
++       * user-space driver exposes a maximum of 65535. Therefore, a 0 in
++       * any dimension means that we have no workgroups and the compute
++       * shader should not be dispatched.
++       */
++      if (!V3D_GET_FIELD(job->args.cfg[0], V3D_CSD_QUEUED_CFG0_NUM_WGS_X) ||
++          !V3D_GET_FIELD(job->args.cfg[1], V3D_CSD_QUEUED_CFG1_NUM_WGS_Y) ||
++          !V3D_GET_FIELD(job->args.cfg[2], V3D_CSD_QUEUED_CFG2_NUM_WGS_Z))
++              return NULL;
++
+       v3d->queue[V3D_CSD].active_job = &job->base;
+       v3d_invalidate_caches(v3d);
+@@ -428,13 +438,13 @@ v3d_rewrite_csd_job_wg_counts_from_indir
+       wg_counts = (uint32_t *)(bo->vaddr + indirect_csd->offset);
+-      if (wg_counts[0] == 0 || wg_counts[1] == 0 || wg_counts[2] == 0)
+-              goto unmap_bo;
+-
+       args->cfg[0] = wg_counts[0] << V3D_CSD_CFG012_WG_COUNT_SHIFT;
+       args->cfg[1] = wg_counts[1] << V3D_CSD_CFG012_WG_COUNT_SHIFT;
+       args->cfg[2] = wg_counts[2] << V3D_CSD_CFG012_WG_COUNT_SHIFT;
++      if (wg_counts[0] == 0 || wg_counts[1] == 0 || wg_counts[2] == 0)
++              goto unmap_bo;
++
+       num_batches = DIV_ROUND_UP(indirect_csd->wg_size, 16) *
+                     (wg_counts[0] * wg_counts[1] * wg_counts[2]);
diff --git a/queue-7.0/drm-v3d-wait-for-pending-l2t-flush-before-cleaning-caches.patch b/queue-7.0/drm-v3d-wait-for-pending-l2t-flush-before-cleaning-caches.patch
new file mode 100644 (file)
index 0000000..3e42d07
--- /dev/null
@@ -0,0 +1,51 @@
+From abf888b03a9805a3bc37948a0df443553b1c0910 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com>
+Date: Sat, 30 May 2026 15:37:42 -0300
+Subject: drm/v3d: Wait for pending L2T flush before cleaning caches
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maíra Canal <mcanal@igalia.com>
+
+commit abf888b03a9805a3bc37948a0df443553b1c0910 upstream.
+
+v3d_clean_caches() starts the cache-clean sequence by writing
+V3D_L2TCACTL_TMUWCF to V3D_CTL_L2TCACTL and then polling for that bit to
+clear. It does not, however, check for an L2T flush (L2TFLS) that may
+still be in flight from a previous operation.
+
+On pre-V3D 7.1 hardware, kicking off the TMU write-combiner flush while an
+L2T flush is still pending can clobber bits in L2TCACTL and cause cache
+inconsistencies.
+
+Poll for L2TFLS to clear before writing L2TCACTL on V3D < 7.1, ensuring
+any pending flush has completed before a new clean is issued.
+
+Cc: stable@vger.kernel.org
+Fixes: d223f98f0209 ("drm/v3d: Add support for compute shader dispatch.")
+Link: https://patch.msgid.link/20260530-v3d-fix-rpi4-freezes-v1-1-c2c8307da6ce@igalia.com
+Signed-off-by: Maíra Canal <mcanal@igalia.com>
+Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/v3d/v3d_gem.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/gpu/drm/v3d/v3d_gem.c
++++ b/drivers/gpu/drm/v3d/v3d_gem.c
+@@ -213,6 +213,14 @@ v3d_clean_caches(struct v3d_dev *v3d)
+       trace_v3d_cache_clean_begin(dev);
++      /* GFXH-1897: Ensure pending flushes complete before writing L2TCACTL */
++      if (v3d->ver < V3D_GEN_71) {
++              if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) &
++                             V3D_L2TCACTL_L2TFLS), 100)) {
++                      drm_err(dev, "Timeout waiting for L2T clean\n");
++              }
++      }
++
+       V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, V3D_L2TCACTL_TMUWCF);
+       if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) &
+                      V3D_L2TCACTL_TMUWCF), 100)) {
diff --git a/queue-7.0/drm-xe-clear-pending_disable-before-signaling-suspend-fence.patch b/queue-7.0/drm-xe-clear-pending_disable-before-signaling-suspend-fence.patch
new file mode 100644 (file)
index 0000000..a55fcac
--- /dev/null
@@ -0,0 +1,46 @@
+From 54f2a0442a30fe7a0f6bc8345e81f8b2db8effbd Mon Sep 17 00:00:00 2001
+From: Tangudu Tilak Tirumalesh <tilak.tirumalesh.tangudu@intel.com>
+Date: Wed, 3 Jun 2026 12:22:16 +0530
+Subject: drm/xe: Clear pending_disable before signaling suspend fence
+
+From: Tangudu Tilak Tirumalesh <tilak.tirumalesh.tangudu@intel.com>
+
+commit 54f2a0442a30fe7a0f6bc8345e81f8b2db8effbd upstream.
+
+In the schedule-disable done path for suspend, we
+signal the suspend fence before clearing pending_disable.
+
+That wakeup can let suspend_wait complete and resume be queued
+immediately. The resume path may then reach enable_scheduling()
+while pending_disable is still set and hit the
+!exec_queue_pending_disable(q) assertion.
+
+Fix this by clearing pending_disable before signaling
+the suspend fence, so any resumed transition observes a
+consistent state.
+
+Fixes: 87651f31ae4e ("drm/xe/guc_submit: fix race around suspend_pending")
+Cc: stable@vger.kernel.org # v7.0+
+Signed-off-by: Tangudu Tilak Tirumalesh <tilak.tirumalesh.tangudu@intel.com>
+Reviewed-by: Thomas Hellstrom <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Link: https://patch.msgid.link/20260603065217.3131066-3-tilak.tirumalesh.tangudu@intel.com
+(cherry picked from commit 4b1ae138b0e103d753773956a84eebc2edbf62c4)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/xe/xe_guc_submit.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/xe/xe_guc_submit.c
++++ b/drivers/gpu/drm/xe/xe_guc_submit.c
+@@ -2760,8 +2760,8 @@ static void handle_sched_done(struct xe_
+               xe_gt_assert(guc_to_gt(guc), exec_queue_pending_disable(q));
+               if (q->guc->suspend_pending) {
+-                      suspend_fence_signal(q);
+                       clear_exec_queue_pending_disable(q);
++                      suspend_fence_signal(q);
+               } else {
+                       if (exec_queue_banned(q)) {
+                               smp_wmb();
diff --git a/queue-7.0/drm-xe-display-fix-oops-in-suspend-shutdown-without-display.patch b/queue-7.0/drm-xe-display-fix-oops-in-suspend-shutdown-without-display.patch
new file mode 100644 (file)
index 0000000..0026656
--- /dev/null
@@ -0,0 +1,80 @@
+From 68938cc08e23a94fd881e845837ff918de005ce7 Mon Sep 17 00:00:00 2001
+From: Jani Nikula <jani.nikula@intel.com>
+Date: Fri, 15 May 2026 19:09:20 +0300
+Subject: drm/xe/display: fix oops in suspend/shutdown without display
+
+From: Jani Nikula <jani.nikula@intel.com>
+
+commit 68938cc08e23a94fd881e845837ff918de005ce7 upstream.
+
+The xe driver keeps track of whether to probe display, and whether
+display hardware is there, using xe->info.probe_display. It gets set to
+false if there's no display after intel_display_device_probe(). However,
+the display may also be disabled via fuses, detected at a later time in
+intel_display_device_info_runtime_init().
+
+In this case, the xe driver does for_each_intel_crtc() on uninitialized
+mode config in xe_display_flush_cleanup_work(), leading to a NULL
+pointer dereference, and generally calls display code with display info
+cleared.
+
+Check for intel_display_device_present() after
+intel_display_device_info_runtime_init(), and reset
+xe->info.probe_display as necessary. Also do unset_display_features()
+for completeness, although display runtime init has already done
+that. This will need to be unified across all cases later.
+
+Move intel_display_device_info_runtime_init() call slightly earlier,
+similar to i915, to avoid a bunch of unnecessary setup for no display
+cases.
+
+Note #1: The xe driver has no business doing low level display plumbing
+like for_each_intel_crtc() to begin with. It all needs to happen in
+display code.
+
+Note #2: The actual bug is present already in commit 44e694958b95
+("drm/xe/display: Implement display support"), but the oops was likely
+introduced later at commit ddf6492e0e50 ("drm/xe/display: Make display
+suspend/resume work on discrete").
+
+Fixes: 44e694958b95 ("drm/xe/display: Implement display support")
+Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/7904
+Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/6150
+Cc: stable@vger.kernel.org # v6.8+
+Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
+Link: https://patch.msgid.link/20260515160920.1082842-1-jani.nikula@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+(cherry picked from commit 7c3eb9f47533220888a67266448185fd0775d4da)
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/xe/display/xe_display.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/xe/display/xe_display.c
++++ b/drivers/gpu/drm/xe/display/xe_display.c
+@@ -119,6 +119,15 @@ int xe_display_init_early(struct xe_devi
+       intel_display_driver_early_probe(display);
++      intel_display_device_info_runtime_init(display);
++
++      /* Display may have been disabled at runtime init */
++      if (!intel_display_device_present(display)) {
++              xe->info.probe_display = false;
++              unset_display_features(xe);
++              return 0;
++      }
++
+       /* Early display init.. */
+       intel_opregion_setup(display);
+@@ -132,8 +141,6 @@ int xe_display_init_early(struct xe_devi
+       intel_bw_init_hw(display);
+-      intel_display_device_info_runtime_init(display);
+-
+       err = intel_display_driver_probe_noirq(display);
+       if (err)
+               goto err_opregion;
diff --git a/queue-7.0/drm-xe-multi_queue-skip-submit-when-primary-queue-is-suspended.patch b/queue-7.0/drm-xe-multi_queue-skip-submit-when-primary-queue-is-suspended.patch
new file mode 100644 (file)
index 0000000..8d6b44e
--- /dev/null
@@ -0,0 +1,44 @@
+From ec4cbdd163f9bb2a2bd44eb93ecf4a2fa0e912a9 Mon Sep 17 00:00:00 2001
+From: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
+Date: Wed, 3 Jun 2026 16:39:47 -0700
+Subject: drm/xe/multi_queue: skip submit when primary queue is suspended
+
+From: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
+
+commit ec4cbdd163f9bb2a2bd44eb93ecf4a2fa0e912a9 upstream.
+
+Return early in submit path when the multi-queue primary exec
+queue is suspended to avoid submitting while suspended.
+
+v2: Remove idle_skip_suspend fix as that feature is being
+reverted here https://patchwork.freedesktop.org/series/167262/
+
+Fixes: bc5775c59258 ("drm/xe/multi_queue: Add GuC interface for multi queue support")
+Cc: stable@vger.kernel.org # v7.0+
+Assisted-by: GitHub-Copilot:claude-sonnet-4.6
+Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
+Link: https://patch.msgid.link/20260603233946.863663-2-niranjana.vishwanathapura@intel.com
+(cherry picked from commit b7fb55cc3364ca128cfff9d50649ffd4327cd01e)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/xe/xe_guc_submit.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/xe/xe_guc_submit.c
++++ b/drivers/gpu/drm/xe/xe_guc_submit.c
+@@ -1104,9 +1104,12 @@ static void submit_exec_queue(struct xe_
+       /*
+        * All queues in a multi-queue group will use the primary queue
+-       * of the group to interface with GuC.
++       * of the group to interface with GuC. If primay is suspended,
++       * just return. Jobs will get scheduled once primary is resumed.
+        */
+       q = xe_exec_queue_multi_queue_primary(q);
++      if (exec_queue_suspended(q))
++              return;
+       if (!exec_queue_enabled(q) && !exec_queue_suspended(q)) {
+               action[len++] = XE_GUC_ACTION_SCHED_CONTEXT_MODE_SET;
index 29d3827388d145de4ce8d7506df451dbb6e7111c..b25cbca7e98176ede343e56686fcab3ce35e5774 100644 (file)
@@ -332,3 +332,27 @@ slimbus-qcom-ngd-ctrl-balance-pm_runtime-enablement-for-ngd.patch
 slimbus-qcom-ngd-ctrl-avoid-abba-on-tx_lock-ctrl-lock.patch
 drm-gem-try-to-fix-change_handle-ioctl-attempt-4.patch
 drm-i915-fix-color-blob-reference-handling-in-intel_plane_state.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-xe-display-fix-oops-in-suspend-shutdown-without-display.patch
+drm-xe-multi_queue-skip-submit-when-primary-queue-is-suspended.patch
+drm-xe-clear-pending_disable-before-signaling-suspend-fence.patch
+drm-v3d-wait-for-pending-l2t-flush-before-cleaning-caches.patch
+drm-v3d-fix-global-performance-monitor-reference-counting.patch
+drm-v3d-fix-vaddr-leak-when-indirect-csd-has-zeroed-workgroups.patch
+drm-v3d-skip-csd-when-it-has-zeroed-workgroups.patch
+drm-amdgpu-fix-waiting-for-all-submissions-for-userptrs.patch
+drm-amdgpu-restart-the-cs-if-some-parts-of-the-vm-are-still-invalidated.patch
+drm-amdgpu-set-noretry-1-as-default-for-gfx-10.1.x-navi10-12-14.patch
+drm-amdgpu-fix-incorrect-vram-gart-mappings-on-non-4k-page-size-systems.patch
+drm-amd-pm-apply-smu-13.0.10-workaround-during-mp1-unload.patch
+drm-amd-pm-fix-smu13-power-limit-default-cap-calculation.patch
+drm-amd-pm-mark-metrics.energy_accumulator-is-invalid-for-smu-14.0.2.patch
+drm-amd-pm-smu_v14_0_0-use-softmin-for-gfxclk-in-set_soft_freq_limited_range.patch
+drm-amd-display-bound-vbios-record-chain-walk-loops.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-add-missing-csc-entries-for-bt.2020-for-dce-ips.patch
+drm-amd-display-fix-null-deref-and-buffer-over-read-in-sdp-debugfs.patch
+drm-amd-display-fix-out-of-bounds-read-in-dp_get_eq_aux_rd_interval.patch
+drm-amd-display-use-krealloc_array-in-dal_vector_reserve.patch