# DF-4389 — `hwmgr->num_vce_state_tables` stored unclamped (up to 255) against `vce_states[6]`; fill loop silently skipped

- `sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c:1328-1333`:

```c
hwmgr->num_vce_state_tables = i = ppt_get_num_of_vce_state_table_entries_v1_0(hwmgr);
if ((i != 0) && (i <= AMD_MAX_VCE_LEVELS)) {        /* guard covers FILL only */
	for (j = 0; j < i; j++)
		ppt_get_vce_state_table_entry_v1_0(hwmgr, j, &(hwmgr->vce_states[j]), NULL, &flags);
}
```

- `i` comes straight from the VBIOS VCE-state-table `ucNumEntries`
  (UCHAR, 0..255 — and when `usVCEStateTableOffset==0`, from whatever byte
  the PowerPlay header alias yields; DF-1576 notes the missing zero-check).
- `hwmgr->vce_states[AMD_MAX_VCE_LEVELS]` = **6** entries
  (`sys/dev/drm/amd/powerplay/inc/hwmgr.h:723`,
  `sys/dev/drm/amd/include/kgd_pp_interface.h:74`).
- The count is stored **unconditionally**; a VBIOS with `ucNumEntries > 6`
  leaves `num_vce_state_tables` up to 255 while the array holds at most 6
  (zeroed or stale) entries.
- Consumer: `pp_dpm_get_vce_clock_state`
  (`sys/dev/drm/amd/powerplay/amd_powerplay.c:868-869`):
  `if (idx < hwmgr->num_vce_state_tables) return &hwmgr->vce_states[idx];`
  — currently reached only from `AMDGPU_INFO_VCE_CLOCK_TABLE`
  (`amdgpu_kms.c:775`) whose loop is bounded by
  `AMDGPU_VCE_CLOCK_TABLE_ENTRIES = 6` (`amdgpu_drm.h:962`), so **today**
  the OOB read is fenced by coincidence: any future consumer trusting the
  stored count (or a raised ioctl bound) reads up to 249 entries past
  `vce_states[]` inside `struct pp_hwmgr` and copies the fields to
  userspace.
- Sibling evidence the clamp is the intended semantics: the amdgpu DPM path
  clamps the very same firmware count —
  `sys/dev/drm/amd/amdgpu/amdgpu_dpm.c:580-581`:
  `numEntries > AMD_MAX_VCE_LEVELS ? AMD_MAX_VCE_LEVELS : numEntries`.

## Build / run

Hardware-gated on the audit guest (no AMD GPU — `run.log`); the clamp
arithmetic is case 7 of `../DF-4388/v1_clamp_test.c` (255 → 6, PASS on the
guest) and the fix rides in DF-4388's `fix.diff` hunk; a standalone minimal
`fix.diff` is included here.

## Expected

With the fix: `num_vce_state_tables` never exceeds 6 and the first 6 VCE
states are populated instead of none.
