i-RISCV Hypervisor Support

The i-RISCV core implements the RISC-V H (Hypervisor) extension. The following mechanisms are supported.

Virtualization Modes and CSRs

  • A virtualization-mode bit V layering VS-mode and VU-mode on top of HS-mode/U-mode; SRET is the only way a hart enters a guest (hstatus.SPV/sstatus.SPP)
  • The full hypervisor CSR set (hstatus, hedeleg/hideleg, hie/hvip/hip, hgeip/hgeie, henvcfg, hcounteren, htimedelta, htval/htinst, hgatp) and the VS-mode shadow CSRs (vsstatus, vsie/vsip, vstvec, vsscratch, vsepc, vscause, vstval, vsatp, vstimecmp)
  • Transparent CSR substitution while V=1: supervisor CSRs redirect to their VS counterparts, including satp/vsatp and stimecmp/vstimecmp
  • henvcfg mirrors menvcfg’s own enable fields (STCE, PBMTE, ADUE, FIOM, CBZE/CBCFE/CBIE, LPE/SSE/DTE) for VS-stage and genuinely gates VS-mode independently of menvcfg – Svpbmt/Zicbom/Zicboz access in VS-mode is gated by henvcfg’s own bit alone; only STCE and ADUE stack both levels (the guest’s effective enable is the AND), with SSE/DTE spec-forced to 0 whenever their menvcfg counterpart clears

Trap Delegation and Virtual Instructions

  • Three-way M/HS/VS trap routing via medeleg/mideleg plus the guest-level hedeleg/hideleg; VS interrupts (VSSIP/VSTIP/VSEIP) and SGEIP are always delegated at least to HS-level, and SGEIP can never be delegated further down
  • Interrupt-cause renumbering when delegated into VS-mode, so a guest sees ordinary supervisor numbering
  • Virtual-instruction exceptions for HS-qualified instructions blocked by V=1, covering both spec groups (VTVM/VTSR-gated and unconditional, incl. WFI under VTW)

Two-Stage Address Translation

  • Separate VS-stage and G-stage walkers/TLBs in Sv39x4/Sv48x4/Sv57x4, mirroring the single-stage modes
  • “Walk of a walk”: every VS-stage page-table read – root pointer and each PTE – is itself G-stage translated before reaching memory
  • Guest-page-fault causes (20/21/23) distinct from ordinary page faults, always attributed to the original access kind – including when a VS-stage PTE fetch (checked as an implicit read) fails in G-stage
  • HS-level mstatus.MXR overrides both stages while guest vsstatus.MXR overrides only the VS stage; HS-level SUM is ignored for two-stage accesses
  • G-stage’s own permission quirks per spec: the U bit is always checked as though in U-mode, and a cached final result is re-checked whenever the access kind or the active VMID changes

Nested Virtualization

  • A single hardware VS/G-stage context supports nested (“L2+”) virtualization through software trap-and-emulate: a guest hypervisor runs at ordinary VS-mode, and its privileged operations (e.g. hgatp writes, HFENCE.GVMA) virtual-instruction-trap to the outer hypervisor for emulation
  • Shadow G-stage page-table merging enforces the inner hypervisor’s intended permissions on top of the outer hosting mapping; arbitrarily deep nesting by recursively re-applying the same technique, with no additional hardware

Hypervisor Instructions and Guest Interrupts

  • HLV/HSV/HLVX explicit guest-memory access that always acts as though V=1 at hstatus.SPVP, overriding MPRV – including execute-for-read substitution in both stages
  • HFENCE.VVMA / HFENCE.GVMA TLB invalidation for the VS-stage and G-stage respectively, reusing SFENCE.VMA’s 4-case selective predicate – rs2 selects an ASID for VVMA, a single VMID for GVMA (see Tagged TLB)
  • Guest interrupt injection via hvip, real per-guest-file MSI delivery through two IMSIC guest files (GEILEN=2) selected by hstatus.VGEIN – each with its own physical MSI region, so migrating a guest between files never moves the device’s write target – and SGEIP/SGEIE pending/enable plumbing
  • VS-mode virtual timer: a real vstimecmp comparator (Sstc) OR’d with hvip.VSTIP, gated by the guest’s own henvcfg.STCE; accessing vstimecmp itself requires that gate stacked on top of HS-level’s menvcfg.STCE; htimedelta offsets the guest’s view of time

Disclosed Simplifications

Spec-legal, not silent:

  • htval/mtval2 always read 0 – software recovers the faulting address via stval (the guest virtual address) alone
  • G-stage checks R rather than X permission for a guest instruction fetch’s final address (the shared walker instance also serves the always-a-read PTE-fetch case); VS-stage’s own X check is unaffected and correctly enforced
  • A hypervisor must still set hvip.VSEIP=1 once per guest-file assignment: the guest file’s real delivery signal is not independently OR’d into hip.VSEIP (the pre-AIA software-injection path remains required)