From: Wayne Lin <[email protected]>

[ Upstream commit 1a38ded4bc8ac09fd029ec656b1e2c98cc0d238c ]

[Why & How]
Although it's dummy updates of surface update for committing stream
updates, we should not have dummy_updates[j].surface all indicating
to the same surface under multiple surfaces case. Otherwise,
copy_surface_update_to_plane() in update_planes_and_stream_state()
will update to the same surface only.

Reviewed-by: Harry Wentland <[email protected]>
Signed-off-by: Wayne Lin <[email protected]>
Signed-off-by: Tom Chung <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---

LLM Generated explanations, may be completely bogus:

## Analysis

### What the commit fixes

This is a clear **indexing bug** in `amdgpu_dm_atomic_commit_tail()`. In
a loop iterating over `status->plane_count` planes:

```c
for (j = 0; j < status->plane_count; j++)
    dummy_updates[j].surface = status->plane_states[0];  // BUG: always
[0]
```

The fix changes `plane_states[0]` to `plane_states[j]`, so each dummy
update references its correct corresponding plane state instead of all
pointing to the first one.

### Bug impact

This bug affects **Multi-Plane Overlay (MPO)** scenarios where
`status->plane_count > 1`. When multiple planes are active:

1. **All dummy updates point to the same surface** -
   `copy_surface_update_to_plane()` processes the same plane repeatedly,
   ignoring other planes in the composition
2. **The sort by `layer_index` becomes meaningless** - all entries have
   the same layer_index since they reference the same plane
3. **`dc_update_planes_and_stream()` operates on incorrect data** -
   stream updates that should touch all planes only affect one

This causes incorrect display behavior under MPO, which is used for
hardware-accelerated video overlay, cursor planes, and compositing.

### Meets stable criteria

- **Obviously correct**: Classic `[0]` vs `[j]` indexing bug in a loop -
  the fix is a single character change
- **Fixes a real bug**: MPO plane updates are broken when multiple
  planes are active
- **Small and contained**: Single line change, zero risk of regression
- **No new features**: Pure bug fix
- **Reviewed and tested**: Has `Reviewed-by: Harry Wentland`, `Tested-
  by: Daniel Wheeler`

### Bug origin

The bug was introduced in commit `efc8278eecfd5` (Feb 2021) which was a
revert that restored older code containing this indexing error. The bug
has been present for ~5 years, affecting all stable trees that contain
this code path.

### Risk assessment

**Extremely low risk.** This is a one-character fix (`0` → `j`) that
corrects an obvious loop indexing mistake. There is no conceivable way
this change could cause a regression - the previous behavior (all
pointing to `plane_states[0]`) was simply wrong.

### Verification

- **Verified the buggy line exists** at `amdgpu_dm.c:10954` via Read
  tool - confirmed `plane_states[0]` in loop
- **Verified bug introduction**: `git log --no-walk efc8278eecfd5`
  confirmed it was a revert from Feb 2021 that restored the buggy code
- **Verified the fix commit**: `git show 1a38ded4bc8ac` confirmed Wayne
  Lin authored the fix, merged to master
- **Verified code flow**: The agent traced
  `dc_update_planes_and_stream()` → `update_planes_and_stream_state()` →
  `copy_surface_update_to_plane()` which iterates over each surface
  update, confirming that having all dummy_updates point to the same
  surface causes only one plane to be updated
- **Verified `dm_plane_layer_index_cmp()`** sorts by
  `surface->layer_index` - with all surfaces the same, sorting is a no-
  op (broken)
- **Verified the fix is in master** via `git branch -a --contains
  1a38ded4bc8ac`
- **Could not independently verify** user-reported display issues under
  MPO, but the code analysis clearly shows the bug mechanism

**YES**

 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index e004fc3893edf..7fae54e47292b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10961,7 +10961,7 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
                        continue;
                }
                for (j = 0; j < status->plane_count; j++)
-                       dummy_updates[j].surface = status->plane_states[0];
+                       dummy_updates[j].surface = status->plane_states[j];
 
                sort(dummy_updates, status->plane_count,
                     sizeof(*dummy_updates), dm_plane_layer_index_cmp, NULL);
-- 
2.51.0

Reply via email to