From 94e25cb6ab7f4f025bcdcd8ea79fda30f12843a4 Mon Sep 17 00:00:00 2001 From: Priya Hosur Date: Thu, 27 Aug 2026 15:02:46 +0530 Subject: [PATCH 01/20] drm/amdkfd: Add TLB flush after MES queue eviction/suspension MES (Micro Engine Scheduler) does not perform heavy-weight TLB invalidation after unmapping queues, unlike HWS which does this automatically. This causes a race condition where in-flight DMA descriptors can access memory that has been unmapped, leading to page faults and GPU queue hangs during SVM page migration. The issue manifests as KFDSVMRangeTest.MultiThreadMigrationTest failures on gfx1151 (Strix Point) with XNACK mode 1 enabled - the GPU compute queue hangs with packets submitted but never consumed. Add kfd_flush_tlb() calls after MES queue removal in two locations: - evict_process_queues_cpsch(): after all queues removed during eviction - suspend_queues(): after debug/criu queue suspension (with mem_fence barrier) This ensures all in-flight memory accesses from unmapped queues are flushed before memory is freed or migrated. Signed-off-by: Priya Hosur Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher (cherry picked from commit f5c4f88e0f9c45a8fb9dfac0c1df726c95e41b77) Cc: stable@vger.kernel.org --- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 4bc947c3bd0d..9811e4e10291 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -1455,6 +1455,14 @@ static int evict_process_queues_cpsch(struct device_queue_manager *dqm, dqm_evict_mqd_bo(dqm, q); } + /* + * Heavy-weight TLB flush after MES removes queues to ensure + * in-flight memory accesses complete before memory is freed/migrated. + * HWS does this automatically, MES does not. + */ + if (dqm->dev->kfd->shared_resources.enable_mes) + kfd_flush_tlb(pdd); + if (!dqm->dev->kfd->shared_resources.enable_mes) { pdd->last_evict_timestamp = get_jiffies_64(); retval = execute_queues_cpsch(dqm, @@ -3746,8 +3754,11 @@ int suspend_queues(struct kfd_process *p, if (!per_device_suspended) { dqm_unlock(dqm); mutex_unlock(&p->event_mutex); - if (total_suspended) + if (total_suspended) { amdgpu_amdkfd_debug_mem_fence(dqm->dev->adev); + /* Heavy-weight TLB flush after MES suspends queues */ + kfd_flush_tlb(pdd); + } continue; } From bd1f08246b8a2564d8ac61df715b6bcd5f994729 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 26 Aug 2026 13:51:02 -0500 Subject: [PATCH 02/20] drm/amdgpu: restrict BAR0 fallback read to SR-IOV VFs only The BAR0 fallback read path was introduced as a workaround for SR-IOV VFs where the VRAM aperture is not available during early init. Restrict this workaround to only SR-IOV VFs where it's needed. Reported-by: gloveless@jqluv.com Fixes: cba4928cdffa ("drm/amdgpu: reduce early full GPU access during SR-IOV init") Acked-by: Alex Deucher Link: https://patch.msgid.link/20260826185102.2269511-1-mario.limonciello@amd.com Signed-off-by: Mario Limonciello Signed-off-by: Alex Deucher (cherry picked from commit d8a0affd207c813bd063fa2c27786f449eaf92b8) --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 44bed0ba64a3..104d1d2cbad9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -771,6 +771,9 @@ static int amdgpu_device_read_fb_via_bar0(struct amdgpu_device *adev, if (!buf || !size) return -EINVAL; + if (!amdgpu_sriov_vf(adev)) + return -EINVAL; + flags = pci_resource_flags(adev->pdev, 0); if ((flags & IORESOURCE_UNSET) || !(flags & IORESOURCE_MEM)) return -EINVAL; From 7346a046c6a9b9f30cb1f7d301449300a9174c71 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 20 Aug 2026 09:02:01 -0400 Subject: [PATCH 03/20] drm/amdgpu/gfx8: only apply compute quantums to KCQs Don't apply to KIQ. Seems to cause problems on KIQ on some ARM platforms. Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/5658 Fixes: 91cf34bc5a55 ("drm/amdgpu/gfx8: align mqd settings with KFD") Reviewed-by: Jesse Zhang Reviewed-by: Kent Russell Signed-off-by: Alex Deucher (cherry picked from commit 6aae7bab029cdccae9a7157facfe36bfc35fc940) Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 6cf427995078..7f91186ef1d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -4546,9 +4546,11 @@ static int gfx_v8_0_mqd_init(struct amdgpu_ring *ring) /* set static priority for a queue/ring */ gfx_v8_0_mqd_set_priority(ring, mqd); tmp = RREG32(mmCP_HQD_QUANTUM); - tmp = REG_SET_FIELD(tmp, CP_HQD_QUANTUM, QUANTUM_EN, 1); - tmp = REG_SET_FIELD(tmp, CP_HQD_QUANTUM, QUANTUM_SCALE, 1); - tmp = REG_SET_FIELD(tmp, CP_HQD_QUANTUM, QUANTUM_DURATION, 10); + if (ring != &adev->gfx.kiq[0].ring) { + tmp = REG_SET_FIELD(tmp, CP_HQD_QUANTUM, QUANTUM_EN, 1); + tmp = REG_SET_FIELD(tmp, CP_HQD_QUANTUM, QUANTUM_SCALE, 1); + tmp = REG_SET_FIELD(tmp, CP_HQD_QUANTUM, QUANTUM_DURATION, 10); + } mqd->cp_hqd_quantum = tmp; /* map_queues packet doesn't need activate the queue, From b428f83c7c2542837c15231c519583cc26b60156 Mon Sep 17 00:00:00 2001 From: Amber Lin Date: Thu, 27 Aug 2026 15:02:53 -0400 Subject: [PATCH 04/20] drm/amdgpu: Update queue reset support version Update queue reset required MES version for MES 12.1 to 0x7b since we change the implementation from detect-and-reset method to per-queue-reset method. Signed-off-by: Amber Lin Reviewed-by: Michael Chen Signed-off-by: Alex Deucher (cherry picked from commit 2160a5cbf0b7917adce4b55421306b614b4a2c8f) --- drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c index b96f94e5169f..1a86a47406b1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c @@ -879,7 +879,7 @@ bool amdgpu_mes_queue_reset_by_mes_supported(struct amdgpu_device *adev) return (ip_maj == 11 && mes_sched >= 0x8c) || ((ip_maj == 12 && ip_min == 0) && mes_sched >= 0x8d) || - ((ip_maj == 12 && ip_min == 1) && mes_sched >= 0x73); + ((ip_maj == 12 && ip_min == 1) && mes_sched >= 0x7b); } /* Fix me -- node_id is used to identify the correct MES instances in the future */ From d6e16df7df4d2c39e2b04b355d0434fb90e2d62c Mon Sep 17 00:00:00 2001 From: Sunil Khatri Date: Thu, 27 Aug 2026 20:33:35 +0530 Subject: [PATCH 05/20] drm/amdgpu: use AMDGPU_GPU_PAGE_SHIFT instead of PAGE_SHIFT For different address types the variable PAGE_SHIFT might not work well and it's better to use the GPU specific one Signed-off-by: Sunil Khatri Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher (cherry picked from commit 3494b77d10375e0f9ab784e9b20763339844b55b) Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index aedf72c2333e..28f29f2d7c14 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -2090,7 +2090,7 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev, after->start = eaddr + 1; after->last = tmp->last; after->offset = tmp->offset; - after->offset += (after->start - tmp->start) << PAGE_SHIFT; + after->offset += (after->start - tmp->start) << AMDGPU_GPU_PAGE_SHIFT; after->flags = tmp->flags; after->bo_va = tmp->bo_va; list_add(&after->list, &tmp->bo_va->invalids); From 90ce19bd11b2864e26e4b43e7acbffabf037b69b Mon Sep 17 00:00:00 2001 From: Sunil Khatri Date: Thu, 27 Aug 2026 21:00:22 +0530 Subject: [PATCH 06/20] drm/amdgpu: fix Idle BOs list in VM debugfs status info amdgpu_debugfs_vm_bo_status_info() prints the "Idle BOs" section by iterating lists->needs_update, the same list already printed just above under "Moved BOs". struct amdgpu_vm_bo_status has a dedicated idle list, populated whenever a BO's state machine settles, but it was never read here, so genuinely idle BOs never show up in the debugfs output and the "Idle BOs" section duplicates "Moved BOs" instead. Iterate lists->idle for the "Idle BOs" section. Fixes: 4cdbba5a16aa ("drm/amdgpu: restructure VM state machine v4") Signed-off-by: Sunil Khatri Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher (cherry picked from commit 451bfc778a8c364841837def00ba15936f72762b) Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 28f29f2d7c14..bb04101b0fb5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -3122,7 +3122,7 @@ static void amdgpu_debugfs_vm_bo_status_info(struct seq_file *m, id = 0; seq_puts(m, "\tIdle BOs:\n"); - list_for_each_entry(base, &lists->needs_update, vm_status) { + list_for_each_entry(base, &lists->idle, vm_status) { if (!base->bo) continue; From ef0e9d12727d0fec762eea5053ff02ba555b8895 Mon Sep 17 00:00:00 2001 From: Ivan Lipski Date: Wed, 12 Aug 2026 23:15:18 -0400 Subject: [PATCH 07/20] drm/amd/display: Fix DCN5/6 DML2 compilation warnings [WHY] A kernel compilation warning was reported caused by upstream of DCN5/6. [HOW] Using plain integer as NULL pointer. Assign NULL to the VActiveLatencyHidingMargin/VActiveLatencyHidingUs pointer members in dml2_core_dcn5_funcs_mode_programming.c, and pass NULL for the pointer arguments to calculate_first_second_splitting() in dml2_pmo_dcn6_stage_optimizers.c. Fixes: 7f7d7ea1fa51 ("drm/amd/display: Add new sources for DCN6") Reviewed-by: Dillon Varone Signed-off-by: Ivan Lipski Signed-off-by: Alex Hung Tested-by: Dan Wheeler Signed-off-by: Alex Deucher (cherry picked from commit d96880560e9f35ba7f8de1b3f90032c8c3eaea88) --- .../src/dml2_core/dml2_core_dcn5_funcs_mode_programming.c | 4 ++-- .../dml21/src/dml2_pmo/dml2_pmo_dcn6_stage_optimizers.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_programming.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_programming.c index 8497eaea012e..297e21e7c68d 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_programming.c +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_programming.c @@ -1128,8 +1128,8 @@ static bool dcn5_mode_programming(struct dml2_core_calcs_mode_programming_ex *in CalculateWatermarks_params->USRRetrainingSupport = &mode_lib->mp.USRRetrainingSupport; CalculateWatermarks_params->temp_read_or_ppt_support = mode_lib->mp.temp_read_or_ppt_support; CalculateWatermarks_params->global_temp_read_or_ppt_supported = &mode_lib->mp.global_temp_read_or_ppt_supported; - CalculateWatermarks_params->VActiveLatencyHidingMargin = 0; - CalculateWatermarks_params->VActiveLatencyHidingUs = 0; + CalculateWatermarks_params->VActiveLatencyHidingMargin = NULL; + CalculateWatermarks_params->VActiveLatencyHidingUs = NULL; dcn5_calculate_watermarks_and_dram_speed_change_support(&mode_lib->scratch, CalculateWatermarks_params); diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn6_stage_optimizers.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn6_stage_optimizers.c index 0b884a8661c8..6d6611a6b5a6 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn6_stage_optimizers.c +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn6_stage_optimizers.c @@ -1414,7 +1414,7 @@ static bool find_shift_for_valid_cache_id_assignment(const int *mcache_boundarie success = true; for (pipe_index = 0; pipe_index < pipe_count; pipe_index++) { if (!calculate_first_second_splitting(mcache_boundaries, num_boundaries, *shift, - pipe_vp_startx[pipe_index], pipe_vp_endx[pipe_index], 0, 0)) { + pipe_vp_startx[pipe_index], pipe_vp_endx[pipe_index], NULL, NULL)) { success = false; break; } From 9ce3169430f1db035d491481086e2fae2552569c Mon Sep 17 00:00:00 2001 From: Roman Li Date: Fri, 14 Aug 2026 18:03:17 -0400 Subject: [PATCH 08/20] drm/amd/display: Set gpuvm min page size to 4K on dcn35/36 [WHY] Splash screen corruption on some 8K monitors. [HOW] Set GPUVM min page size to 4K for DCN35/36 to use the correct DML2 calculations, avoiding the corruption path observed during splash. Fixes: 115009d11ccf ("drm/amd/display: Add DCN35 DML2 support") Cc: Mario Limonciello Cc: Alex Deucher Reviewed-by: Alex Hung Signed-off-by: Roman Li Signed-off-by: Alex Hung Tested-by: Dan Wheeler Signed-off-by: Alex Deucher (cherry picked from commit 2cbfb03dead5088a7bdfe2ce392a5caa3d1b3719) Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/dc/dml2_0/dml2_translation_helper.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_translation_helper.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_translation_helper.c index 166f10b8862f..c82886323a51 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_translation_helper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_translation_helper.c @@ -301,6 +301,7 @@ void dml2_init_socbb_params(struct dml2_context *dml2, const struct dc *in_dc, s out->smn_latency_us = 2; out->dispclk_dppclk_vco_speed_mhz = 3600; out->pct_ideal_dram_bw_after_urgent_pixel_only = 65.0; + out->gpuvm_min_page_size_kbytes = 4; break; From 93a77d353cb26772ae2fba50ae7321ae996b7f00 Mon Sep 17 00:00:00 2001 From: Austin Zheng Date: Wed, 19 Aug 2026 09:33:57 -0400 Subject: [PATCH 09/20] drm/amd/display: Remove const Qualifier From Non-Pointer Fields [WHY/HOW] Integer values for dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params should not have the const qualifier. This prevents using different values of the inputs when the function is called again. Reviewed-by: Dillon Varone Signed-off-by: Austin Zheng Signed-off-by: Alex Hung Tested-by: Dan Wheeler Signed-off-by: Alex Deucher (cherry picked from commit 342280aae4f33816e8d07c15cb538a3b375a7f8f) Cc: stable@vger.kernel.org --- .../dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h index 8a371bd1a7a5..28f4a53d0617 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h @@ -1819,8 +1819,8 @@ struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_param bool UnboundedRequestEnabled; unsigned int CompressedBufferSizeInkByte; bool max_outstanding_when_urgent_expected; - const unsigned int max_outstanding_requests; - const unsigned int max_request_size_bytes; + unsigned int max_outstanding_requests; + unsigned int max_request_size_bytes; const unsigned int *meta_row_height_l; const unsigned int *meta_row_height_c; const enum dml2_pstate_method *uclk_pstate_switch_modes; From 5a67d2e055897a36acb4e48082986fb4a4eebdd3 Mon Sep 17 00:00:00 2001 From: Roman Li Date: Fri, 21 Aug 2026 12:19:10 -0400 Subject: [PATCH 10/20] drm/amd/display: Fix backlight control for luminance-capable OLED [WHY] For some eDP panels VESA aux backlight control is necessary, otherwise they stay black. [HOW] When AUX backlight control is used, select BACKLIGHT_CONTROL_VESA_AUX for panels that advertise panel_luminance_control. Reviewed-by: Hansen Dsouza Signed-off-by: Roman Li Signed-off-by: Alex Hung Tested-by: Dan Wheeler Signed-off-by: Alex Deucher (cherry picked from commit 42f698bd061d76d5f4c84a195e465cfbeec775e4) --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c index e61bbc310f33..b9e90ea449ca 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c @@ -534,8 +534,12 @@ void amdgpu_dm_update_connector_ext_caps(struct amdgpu_dm_connector *aconnector) else if (!IS_ERR_OR_NULL(panel_backlight_quirk) && panel_backlight_quirk->force_pwm) caps->aux_support = false; - if (caps->aux_support) - aconnector->dc_link->backlight_control_type = BACKLIGHT_CONTROL_AMD_AUX; + if (caps->aux_support) { + if (aconnector->dc_link->dpcd_caps.panel_luminance_control) + aconnector->dc_link->backlight_control_type = BACKLIGHT_CONTROL_VESA_AUX; + else + aconnector->dc_link->backlight_control_type = BACKLIGHT_CONTROL_AMD_AUX; + } luminance_range = &conn_base->display_info.luminance_range; From 4278d65a41a2f6530437738f158f69e379bddb1c Mon Sep 17 00:00:00 2001 From: Melissa Wen Date: Thu, 20 Aug 2026 11:26:37 +0200 Subject: [PATCH 11/20] drm/amd/display: use halving distribution for all encode-to-linear curves In encode-to-linear conversions, LUT entries should be uniformly distributed across the input range: non-linear encodings are already approximately perceptually uniform, so every input code carries the same weight. A fixed count per region does the opposite, concentrating entries on the darker values and leaving few for the bright end, whereas halving distribution spaces all 256 entries uniformly. This holds for any encoded input, so remove the PQ/sRGB condition from commit "drm/amd/display: use halving distribution for PQ/sRGB linearizing LUT" and apply halving to all encode-to-linear operations (pre-defined TF or user LUTs). It fixes the following IGT kms_colorop subtests: - plane-XR30-XR30-srgb_inv_eotf_lut-srgb_eotf_lut - plane-XR30-XR30-gamma_2_2-gamma_2_2_inv-gamma_2_2 Fixes: a71d2b051f33 ("drm/amd/display: use halving distribution for PQ/sRGB linearizing LUT") Reviewed-by: Alex Hung Reviewed-by: Harry Wentland Signed-off-by: Melissa Wen Signed-off-by: Alex Deucher (cherry picked from commit 6df7c9c307e72e7f13829e94edc89134f0764775) --- .../amd/display/dc/dcn30/dcn30_cm_common.c | 34 ++++++------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c index 66fe7f313ea3..62ca235cd649 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c @@ -320,6 +320,8 @@ static struct fixed31_32 interp_tf_pts(const struct fixed31_32 *output_tf_channe return value; } +#define NUM_DEGAMMA_REGIONS 9 + bool cm3_helper_translate_curve_to_degamma_hw_format( const struct dc_transfer_func *output_tf, struct pwl_params *lut_params) @@ -343,31 +345,15 @@ bool cm3_helper_translate_curve_to_degamma_hw_format( memset(lut_params, 0, sizeof(struct pwl_params)); memset(seg_distr, 0, sizeof(seg_distr)); - if (output_tf->tf == TRANSFER_FUNCTION_PQ || - output_tf->tf == TRANSFER_FUNCTION_SRGB) { - /* 9 segments - * segments are from 2^-9 to 0 - */ - const uint8_t SEG_COUNT = 9; - seg_distr[0] = 0; // Since we only have one point in darkest region - for (k = 1; k < SEG_COUNT; k++) - seg_distr[k] = k - 1; // 2^(k-1) points per region; halves as k decreases + /* 9 segments + * segments are from 2^-9 to 2^0 + */ + seg_distr[0] = 0; // Since we only have one point in darkest region + for (k = 1; k < NUM_DEGAMMA_REGIONS; k++) + seg_distr[k] = k - 1; // 2^(k-1) points per region; halves as k decreases - region_start = -SEG_COUNT; - region_end = 0; - } else { - /* 12 segments - * segments are from 2^-12 to 2^0 - * There are less than 256 points, for optimization - */ - const uint8_t SEG_COUNT = 12; - - for (i = 0; i < SEG_COUNT; i++) - seg_distr[i] = 4; - - region_start = -SEG_COUNT; - region_end = 0; - } + region_start = -NUM_DEGAMMA_REGIONS; + region_end = 0; for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++) seg_distr[i] = -1; From f63de9054da858d57054474c32464106f8375e0d Mon Sep 17 00:00:00 2001 From: Hari Mishal Date: Sat, 22 Aug 2026 16:57:51 +0200 Subject: [PATCH 12/20] drm/amd/display: fix division by zero in get_estimated_bw() get_estimated_bw() divides by link->dpia_bw_alloc_config.bw_granularity, which is zeroed by reset_bw_alloc_struct() and only populated once DP_TUNNELING_BW_ALLOC_CAP_CHANGED has been handled. link_dp_dpia_handle_bw_alloc_status(), the DPCD interrupt handler, calls get_estimated_bw() whenever DP_TUNNELING_ESTIMATED_BW_CHANGED is set, independently of whether DP_TUNNELING_BW_ALLOC_CAP_CHANGED has ever fired for that link. A connected USB4/DPIA tunneling device that reports an estimated-bandwidth change before ever reporting a capability change drives a division by zero in this IRQ path. link_dpia_send_bw_alloc_request() already guards the same bw_granularity division; add the identical guard here rather than introducing a new pattern. Fixes: 8e5cfe547bf3 ("drm/amd/display: upstream link_dp_dpia_bw.c") Reviewed-by: Alex Hung Assisted-by: gkh_clanker_t1000 Signed-off-by: Hari Mishal Signed-off-by: Alex Deucher (cherry picked from commit f2a961457c33dc34223aad5c9e8971de34a4eed3) Cc: stable@vger.kernel.org --- .../gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c index dd854d992692..f43fc4b78a8d 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c @@ -103,6 +103,11 @@ static int get_estimated_bw(struct dc_link *link) { uint8_t bw_estimated_bw = 0; + if (link->dpia_bw_alloc_config.bw_granularity == 0) { + DC_LOG_ERROR("%s: BW granularity is zero!\n", __func__); + return 0; + } + core_link_read_dpcd( link, ESTIMATED_BW, From 012a026bae0212952b423a842b7e2c0bf21f8e7a Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 31 Aug 2026 08:00:51 -0500 Subject: [PATCH 13/20] drm/amdkfd: fix scope of mqd_mgr dereference in pqm_debugfs_mqds Reading /sys/kernel/debug/kfd/mqds while a process holds an active KFD queue triggers a NULL pointer dereference because the for loop that calls mqd_mgr->debugfs_show_mqd() is incorrectly placed outside the if (pqn->q) block that initializes mqd_mgr. The queue list can contain entries where pqn->q is NULL (kernel queues where only pqn->kq is valid). In the original code: if (pqn->q) { ... mqd_mgr = q->device->dqm->mqd_mgrs[mqd_type]; size = mqd_mgr->mqd_stride(...); } for (xcc = 0; xcc < num_xccs; xcc++) { // WRONG: outside if block mqd = q->mqd + size * xcc; r = mqd_mgr->debugfs_show_mqd(m, mqd); } When iterating over a queue node where pqn->q is NULL: 1. The if (pqn->q) block is skipped 2. mqd_mgr remains uninitialized (NULL from declaration) 3. The for loop executes anyway 4. mqd_mgr->debugfs_show_mqd(m, mqd) dereferences NULL The crash manifests as: BUG: kernel NULL pointer dereference, address: 0000000000000000 #PF: supervisor instruction fetch in kernel mode RIP: 0010:0x0 Call Trace: pqm_debugfs_mqds+0x10c/0x1d0 [amdgpu] kfd_debugfs_mqds_by_process+0x9b/0x110 [amdgpu] seq_read_iter+0x132/0x4b0 ... Fix by moving the for loop inside the if (pqn->q) block, so mqd_mgr and related variables are only used when properly initialized. Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/5689 Reviewed-by: Alex Deucher Link: https://patch.msgid.link/20260831130051.2031435-1-mario.limonciello@amd.com Signed-off-by: Mario Limonciello Signed-off-by: Alex Deucher (cherry picked from commit 8bfe29d5c798940f797aa24135d2734c3ffce9de) Cc: stable@vger.kernel.org --- .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index ef1d1cb46152..4fe40e9fcfc8 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -1169,13 +1169,13 @@ int pqm_debugfs_mqds(struct seq_file *m, void *data) mqd_mgr = q->device->dqm->mqd_mgrs[mqd_type]; size = mqd_mgr->mqd_stride(mqd_mgr, &q->properties); - } - for (xcc = 0; xcc < num_xccs; xcc++) { - mqd = q->mqd + size * xcc; - r = mqd_mgr->debugfs_show_mqd(m, mqd); - if (r != 0) - break; + for (xcc = 0; xcc < num_xccs; xcc++) { + mqd = q->mqd + size * xcc; + r = mqd_mgr->debugfs_show_mqd(m, mqd); + if (r != 0) + break; + } } } From 3b5c4f4a479d0e58a7500cbd2b09d62f719f48b8 Mon Sep 17 00:00:00 2001 From: Sunil Khatri Date: Mon, 31 Aug 2026 21:01:39 +0530 Subject: [PATCH 14/20] drm/amdgpu: fix byte/dword unit mismatch in coredump IB dump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In amdgpu_devcoredump_print_ibs(), the NO_CPU_ACCESS VRAM path passed cursor.start/4 and cursor.size/4 to amdgpu_device_mm_access(), but that function's pos/size parameters are byte offsets/lengths (confirmed by amdgpu_ttm_vram_mm_access() and leading to wrong size calculation. Similarly with that change the off index needs to be calculated based on dword since that is a u32 type. Fixes: 7b15fc2d1f1a ("drm/amdgpu: dump job ibs in the devcoredump") Signed-off-by: Sunil Khatri Reviewed-by: Vitaly Prosyak Acked-by: Christian König Signed-off-by: Alex Deucher (cherry picked from commit 1bd613b0ed98a23575b18674c94b8b3392614681) Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c index 87e15e39eb30..ec6e5bde7f80 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c @@ -299,10 +299,10 @@ amdgpu_devcoredump_print_ibs(struct drm_printer *p, amdgpu_res_first(abo->tbo.resource, offset, coredump->ibs[i].ib_size_dw * 4, &cursor); while (cursor.remaining) { - amdgpu_device_mm_access(adev, cursor.start / 4, - &ib_content[off], cursor.size / 4, + amdgpu_device_mm_access(adev, cursor.start, + &ib_content[off], cursor.size, false); - off += cursor.size; + off += cursor.size / 4; amdgpu_res_next(&cursor, cursor.size); } emit_content = true; From c748dd03df33360549ad60cdccee13570e9c0f90 Mon Sep 17 00:00:00 2001 From: Sunil Khatri Date: Mon, 31 Aug 2026 20:17:17 +0530 Subject: [PATCH 15/20] drm/amdgpu: update the fw version for gfx11 userqueues Update to the latest stable fw versions where userqueues is working as it is expected with major fixes. Signed-off-by: Sunil Khatri Acked-by: Alex Deucher Signed-off-by: Alex Deucher (cherry picked from commit d50201b891604ab97f305d4a20d888ba93305b48) Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index 69776dbe188d..0ff5a80aa918 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -1651,10 +1651,10 @@ static int gfx_v11_0_sw_init(struct amdgpu_ip_block *ip_block) case IP_VERSION(11, 0, 2): case IP_VERSION(11, 0, 3): if (!adev->gfx.disable_uq && - adev->gfx.me_fw_version >= 2420 && - adev->gfx.pfp_fw_version >= 2580 && - adev->gfx.mec_fw_version >= 2650 && - adev->mes.fw_version[0] >= 120) { + adev->gfx.me_fw_version >= 3090 && + adev->gfx.pfp_fw_version >= 3190 && + adev->gfx.mec_fw_version >= 3450 && + adev->mes.fw_version[0] >= 147) { adev->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_mes_funcs; adev->userq_funcs[AMDGPU_HW_IP_COMPUTE] = &userq_mes_funcs; } From 49a74a2388528c1a2e96f01114c4513e635605fe Mon Sep 17 00:00:00 2001 From: Sunil Khatri Date: Mon, 31 Aug 2026 20:18:31 +0530 Subject: [PATCH 16/20] drm/amdgpu: update the fw version for gfx12 userqueues Update to the latest stable fw versions where userqueues is working as it is expected with major fixes. Signed-off-by: Sunil Khatri Acked-by: Alex Deucher Signed-off-by: Alex Deucher (cherry picked from commit 69fa36e3ac92f2544ee7a1b719ec212b8247a2da) Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c index 1e5fd1ef8f1d..e2a81a55c63b 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c @@ -1436,10 +1436,10 @@ static int gfx_v12_0_sw_init(struct amdgpu_ip_block *ip_block) case IP_VERSION(12, 0, 0): case IP_VERSION(12, 0, 1): if (!adev->gfx.disable_uq && - adev->gfx.me_fw_version >= 2780 && - adev->gfx.pfp_fw_version >= 2840 && - adev->gfx.mec_fw_version >= 3050 && - adev->mes.fw_version[0] >= 123) { + adev->gfx.me_fw_version >= 3090 && + adev->gfx.pfp_fw_version >= 3190 && + adev->gfx.mec_fw_version >= 3450 && + adev->mes.fw_version[0] >= 147) { adev->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_mes_funcs; adev->userq_funcs[AMDGPU_HW_IP_COMPUTE] = &userq_mes_funcs; } From a26301203a196a991527f7b1ab884d4dd0e7c95e Mon Sep 17 00:00:00 2001 From: Kanala Ramalingeswara Reddy Date: Mon, 31 Aug 2026 19:59:11 +0530 Subject: [PATCH 17/20] drm/amdgpu: Skip accessing psp rum time db for APUs Psp runtime DB is for dGPUs only. Signed-off-by: Kanala Ramalingeswara Reddy Acked-by: Alex Deucher Signed-off-by: Alex Deucher (cherry picked from commit dce8195027f146467c9378efb2bb1b0859cb735e) Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 04f6ebf31cca..42adc8e738d8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -396,6 +396,12 @@ static bool psp_get_runtime_db_entry(struct amdgpu_device *adev, bool ret = false; int i; + /* + * Runtime DB is for dGPUs only. + */ + if (adev->flags & AMD_IS_APU) + return false; + if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6) || amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 12) || amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14) || From 8b4a4193f3c0b532054990783f40930083c37618 Mon Sep 17 00:00:00 2001 From: Sunil Khatri Date: Tue, 1 Sep 2026 16:30:35 +0530 Subject: [PATCH 18/20] drm/amdgpu/userq: dont overwrite the error of subsequent map call If a queue fails to map that we need to return the error code back to the caller and not overwrite with a success specifically. Accumulate the failure and return that. Signed-off-by: Sunil Khatri Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher (cherry picked from commit 42a0197d10039e9518c0324c43331eb22b44d5f8) --- drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c index 0a816b3c5ff9..e43bda0cab3f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c @@ -1544,7 +1544,7 @@ int amdgpu_userq_post_reset(struct amdgpu_device *adev, bool vram_lost) struct amdgpu_usermode_queue *queue; const struct amdgpu_userq_funcs *userq_funcs; unsigned long queue_id; - int r = 0; + int ret = 0, r; xa_for_each(&adev->userq_doorbell_xa, queue_id, queue) { if (queue->state == AMDGPU_USERQ_STATE_HUNG && !vram_lost) { @@ -1555,6 +1555,7 @@ int amdgpu_userq_post_reset(struct amdgpu_device *adev, bool vram_lost) r = userq_funcs->map(queue); if (r) { dev_err(adev->dev, "Failed to remap queue %ld\n", queue_id); + ret = r; continue; } trace_amdgpu_userq_state_changed(queue, AMDGPU_USERQ_STATE_MAPPED); @@ -1562,5 +1563,5 @@ int amdgpu_userq_post_reset(struct amdgpu_device *adev, bool vram_lost) } } - return r; + return ret; } From 6293f2e1439fb440be1b606e647ce88e65562a38 Mon Sep 17 00:00:00 2001 From: Yuling Li Date: Tue, 1 Sep 2026 15:37:18 +0800 Subject: [PATCH 19/20] drm/amd/display: Fix cursor disable with horizontally split planes [WHY] resource_can_pipe_disable_cursor() disables the hardware cursor on a pipe when a higher layer fully covers that pipe's recout, to avoid double-cursor and scaling artifacts. When merging pipe-split halves of the same overlay layer, the inner loop walks every pipe above the current one and looks for siblings sharing test_pipe's layer_index. Because test_pipe itself satisfies that condition, it can be treated as its own split partner. That incorrectly doubles r2.width and makes the covering check succeed even when the overlay does not fully contain the underlying pipe. On horizontally split or multi-quadrant layouts this causes the cursor to disappear over overlay regions while input/coordinate mapping remains correct. [HOW] Skip test_pipe when searching for a pipe-split sibling on the same layer, so only the other half of the split plane is merged into r2. Signed-off-by: Yuling Li Reviewed-by: Leo Li Signed-off-by: Alex Deucher (cherry picked from commit 85ccd2c39cca9351d4db393e24acea8bf943d350) --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 7eaaf38cd9ab..fc9080f0c093 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1797,7 +1797,11 @@ bool resource_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx) * pipe-split, merge together per same height. */ for (split_pipe = pipe_ctx->top_pipe; split_pipe; - split_pipe = split_pipe->top_pipe) + split_pipe = split_pipe->top_pipe) { + + if (split_pipe == test_pipe) + continue; + if (split_pipe->plane_state->layer_index == test_pipe->plane_state->layer_index) { struct rect r2_half; @@ -1809,6 +1813,7 @@ bool resource_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx) r2_bottom = min(r2_bottom, r2_half.y + r2_half.height); break; } + } if (r1.x >= r2.x && r1.y >= r2.y && r1_right <= r2_right && r1_bottom <= r2_bottom) return true; From 13af55f71399f5e562f6cb59ad413476e513c4d4 Mon Sep 17 00:00:00 2001 From: Yogesh Mohan Marimuthu Date: Thu, 20 Aug 2026 09:52:50 +0530 Subject: [PATCH 20/20] drm/amdgpu/userq: fix struct drm_amdgpu_info_device padding for 32bit compile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit need to pad before __u64 tcc_disabled_mask variable. This patch fixes 64bit Kernel + 32 bit mesa combination. But at the same time it will break 32bit Kernel(using this patch) + older 32bit mesa(not using this patch). This issue was discussd with alexander.deucher@amd.com, christian.koenig@amd.com and pierre-eric.pelloux-prayer@amd.com. Currently today 32 bit kernel + 32 bit userspace and 64 bit kernel and 64 bit userspace work. Mixed 64 bit kernel and 32 bit userspace is currently broken. Since 32 bit kernel and userspace is probably pretty rare these days and the data affected by this is not critical, Hence we can go ahead with this patch. Fixes: cf21e76a6005 ("drm/amdgpu: return tcc_disabled_mask to userspace") Signed-off-by: Yogesh Mohan Marimuthu Reviewed-by: Christian König Signed-off-by: Alex Deucher (cherry picked from commit 497b5090f2857ef8ad9a162aa31ada0de5814663) --- include/uapi/drm/amdgpu_drm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index b32c72a662b6..42a5fa8ad6b0 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -1512,6 +1512,7 @@ struct drm_amdgpu_info_device { __u64 high_va_max; /* gfx10 pa_sc_tile_steering_override */ __u32 pa_sc_tile_steering_override; + __u32 pad; /* disabled TCCs */ __u64 tcc_disabled_mask; __u64 min_engine_clock; @@ -1536,7 +1537,6 @@ struct drm_amdgpu_info_device { __u32 csa_alignment; /* Userq IP mask (1 << AMDGPU_HW_IP_*) */ __u32 userq_ip_mask; - __u32 pad; }; struct drm_amdgpu_info_hw_ip {