aboutsummaryrefslogtreecommitdiffstats

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 in FINDING-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:

  1. the PSP's [0x21500,0x21B78] is a different address space from host SMN 0x21xxx, and the NV22 names do not apply to it;
  2. it is the same space, is UVD/VCN, and mirrors only because VCN is power-gated;
  3. 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.