# DF-5205 — trinity_notify_message_to_smu() fail-open SMC response validation

File: `sys/dev/drm/radeon/trinity_smc.c:43-53` (radeon Trinity/TN/RL — HD 7xxx APU)
Family: radeon twin of DF-5137 (`sys/dev/drm/radeon/kv_smc.c`) / DF-5132 (amdgpu `kv_smc.c`).
Severity: Info — hardware-reliability fail-open on a path with no attacker-controlled data.

## The defect

`trinity_notify_message_to_smu()` sends a message id to the SMC microcontroller and
polls `SMC_RESP_0` for up to `rdev->usec_timeout` µs (RADEON_MAX_USEC_TIMEOUT =
100000 = 100 ms, radeon.h:131). It then validates the response:

```c
        v = RREG32(SMC_RESP_0);                    /* trinity_smc.c:41 — RAW 32-bit */

        if (v != 1) {                              /* :43 */
                if (v == 0xFF) { ... return -EINVAL; }   /* :44-46 */
                else if (v == 0xFE) { ... return -EINVAL; } /* :47-49 */
        }                                          /* :50 — NO else: falls through */
        return 0;                                  /* :53 — SUCCESS */
```

Only the *two* explicit SMC error codes (0xFF "failed", 0xFE "unknown message")
produce an error. Every other non-1 value — most importantly:

* `v == 0` — the SMC never responded at all (poll loop exhausted, i.e. **timeout**), and
* `v ∈ {0x02 … 0xFD}` — undefined response codes, and
* any stray bits in the upper 16 bits (trinity reads the register **unmasked**;
  the kv twin at least applies `SMC_RESP_MASK` = 0xffff, cikd.h:431 — Trinity has
  no such mask anywhere in trinityd.h)

— falls out of the `if (v != 1)` block and the function **returns 0 (success)**.

## Consequence

All 10 exported wrappers (`trinity_dpm_config` :64, `trinity_dpm_force_state` :74,
`trinity_dpm_n_levels_disabled` :81, `trinity_uvd_dpm_config` :88,
`trinity_dpm_no_forced_level` :93, `trinity_dpm_bapm_enable` :56,
`trinity_dce_enable_voltage_adjustment` :98, `trinity_gfx_dynamic_mgpg_config` :107)
report success to the trinity_dpm power-management state machine. The consumers
then believe PM reconfiguration that never happened, e.g.
`trinity_dpm_enable()` (trinity_dpm.c:1105-1132) sends DPM-enable messages that
silently failed and still `return 0`, after which the radeon PM core marks DPM
enabled and keeps transitioning clock/voltage state against non-responsive SMC
hardware. Reliability defect (mis-clocked/mis-volted GPU, dead PM state machine),
not memory corruption; no unprivileged input reaches this path (message ids are
compile-time constants, the `n` arguments are driver-derived).

## Why untested (see VERDICT.md)

Requires AMD Trinity (HD 7xxx APU) hardware with a live SMC firmware that can be
made to time out or return an undefined response code. The audit QEMU guest has
no radeon GPU, and this is an Info-class hardening finding, which the audit
contract exempts from guest verification. `fix.diff` is authored but not
build/runtime-validated on hardware.

## Fix

`fix.diff` — add the missing catch-all: any `v != 1` that is neither 0xFF nor
0xFE is an error (`-EINVAL`), matching the SMC message protocol. Applies clean
with `git apply`.
