From: Ostrowski Rafal rostrows@amd.com
[ Upstream commit 19f76f2390be5abe8d5ed986780b73564ba2baca ]
[Why & How] Tiled command rect dimensions is 1 based, do rect_x/y - 1 internally
Reviewed-by: Alvin Lee alvin.lee2@amd.com Signed-off-by: Ostrowski Rafal rostrows@amd.com Signed-off-by: Wayne Lin wayne.lin@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
YES
Explanation
- What changed - In `drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c`, function `dmub_lsdma_send_tiled_to_tiled_copy_command`, the fields `rect_x` and `rect_y` are now encoded as `params.rect_x - 1` and `params.rect_y - 1` instead of passing the values through unmodified. - The rest of the command payload remains unchanged, including the existing “minus-one” encoding for dimensions: - `src_width = params.src_width - 1` - `dst_width = params.dst_width - 1` - `src_height = params.src_height - 1` - `dst_height = params.dst_height - 1`
- Why it matters - The commit message explicitly states that the “tiled command rect dimensions is 1 based,” so the command fields must be encoded as N-1 before being sent to the LSDMA controller. Prior to this change, `rect_x`/`rect_y` were not adjusted, creating an off-by-one error relative to the hardware’s expected encoding. - This bug would cause the copied rectangle to be shifted by one unit (tile/element) in both X and Y, leading to incorrect or corrupted copies. Near edges, it could also risk out-of-bounds accesses by the DMA engine (a correctness and potential stability issue). - The fix makes `rect_x`/`rect_y` consistent with the already-correct “minus-one” encoding used for width and height fields in the same command packet, aligning all rectangle-related fields with the LSDMA protocol.
- Scope and risk - Change is minimal and fully localized to two assignments in a single function that builds the DMUB LSDMA “tiled-to-tiled copy” command. - No architectural changes, no new features, and no behavior changes outside this specific command payload. - The driver-side `params.rect_x/rect_y` are documented/assumed as 1-based in this path (consistent with the commit message); subtracting 1 before writing the command field is the correct, low- risk fix. - Potential regression risk is low: the only hazard would be if any caller had incorrectly pre-applied the minus-one encoding already, which is unlikely given the commit rationale and the inconsistency that previously existed only for rect_x/rect_y (while width/height were already encoded as -1).
- Stable backport considerations - Fixes a real, user-visible bug (off-by-one in copy origin) that can cause display corruption and possibly out-of-bounds DMA on edge cases. - The patch is simple, small, and self-contained with minimal regression risk. - No API or ABI changes; no dependencies on other changes. - Although the commit message lacks a “Fixes:” or “Cc: stable” tag, it squarely fits stable criteria. - Practical applicability: Only relevant for stable branches that already include `dmub_lsdma_send_tiled_to_tiled_copy_command` and use the LSDMA tiled-to-tiled copy path. For branches without this code path, the patch is not applicable.
- Conclusion - This is a straightforward, correctness fix for an off-by-one error in the DMUB LSDMA tiled-to-tiled copy command encoding. It should be backported to all stable kernels that contain this functionality.
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index f5ef1a07078e5..714c468c010d3 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -2072,8 +2072,8 @@ bool dmub_lsdma_send_tiled_to_tiled_copy_command( lsdma_data->u.tiled_copy_data.dst_swizzle_mode = params.swizzle_mode; lsdma_data->u.tiled_copy_data.src_element_size = params.element_size; lsdma_data->u.tiled_copy_data.dst_element_size = params.element_size; - lsdma_data->u.tiled_copy_data.rect_x = params.rect_x; - lsdma_data->u.tiled_copy_data.rect_y = params.rect_y; + lsdma_data->u.tiled_copy_data.rect_x = params.rect_x - 1; + lsdma_data->u.tiled_copy_data.rect_y = params.rect_y - 1; lsdma_data->u.tiled_copy_data.dcc = params.dcc; lsdma_data->u.tiled_copy_data.tmz = params.tmz; lsdma_data->u.tiled_copy_data.read_compress = params.read_compress;