# DF-3889 — `boot_ps` NULL dereference in `kv_dpm_disable` when the VBIOS power table has no BOOT-classified state

**File:** `sys/dev/drm/amd/amdgpu/kv_dpm.c:1400` (sink: `kv_update_current_ps(adev, adev->pm.dpm.boot_ps)`), `:3026` (unvalidated NULL assignment in sw_init)
**Class:** CWE-476 NULL-pointer dereference (boot_ps family: DF-3586/3610/3623/3646/3754 twins — this is the amdgpu kv_dpm instance, unfixed)
**Verdict:** `inconclusive` at runtime on this guest (no AMD GPU); **source-certain**; harness proves the verbatim NULL+40 deref → SIGSEGV.

## Build (on the DragonFly guest, as root)

    mkdir -p /tmp/DF-3889 && cp boot_ps_null.c /tmp/DF-3889/h.c
    cd /tmp/DF-3889 && cc -Wall -O0 -o t h.c

## Run

    ./t          # accounting — dereference site and offset (ps_priv at +40)
    ./t crash    # verbatim kv_get_ps(NULL) -> SIGSEGV (exit 139)

## Expected

- accounting: `offsetof(struct amdgpu_ps, ps_priv) = 40`;
  `kv_dpm_disable (:1400) -> kv_update_current_ps(adev, NULL) ->
  kv_get_ps(NULL) (:371-373): rps->ps_priv reads *(void**)(NULL + 40)`.
- crash: `Segmentation fault`, exit=139 (kernel equivalent: page fault in kernel
  mode → panic).

## Kernel trigger

`kv_parse_pplib_non_clock_info` (kv_dpm.c:2672-2675) only assigns
`adev->pm.dpm.boot_ps` for a state with `ATOM_PPLIB_CLASSIFICATION_BOOT`. A VBIOS
power table without such a state leaves `boot_ps == NULL` while DPM otherwise
inits and runs (`num_ps > 0`, `dpm_enabled = true`). Then:

- suspend/resume or driver detach → `kv_dpm_hw_fini`/`kv_dpm_suspend` →
  `kv_dpm_disable` → `kv_update_current_ps(adev, NULL)` (kv_dpm.c:1400) →
  `kv_get_ps(NULL)` (kv_dpm.c:371-373) → `rps->ps_priv` at NULL+40 → panic;
- `kv_dpm_sw_init` (:3026) and `kv_dpm_suspend` (:3096) also propagate the NULL
  into `current_ps`/`requested_ps` (benign assignments here, but the same unvalidated
  assumption).
