The H extension hypervisor extension The H extension: turns S-mode into HS-mode and adds guest modes VS/VU (virtualization bit V=1) with two-stage address translation, hypervisor CSRs (hstatus, hgatp, hedeleg…), VS shadow CSRs that substitute when V=1, HLV/HSV guest-memory instructions, and HFENCE fences. misa bit 7. defined in ch. II·15 — open in glossary (misa bit 7 — preferably not hardwired) makes guests architectural: S-mode becomes HS-mode, and a new virtualization bit V spawns two guest modes. It requires full RV32I/RV64I (not E), a non-zero mtval, and paging (Sv32, or ≥Sv39 on RV64). An unmodified S-mode OS boots identically in HS-mode or as a VS-mode guest — that’s the design test.
| V | Nominal priv | Two-stage translation | |
|---|---|---|---|
| M-mode | 0 | M | off |
| HS-mode — hypervisor-extended supervisor | 0 | S | off |
| U-mode | 0 | U | off |
| VS-mode — virtual supervisor (guest kernel) | 1 | S | on |
| VU-mode — virtual user (guest userspace) | 1 | U | on |
The CSR substitution scheme
HS-mode gets additional CSRs (hstatus, hedeleg/hideleg, hvip/hip/hie,
hgeip/hgeie, henvcfg, hcounteren, htimedelta, htval, htinst, hgatp).
And the trap-critical supervisor CSRs get VS twins — vsstatus,
vsip/vsie, vstvec, vsscratch, vsepc, vscause, vstval, vsatp,
vstimecmp. When V=1, an access to sstatus transparently reads
vsstatus, and so on; the vs* CSRs’ own addresses trap from VS
(virtual-instruction) and answer only to M/HS. CSRs without twins
(senvcfg, scounteren…) stay live under V=1 with VS/VU substituting for
HS/U — hypervisors swap those manually at world switch. The
duplication criterion: only CSRs that traps write, or that must be
correct in the first instructions of a handler, get hardware twins.
hstatus
hstatus (0x600), HSXLEN=64 — Figure 48
Delegation: three levels deep
Traps from V=1 route M → (medeleg/mideleg) → HS → (hedeleg/hideleg) → VS. hedeleg mirrors medeleg’s layout, but Table 45 pins the policy: bits 1–8, 12, 13, 15, 18, 19 must be writable (plus bit 0 if IALIGN=32); ecalls from HS/VS/M (9/10/11), double trap (16), guest-page faults (20/21/23), and virtual instruction (22) are read-only zero — those are the hypervisor interface, so pushing them into the guest would be circular. In hideleg, VS interrupts (bits 10/6/2) are writable and, when delegated, renumber on the way down: VSEI (10) presents to the guest as SEI (9), VSTI (6) as STI (5), VSSI (2) as SSI (1) — vscause included. The guest sees a plain S-mode world.
The hypervisor interrupt registers
hvip is the injection register: writable VSEIP[10]/VSTIP[6]/VSSIP[2]
assert virtual interrupts for the guest. hip/hie supplement
sip/sie with the hypervisor interrupts — and their active bits are
required to be disjoint from sip/sie’s (an emulability guarantee:
S-mode software can’t have its sip bits re-purposed):
| Source / behavior | |
|---|---|
| SGEIP [12] (RO) | 1 iff hgeip & hgeie ≠ 0 — the hypervisor’s own “some guest device needs routing” interrupt. |
| VSEIP [10] (RO) | OR of: hvip.VSEIP (software-injected) | hgeip bit selected by VGEIN (pass-through) | platform signals. |
| VSTIP [6] (RO) | hvip.VSTIP | vstimecmp comparator output (Sstc). Defined even while V=0. |
| VSSIP [2] (RW) | Writable alias of hvip.VSSIP. |
HS-mode interrupt priority: SEI, SSI, STI, SGEI, VSEI, VSSI, VSTI, LCOFI — host before guest.
hgeip/hgeie (guest external interrupts) exist for device
pass-through: bit i aggregates all pending interrupts an interrupt
controller has collected for virtual hart i. GEILEN (0…31/63) bits
are implemented from bit 1 up. hgeie picks which of them wake the
hypervisor (SGEI); hstatus.VGEIN picks the one wired through as
the guest’s external interrupt — two independent consumers of the
same pending bits.
Hardware Designer Notes
The expensive parts of H live in later pages (two-stage TLB, the G-stage walker). This page’s state is cheap: one V flop, ~10 new CSRs, and mux trees. Get the substitution architecture right first — every later feature keys off “which world am I in”.
Minimal Linux-boot hart MUST
- Make V fan into four muxes: CSR address remap (s* → vs*), trap-target resolution (M/HS/VS by the three delegation levels), translation-enable selection, and virtual-vs-illegal exception choice
- Keep hip/hie active bits disjoint from sip/sie, with the VSEIP/VSTIP OR-trees exactly as specified
- Implement the interrupt renumbering (10→9, 6→5, 2→1) on VS delivery, including the vscause value
MAY simplify / trap-and-emulate
- Hardwire GEILEN=0 (no pass-through; VGEIN RO-0) — KVM works fine with hvip injection only
- Hardwire VSXL/VSBE (single XLEN, little-endian)
- Omit H entirely for a Linux-boot v1 — misa.H=0; the extension was designed to be trap-and-emulated on top of plain S-mode when needed
Check yourself — H modes, hstatus, delegation
1.A guest kernel in VS-mode executes `csrr t0, sstatus`. What does hardware actually do?
2.Why does hstatus need SPVP when sstatus already has SPP?
3.Which hedeleg bits MUST be read-only zero, and what's the pattern?
4.How does hip.VSEIP get asserted?
5.Why are hip/hie's active bits required to be DISJOINT from sip/sie's, rather than merged into them?