The remaining VS twins
vstvec, vsscratch, vsepc, vscause, vstval are exact structural copies of their supervisor originals — same WARL/WLRL value sets — substituting when V=1 and inert (but accessible from M/HS) when V=0. Two have real subtleties:
- vsatp: satp’s layout with the guest’s ASID space. Active unless (U-mode ∧ HU=0), but speculative execution may not set VS-stage A bits unless the effective privilege is really VS/VU — a mispredicted HLV must leave guest page tables untouched. When V=1, a guest’s satp write with unsupported MODE is wholly ignored (satp semantics); when V=0, a direct vsatp write may either behave that way or WARL normally — implementation’s choice.
- vstimecmp: VSTIP pends while
(time + htimedelta) ≥ vstimecmp(64-bit wrap, eventual propagation) — the guest’s Sstc timer, accessed as stimecmp when V=1 given henvcfg.STCE.
HLV / HLVX / HSV — touching guest memory
Valid in M/HS (and U when hstatus.HU=1; V=1 → virtual-instruction). Each performs one explicit access as the guest: effective privilege VS (SPVP=1) or VU (SPVP=0), two-stage translation, HS-level SUM ignored, HS-level MXR opening executable pages across both stages while vsstatus.MXR covers only VS-stage. The full set mirrors the base loads/stores: HLV.B/BU/H/HU/W/WU/D, HSV.B/H/W/D. HLVX.HU / HLVX.WU swap read permission for execute permission (both stages; physical PMP must still grant read) — the instruction-fetch emulation primitive, exempt from pointer masking, still raising load-type exceptions.
HFENCE.VVMA and HFENCE.GVMA
| Orders / invalidates | Validity | |
|---|---|---|
| HFENCE.VVMA (funct7 0010001) — rs1 = guest VA, rs2 = guest ASID | “SFENCE.VMA as if in VS-mode”: stores vs VS-stage implicit reads, for instructions executing with the SAME hgatp.VMID as at fence time. One virtual machine only. | M or HS. Never trapped by TVM or VTVM. |
| HFENCE.GVMA (funct7 0110001) — rs1 = GPA >> 2, rs2 = VMID | Stores vs G-stage implicit reads; invalidates G-stage (and combined) translations matching address+VMID. | HS with mstatus.TVM=0, or M always; TVM=1 → illegal-instruction. Required after ANY hgatp.MODE change, even to/from Bare. |
V=1 attempts at either raise virtual-instruction; U-mode raises illegal. Simple cores may over-fence globally, ignoring all operands.
What H does to machine level
- mstatus.MPV[39] + GVA[38] (mstatush[7:6] on RV32): traps into M record V alongside MPP; MRET restores V=MPV unless MPP=3. GVA=1 iff mtval got a guest VA.
- TSR/TVM constrain HS only (VS has the V* twins in hstatus); TW covers every mode below M. TVM=1 co-opts hgatp + HFENCE.GVMA/HINVAL.GVMA — but deliberately not vsatp or VVMA, because M-level shadow paging only needs to interpose on G-stage.
- MPRV (Table 49): explicit M accesses translate as the (MPV, MPP) world — MPV=1/MPP=0 → VU two-stage, MPV=1/MPP=1 → VS two-stage (with vsstatus.SUM in force), MPP=3 → untranslated. HLV/HLVX/HSV ignore MPRV outright.
- mideleg: bits 10/6/2 read-only one (VS interrupts always pass M to HS; bit 12 too if GEILEN>0); zero mideleg bits pin the matching hideleg/hip/hie bits to zero.
- mip/mie gain SGEIP/VSEIP/VSTIP/VSSIP as aliases of hip/hie.
- mtval2/mtinst: the M-level htval/htinst — guest-page faults write the GPA>>2 to mtval2 and instruction info to mtinst (formats on the traps page).
Hardware Designer Notes
HLV/HSV are the H extension’s hot loop: every MMIO emulation and every guest syscall argument copy runs through them. Their two-stage translation should share the regular TLB path (tagged VMID+ASID), not a slow side path — a hypervisor doing 10⁵ exits/second will notice.
Minimal Linux-boot hart MUST
- Give HLV/HLVX/HSV their own effective-privilege source (SPVP + forced V=1) bypassing MPRV, with the MXR two-stage/one-stage split
- Block speculative VS-stage A-bit updates for mispredicted HLV/HSV — gate the walker’s A-write on architectural execution when eff-priv isn’t VS/VU
- Wire the TVM trap set exactly: hgatp + GVMA flavors, never vsatp + VVMA flavors
MAY simplify / trap-and-emulate
- Decode HFENCE.* to full global TLB flushes initially
- Implement HLV/HSV as microcoded sequences (set shadow mode, one access, restore) if a hardware privilege-override path is costly
Check yourself — HLV/HSV, HFENCE, machine CSRs
1.What distinguishes HLVX.HU from HLV.HU?
2.A hypervisor changes hgatp.MODE from Sv39x4 to Bare for a VMID. What must follow?
3.With MPRV=1, MPV=1, MPP=1, an M-mode load executes. How is it translated?
4.Why are mideleg bits 10, 6, and 2 read-only ONE when H is implemented?