Re-rating Route C: the VCN hypothesis, and its REFUTATION on hardware
Outcome: the VCN reading is REFUTED. The escalation argument below does not hold. Route C's target block remains unidentified, but it is NOT shown to be UVD/VCN, and the original dismissal is not overturned by this line of reasoning. Kept in full because the reasoning and the test are worth having on record.
Route C (VULN-LOADIPFW-UNSIGNED-REGWRITE.md, LOAD_IP_FW type 85) is a
proven, host-reachable, pre-signature primitive: up to 64 writes per call of
a full host-controlled 32-bit value to a host-chosen address in
[0x21500, 0x21B78], issued by the PSP via SVC 0x7C so they carry the PSP's
initiator identity, with verify_image_signature never reached.
It was deflated to "capability real, impact unestablished" on the strength of one argument:
an exhaustive scan found nothing reads those registers
That scan covered the firmware images we hold — sOS, SYS_DRV, the four TAs. This note argues the scan could not have been exhaustive over the actual consumers.
What the NV22 map says the window is
Every named row in [0x21500, 0x21B78] belongs to a UVD/VCN block:
| block | rows in window |
|---|---|
UVD_AVM |
82 |
UVD_UVDENT |
45 |
UVD_VREG |
43 |
UVD_UVDIME |
36 |
UVD_SAOE |
10 |
including UVD_AVM_GP_SCRATCH0/1, UVD_AVM_FW_GPR_S0..S15 (VCN firmware
general-purpose registers), AVM_CGC_CTRL (clock gating), and
UVD_AVM_HDCP_AUD_INPUTCTR_H/L — an HDCP audio input counter.
Why that matters for the dismissal
If the window is UVD/VCN space, then its consumers are VCN hardware and VCN firmware. Neither is in our image set:
- VCN firmware is not on the card — flash holds only a 0x60-byte
"VCN\0"descriptor at 0xB634C, not a code image (established inFINDING-LOADIPFW-VCN-REGWRITE.md); - it is host-supplied (
amdgpu/vcn_4_0_x.bin) and tinygrad never loads it.
So a scan over sOS/SYS_DRV/TAs could not have found a reader that lives in VCN
firmware or is implemented in hardware. "Nothing reads them" is evidence about
our images, not about the register block. A register also does not need a
software reader to have effect — AVM_CGC_CTRL is clock gating.
The connection the project missed
FINDING-LOADIPFW-VCN-REGWRITE.md treats types 49/50 (VCN0/VCN1) as a
different and wider window than Route C, and rates their impact as
"genuinely open rather than known-low" precisely because the VCN block has not
been audited. If Route C's window is also VCN space, the two paths point at the
same block, and Route C inherits "open", not "deflated".
Route C is the better of the two, because it has no engine gate:
| Route C (type 85) | types 49/50 | |
|---|---|---|
| gate | none — case 85 copies and returns |
loadfw_engine_step requires the VCN enable bit in dword_E257C0 |
| reachable as we drive the card | yes (ring 0xFFFF hardcoded) |
no — VCN never brought up |
| pre-signature | yes | yes |
So the path with no gate may target the block whose impact was called open.
Honest ambiguity — this is NOT established
Our own firmware uses two addresses inside the window for something that is
clearly not VCN: bl_set_boot_stage writes 0x215C0 and 0x2161C to record
the PSP's boot stage. That is direct evidence from our own images and it
contradicts a pure UVD reading.
Attempted to settle it by reading the window over host SMN. All 12 targeted
addresses mirror (value == byteswap(addr)), including the two boot-stage
registers and the NV22-named UVD ones, while the C2PMSG control decoded
correctly. That does not separate the hypotheses, because a power-gated block
also fails to decode — this project already measured exactly that for DCE
("only base 0x34c0 decodes; the rest read 0 because nothing brought the display
block out of reset"), and VCN is likewise never brought up here.
So three readings remain live:
- the PSP's
[0x21500,0x21B78]is a different address space from host SMN0x21xxx, and the NV22 names do not apply to it; - it is the same space, is UVD/VCN, and mirrors only because VCN is power-gated;
- it is the same space and holds both — a block that carries boot-stage state and UVD registers at different offsets.
The NV22 map is Navi22 and the card is Navi31, which is a further reason not to treat the naming as fact.
What would settle it
Bring VCN up (load vcn_4_0_x.bin, create the ring) so the block is no longer
power-gated, then re-read the window over SMN. If it decodes, reading 1 is dead
and Route C's target is identified. A Route C write to a decoded, readable
scratch register (UVD_AVM_GP_SCRATCH0 at 0x21B04) followed by an SMN read back
would then be decisive — it would prove the PSP's window and host SMN
0x21xxx are the same space, and give a readback channel for the primitive.
Status
Not a new vulnerability. A re-rating with a mechanism: the argument that closed Route C rests on a scan that structurally could not see the candidate consumers, and the block the map points at is the same one another path's impact was left open on. Route C should not be cited as "impact known-low" until the window is identified.
REFUTED: the window is not host SMN 0x21xxx
The hypothesis needed the window to mirror because VCN is power-gated. Tested that directly, in two stages, each with its own control.
Stage 1 -- load VCN firmware. LOAD_IP_FW with GFX_FW_TYPE_VCN (0xd) and
the real vcn_4_0_0.bin ucode (390096 bytes) was accepted, PSP healthy
after. Window unchanged: 0/6 decoded. But a PSP firmware load is a weak
bring-up -- on AMD parts the block is un-gated by the SMU, not by loading ucode
-- so this stage proves little on its own.
Stage 2 -- actually power the block. PPSMC_MSG_PowerUpVcn (0x2A) with
arg=0 returned OK, with is_smu_alive() true and the PSP heartbeat
advancing afterwards. That is the positive control the experiment needed: the
un-gate command genuinely succeeded.
The window still read 0/6 decoded, every address mirroring, including both
UVD_AVM_GP_SCRATCH0/1 and the two bl_set_boot_stage registers, while the
C2PMSG_58 control decoded correctly as 0x310036 throughout.
So VCN instance 0 is powered and host SMN 0x21xxx still does not decode. Of
the three readings listed above, this selects reading 1: the PSP's
[0x21500,0x21B78] is a different address space from host SMN 0x21xxx --
consistent with it being reached through vawin_map_fixed, a PSP-internal
mapping, which is exactly how the firmware evidence (bl_set_boot_stage)
described it in the first place.
Consequences, stated plainly:
- the NV22 UVD/VCN naming does not apply to Route C's window;
- the escalation argument -- "its consumers are VCN firmware and hardware, which the scan could not see" -- is dead;
- the
AVM_CGC_CTRL/ HDCP-audio-counter observations are irrelevant to Route C; - Route C's target block is still unidentified, and the project's original concern (the "nothing reads them" scan covered only our images) remains a genuine limitation, but it is no longer attached to a specific escalation story.
The one piece of the original argument that survives is the weakest and most general form: a scan over sOS/SYS_DRV/TAs cannot prove "nothing reads" a block whose identity is unknown. That is a reason not to cite the finding as impact-known-low, not a reason to rate it high.
Cost: PowerUpVcn with arg=1 (second instance) timed out and wedged the
SMU; one ATX cycle restored everything (VRAM 24560 MB, PSP 0x310036, heartbeat
advancing, compute correct). Instance 0 succeeding is what carries the result,
so the wedge cost nothing evidentially.
