# DF-5131 — radeon_sync_resv()/radeon_sync_rings() returns discarded by 7 remaining callers (DF-4871 family completion)

File: `sys/dev/drm/radeon/radeon_sync.c` (pass 2) — findings live at the call sites
enumerated below; the sync engine (`radeon_sync.c:89-201`) correctly returns the
error, the callers drop it.

## What this is

`radeon_sync_resv()` (radeon_sync.c:89-125) and `radeon_sync_rings()`
(radeon_sync.c:137-201) return `int` precisely so a submitter can abort when a
cross-ring dependency cannot be established (interrupted fence wait
`-ERESTARTSYS`, semaphore SA-bo allocation `-ENOMEM`, `radeon_ring_alloc()`
fence-wait failure, disabled source ring `-EINVAL`). Pass 1 already filed two
of the offenders:

- DF-4871 — `sys/dev/drm/radeon/r600_dma.c:466-467` (`r600_copy_dma`)
- DF-5089 — `sys/dev/drm/radeon/si_dma.c:255-256` (`si_copy_dma`)

This pass found **seven more call sites that discard the return**, none covered
by an existing finding (checked against `findings` for cik_sdma.c, r600.c,
rv770_dma.c, evergreen_dma.c, cik.c, radeon_vm.c):

| # | Site | Function | What is dropped |
|---|------|---------------------------|
| 1 | `sys/dev/drm/radeon/r600.c:2997-2998` | `r600_copy_blit` | resv + rings |
| 2 | `sys/dev/drm/radeon/cik.c:3695-3696` | `cik_copy_blit` | resv + rings |
| 3 | `sys/dev/drm/radeon/evergreen_dma.c:130-131` | `evergreen_copy_dma` | resv + rings |
| 4 | `sys/dev/drm/radeon/rv770_dma.c:66-67` | `rv770_copy_dma` | resv + rings |
| 5 | `sys/dev/drm/radeon/cik_sdma.c:601-602` | `cik_copy_dma` | resv + rings |
| 6 | `sys/dev/drm/radeon/radeon_vm.c:705` | `radeon_vm_update_page_tables` | resv (PD fence) |
| 7 | `sys/dev/drm/radeon/radeon_vm.c:833` | `radeon_vm_update_ptes` | resv — and `r` is *immediately clobbered* by the following `reservation_object_reserve_shared()` call, so the failure could never be observed even by accident |

All five copy sites hold `rdev->ring_lock` at the point of the call (so the
sync engine's cross-ring `radeon_ring_alloc()` is serialized — not a locking
bug), and all proceed to emit the copy/PT-update commands and commit the ring
after the unchecked sync failure.

## Impact

On any sync failure the DMA copy / blit / page-table update is submitted
**without the cross-ring dependency it exists to enforce**:

- copy paths: silent stale-data bo corruption (the GPU reads the destination
  before the signaling ring finished writing it) — integrity impact;
- VM paths (6,7): page-table updates racing the fences on the PD/PT resv —
  GPU-visible memory-consistency violation, i.e. the GPU can walk page tables
  mid-update;
- the `-ENOMEM` / disabled-ring cases then also leak nothing (sync_free is
  still called on the success tail), but the ordering guarantee is silently
  gone.

Severity Low (family precedent DF-4871/DF-5089): hardware-gated to radeon GPUs,
needs a sync failure to coincide with a cross-ring dependency — but the code
path is certain, static, and trivially fixed.

## Reproduce (static)

    ./check_static.sh

enumerates every `radeon_sync_resv`/`radeon_sync_rings` call in
`sys/dev/drm/radeon/` and classifies checked vs bare — expect exactly the
7 sites above reported BARE (plus the 2 known DF-4871/DF-5089 sites), and
`radeon_ib.c:149` / `radeon_cs.c:256` reported CHECKED.

Runtime reproduction requires a physical radeon GPU with ≥2 initialized rings
plus an induced `radeon_sync_rings()` failure (e.g. signal-pending
`dma_fence_wait`); the QEMU audit guest has no AMD GPU (`pciconf` shows none),
so no runtime PoC is possible on it — see VERDICT.md.

## Fix

`fix.diff` — check both returns at all 7 sites with the canonical rollback
(`radeon_ring_unlock_undo()` + `radeon_sync_free()` + `ERR_PTR(r)` for the
copy paths; propagate `r` for the two VM sites, un-clobbering the variable at
radeon_vm.c:833).
