diff options
Diffstat (limited to 'src/hypervisor.adoc')
| -rw-r--r-- | src/hypervisor.adoc | 2599 |
1 files changed, 2599 insertions, 0 deletions
diff --git a/src/hypervisor.adoc b/src/hypervisor.adoc new file mode 100644 index 0000000..493963e --- /dev/null +++ b/src/hypervisor.adoc @@ -0,0 +1,2599 @@ +[[hypervisor]] +== "H" Extension for Hypervisor Support, Version 1.0 + +This chapter describes the RISC-V hypervisor extension, which +virtualizes the supervisor-level architecture to support the efficient +hosting of guest operating systems atop a type-1 or type-2 hypervisor. +The hypervisor extension changes supervisor mode into +_hypervisor-extended supervisor mode_ (HS-mode, or _hypervisor mode_ for +short), where a hypervisor or a hosting-capable operating system runs. +The hypervisor extension also adds another stage of address translation, +from _guest physical addresses_ to supervisor physical addresses, to +virtualize the memory and memory-mapped I/O subsystems for a guest +operating system. HS-mode acts the same as S-mode, but with additional +instructions and CSRs that control the new stage of address translation +and support hosting a guest OS in virtual S-mode (VS-mode). Regular +S-mode operating systems can execute without modification either in +HS-mode or as VS-mode guests. + +In HS-mode, an OS or hypervisor interacts with the machine through the +same SBI as an OS normally does from S-mode. An HS-mode hypervisor is +expected to implement the SBI for its VS-mode guest. + +The hypervisor extension depends on an "I" base integer ISA with 32 +`x` registers (RV32I or RV64I), not RV32E or RV64E, which have only 16 `x` +registers. CSR `mtval` must not be read-only zero, and standard +page-based address translation must be supported, either Sv32 for RV32, +or a minimum of Sv39 for RV64. + +The hypervisor extension is enabled by setting bit 7 in the `misa` CSR, +which corresponds to the letter H. RISC-V harts that implement the +hypervisor extension are encouraged not to hardwire `misa`[7], so that +the extension may be disabled. + +[NOTE] +==== +The baseline privileged architecture is designed to simplify the use of +classic virtualization techniques, where a guest OS is run at +user-level, as the few privileged instructions can be easily detected +and trapped. The hypervisor extension improves virtualization +performance by reducing the frequency of these traps. + +The hypervisor extension has been designed to be efficiently emulable on +platforms that do not implement the extension, by running the hypervisor +in S-mode and trapping into M-mode for hypervisor CSR accesses and to +maintain shadow page tables. The majority of CSR accesses for type-2 +hypervisors are valid S-mode accesses so need not be trapped. +Hypervisors can support nested virtualization analogously. +==== + +=== Privilege Modes + +The current _virtualization mode_, denoted V, indicates whether the hart +is currently executing in a guest. When V=1, the hart is either in +virtual S-mode (VS-mode), or in virtual U-mode (VU-mode) atop a guest OS +running in VS-mode. When V=0, the hart is either in M-mode, in HS-mode, +or in U-mode atop an OS running in HS-mode. The virtualization mode also +indicates whether two-stage address translation is active (V=1) or +inactive (V=0). <<HPrivModes>> lists the +possible privilege modes of a RISC-V hart with the hypervisor extension. + +<<< + +[[HPrivModes]] +.Privilege modes with the hypervisor extension. +[float="center",align="center",cols="~,~,~,~,~"] +|=== +^|Virtualization + +Mode (V) ^|Nominal Privilege |Abbreviation |Name |Two-Stage Translation + +^|0 + +0 + +0 +^| U + +S + +M +|U-mode + +HS-mode + +M-mode +|User mode + +Hypervisor-extended supervisor mode + +Machine mode +|Off + +Off + +Off +^|1 + +1 +^|U + +S +|VU-mode + +VS-mode +|Virtual user mode + +Virtual supervisor mode +|On + +On +|=== + +For privilege modes U and VU, the _nominal privilege mode_ is U, and for +privilege modes HS and VS, the nominal privilege mode is S. + +HS-mode is more privileged than VS-mode, and VS-mode is more privileged +than VU-mode. VS-mode interrupts are globally disabled when executing in +U-mode. + +[NOTE] +==== +This description does not consider the possibility of U-mode or VU-mode +interrupts and will be revised if an extension for user-level interrupts +is adopted. +==== + +=== Hypervisor and Virtual Supervisor CSRs + +An OS or hypervisor running in HS-mode uses the supervisor CSRs to +interact with the exception, interrupt, and address-translation +subsystems. Additional CSRs are provided to HS-mode, but not to VS-mode, +to manage two-stage address translation and to control the behavior of a +VS-mode guest: `hstatus`, `hedeleg`, `hideleg`, `hvip`, `hip`, `hie`, +`hgeip`, `hgeie`, `henvcfg`, `henvcfgh`, `hcounteren`, `htimedelta`, +`htimedeltah`, `htval`, `htinst`, and `hgatp`. + +Furthermore, several _virtual supervisor_ CSRs (VS CSRs) are replicas of +the normal supervisor CSRs. For example, `vsstatus` is the VS CSR that +duplicates the usual `sstatus` CSR. + +When V=1, the VS CSRs substitute for the corresponding supervisor CSRs, +taking over all functions of the usual supervisor CSRs except as +specified otherwise. Instructions that normally read or modify a +supervisor CSR shall instead access the corresponding VS CSR. When V=1, +an attempt to read or write a VS CSR directly by its own separate CSR +address causes a virtual-instruction exception. (Attempts from U-mode +cause an illegal-instruction exception as usual.) The VS CSRs can be +accessed as themselves only from M-mode or HS-mode. + +While V=1, the normal HS-level supervisor CSRs that are replaced by VS +CSRs retain their values but do not affect the behavior of the machine +unless specifically documented to do so. Conversely, when V=0, the VS +CSRs do not ordinarily affect the behavior of the machine other than +being readable and writable by CSR instructions. + +Some standard supervisor CSRs (`senvcfg`, `scounteren`, and `scontext`, +possibly others) have no matching VS CSR. These supervisor CSRs continue +to have their usual function and accessibility even when V=1, except +with VS-mode and VU-mode substituting for HS-mode and U-mode. Hypervisor +software is expected to manually swap the contents of these registers as +needed. + +[NOTE] +==== +Matching VS CSRs exist only for the supervisor CSRs that must be +duplicated, which are mainly those that get automatically written by +traps or that impact instruction execution immediately after trap entry +and/or right before SRET, when software alone is unable to swap a CSR at +exactly the right moment. Currently, most supervisor CSRs fall into this +category, but future ones might not. +==== + +In this chapter, we use the term _HSXLEN_ to refer to the effective XLEN +when executing in HS-mode, and _VSXLEN_ to refer to the effective XLEN +when executing in VS-mode. + +[[sec:hstatus]] +==== Hypervisor Status (`hstatus`) Register + +The `hstatus` register is an HSXLEN-bit read/write register formatted as +shown in <<hstatusreg-rv32>> when HSXLEN=32 +and <<hstatusreg>> when HSXLEN=64. The `hstatus` +register provides facilities analogous to the `mstatus` register for +tracking and controlling the exception behavior of a VS-mode guest. + +[[hstatusreg-rv32]] +.Hypervisor status register (`hstatus`) when HSXLEN=32 +[wavedrom,, svg] +.... +{reg: [ + {bits: 5, name: 'WPRI'}, + {bits: 1, name: 'VSBE'}, + {bits: 1, name: 'GVA'}, + {bits: 1, name: 'SPV'}, + {bits: 1, name: 'SPVP'}, + {bits: 1, name: 'HU'}, + {bits: 2, name: 'WPRI'}, + {bits: 6, name: 'VGEIN'}, + {bits: 2, name: 'WPRI'}, + {bits: 1, name: 'VTVM'}, + {bits: 1, name: 'VTW'}, + {bits: 1, name: 'VTSR'}, + {bits: 9, name: 'WPRI'}, +], config:{lanes: 2, hspace:1024}} +.... + +[[hstatusreg]] +.Hypervisor status register (`hstatus`) when HSXLEN=64. +[wavedrom,, svg] +.... +{reg: [ + {bits: 5, name: 'WPRI'}, + {bits: 1, name: 'VSBE'}, + {bits: 1, name: 'GVA'}, + {bits: 1, name: 'SPV'}, + {bits: 1, name: 'SPVP'}, + {bits: 1, name: 'HU'}, + {bits: 2, name: 'WPRI'}, + {bits: 6, name: 'VGEIN'}, + {bits: 2, name: 'WPRI'}, + {bits: 1, name: 'VTVM'}, + {bits: 1, name: 'VTW'}, + {bits: 1, name: 'VTSR'}, + {bits: 9, name: 'WPRI'}, + {bits: 2, name: 'VSXL'}, + {bits: 14, name: 'WPRI'}, + {bits: 2, name: 'HUPMM'}, + {bits: 14, name: 'WPRI'}, +], config:{lanes: 4, hspace:1024}} +.... + +The VSXL field controls the effective XLEN for VS-mode (known as +VSXLEN), which may differ from the XLEN for HS-mode (HSXLEN). When +HSXLEN=32, the VSXL field does not exist, and VSXLEN=32. When HSXLEN=64, +VSXL is a *WARL* field that is encoded the same as the MXL field of `misa`, +shown in <<misabase>>. In particular, an +implementation may make VSXL be a read-only field whose value always +ensures that VSXLEN=HSXLEN. + +If HSXLEN is changed from 32 to a wider width, and if field VSXL is not +restricted to a single value, it gets the value corresponding to the +widest supported width not wider than the new HSXLEN. + +The `hstatus` fields VTSR, VTW, and VTVM are defined analogously to the +`mstatus` fields TSR, TW, and TVM, but affect execution only in VS-mode, +and cause virtual-instruction exceptions instead of illegal-instruction +exceptions. When VTSR=1, an attempt in VS-mode to execute SRET raises a +virtual-instruction exception. When VTW=1 (and assuming `mstatus`.TW=0), +an attempt in VS-mode to execute WFI raises a virtual-instruction +exception if the WFI does not complete within an +implementation-specific, bounded time limit. An implementation may have +WFI always raise a virtual-instruction exception in VS-mode when VTW=1 +(and `mstatus`.TW=0), even if there are pending globally-disabled +interrupts when the instruction is executed. When VTVM=1, an attempt in +VS-mode to execute SFENCE.VMA or SINVAL.VMA or to access CSR `satp` +raises a virtual-instruction exception. + +The VGEIN (Virtual Guest External Interrupt Number) field selects a +guest external interrupt source for VS-level external interrupts. VGEIN +is a *WLRL* field that must be able to hold values between zero and the +maximum guest external interrupt number (known as GEILEN), inclusive. +When VGEIN=0, no guest external interrupt source is selected for +VS-level external interrupts. GEILEN may be zero, in which case VGEIN +may be read-only zero. Guest external interrupts are explained in +<<hgeinterruptregs>>, and the use of VGEIN is covered +further in <<hinterruptregs>>. + +Field HU (Hypervisor in U-mode) controls whether the virtual-machine +load/store instructions, HLV, HLVX, and HSV, can be used also in U-mode. +When HU=1, these instructions can be executed in U-mode the same as in +HS-mode. When HU=0, all hypervisor instructions cause an +illegal-instruction exception in U-mode. + +[NOTE] +==== +The HU bit allows a portion of a hypervisor to be run in U-mode for +greater protection against software bugs, while still retaining access +to a virtual machine’s memory. +==== + +The SPV bit (Supervisor Previous Virtualization mode) is written by the +implementation whenever a trap is taken into HS-mode. Just as the SPP +bit in `sstatus` is set to the (nominal) privilege mode at the time of +the trap, the SPV bit in `hstatus` is set to the value of the +virtualization mode V at the time of the trap. When an SRET instruction +is executed when V=0, V is set to SPV. + +When V=1 and a trap is taken into HS-mode, bit SPVP (Supervisor Previous +Virtual Privilege) is set to the nominal privilege mode at the time of +the trap, the same as `sstatus`.SPP. But if V=0 before a trap, SPVP is +left unchanged on trap entry. SPVP controls the effective privilege of +explicit memory accesses made by the virtual-machine load/store +instructions, HLV, HLVX, and HSV. + +[NOTE] +==== +Without SPVP, if instructions HLV, HLVX, and HSV looked instead to +`sstatus`.SPP for the effective privilege of their memory accesses, +then, even with HU=1, U-mode could not access virtual machine memory at +VS-level, because to enter U-mode using SRET always leaves SPP=0. Unlike +SPP, field SPVP is untouched by transitions back-and-forth between +HS-mode and U-mode. +==== + +Field GVA (Guest Virtual Address) is written by the implementation +whenever a trap is taken into HS-mode. For any trap (breakpoint, address +misaligned, access fault, page fault, or guest-page fault) that writes a +guest virtual address to `stval`, GVA is set to 1. For any other trap +into HS-mode, GVA is set to 0. + +[NOTE] +==== +For breakpoint and memory access traps that write a nonzero value to +`stval`, GVA is redundant with field SPV (the two bits are set the same) +except when the explicit memory access of an HLV, HLVX, or HSV +instruction causes a fault. In that case, SPV=0 but GVA=1. +==== + +The VSBE bit is a *WARL* field that controls the endianness of explicit memory +accesses made from VS-mode. If VSBE=0, explicit load and store memory +accesses made from VS-mode are little-endian, and if VSBE=1, they are +big-endian. VSBE also controls the endianness of all implicit accesses +to VS-level memory management data structures, such as page tables. An +implementation may make VSBE a read-only field that always specifies the +same endianness as HS-mode. + +==== Hypervisor Trap Delegation (`hedeleg` and `hideleg`) Registers + +Register `hedeleg` is a 64-bit read/write register, formatted as shown in +<<hedelegreg>>. +Register `hideleg` is an HSXLEN-bit read/write register, formatted as shown in +<<hidelegreg>>. +By default, all traps at +any privilege level are handled in M-mode, though M-mode usually uses +the `medeleg` and `mideleg` CSRs to delegate some traps to HS-mode. The +`hedeleg` and `hideleg` CSRs allow these traps to be further delegated +to a VS-mode guest; their layout is the same as `medeleg` and `mideleg`. + +[[hedelegreg]] +.Hypervisor exception delegation register (`hedeleg`). +include::images/bytefield/hedelegreg.edn[] + +[[hidelegreg]] +.Hypervisor interrupt delegation register (`hideleg`). +include::images/bytefield/hidelegreg.edn[] + +A synchronous trap that has been delegated to HS-mode (using `medeleg`) +is further delegated to VS-mode if V=1 before the trap and the +corresponding `hedeleg` bit is set. Each bit of `hedeleg` shall be +either writable or read-only zero. Many bits of `hedeleg` are required +specifically to be writable or zero, as enumerated in +<<hedeleg-bits>>. Bit 0, corresponding to +instruction address-misaligned exceptions, must be writable if +IALIGN=32. + +[NOTE] +==== +Requiring that certain bits of `hedeleg` be writable reduces some of the +burden on a hypervisor to handle variations of implementation. +==== + +When XLEN=32, `hedelegh` is a 32-bit read/write register +that aliases bits 63:32 of `hedeleg`. +Register `hedelegh` does not exist when XLEN=64. + +An interrupt that has been delegated to HS-mode (using `mideleg`) is +further delegated to VS-mode if the corresponding `hideleg` bit is set. +Among bits 15:0 of `hideleg`, bits 10, 6, and 2 (corresponding to the +standard VS-level interrupts) are writable, and bits 12, 9, 5, and 1 +(corresponding to the standard S-level interrupts) are read-only zeros. + +When a virtual supervisor external interrupt (code 10) is delegated to +VS-mode, it is automatically translated by the machine into a supervisor +external interrupt (code 9) for VS-mode, including the value written to +`vscause` on an interrupt trap. Likewise, a virtual supervisor timer +interrupt (6) is translated into a supervisor timer interrupt (5) for +VS-mode, and a virtual supervisor software interrupt (2) is translated +into a supervisor software interrupt (1) for VS-mode. Similar +translations may or may not be done for platform interrupt +causes (codes 16 and above). + +[[hedeleg-bits]] +.Bits of `hedeleg` that must be writable or must be read-only zero. +[%autowidth,float="center",align="center",cols=">,<,<",options="header"] +|=== +|Bit |Attribute |Corresponding Exception +|0 + +1 + +2 + +3 + +4 + +5 + +6 + +7 + +8 + +9 + +10 + +11 + +12 + +13 + +15 + +16 + +18 + +19 + +20 + +21 + +22 + +23 +|(See text) + +Writable + +Writable + +Writable + +Writable + +Writable + +Writable + +Writable + +Writable + +Read-only 0 + +Read-only 0 + +Read-only 0 + +Writable + +Writable + +Writable + +Read-only 0 + +Writable + +Writable + +Read-only 0 + +Read-only 0 + +Read-only 0 + +Read-only 0 +|Instruction address misaligned + +Instruction access fault + +Illegal instruction + +Breakpoint + +Load address misaligned + +Load access fault + +Store/AMO address misaligned + +Store/AMO access fault + +Environment call from U-mode or VU-mode + +Environment call from HS-mode + +Environment call from VS-mode + +Environment call from M-mode + +Instruction page fault + +Load page fault + +Store/AMO page fault + +Double trap + +Software check + +Hardware error + +Instruction guest-page fault + +Load guest-page fault + +Virtual instruction + +Store/AMO guest-page fault +|=== + +[[hinterruptregs]] +==== Hypervisor Interrupt (`hvip`, `hip`, and `hie`) Registers + +Register `hvip` is an HSXLEN-bit read/write register that a hypervisor +can write to indicate virtual interrupts intended for VS-mode. Bits of +`hvip` that are not writable are read-only zeros. + +[[hvipreg]] +.Hypervisor virtual-interrupt-pending register(`hvip`). +include::images/bytefield/hvipreg.edn[] + +The standard portion (bits 15:0) of `hvip` is formatted as shown in +<<hvipreg-standard>>. Bits VSEIP, VSTIP, +and VSSIP of `hvip` are writable. Setting VSEIP=1 in `hvip` asserts a +VS-level external interrupt; setting VSTIP asserts a VS-level timer +interrupt; and setting VSSIP asserts a VS-level software interrupt. + +[[hvipreg-standard]] +.Standard portion (bits 15:0) of `hvip`. +include::images/bytefield/hvipreg-standard.edn[] + +Registers `hip` and `hie` are HSXLEN-bit read/write registers that +supplement HS-level’s `sip` and `sie` respectively. The `hip` register +indicates pending VS-level and hypervisor-specific interrupts, while +`hie` contains enable bits for the same interrupts. + +[[hipreg]] +.Hypervisor interrupt-pending register (`hip`). +include::images/bytefield/hipreg.edn[] + +[[hiereg]] +.Hypervisor interrupt-enable register (`hie`). +include::images/bytefield/hiereg.edn[] + +For each writable bit in `sie`, the corresponding bit shall be read-only +zero in both `hip` and `hie`. Hence, the nonzero bits in `sie` and `hie` +are always mutually exclusive, and likewise for `sip` and `hip`. + +[NOTE] +==== +The active bits of `hip` and `hie` cannot be placed in HS-level’s `sip` +and `sie` because doing so would make it impossible for software to +emulate the hypervisor extension on platforms that do not implement it +in hardware. +==== + +An interrupt _i_ will trap to HS-mode whenever all of the following are +true: (a) either the current operating mode is HS-mode and the SIE bit +in the `sstatus` register is set, or the current operating mode has less +privilege than HS-mode; (b) bit _i_ is set in both `sip` and `sie`, or +in both `hip` and `hie`; and (c) bit _i_ is not set in `hideleg`. + +If bit _i_ of `sie` is read-only zero, the same bit in register `hip` +may be writable or may be read-only. When bit _i_ in `hip` is writable, +a pending interrupt _i_ can be cleared by writing 0 to this bit. If +interrupt _i_ can become pending in `hip` but bit _i_ in `hip` is +read-only, then either the interrupt can be cleared by clearing bit _i_ +of `hvip`, or the implementation must provide some other mechanism for +clearing the pending interrupt (which may involve a call to the +execution environment). + +A bit in `hie` shall be writable if the corresponding interrupt can ever +become pending in `hip`. Bits of `hie` that are not writable shall be +read-only zero. + +The standard portions (bits 15:0) of registers `hip` and `hie` are +formatted as shown in <<hipreg-standard>> and <<hiereg-standard>> respectively. + +[[hipreg-standard]] +.Standard portion (bits 15:0) of `hip`. +include::images/bytefield/hipreg-standard.edn[] + +[[hiereg-standard]] +.Standard portion (bits 15:0) of `hie`. +include::images/bytefield/hiereg-standard.edn[] + + +Bits `hip`.SGEIP and `hie`.SGEIE are the interrupt-pending and +interrupt-enable bits for guest external interrupts at supervisor level +(HS-level). SGEIP is read-only in `hip`, and is 1 if and only if the +bitwise logical-AND of CSRs `hgeip` and `hgeie` is nonzero in any bit. +(See <<hgeinterruptregs>>.) + +Bits `hip`.VSEIP and `hie`.VSEIE are the interrupt-pending and +interrupt-enable bits for VS-level external interrupts. VSEIP is +read-only in `hip`, and is the logical-OR of these interrupt sources: + +* bit VSEIP of `hvip`; +* the bit of `hgeip` selected by `hstatus`.VGEIN; and +* any other platform-specific external interrupt signal directed to +VS-level. + +Bits `hip`.VSTIP and `hie`.VSTIE are the interrupt-pending and +interrupt-enable bits for VS-level timer interrupts. VSTIP is read-only +in `hip`, and is the logical-OR of `hvip`.VSTIP and any other +platform-specific timer interrupt signal directed to VS-level. + +Bits `hip`.VSSIP and `hie`.VSSIE are the interrupt-pending and +interrupt-enable bits for VS-level software interrupts. VSSIP in `hip` +is an alias (writable) of the same bit in `hvip`. + +Multiple simultaneous interrupts destined for HS-mode are handled in the +following decreasing priority order: SEI, SSI, STI, SGEI, VSEI, VSSI, +VSTI, LCOFI. + +[[hgeinterruptregs]] +==== Hypervisor Guest External Interrupt Registers (`hgeip` and `hgeie`) + +The `hgeip` register is an HSXLEN-bit read-only register, formatted as +shown in <<hgeipreg>>, that indicates pending guest +external interrupts for this hart. The `hgeie` register is an HSXLEN-bit +read/write register, formatted as shown in +<<hgeiereg>>, that contains enable bits for the +guest external interrupts at this hart. Guest external interrupt number +_i_ corresponds with bit _i_ in both `hgeip` and `hgeie`. + +[[hgeipreg]] +.Hypervisor guest external interrupt-pending register (`hgeip`). +include::images/bytefield/hgeipreg.edn[] + + +[[hgeiereg]] +.Hypervisor guest external interrupt-enable register (`hgeie`). +include::images/bytefield/hgeiereg.edn[] + +Guest external interrupts represent interrupts directed to individual +virtual machines at VS-level. If a RISC-V platform supports placing a +physical device under the direct control of a guest OS with minimal +hypervisor intervention (known as _pass-through_ or _direct assignment_ +between a virtual machine and the physical device), then, in such +circumstance, interrupts from the device are intended for a specific +virtual machine. Each bit of `hgeip` summarizes _all_ pending interrupts +directed to one virtual hart, as collected and reported by an interrupt +controller. To distinguish specific pending interrupts from multiple +devices, software must query the interrupt controller. + +[NOTE] +==== +Support for guest external interrupts requires an interrupt controller +that can collect virtual-machine-directed interrupts separately from +other interrupts. +==== + +The number of bits implemented in `hgeip` and `hgeie` for guest external +interrupts is UNSPECIFIED and may be zero. This number is known as _GEILEN_. The +least-significant bits are implemented first, apart from bit 0. Hence, +if GEILEN is nonzero, bits GEILEN:1 shall be writable in `hgeie`, and +all other bit positions shall be read-only zeros in both `hgeip` and +`hgeie`. + +[NOTE] +==== +The set of guest external interrupts received and handled at one +physical hart may differ from those received at other harts. Guest +external interrupt number _i_ at one physical hart is typically expected +not to be the same as guest external interrupt _i_ at any other hart. +For any one physical hart, the maximum number of virtual harts that may +directly receive guest external interrupts is limited by GEILEN. The +maximum this number can be for any implementation is 31 for RV32 and 63 +for RV64, per physical hart. + +A hypervisor is always free to _emulate_ devices for any number of +virtual harts without being limited by GEILEN. Only direct pass-through +(direct assignment) of interrupts is affected by the GEILEN limit, and +the limit is on the number of virtual harts receiving such interrupts, +not the number of distinct interrupts received. The number of distinct +interrupts a single virtual hart may receive is determined by the +interrupt controller. +==== + +Register `hgeie` selects the subset of guest external interrupts that +cause a supervisor-level (HS-level) guest external interrupt. The enable +bits in `hgeie` do not affect the VS-level external interrupt signal +selected from `hgeip` by `hstatus`.VGEIN. + +[[sec:henvcfg]] +==== Hypervisor Environment Configuration Register (`henvcfg`) + +The `henvcfg` CSR is a 64-bit read/write register, formatted +as shown in <<henvcfg>>, that controls +certain characteristics of the execution environment when virtualization +mode V=1. + +[[henvcfg]] +.Hypervisor environment configuration register (`henvcfg`). +[wavedrom, ,svg] +.... +{reg: [ + {bits: 1, name: 'FIOM'}, + {bits: 1, name: 'WPRI'}, + {bits: 1, name: 'LPE'}, + {bits: 1, name: 'SSE'}, + {bits: 2, name: 'CBIE'}, + {bits: 1, name: 'CBCFE'}, + {bits: 1, name: 'CBZE'}, + {bits: 24, name: 'WPRI'}, + {bits: 2, name: 'PMM'}, + {bits: 25, name: 'WPRI'}, + {bits: 1, name: 'DTE'}, + {bits: 1, name: 'WPRI'}, + {bits: 1, name: 'ADUE'}, + {bits: 1, name: 'PBMTE'}, + {bits: 1, name: 'STCE'}, +], config:{lanes: 4, hspace:1024}} +.... + +If bit FIOM (Fence of I/O implies Memory) is set to one in `henvcfg`, +FENCE instructions executed when V=1 are modified so the requirement to +order accesses to device I/O implies also the requirement to order main +memory accesses. <<henvcfg-FIOM>> details the modified +interpretation of FENCE instruction bits PI, PO, SI, and SO when FIOM=1 +and V=1. + +Similarly, when FIOM=1 and V=1, if an atomic instruction that accesses a +region ordered as device I/O has its _aq_ and/or _rl_ bit set, then that +instruction is ordered as though it accesses both device I/O and memory. + +[[henvcfg-FIOM]] +.Modified interpretation of FENCE predecessor and successor sets when FIOM=1 and virtualization mode V=1. +[%autowidth,float="center",align="center",cols="^,<",options="header"] +|=== +|Instruction bit |Meaning when set +|PI + +PO +|Predecessor device input and memory reads (PR implied) + +Predecessor device output and memory writes (PW implied) +|SI + +SO +|Successor device input and memory reads (SR implied) + +Successor device output and memory writes (SW implied) +|=== + +The PBMTE bit controls whether the Svpbmt extension is available for use +in VS-stage address translation. When PBMTE=1, Svpbmt is available for +VS-stage address translation. When PBMTE=0, the implementation behaves +as though Svpbmt were not implemented for VS-stage address translation. +If Svpbmt is not implemented, PBMTE is read-only zero. + +If the Svadu extension is implemented, the ADUE bit controls whether hardware +updating of PTE A/D bits is enabled for VS-stage address translation. +When ADUE=1, hardware updating of PTE A/D bits is enabled during VS-stage +address translation, and the implementation behaves as though the Svade +extension were not implemented for VS-mode address translation. +When ADUE=0, the implementation behaves as though Svade were implemented for +VS-stage address translation. +If Svadu is not implemented, ADUE is read-only zero. + +The definition of the STCE field is furnished by the Sstc extension. + +The definition of the CBZE field is furnished by the Zicboz extension. + +The definitions of the CBCFE and CBIE fields are furnished by the Zicbom extension. + +The definition of the PMM field is furnished by the Ssnpm extension. + +The Zicfilp extension adds the `LPE` field in `henvcfg`. When the `LPE` field +is set to 1, the Zicfilp extension is enabled in VS-mode. When the `LPE` field +is 0, the Zicfilp extension is not enabled in VS-mode and the following rules +apply to VS-mode: + +* The hart does not update the `ELP` state; it remains as `NO_LP_EXPECTED`. +* The `LPAD` instruction operates as a no-op. + +The Zicfiss extension adds the `SSE` field in `henvcfg`. If the `SSE` field is +set to 1, the Zicfiss extension is activated in VS-mode. When the `SSE` field is +0, the Zicfiss extension remains inactive in VS-mode, and the following rules +apply when `V=1`: + +* 32-bit Zicfiss instructions will revert to their behavior as defined by Zimop. +* 16-bit Zicfiss instructions will revert to their behavior as defined by Zcmop. +* The `pte.xwr=010b` encoding in VS-stage page tables becomes reserved. +* The `senvcfg.SSE` field will read as zero and is read-only. +* When `menvcfg.SSE` is one, `SSAMOSWAP.W/D` raises a virtual-instruction + exception. + +The Ssdbltrp extension adds the double-trap-enable (`DTE`) field in `henvcfg`. +When `henvcfg.DTE` is zero, the implementation behaves as though Ssdbltrp is not +implemented for VS-mode and the `vsstatus.SDT` bit is read-only zero. + +When XLEN=32, `henvcfgh` is a +32-bit read/write register that aliases bits 63:32 +of `henvcfg`. Register `henvcfgh` does not exist when +XLEN=64. + +==== Hypervisor Counter-Enable (`hcounteren`) Register + +The counter-enable register `hcounteren` is a 32-bit register that +controls the availability of the hardware performance monitoring +counters to the guest virtual machine. + +.Hypervisor counter-enable register (`hcounteren`). +include::images/bytefield/hcounterenreg.edn[] + +When the CY, TM, IR, or HPM__n__ bit in the `hcounteren` register is +clear, attempts to read the `cycle`, `time`, `instret`, or +`hpmcounter` _n_ register while V=1 will cause a virtual-instruction +exception if the same bit in `mcounteren` is 1. When one of these bits +is set, access to the corresponding register is permitted when V=1, +unless prevented for some other reason. In VU-mode, a counter is not +readable unless the applicable bits are set in both `hcounteren` and +`scounteren`. + +`hcounteren` must be implemented. However, any of the bits may be +read-only zero, indicating reads to the corresponding counter will cause +an exception when V=1. Hence, they are effectively *WARL* fields. + +==== Hypervisor Time Delta (`htimedelta`) Register + +The `htimedelta` CSR is a 64-bit read/write register that contains the delta +between the value of the `time` CSR and the value returned in VS-mode or +VU-mode. That is, reading the `time` CSR in VS or VU mode returns the +sum of the contents of `htimedelta` and the actual value of `time`. + +[NOTE] +==== +Because overflow is ignored when summing `htimedelta` and `time`, large +values of `htimedelta` may be used to represent negative time offsets. +==== + +.Hypervisor time delta register. +include::images/bytefield/htimedelta.edn[] + +When XLEN=32, `htimedeltah` is a 32-bit read/write register +that aliases bits 63:32 of `htimedelta`. +Register `htimedeltah` does not exist when XLEN=64. + +If the `time` CSR is implemented, `htimedelta` (and `htimedeltah` for XLEN=32) +must be implemented. + +==== Hypervisor Trap Value (`htval`) Register + +The `htval` register is an HSXLEN-bit read/write register formatted as +shown in <<htvalreg>>. When a trap is taken into +HS-mode, `htval` is written with additional exception-specific +information, alongside `stval`, to assist software in handling the trap. + +[[htvalreg]] +.Hypervisor trap value register (`htval`). +include::images/bytefield/htvalreg.edn[] + +When a guest-page-fault trap is taken into HS-mode, `htval` is written +with either zero or the guest physical address that faulted, shifted +right by 2 bits. For other traps, `htval` is set to zero, but a future +standard or extension may redefine `htval's` setting for other traps. + +A guest-page fault may arise due to an implicit memory access during +first-stage (VS-stage) address translation, in which case a guest +physical address written to `htval` is that of the implicit memory +access that faulted—for example, the address of a VS-level page table +entry that could not be read. (The guest physical address corresponding +to the original virtual address is unknown when VS-stage translation +fails to complete.) Additional information is provided in CSR `htinst` +to disambiguate such situations. + +Otherwise, for misaligned loads and stores that cause guest-page faults, +a nonzero guest physical address in `htval` corresponds to the faulting +portion of the access as indicated by the virtual address in `stval`. +For instruction guest-page faults on systems with variable-length +instructions, a nonzero `htval` corresponds to the faulting portion of +the instruction as indicated by the virtual address in `stval`. + +[NOTE] +==== +A guest physical address written to `htval` is shifted right by 2 bits +to accommodate addresses wider than the current XLEN. For RV32, the +hypervisor extension permits guest physical addresses as wide as 34 +bits, and `htval` reports bits 33:2 of the address. This shift-by-2 +encoding of guest physical addresses matches the encoding of physical +addresses in PMP address registers (<<pmp>>) and in +page table entries (<<sv32>>, <<sv39>>, <<sv48>>, and <<sv57>>). + +If the least-significant two bits of a faulting guest physical address +are needed, these bits are ordinarily the same as the least-significant +two bits of the faulting virtual address in `stval`. For faults due to +implicit memory accesses for VS-stage address translation, the +least-significant two bits are instead zeros. These cases can be +distinguished using the value provided in register `htinst`. +==== + +`htval` is a *WARL* register that must be able to hold zero and may be capable +of holding only an arbitrary subset of other 2-bit-shifted guest +physical addresses, if any. + +[NOTE] +==== +Unless it has reason to assume otherwise (such as a platform standard), +software that writes a value to `htval` should read back from `htval` to +confirm the stored value. +==== + +==== Hypervisor Trap Instruction (`htinst`) Register + +The `htinst` register is an HSXLEN-bit read/write register formatted as +shown in <<htinstreg>>. When a trap is taken into +HS-mode, `htinst` is written with a value that, if nonzero, provides +information about the instruction that trapped, to assist software in +handling the trap. The values that may be written to `htinst` on a trap +are documented in <<tinst-vals>>. + +[[htinstreg]] +.Hypervisor trap instruction (`htinst`) register. +include::images/bytefield/htinstreg.edn[] + +`htinst` is a *WARL* register that need only be able to hold the values that +the implementation may automatically write to it on a trap. + +[[hgatp]] +==== Hypervisor Guest Address Translation and Protection (`hgatp`) Register + +The `hgatp` register is an HSXLEN-bit read/write register, formatted as +shown in <<rv32hgatp>> for HSXLEN=32 and +<<rv64hgatp>> for HSXLEN=64, which controls +G-stage address translation and protection, the second stage of +two-stage translation for guest virtual addresses (see +<<two-stage-translation>>). Similar to CSR `satp`, this +register holds the physical page number (PPN) of the guest-physical root +page table; a virtual machine identifier (VMID), which facilitates +address-translation fences on a per-virtual-machine basis; and the MODE +field, which selects the address-translation scheme for guest physical +addresses. When `mstatus`.TVM=1, attempts to read or write `hgatp` while +executing in HS-mode will raise an illegal-instruction exception. + +[[rv32hgatp]] +.Hypervisor guest address translation and protection register `hgatp` when HSXLEN=32. +include::images/bytefield/rv32hgatp.edn[] + +[[rv64hgatp]] +.Hypervisor guest address translation and protection register `hgatp` when HSXLEN=64 for MODE values Bare, Sv39x4, Sv48x4, and Sv57x4. +include::images/bytefield/rv64hgatp.edn[] + +<<hgatp-mode>> shows the encodings of the MODE field when +HSXLEN=32 and HSXLEN=64. When MODE=Bare, guest physical addresses are +equal to supervisor physical addresses, and there is no further memory +protection for a guest virtual machine beyond the physical memory +protection scheme described in <<pmp>>. In this +case, software must write zero to the remaining fields in `hgatp`. +Attempting to select MODE=Bare with a nonzero pattern in the remaining fields +has an UNSPECIFIED effect on the value that the remaining fields assume and an +UNSPECIFIED effect on G-stage address translation and protection behavior. + +When HSXLEN=32, the only other valid setting for MODE is Sv32x4, which +is a modification of the usual Sv32 paged virtual-memory scheme, +extended to support 34-bit guest physical addresses. When HSXLEN=64, +modes Sv39x4, Sv48x4, and Sv57x4 are defined as modifications of the +Sv39, Sv48, and Sv57 paged virtual-memory schemes. All of these paged +virtual-memory schemes are described in +<<guest-addr-translation>>. + +The remaining MODE settings when HSXLEN=64 are reserved for future use +and may define different interpretations of the other fields in `hgatp`. + +[[hgatp-mode]] +.Encoding of `hgatp` MODE field. +[%autowidth,float="center",align="center",cols="^,^,<",options="header"] +|=== +3+|HSXLEN=32 +|Value |Name |Description +|0 + +1 +|Bare + +Sv32x4 +|No translation or protection. + +Page-based 34-bit virtual addressing (2-bit extension of +Sv32). +3+s|HSXLEN=64 +|Value |Name |Description +|0 + +1-7 + +8 + +9 + +10 + +11-15 +|Bare + +— + +Sv39x4 + +Sv48x4 + +Sv57x4 + +— +|No translation or protection. + +_Reserved_ + +Page-based 41-bit virtual addressing (2-bit extension of +Sv39). + +Page-based 50-bit virtual addressing (2-bit extension of +Sv48). + +Page-based 59-bit virtual addressing (2-bit extension of +Sv57). + +_Reserved_ +|=== + +Implementations are not required to support all defined MODE settings +when HSXLEN=64. + +A write to `hgatp` with an unsupported MODE value is not ignored as it +is for `satp`. Instead, the fields of `hgatp` are *WARL* in the normal way, +when so indicated. + +As explained in <<guest-addr-translation>>, for the +paged virtual-memory schemes (Sv32x4, Sv39x4, Sv48x4, and Sv57x4), the +root page table is 16 KiB and must be aligned to a 16-KiB boundary. In +these modes, the lowest two bits of the physical page number (PPN) in +`hgatp` always read as zeros. An implementation that supports only the +defined paged virtual-memory schemes and/or Bare may make PPN[1:0] +read-only zero. + +The number of VMID bits is UNSPECIFIED and may be zero. The number of implemented +VMID bits, termed _VMIDLEN_, may be determined by writing one to every +bit position in the VMID field, then reading back the value in `hgatp` +to see which bit positions in the VMID field hold a one. The +least-significant bits of VMID are implemented first: that is, if +VMIDLEN > 0, VMID[VMIDLEN-1:0] is writable. The maximal +value of VMIDLEN, termed VMIDMAX, is 7 for Sv32x4 or 14 for Sv39x4, +Sv48x4, and Sv57x4. + +The `hgatp` register is considered _active_ for the purposes of the +address-translation algorithm _unless_ the effective privilege mode is U +and `hstatus`.HU=0. + +[NOTE] +==== +This definition simplifies the implementation of speculative execution +of HLV, HLVX, and HSV instructions. +==== + +Note that writing `hgatp` does not imply any ordering constraints +between page-table updates and subsequent G-stage address translations. +If the new virtual machine’s guest physical page tables have been +modified, or if a VMID is reused, it may be necessary to execute an +HFENCE.GVMA instruction (see <<hfence.vma>>) before or +after writing `hgatp`. + +[[vsstatus]] +==== Virtual Supervisor Status (`vsstatus`) Register + +The `vsstatus` register is a VSXLEN-bit read/write register that is +VS-mode’s version of supervisor register `sstatus`, formatted as shown +in <<vsstatusreg-rv32>> when VSXLEN=32 and +<<vsstatusreg>> when VSXLEN=64. When V=1, +`vsstatus` substitutes for the usual `sstatus`, so instructions that +normally read or modify `sstatus` actually access `vsstatus` instead. + +[[vsstatusreg-rv32]] +.Virtual supervisor status (`vsstatus`) register when VSXLEN=32. +[wavedrom, ,svg] +.... +{reg: [ + {bits: 1, name: 'WPRI'}, + {bits: 1, name: 'SIE'}, + {bits: 3, name: 'WPRI'}, + {bits: 1, name: 'SPIE'}, + {bits: 1, name: 'UBE'}, + {bits: 1, name: 'WPRI'}, + {bits: 1, name: 'SPP'}, + {bits: 2, name: 'VS[1:0]'}, + {bits: 2, name: 'WPRI'}, + {bits: 2, name: 'FS[1:0]'}, + {bits: 2, name: 'XS[1:0]'}, + {bits: 1, name: 'WPRI'}, + {bits: 1, name: 'SUM'}, + {bits: 1, name: 'MXR'}, + {bits: 3, name: 'WPRI'}, + {bits: 1, name: 'SPELP'}, + {bits: 1, name: 'SDT'}, + {bits: 6, name: 'WPRI'}, + {bits: 1, name: 'SD'}, +], config:{lanes: 2, hspace:1024}} +.... + +[[vsstatusreg]] +.Virtual supervisor status (`vsstatus`) register when VSXLEN=64. +[wavedrom, ,svg] +.... +{reg: [ + {bits: 1, name: 'WPRI'}, + {bits: 1, name: 'SIE'}, + {bits: 3, name: 'WPRI'}, + {bits: 1, name: 'SPIE'}, + {bits: 1, name: 'UBE'}, + {bits: 1, name: 'WPRI'}, + {bits: 1, name: 'SPP'}, + {bits: 2, name: 'VS[1:0]'}, + {bits: 2, name: 'WPRI'}, + {bits: 2, name: 'FS[1:0]'}, + {bits: 2, name: 'XS[1:0]'}, + {bits: 1, name: 'WPRI'}, + {bits: 1, name: 'SUM'}, + {bits: 1, name: 'MXR'}, + {bits: 3, name: 'WPRI'}, + {bits: 1, name: 'SPELP'}, + {bits: 1, name: 'SDT'}, + {bits: 7, name: 'WPRI'}, + {bits: 2, name: 'UXL[1:0]'}, + {bits: 29, name: 'WPRI'}, + {bits: 1, name: 'SD'}, +], config:{lanes: 4, hspace:1024}} +.... + +The UXL field controls the effective XLEN for VU-mode, which may differ +from the XLEN for VS-mode (VSXLEN). When VSXLEN=32, the UXL field does +not exist, and VU-mode XLEN=32. When VSXLEN=64, UXL is a *WARL* field that is +encoded the same as the MXL field of `misa`, shown in <<misabase>>. In particular, an implementation may make UXL be a read-only copy of field VSXL of `hstatus`, forcing VU-mode XLEN=VSXLEN. + +If VSXLEN is changed from 32 to a wider width, and if field UXL is not +restricted to a single value, it gets the value corresponding to the +widest supported width not wider than the new VSXLEN. + +When V=1, both `vsstatus`.FS and the HS-level `sstatus`.FS are in +effect. Attempts to execute a floating-point instruction when either +field is 0 (Off) raise an illegal-instruction exception. Modifying the +floating-point state when V=1 causes both fields to be set to 3 (Dirty). + +[NOTE] +==== +For a hypervisor to benefit from the extension context status, it must +have its own copy in the HS-level `sstatus`, maintained independently of +a guest OS running in VS-mode. While a version of the extension context +status obviously must exist in `vsstatus` for VS-mode, a hypervisor +cannot rely on this version being maintained correctly, given that +VS-level software can change `vsstatus`.FS arbitrarily. If the HS-level +`sstatus`.FS were not independently active and maintained by the +hardware in parallel with `vsstatus`.FS while V=1, hypervisors would +always be forced to conservatively swap all floating-point state when +context-switching between virtual machines. +==== + +Similarly, when V=1, both `vsstatus`.VS and the HS-level `sstatus`.VS +are in effect. Attempts to execute a vector instruction when either +field is 0 (Off) raise an illegal-instruction exception. Modifying the +vector state when V=1 causes both fields to be set to 3 (Dirty). + +Read-only fields SD and XS summarize the extension context status as it +is visible to VS-mode only. For example, the value of the HS-level +`sstatus`.FS does not affect `vsstatus`.SD. + +An implementation may make field UBE be a read-only copy of +`hstatus`.VSBE. + +When V=0, `vsstatus` does not directly affect the behavior of the +machine, unless a virtual-machine load/store (HLV, HLVX, or HSV) or the +MPRV feature in the `mstatus` register is used to execute a load or +store _as though_ V=1. + +The Zicfilp extension adds the `SPELP` field that holds the previous `ELP`, and +is updated as specified in <<ZICFILP_FORWARD_TRAPS>>. The `SPELP` field is +encoded as follows: + +* 0 - `NO_LP_EXPECTED` - no landing pad instruction expected. +* 1 - `LP_EXPECTED` - a landing pad instruction is expected. + +The Ssdbltrp adds an S-mode-disable-trap (`SDT`) field extension to address +double trap (See <<supv-double-trap>>) in VS-mode. + +==== Virtual Supervisor Interrupt (`vsip` and `vsie`) Registers + +The `vsip` and `vsie` registers are VSXLEN-bit read/write registers that +are VS-mode’s versions of supervisor CSRs `sip` and `sie`, formatted as +shown in <<vsipreg>> and <<vsiereg>> +respectively. When V=1, `vsip` and `vsie` substitute for the usual `sip` +and `sie`, so instructions that normally read or modify `sip`/`sie` +actually access `vsip`/`vsie` instead. However, interrupts directed to +HS-level continue to be indicated in the HS-level `sip` register, not in +`vsip`, when V=1. + +[[vsipreg]] +.Virtual supervisor interrupt-pending register (`vsip`). +include::images/bytefield/vsipreg.edn[] + +[[vsiereg]] +.Virtual supervisor interrupt-enable register (`vsie`). +include::images/bytefield/vsiereg.edn[] + +The standard portions (bits 15:0) of registers `vsip` and `vsie` are +formatted as shown in <<vsipreg-standard>> +and <<vsiereg-standard>> respectively. + +[[vsipreg-standard]] +.Standard portion (bits 15:0) of `vsip`. +include::images/bytefield/vsipreg-standard.edn[] + +[[vsiereg-standard]] +.Standard portion (bits 15:0) of `vsie`. +include::images/bytefield/vsiereg-standard.edn[] + +Extension Shlcofideleg supports delegating LCOFI interrupts to VS-mode. +If the Shlcofideleg extension is implemented, `hideleg` bit 13 is +writable; otherwise, it is read-only zero. +When bit 13 of `hideleg` is zero, `vsip`.LCOFIP and `vsie`.LCOFIE +are read-only zeros. +Else, `vsip`.LCOFIP and `vsie`.LCOFIE are aliases of `sip`.LCOFIP +and `sie`.LCOFIE. + +When bit 10 of `hideleg` is zero, `vsip`.SEIP and `vsie`.SEIE are +read-only zeros. Else, `vsip`.SEIP and `vsie`.SEIE are aliases of +`hip`.VSEIP and `hie`.VSEIE. + +When bit 6 of `hideleg` is zero, `vsip`.STIP and `vsie`.STIE are +read-only zeros. Else, `vsip`.STIP and `vsie`.STIE are aliases of +`hip`.VSTIP and `hie`.VSTIE. + +When bit 2 of `hideleg` is zero, `vsip`.SSIP and `vsie`.SSIE are +read-only zeros. Else, `vsip`.SSIP and `vsie`.SSIE are aliases of +`hip`.VSSIP and `hie`.VSSIE. + +==== Virtual Supervisor Trap Vector Base Address (`vstvec`) Register + +The `vstvec` register is a VSXLEN-bit read/write register that is +VS-mode’s version of supervisor register `stvec`, formatted as shown in +<<vstvecreg>>. When V=1, `vstvec` substitutes for +the usual `stvec`, so instructions that normally read or modify `stvec` +actually access `vstvec` instead. When V=0, `vstvec` does not directly +affect the behavior of the machine. + +[[vstvecreg]] +.Virtual supervisor trap vector base address register `vstvec`. +include::images/bytefield/vstvecreg.edn[] + +==== Virtual Supervisor Scratch (`vsscratch`) Register + +The `vsscratch` register is a VSXLEN-bit read/write register that is +VS-mode’s version of supervisor register `sscratch`, formatted as shown +in <<vsscratchreg>>. When V=1, `vsscratch` +substitutes for the usual `sscratch`, so instructions that normally read +or modify `sscratch` actually access `vsscratch` instead. The contents +of `vsscratch` never directly affect the behavior of the machine. + +[[vsscratchreg]] +.Virtual supervisor scratch register `vsscratch`. +include::images/bytefield/vsscratchreg.edn[] + +==== Virtual Supervisor Exception Program Counter (`vsepc`) Register + +The `vsepc` register is a VSXLEN-bit read/write register that is +VS-mode’s version of supervisor register `sepc`, formatted as shown in +<<vsepcreg>>. When V=1, `vsepc` substitutes for the +usual `sepc`, so instructions that normally read or modify `sepc` +actually access `vsepc` instead. When V=0, `vsepc` does not directly +affect the behavior of the machine. + +`vsepc` is a *WARL* register that must be able to hold the same set of values +that `sepc` can hold. + +[[vsepcreg]] +.Virtual supervisor exception program counter (`vsepc`). +include::images/bytefield/vsepcreg.edn[] + +==== Virtual Supervisor Cause (`vscause`) Register + +The `vscause` register is a VSXLEN-bit read/write register that is +VS-mode’s version of supervisor register `scause`, formatted as shown in +<<vscausereg>>. When V=1, `vscause` substitutes +for the usual `scause`, so instructions that normally read or modify +`scause` actually access `vscause` instead. When V=0, `vscause` does not +directly affect the behavior of the machine. + +`vscause` is a *WLRL* register that must be able to hold the same set of +values that `scause` can hold. + +[[vscausereg]] +.Virtual supervisor cause register (`vscause`). +include::images/bytefield/vscausereg.edn[] + +==== Virtual Supervisor Trap Value (`vstval`) Register + +The `vstval` register is a VSXLEN-bit read/write register that is +VS-mode’s version of supervisor register `stval`, formatted as shown in +<<vstvalreg>>. When V=1, `vstval` substitutes for +the usual `stval`, so instructions that normally read or modify `stval` +actually access `vstval` instead. When V=0, `vstval` does not directly +affect the behavior of the machine. + +`vstval` is a *WARL* register that must be able to hold the same set of values +that `stval` can hold. + +[[vstvalreg]] +.Virtual supervisor trap value register (`vstval`). +include::images/bytefield/vstvalreg.edn[] + +==== Virtual Supervisor Address Translation and Protection (`vsatp`) Register + +The `vsatp` register is a VSXLEN-bit read/write register that is +VS-mode’s version of supervisor register `satp`, formatted as shown in +<<rv32vsatpreg>> for VSXLEN=32 and <<rv64vsatpreg>> for VSXLEN=64. When V=1, +`vsatp` substitutes for the usual `satp`, so instructions that normally +read or modify `satp` actually access `vsatp` instead. `vsatp` controls +VS-stage address translation, the first stage of two-stage translation +for guest virtual addresses (see +<<two-stage-translation>>). + +[[rv32vsatpreg]] +.Virtual supervisor address translation and protection `vsatp` register when VSXLEN=32. +include::images/bytefield/rv32vsatpreg.edn[] + +[[rv64vsatpreg]] +.Virtual supervisor address translation and protection `vsatp` register when VSXLEN=64. +include::images/bytefield/rv64vsatpreg.edn[] + +The `vsatp` register is considered _active_ for the purposes of the +address-translation algorithm _unless_ the effective privilege mode is U +and `hstatus`.HU=0. However, even when `vsatp` is active, VS-stage +page-table entries’ A bits must not be set as a result of speculative +execution, unless the effective privilege mode is VS or VU. + +[NOTE] +==== +In particular, virtual-machine load/store (HLV, HLVX, or HSV) +instructions that are mispredicted must not cause VS-stage +A bits to be set. +==== + +When V=0, a write to `vsatp` with an unsupported MODE value is either +ignored as it is for `satp`, or the fields of `vsatp` are treated as *WARL* in +the normal way. However, when V=1, a write to `satp` with an unsupported +MODE value _is_ ignored and no write to `vsatp` is effected. + +When V=0, `vsatp` does not directly affect the behavior of the machine, +unless a virtual-machine load/store (HLV, HLVX, or HSV) or the MPRV +feature in the `mstatus` register is used to execute a load or store _as +though_ V=1. + +=== Hypervisor Instructions + +The hypervisor extension adds virtual-machine load and store +instructions and two privileged fence instructions. + +==== Hypervisor Virtual-Machine Load and Store Instructions + +include::images/wavedrom/hypv-virt-load-and-store.edn[] + +The hypervisor virtual-machine load and store instructions are valid +only in M-mode or HS-mode, or in U-mode when `hstatus`.HU=1. Each +instruction performs an explicit memory access with an effective privilege mode +of VS or VU. The effective privilege mode of the explicit memory access is VU +when `hstatus`.SPVP=0, and VS when `hstatus`.SPVP=1. As usual for VS-mode and +VU-mode, two-stage address translation is applied, and +the HS-level `sstatus`.SUM is ignored. HS-level `sstatus`.MXR makes +execute-only pages readable by explicit loads for both stages of address translation +(VS-stage and G-stage), whereas `vsstatus`.MXR affects only the first +translation stage (VS-stage). + +For every RV32I or RV64I load instruction, LB, LBU, LH, LHU, LW, LWU, +and LD, there is a corresponding virtual-machine load instruction: +HLV.B, HLV.BU, HLV.H, HLV.HU, HLV.W, HLV.WU, and HLV.D. For every RV32I +or RV64I store instruction, SB, SH, SW, and SD, there is a corresponding +virtual-machine store instruction: HSV.B, HSV.H, HSV.W, and HSV.D. +Instructions HLV.WU, HLV.D, and HSV.D are not valid for RV32, of course. + +Instructions HLVX.HU and HLVX.WU are the same as HLV.HU and HLV.WU, +except that _execute_ permission takes the place of _read_ permission +during address translation. That is, the memory being read must be +executable in both stages of address translation, but read permission is +not required. For the supervisor physical address that results from +address translation, the supervisor physical memory attributes must +grant both _execute_ and _read_ permissions. (The _supervisor physical +memory attributes_ are the machine’s physical memory attributes as +modified by physical memory protection, <<pmp>>, for +supervisor level.) + +[NOTE] +==== +HLVX cannot override machine-level physical memory protection (PMP), so +attempting to read memory that PMP designates as execute-only still +results in an access-fault exception. + +Although HLVX instructions’ explicit memory accesses require execute +permissions, they still raise the same exceptions as other load +instructions, rather than raising fetch exceptions instead. +==== + +HLVX.WU is valid for RV32, even though LWU and HLV.WU are not. (For +RV32, HLVX.WU can be considered a variant of HLV.W, as sign extension is +irrelevant for 32-bit values.) + +Attempts to execute a virtual-machine load/store instruction (HLV, HLVX, +or HSV) when V=1 cause a virtual-instruction exception. Attempts to execute +one of these same instructions from U-mode when `hstatus`.HU=0 cause an +illegal-instruction exception. + +[[hfence.vma]] +==== Hypervisor Memory-Management Fence Instructions + +include::images/wavedrom/hypv-mm-fence.edn[] + +The hypervisor memory-management fence instructions, HFENCE.VVMA and +HFENCE.GVMA, perform a function similar to SFENCE.VMA +(<<sfence.vma>>), except applying to the +VS-level memory-management data structures controlled by CSR `vsatp` +(HFENCE.VVMA) or the guest-physical memory-management data structures +controlled by CSR `hgatp` (HFENCE.GVMA). Instruction SFENCE.VMA applies +only to the memory-management data structures controlled by the current +`satp` (either the HS-level `satp` when V=0 or `vsatp` when V=1). + +HFENCE.VVMA is valid only in M-mode or HS-mode. Its effect is much the +same as temporarily entering VS-mode and executing SFENCE.VMA. Executing +an HFENCE.VVMA guarantees that any previous stores already visible to +the current hart are ordered before all implicit reads by that hart done +for VS-stage address translation for instructions that + +* are subsequent to the HFENCE.VVMA, and +* execute when `hgatp`.VMID has the same setting as it did when +HFENCE.VVMA executed. + +Implicit reads need not be ordered when `hgatp`.VMID is different than +at the time HFENCE.VVMA executed. If operand __rs1__≠`x0`, it specifies a single guest virtual address, and if operand __rs2__≠`x0`, it specifies a single guest address-space identifier (ASID). + +[NOTE] +==== +An HFENCE.VVMA instruction applies only to a single virtual machine, +identified by the setting of `hgatp`.VMID when HFENCE.VVMA executes. +==== + +When __rs2__≠`x0`, bits XLEN-1:ASIDMAX of the value held +in _rs2_ are reserved for future standard use. Until their use is +defined by a standard extension, they should be zeroed by software and +ignored by current implementations. Furthermore, if +ASIDLEN < ASIDMAX, the implementation shall ignore bits +ASIDMAX-1:ASIDLEN of the value held in _rs2_. + +[NOTE] +==== +Simpler implementations of HFENCE.VVMA can ignore the guest virtual +address in _rs1_ and the guest ASID value in _rs2_, as well as +`hgatp`.VMID, and always perform a global fence for the VS-level memory +management of all virtual machines, or even a global fence for all +memory-management data structures. +==== + +Neither `mstatus`.TVM nor `hstatus`.VTVM causes HFENCE.VVMA to trap. + +HFENCE.GVMA is valid only in HS-mode when `mstatus`.TVM=0, or in M-mode +(irrespective of `mstatus`.TVM). Executing an HFENCE.GVMA instruction +guarantees that any previous stores already visible to the current hart +are ordered before all implicit reads by that hart done for G-stage +address translation for instructions that follow the HFENCE.GVMA. If +operand __rs1__≠`x0`, it specifies a single guest +physical address, shifted right by 2 bits, and if operand +__rs2__≠`x0`, it specifies a single virtual machine +identifier (VMID). + +[NOTE] +==== +Conceptually, an implementation might contain two address-translation +caches: one that maps guest virtual addresses to guest physical +addresses, and another that maps guest physical addresses to supervisor +physical addresses. HFENCE.GVMA need not flush the former cache, but it +must flush entries from the latter cache that match the HFENCE.GVMA’s +address and VMID arguments. + +More commonly, implementations contain address-translation caches that +map guest virtual addresses directly to supervisor physical addresses, +removing a level of indirection. For such implementations, any entry +whose guest virtual address maps to a guest physical address that +matches the HFENCE.GVMA’s address and VMID arguments must be flushed. +Selectively flushing entries in this fashion requires tagging them with +the guest physical address, which is costly, and so a common technique +is to flush all entries that match the HFENCE.GVMA’s VMID argument, +regardless of the address argument. + +*** + +Like for a guest physical address written to `htval` on a trap, a guest +physical address specified in _rs1_ is shifted right by 2 bits to +accommodate addresses wider than the current XLEN. +==== + +When __rs2__≠`x0`, bits XLEN-1:VMIDMAX of the value held +in _rs2_ are reserved for future standard use. Until their use is +defined by a standard extension, they should be zeroed by software and +ignored by current implementations. Furthermore, if +VMIDLEN < VMIDMAX, the implementation shall ignore bits +VMIDMAX-1:VMIDLEN of the value held in _rs2_. + +[NOTE] +==== +Simpler implementations of HFENCE.GVMA can ignore the guest physical +address in _rs1_ and the VMID value in _rs2_ and always perform a global +fence for the guest-physical memory management of all virtual machines, +or even a global fence for all memory-management data structures. +==== + +If `hgatp`.MODE is changed for a given VMID, an HFENCE.GVMA with +_rs1_=`x0` (and _rs2_ set to either `x0` or the VMID) must be executed +to order subsequent guest translations with the MODE change—even if the +old MODE or new MODE is Bare. + +Attempts to execute HFENCE.VVMA or HFENCE.GVMA when V=1 cause a +virtual-instruction exception, while attempts to do the same in U-mode cause an +illegal-instruction exception. Attempting to execute HFENCE.GVMA in HS-mode +when `mstatus`.TVM=1 also causes an illegal-instruction exception. + +=== Machine-Level CSRs + +The hypervisor extension augments or modifies machine CSRs `mstatus`, +`mstatush`, `mideleg`, `mip`, and `mie`, and adds CSRs `mtval2` and +`mtinst`. + +==== Machine Status (`mstatus` and `mstatush`) Registers + +The hypervisor extension adds two fields, MPV and GVA, to the +machine-level `mstatus` or `mstatush` CSR, and modifies the behavior of +several existing `mstatus` fields. +<<hypervisor-mstatus>> shows the modified +`mstatus` register when the hypervisor extension is implemented and +MXLEN=64. When MXLEN=32, the hypervisor extension adds MPV and GVA not +to `mstatus` but to `mstatush`. +<<hypervisor-mstatush>> shows the +`mstatush` register when the hypervisor extension is implemented and +MXLEN=32. + +[[hypervisor-mstatus]] +.Machine status (`mstatus`) register for RV64 when the hypervisor extension is implemented. +include::images/bytefield/hypv-mstatus.edn[] + +[[hypervisor-mstatush]] +.Additional machine status (`mstatush`) register for RV32 when the hypervisor extension is implemented. The format of `mstatus` is unchanged for RV32. +include::images/bytefield/hypv-mstatush.edn[] + +The MPV bit (Machine Previous Virtualization Mode) is written by the +implementation whenever a trap is taken into M-mode. Just as the MPP +field is set to the (nominal) privilege mode at the time of the trap, +the MPV bit is set to the value of the virtualization mode V at the time +of the trap. When an MRET instruction is executed, the virtualization +mode V is set to MPV, unless MPP=3, in which case V remains 0. + +Field GVA (Guest Virtual Address) is written by the implementation +whenever a trap is taken into M-mode. For any trap (breakpoint, address +misaligned, access fault, page fault, or guest-page fault) that writes a +guest virtual address to `mtval`, GVA is set to 1. For any other trap +into M-mode, GVA is set to 0. + +The TSR and TVM fields of `mstatus` affect execution only in HS-mode, +not in VS-mode. The TW field affects execution in all modes except +M-mode. + +Setting TVM=1 prevents HS-mode from accessing `hgatp` or executing +HFENCE.GVMA or HINVAL.GVMA, but has no effect on accesses to `vsatp` or +instructions HFENCE.VVMA or HINVAL.VVMA. + +[NOTE] +==== +TVM exists in `mstatus` to allow machine-level software to modify the +address translations managed by a supervisor-level OS, usually for the +purpose of inserting another stage of address translation below that +controlled by the OS. The instruction traps enabled by TVM=1 permit +machine level to co-opt both `satp` and `hgatp` and substitute _shadow +page tables_ that merge the OS’s chosen page translations with M-level’s +lower-stage translations, all without the OS being aware. M-level +software needs this ability not only to emulate the hypervisor extension +if not already supported, but also to emulate any future RISC-V +extensions that may modify or add address translation stages, perhaps, +for example, to improve support for nested hypervisors, i.e., running +hypervisors atop other hypervisors. + +However, setting TVM=1 does not cause traps for accesses to `vsatp` or +instructions HFENCE.VVMA or HINVAL.VVMA, or for any actions taken in +VS-mode, because M-level software is not expected to need to involve +itself in VS-stage address translation. For virtual machines, it should +be sufficient, and in all likelihood faster as well, to leave VS-stage +address translation alone and merge all other translation stages into +G-stage shadow page tables controlled by `hgatp`. This assumption does +place some constraints on possible future RISC-V extensions that current +machines will be able to emulate efficiently. +==== + +The hypervisor extension changes the behavior of the Modify Privilege +field, MPRV, of `mstatus`. When MPRV=0, translation and protection +behave as normal. When MPRV=1, explicit memory accesses are translated +and protected, and endianness is applied, as though the current +virtualization mode were set to MPV and the current nominal privilege +mode were set to MPP. <<h-mprv>> enumerates the cases. + +[[h-mprv]] +.Effect of MPRV on the translation and protection of explicit memory accesses. +[float="center",align="center",cols="^15,^10,^10,<70",options="header"] +|=== +|MPRV |MPV |MPP |Effect +|0 |- |- |Normal access; current privilege mode applies. + +|1 |0 |0 |U-level access with HS-level translation and protection only. + +|1 |0 |1 |HS-level access with HS-level translation and protection only. + +|1 |- |3 |M-level access with no translation. + +|1 |1 |0 |VU-level access with two-stage translation and protection. The +HS-level MXR bit makes any executable page readable. `vsstatus`.MXR +makes readable those pages marked executable at the VS translation +stage, but only if readable at the guest-physical translation stage. + +|1 |1 |1 |VS-level access with two-stage translation and protection. The +HS-level MXR bit makes any executable page readable. `vsstatus`.MXR +makes readable those pages marked executable at the VS translation +stage, but only if readable at the guest-physical translation stage. +`vsstatus`.SUM applies instead of the HS-level SUM bit. +|=== + +MPRV does not affect the virtual-machine load/store instructions, HLV, +HLVX, and HSV. The explicit loads and stores of these instructions +always act as though V=1 and the nominal privilege mode were +`hstatus`.SPVP, overriding MPRV. + +The `mstatus` register is a superset of the HS-level `sstatus` register +but is not a superset of `vsstatus`. + +==== Machine Interrupt Delegation (`mideleg`) Register + +When the hypervisor extension is implemented, bits 10, 6, and 2 of +`mideleg` (corresponding to the standard VS-level interrupts) are each +read-only one. Furthermore, if any guest external interrupts are +implemented (GEILEN is nonzero), bit 12 of `mideleg` (corresponding to +supervisor-level guest external interrupts) is also read-only one. +VS-level interrupts and guest external interrupts are always delegated +past M-mode to HS-mode. + +For bits of `mideleg` that are zero, the corresponding bits in +`hideleg`, `hip`, and `hie` are read-only zeros. + +==== Machine Interrupt (`mip` and `mie`) Registers + +The hypervisor extension gives registers `mip` and `mie` additional +active bits for the hypervisor-added interrupts. <<hypervisor-mipreg-standard>> and <<hypervisor-miereg-standard>> show the +standard portions (bits 15:0) of registers `mip` and `mie` when the +hypervisor extension is implemented. + +[[hypervisor-mipreg-standard]] +.Standard portion (bits 15:0) of `mip`. +include::images/bytefield/hypv-mipreg-standard.edn[] + +[[hypervisor-miereg-standard]] +.Standard portion (bits 15:0) of `mie`. +include::images/bytefield/hypv-miereg-standard.edn[] + +Bits SGEIP, VSEIP, VSTIP, and VSSIP in `mip` are aliases for the same +bits in hypervisor CSR `hip`, while SGEIE, VSEIE, VSTIE, and VSSIE in +`mie` are aliases for the same bits in `hie`. + +==== Machine Second Trap Value (`mtval2`) Register + +The `mtval2` register is an MXLEN-bit read/write register formatted as +shown in <<mtval2reg>>. When a trap is taken into +M-mode, `mtval2` is written with additional exception-specific +information, alongside `mtval`, to assist software in handling the trap. + +[[mtval2reg]] +.Machine second trap value register (`mtval2`). +include::images/bytefield/mtval2reg.edn[] + + +When a guest-page-fault trap is taken into M-mode, `mtval2` is written +with either zero or the guest physical address that faulted, shifted +right by 2 bits. For other traps, `mtval2` is set to zero, but a future +standard or extension may redefine `mtval2's` setting for other traps. + +If a guest-page fault is due to an implicit memory access during +first-stage (VS-stage) address translation, a guest physical address +written to `mtval2` is that of the implicit memory access that faulted. +Additional information is provided in CSR `mtinst` to disambiguate such +situations. + +Otherwise, for misaligned loads and stores that cause guest-page faults, +a nonzero guest physical address in `mtval2` corresponds to the faulting +portion of the access as indicated by the virtual address in `mtval`. +For instruction guest-page faults on systems with variable-length +instructions, a nonzero `mtval2` corresponds to the faulting portion of +the instruction as indicated by the virtual address in `mtval`. + +`mtval2` is a *WARL* register that must be able to hold zero and may be +capable of holding only an arbitrary subset of other 2-bit-shifted guest +physical addresses, if any. + +The Ssdbltrap extension (See <<ssdbltrp>>) requires the implementation of +the `mtval2` CSR. + +==== Machine Trap Instruction (`mtinst`) Register + +The `mtinst` register is an MXLEN-bit read/write register formatted as +shown in <<mtinstreg>>. When a trap is taken into +M-mode, `mtinst` is written with a value that, if nonzero, provides +information about the instruction that trapped, to assist software in +handling the trap. The values that may be written to `mtinst` on a trap +are documented in <<tinst-vals>>. + +[[mtinstreg]] +.Machine trap instruction (`mtinst`) register. +include::images/bytefield/mtinstreg.edn[] + +`mtinst` is a *WARL* register that need only be able to hold the values that +the implementation may automatically write to it on a trap. + +[[two-stage-translation]] +=== Two-Stage Address Translation + +Whenever the current virtualization mode V is 1, two-stage address +translation and protection is in effect. For any virtual memory access, +the original virtual address is converted in the first stage by VS-level +address translation, as controlled by the `vsatp` register, into a +_guest physical address_. The guest physical address is then converted +in the second stage by guest physical address translation, as controlled +by the `hgatp` register, into a supervisor physical address. The two +stages are known also as VS-stage and G-stage translation. Although +there is no option to disable two-stage address translation when V=1, +either stage of translation can be effectively disabled by zeroing the +corresponding `vsatp` or `hgatp` register. + +The `vsstatus` field MXR, which makes execute-only pages readable by explicit loads, only +overrides VS-stage page protection. Setting MXR at VS-level does not +override guest-physical page protections. Setting MXR at HS-level, +however, overrides both VS-stage and G-stage execute-only permissions. + +When V=1, memory accesses that would normally bypass address translation +are subject to G-stage address translation alone. This includes memory +accesses made in support of VS-stage address translation, such as reads +and writes of VS-level page tables. + +Machine-level physical memory protection applies to supervisor physical +addresses and is in effect regardless of virtualization mode. + +[[guest-addr-translation]] +==== Guest Physical Address Translation + +The mapping of guest physical addresses to supervisor physical addresses +is controlled by CSR `hgatp` (<<hgatp>>). + +When the address translation scheme selected by the MODE field of +`hgatp` is Bare, guest physical addresses are equal to supervisor +physical addresses without modification, and no memory protection +applies in the trivial translation of guest physical addresses to +supervisor physical addresses. + +When `hgatp`.MODE specifies a translation scheme of Sv32x4, Sv39x4, +Sv48x4, or Sv57x4, G-stage address translation is a variation on the +usual page-based virtual address translation scheme of Sv32, Sv39, Sv48, +or Sv57, respectively. In each case, the size of the incoming address is +widened by 2 bits (to 34, 41, 50, or 59 bits). To accommodate the +2 extra bits, the root page table (only) is expanded by a factor of four +to be 16 KiB instead of the usual 4 KiB. Matching its larger size, the +root page table also must be aligned to a 16 KiB boundary instead of the +usual 4 KiB page boundary. Except as noted, all other aspects of Sv32, +Sv39, Sv48, or Sv57 are adopted unchanged for G-stage translation. +Non-root page tables and all page table entries (PTEs) have the same +formats as documented in <<sv32>>, <<sv39>>, <<sv48>>, and <<sv57>>. + +For Sv32x4, an incoming guest physical address is partitioned into a +virtual page number (VPN) and page offset as shown in +<<sv32x4va>>. This partitioning is identical to +that for an Sv32 virtual address as depicted in +<<sv32va>>, except with 2 more bits at the +high end in VPN[1]. (Note that the fields of a partitioned guest +physical address also correspond one-for-one with the structure that +Sv32 assigns to a physical address, depicted in +<<sv32va>>.) + +[[sv32x4va]] +.Sv32x4 virtual address (guest physical address). +include::images/bytefield/sv32x4va.edn[] + +For Sv39x4, an incoming guest physical address is partitioned as shown +in <<sv39x4va>>. This partitioning is identical to that for an Sv39 virtual address as depicted in <<sv39va>>, except with 2 more bits at the +high end in VPN[2]. Address bits 63:41 must all be zeros, or else a +guest-page-fault exception occurs. + +[[sv39x4va]] +.Sv39x4 virtual address (guest physical address). +include::images/bytefield/sv39x4va.edn[] + +For Sv48x4, an incoming guest physical address is partitioned as shown +in <<sv48x4va>>. This partitioning is identical to +that for an Sv48 virtual address as depicted in +<<sv48va>>, except with 2 more bits at the +high end in VPN[3]. Address bits 63:50 must all be zeros, or else a +guest-page-fault exception occurs. + +[[sv48x4va]] +.Sv48x4 virtual address (guest physical address). +include::images/bytefield/sv48x4va.edn[] + +For Sv57x4, an incoming guest physical address is partitioned as shown +in <<sv57x4va>>. This partitioning is identical to +that for an Sv57 virtual address as depicted in +<<sv57va>>, except with 2 more bits at the +high end in VPN[4]. Address bits 63:59 must all be zeros, or else a +guest-page-fault exception occurs. + +[[sv57x4va]] +.Sv57x4 virtual address (guest physical address). +include::images/bytefield/sv57x4va.edn[] + +[NOTE] +==== +The page-based G-stage address translation scheme for RV32, Sv32x4, is +defined to support a 34-bit guest physical address so that an RV32 +hypervisor need not be limited in its ability to virtualize real 32-bit +RISC-V machines, even those with 33-bit or 34-bit physical addresses. +This may include the possibility of a machine virtualizing itself, if it +happens to use 33-bit or 34-bit physical addresses. Multiplying the size +and alignment of the root page table by a factor of four is the cheapest +way to extend Sv32 to cover a 34-bit address. The possible wastage of +12 KiB for an unnecessarily large root page table is expected to be of +negligible consequence for most (maybe all) real uses. + +A consistent ability to virtualize machines having as much as four times +the physical address space as virtual address space is believed to be of +some utility also for RV64. For a machine implementing 39-bit virtual +addresses (Sv39), for example, this allows the hypervisor extension to +support up to a 41-bit guest physical address space without either +necessitating hardware support for 48-bit virtual addresses (Sv48) or +falling back to emulating the larger address space using shadow page +tables. +==== + +The conversion of an Sv32x4, Sv39x4, Sv48x4, or Sv57x4 guest physical +address is accomplished with the same algorithm used for Sv32, Sv39, +Sv48, or Sv57, as presented in +<<sv32algorithm>>, except that: + +* `hgatp` substitutes for the usual `satp`; +* for the translation to begin, the effective privilege mode must be +VS-mode or VU-mode; +* when checking the U bit, the current privilege mode is always taken to +be U-mode; and +* guest-page-fault exceptions are raised instead of regular page-fault +exceptions. + +For G-stage address translation, all memory accesses (including those +made to access data structures for VS-stage address translation) are +considered to be user-level accesses, as though executed in U-mode. +Access type permissions—readable, writable, or executable—are checked +during G-stage translation the same as for VS-stage translation. For a +memory access made to support VS-stage address translation (such as to +read/write a VS-level page table), permissions and the need to set A +and/or D bits at the G-stage level are checked as though for an implicit +load or store, not for the original access type. However, any exception +is always reported for the original access type (instruction, load, or +store/AMO). + +The G bit in all G-stage PTEs is currently not used. Until +its use is defined by a standard extension, it should be cleared by +software for forward compatibility, and must be ignored by hardware. + +[NOTE] +==== +G-stage address translation uses the identical format for PTEs as +regular address translation, even including the U bit, due to the +possibility of sharing some (or all) page tables between G-stage +translation and regular HS-level address translation. Regardless of +whether this usage will ever become common, we chose not to preclude it. +==== + +==== Guest-Page Faults + +Guest-page-fault traps may be delegated from M-mode to HS-mode under the +control of CSR `medeleg`, but cannot be delegated to other privilege +modes. On a guest-page fault, CSR `mtval` or `stval` is written with the +faulting guest virtual address as usual, and `mtval2` or `htval` is +written either with zero or with the faulting guest physical address, +shifted right by 2 bits. CSR `mtinst` or `htinst` may also be written +with information about the faulting instruction or other reason for the +access, as explained in <<tinst-vals>>. + +When an instruction fetch or a misaligned memory access straddles a page +boundary, two different address translations are involved. When a +guest-page fault occurs in such a circumstance, the faulting virtual +address written to `mtval`/`stval` is the same as would be required for +a regular page fault. Thus, the faulting virtual address may be a +page-boundary address that is higher than the instruction's original +virtual address, if the byte at that page boundary is among the accessed +bytes. + +When a guest-page fault is not due to an implicit memory access for +VS-stage address translation, a nonzero guest physical address written +to `mtval2`/`htval` shall correspond to the exact virtual address +written to `mtval`/`stval`. + +[[hyp-mm-fences]] +==== Memory-Management Fences + +The behavior of the SFENCE.VMA instruction is affected by the current +virtualization mode V. When V=0, the virtual-address argument is an +HS-level virtual address, and the ASID argument is an HS-level ASID. The +instruction orders stores only to HS-level address-translation +structures with subsequent HS-level address translations. + +When V=1, the virtual-address argument to SFENCE.VMA is a guest virtual +address within the current virtual machine, and the ASID argument is a +VS-level ASID within the current virtual machine. The current virtual +machine is identified by the VMID field of CSR `hgatp`, and the +effective ASID can be considered to be the combination of this VMID with +the VS-level ASID. The SFENCE.VMA instruction orders stores only to the +VS-level address-translation structures with subsequent VS-stage address +translations for the same virtual machine, i.e., only when `hgatp`.VMID +is the same as when the SFENCE.VMA executed. + +Hypervisor instructions HFENCE.VVMA and HFENCE.GVMA provide additional +memory-management fences to complement SFENCE.VMA. These instructions +are described in <<hfence.vma>>. + +<<pmp-vmem>> discusses the intersection between +physical memory protection (PMP) and page-based address translation. It +is noted there that, when PMP settings are modified in a manner that +affects either the physical memory that holds page tables or the +physical memory to which page tables point, M-mode software must +synchronize the PMP settings with the virtual memory system. For +HS-level address translation, this is accomplished by executing in +M-mode an SFENCE.VMA instruction with _rs1_=`x0` and _rs2_=`x0`, after +the PMP CSRs are written. Synchronization with G-stage and VS-stage data +structures is also needed. Executing an HFENCE.GVMA instruction with +_rs1_=`x0` and _rs2_=`x0` suffices to flush all G-stage or VS-stage +address-translation cache entries that have cached PMP settings +corresponding to the final translated supervisor physical address. An +HFENCE.VVMA instruction is not required. + +Similarly, if the setting of the PBMTE or ADUE bits in `menvcfg` are changed, an +HFENCE.GVMA instruction with _rs1_=`x0` and _rs2_=`x0` suffices to synchronize +with respect to the altered interpretation of G-stage and VS-stage PTEs' PBMT +and A/D bit fields, respectively. + +By contrast, if the PBMTE or ADUE bits in `henvcfg` are changed, executing an +HFENCE.VVMA with _rs1_=`x0` and _rs2_=`x0` suffices to synchronize with +respect to the altered interpretation of VS-stage PTEs' PBMT and A/D bit fields +for the currently active VMID. + +NOTE: No mechanism is provided to atomically change `vsatp` and `hgatp` +together. Hence, to prevent speculative execution causing one guest's +VS-stage translations to be cached under another guest's VMID, world-switch +code should zero `vsatp`, then swap `hgatp`, then finally write the new +`vsatp` value. Similarly, if `henvcfg`.PBMTE/ADUE need be world-switched, they +should be switched after zeroing `vsatp` but before writing the new `vsatp` +value, obviating the need to execute an HFENCE.VVMA instruction. + +=== Traps + +[[sec:hcauses]] +==== Trap Cause Codes + +The hypervisor extension augments the trap cause encoding. +<<hcauses>> lists the possible M-mode and HS-mode +trap cause codes when the hypervisor extension is implemented. Codes are +added for VS-level interrupts (interrupts 2, 6, 10), for +supervisor-level guest external interrupts (interrupt 12), for +virtual-instruction exceptions (exception 22), and for guest-page faults +(exceptions 20, 21, 23). Furthermore, environment calls from VS-mode are +assigned cause 10, whereas those from HS-mode or S-mode use cause 9 as +usual. + +[[hcauses]] +.Machine and supervisor cause register (`mcause` and `scause`) values when the hypervisor extension is implemented. +[%autowidth,float="center",align="center",cols=">,>,<",options="header"] +|=== +|Interrupt |Exception Code |Description +|1 + +1 + +1 + +1 +|0 + +1 + +2 + +3 +|_Reserved_ + +Supervisor software interrupt + +Virtual supervisor software interrupt + +Machine software interrupt +|1 + +1 + +1 + +1 +|4 + +5 + +6 + +7 +|_Reserved_ + +Supervisor timer interrupt + +Virtual supervisor timer interrupt + +Machine timer interrupt +|1 + +1 + +1 + +1 +|8 + +9 + +10 + +11 +|_Reserved_ + +Supervisor external interrupt + +Virtual supervisor external interrupt + +Machine external interrupt +|1 + +1 + +1 + +1 +|12 + +13 + +14-15 + +{ge}16 +|Supervisor guest external interrupt + +_Reserved for counter-overflow interrupt_ + +_Reserved_ + +_Designated for platform use_ +|0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +|0 + +1 + +2 + +3 + +4 + +5 + +6 + +7 + +8 + +9 + +10 + +11 + +12 + +13 + +14 + +15 + +16 + +17 + +18 + +19 + +20 + +21 + +22 + +23 + +24-31 + +32-47 + +48-63 + +{ge}64 +|Instruction address misaligned + +Instruction access fault + +Illegal instruction + +Breakpoint + +Load address misaligned + +Load access fault + +Store/AMO address misaligned + +Store/AMO access fault + +Environment call from U-mode or VU-mode + +Environment call from HS-mode + +Environment call from VS-mode + +Environment call from M-mode + +Instruction page fault + +Load page fault + +_Reserved_ + +Store/AMO page fault + +Double trap + +_Reserved_ + +Software check + +Hardware error + +Instruction guest-page fault + +Load guest-page fault + +Virtual instruction + +Store/AMO guest-page fault + +_Designated for custom use_ + +_Reserved_ + +_Designated for custom use_ + +_Reserved_ +|=== + +HS-mode and VS-mode ECALLs use different cause values so they can be +delegated separately. + +When V=1, a virtual-instruction exception (code 22) is normally raised +instead of an illegal-instruction exception if the attempted instruction +is _HS-qualified_ but is prevented from executing when V=1 either due to +insufficient privilege or because the instruction is expressly disabled +by a supervisor or hypervisor CSR such as `scounteren` or `hcounteren`. +An instruction is _HS-qualified_ if it would be valid to execute in +HS-mode (for some values of the instruction's register operands), +assuming fields TSR and TVM of CSR `mstatus` are both zero. + +A special rule applies for CSR instructions that access 32-bit high-half +CSRs such as `cycleh` and `htimedeltah`. When V=1 and +XLEN=32, an invalid attempt to access a high-half CSR +raises a virtual-instruction +exception instead of an illegal-instruction exception if the same CSR +instruction for the corresponding _low-half_ CSR (e.g.`cycle` or +`htimedelta`) is HS-qualified. + +[NOTE] +==== +When XLEN>32, an attempt to access a high-half CSR +always raises an illegal-instruction exception. +==== + +Specifically, a virtual-instruction exception is raised for the +following cases: + +* in VS-mode, attempts to access a non-high-half counter CSR when the +corresponding bit in `hcounteren` is 0 and the same bit in `mcounteren` +is 1; +* in VS-mode, if XLEN=32, attempts to access a high-half counter CSR +when the corresponding bit in `hcounteren` is 0 and the same bit in +`mcounteren` is 1; +* in VU-mode, attempts to access a non-high-half counter CSR when the +corresponding bit in either `hcounteren` or `scounteren` is 0 and the +same bit in `mcounteren` is 1; +* in VU-mode, if XLEN=32, attempts to access a high-half counter CSR +when the corresponding bit in either `hcounteren` or `scounteren` is 0 +and the same bit in `mcounteren` is 1; +* in VS-mode or VU-mode, attempts to execute a hypervisor instruction +(HLV, HLVX, HSV, or HFENCE); +* in VS-mode or VU-mode, attempts to access an implemented non-high-half +hypervisor CSR or VS CSR when the same access (read/write) would be +allowed in HS-mode, assuming `mstatus`.TVM=0; +* in VS-mode or VU-mode, if XLEN=32, attempts to access an implemented +high-half hypervisor CSR or high-half VS CSR when the same access +(read/write) to the CSR"s low-half partner would be allowed in HS-mode, +assuming `mstatus`.TVM=0; +* in VU-mode, attempts to execute WFI when `mstatus`.TW=0, or to execute +a supervisor instruction (SRET or SFENCE); +* in VU-mode, attempts to access an implemented non-high-half supervisor +CSR when the same access (read/write) would be allowed in HS-mode, +assuming `mstatus`.TVM=0; +* in VU-mode, if XLEN=32, attempts to access an implemented high-half +supervisor CSR when the same access to the CSR's low-half partner would +be allowed in HS-mode, assuming `mstatus`.TVM=0; +* in VS-mode, attempts to execute WFI when `hstatus`.VTW=1 and +`mstatus`.TW=0, unless the instruction completes within an +implementation-specific, bounded time; +* in VS-mode, attempts to execute SRET when `hstatus`.VTSR=1; and +* in VS-mode, attempts to execute an SFENCE.VMA or SINVAL.VMA +instruction or to access `satp`, when `hstatus`.VTVM=1. + +Other extensions to the RISC-V Privileged Architecture may add to the +set of circumstances that cause a virtual-instruction exception when +V=1. + +On a virtual-instruction trap, `mtval` or `stval` is written the same as +for an illegal-instruction trap. + +[NOTE] +==== +It is not unusual that hypervisors must emulate the instructions that +raise virtual-instruction exceptions, to support nested hypervisors or +for other reasons. Machine level is expected ordinarily to delegate +virtual-instruction traps directly to HS-level, whereas +illegal-instruction traps are likely to be processed first in M-mode before +being conditionally delegated (by software) to HS-level. Consequently, +virtual-instruction traps are expected typically to be handled faster +than illegal-instruction traps. + +When not emulating the trapping instruction, a hypervisor should convert +a virtual-instruction trap into an illegal-instruction exception for the +guest virtual machine. + +*** + +Because TSR and TVM in `mstatus` are intended to impact only S-mode +(HS-mode), they are ignored for determining exceptions in VS-mode. +==== + +Fields FS and VS in registers `sstatus` and `vsstatus` deviate from the usual +_HS-qualified_ rule. +If an instruction is prevented from executing because FS or VS is zero in +either `sstatus` or `vsstatus`, the exception raised is always an +illegal-instruction exception, never a virtual-instruction exception. + +[NOTE] +==== +Early implementations of the H extension treated FS and VS in `sstatus` and +`vsstatus` specially this way, and the behavior has been codified to maintain +compatibility for software. +==== + +<<< + +[[HSyncExcPrio]] +.Synchronous exception priority when the hypervisor extension is implemented. +[%autowidth,float="center",align="center",cols="<,>,<",options="header"] +|=== +|Priority |Exc.Code |Description +|_Highest_ |3 |Instruction address breakpoint + +| .>|12, 20, 1 |During instruction address translation: + +{nbsp}{nbsp}{nbsp}First encountered page fault, guest-page fault, or access +fault + +| .>|1 |With physical address for instruction: + +{nbsp}{nbsp}{nbsp}Instruction access fault + +| |2 + +22 + +0 + +8, 9, 10, 11 + +3 + +3|Illegal instruction + +Virtual instruction + +Instruction address misaligned + +Environment call + +Environment break + +{nbsp}{nbsp}{nbsp}Load/store/AMO address breakpoint + +| .>|4,6 |Optionally: + +{nbsp}{nbsp}{nbsp}Load/store/AMO address misaligned + +| .>|13, 15, 21, 23, 5, 7 |During address translation for an explicit memory access: + +{nbsp}{nbsp}{nbsp}First encountered page fault, guest-page fault, +or access fault + +| .>|5, 7 |With physical address for an explicit memory access: + +{nbsp}{nbsp}{nbsp}Load/store/AMO access fault + +.>|_Lowest_ .>|4, 6 |If not higher priority: + +{nbsp}{nbsp}{nbsp}Load/store/AMO address misaligned +|=== + +If an instruction may raise multiple synchronous exceptions, the +decreasing priority order of <<HSyncExcPrio>> +indicates which exception is taken and reported in `mcause` or `scause`. + +==== Trap Entry + +When a trap occurs in HS-mode or U-mode, it goes to M-mode, unless +delegated by `medeleg` or `mideleg`, in which case it goes to HS-mode. +When a trap occurs in VS-mode or VU-mode, it goes to M-mode, unless +delegated by `medeleg` or `mideleg`, in which case it goes to HS-mode, +unless further delegated by `hedeleg` or `hideleg`, in which case it +goes to VS-mode. + +When a trap is taken into M-mode, virtualization mode V gets set to 0, +and fields MPV and MPP in `mstatus` (or `mstatush`) are set according to +<<h-mpp>>. A trap into M-mode also writes fields GVA, +MPIE, and MIE in `mstatus`/`mstatush` and writes CSRs `mepc`, `mcause`, +`mtval`, `mtval2`, and `mtinst`. + +[[h-mpp]] +.Value of `mstatus`/`mstatush` fields MPV and MPP after a trap into M-mode. Upon trap return, MPV is ignored when MPP=3. +[%autowidth,float="center",align="center",cols="<,^,^",options="header"] +|=== +|Previous Mode |MPV |MPP +|U-mode + +HS-mode + +M-mode|0 + +0 + +0|0 + +1 + +3 +|VU-mode + +VS-mode|1 + +1|0 + +1 +|=== + +When a trap is taken into HS-mode, virtualization mode V is set to 0, +and `hstatus`.SPV and `sstatus`.SPP are set according to +<<h-spp>>. If V was 1 before the trap, field SPVP in +`hstatus` is set the same as `sstatus`.SPP; otherwise, SPVP is left +unchanged. A trap into HS-mode also writes field GVA in `hstatus`, +fields SPIE and SIE in `sstatus`, and CSRs `sepc`, `scause`, `stval`, +`htval`, and `htinst`. + +[[h-spp]] +.Value of `hstatus` field SPV and `sstatus` field SPP after a trap into HS-mode. +[%autowidth,float="center",align="center",cols="<,^,^",options="header"] +|=== +|Previous Mode |SPV |SPP +|U-mode + +HS-mode + |0 + +0 |0 + +1 +|VU-mode + +VS-mode|1 + +1 |0 + +1 +|=== + +When a trap is taken into VS-mode, `vsstatus`.SPP is set according to +<<h-vspp>>. Register `hstatus` and the HS-level +`sstatus` are not modified, and the virtualization mode V remains 1. A +trap into VS-mode also writes fields SPIE and SIE in `vsstatus` and +writes CSRs `vsepc`, `vscause`, and `vstval`. + +[[h-vspp]] +.Value of `vsstatus` field SPP after a trap into VS-mode. +[%autowidth,float="center",align="center",cols="<,^",options="header"] +|=== +|Previous Mode |SPP +|VU-mode + +VS-mode |0 + +1 +|=== + +[[tinst-vals]] +==== Transformed Instruction or Pseudoinstruction for `mtinst` or `htinst` + +On any trap into M-mode or HS-mode, one of these values is written +automatically into the appropriate trap instruction CSR, `mtinst` or +`htinst`: + +* zero; +* a transformation of the trapping instruction; +* a custom value (allowed only if the trapping instruction is +non-standard); or +* a special pseudoinstruction. + +Except when a pseudoinstruction value is required (described later), the +value written to `mtinst` or `htinst` may always be zero, indicating +that the hardware is providing no information in the register for this +particular trap. + +[NOTE] +==== +The value written to the trap instruction CSR serves two purposes. The +first is to improve the speed of instruction emulation in a trap +handler, partly by allowing the handler to skip loading the trapping +instruction from memory, and partly by obviating some of the work of +decoding and executing the instruction. The second purpose is to supply, +via pseudoinstructions, additional information about guest-page-fault +exceptions caused by implicit memory accesses done for VS-stage address +translation. + +A _transformation_ of the trapping instruction is written instead of +simply a copy of the original instruction in order to minimize the +burden for hardware yet still provide to a trap handler the information +needed to emulate the instruction. An implementation may at any time +reduce its effort by substituting zero in place of the transformed +instruction. +==== + +On an interrupt, the value written to the trap instruction register is +always zero. On a synchronous exception, if a nonzero value is written, +one of the following shall be true about the value: + +* Bit 0 is `1`, and replacing bit 1 with `1` makes the value into a +valid encoding of a standard instruction. ++ +In this case, the instruction that trapped is the same kind as indicated +by the register value, and the register value is the transformation of +the trapping instruction, as defined later. For example, if bits 1:0 are +binary `11` and the register value is the encoding of a standard LW +(load word) instruction, then the trapping instruction is LW, and the +register value is the transformation of the trapping LW instruction. +* Bit 0 is `1`, and replacing bit 1 with `1` makes the value into an +instruction encoding that is explicitly designated for a custom +instruction (_not_ an unused reserved encoding). ++ +This is a _custom value_. The instruction that trapped is a non-standard +instruction. The interpretation of a custom value is not otherwise +specified by this standard. +* The value is one of the special pseudoinstructions defined later, all +of which have bits 1:0 equal to `00`. + +These three cases exclude a large number of other possible values, such +as all those having bits 1:0 equal to binary `10`. A future standard or +extension may define additional cases, thus allowing values that are +currently excluded. Software may safely treat an unrecognized value in a +trap instruction register the same as zero. + +[NOTE] +==== +To be forward-compatible with future revisions of this standard, +software that interprets a nonzero value from `mtinst` or `htinst` must +fully verify that the value conforms to one of the cases listed above. +For instance, for RV64, discovering that bits 6:0 of `mtinst` are +`0000011` and bits 14:12 are `010` is not sufficient to establish that +the first case applies and the trapping instruction is a standard LW +instruction; rather, software must also confirm that bits 63:32 of +`mtinst` are all zeros. A future standard might define new values for +64-bit `mtinst` that are nonzero in bits 63:32 yet may coincidentally +have in bits 31:0 the same bit patterns as standard RV64 instructions. + +*** + +Unlike for standard instructions, there is no requirement that the +instruction encoding of a custom value be of the same ``kind'' as the +instruction that trapped (or even have any correlation with the trapping +instruction). +==== + +<<tinst-values>> shows the values that may be +automatically written to the trap instruction register for each standard +exception cause. For exceptions that prevent the fetching of an +instruction, only zero or a pseudoinstruction value may be written. A +custom value may be automatically written only if the instruction that +traps is non-standard. A future standard or extension may permit other +values to be written, chosen from the set of allowed values established +earlier. + +<<< + +[[tinst-values]] +.Values that may be automatically written to the trap instruction (`mtinst` or `htinst`) register on an exception trap. +[float="center",align="center",cols="2,^,^,^,^",options="header"] +|=== +<.>|Exception +^.>|Zero +|Transformed + +Standard + +Instruction +^.>|Custom Value +^.>|Pseudoinstruction Value +|Instruction address misaligned |Yes |No |Yes |No +|Instruction access fault + +Illegal instruction + +Breakpoint + +Virtual instruction +|Yes + +Yes + +Yes + +Yes +|No + +No + +No + +No + +|No + +No + +Yes + +Yes +|No + +No + +No + +No +|Load address misaligned + +Load access fault + +Store/AMO address misaligned + +Store/AMO access fault +|Yes + +Yes + +Yes + +Yes +|Yes + +Yes + +Yes + +Yes +|Yes + +Yes + +Yes + +Yes +|No + +No + +No + +No +|Environment call |Yes |No |Yes |No +|Instruction page fault + +Load page fault + +Store/AMO page fault +|Yes + +Yes + +Yes +|No + +Yes + +Yes +|No + +Yes + +Yes +|No + +No + +No +|Instruction guest-page fault + +Load guest-page fault + +Store/AMO guest-page fault +|Yes + +Yes + +Yes +|No + +Yes + +Yes +|No + +Yes + +Yes +|Yes + +Yes + +Yes +|=== + +As enumerated in the table, a synchronous exception may write to the +trap instruction register a standard transformation of the trapping +instruction only for exceptions that arise from explicit memory accesses +(from loads, stores, and AMO instructions). Accordingly, standard +transformations are currently defined only for these memory-access +instructions. If a synchronous trap occurs for a standard instruction +for which no transformation has been defined, the trap instruction +register shall be written with zero (or, under certain circumstances, +with a special pseudoinstruction value). + +For a standard load instruction that is not a compressed instruction and +is one of LB, LBU, LH, LHU, LW, LWU, LD, FLW, FLD, FLQ, or FLH, the +transformed instruction has the format shown in +<<transformedloadinst>>. + +[[transformedloadinst]] +.Transformed load instruction (LB, LBU, LH, LHU, LW, LWU, LD, FLW, FLD, FLQ, or FLH). Fields funct3, rd, and opcode are the same as the trapping load instruction. +include::images/wavedrom/transformedloadinst.edn[] + +For a standard store instruction that is not a compressed instruction +and is one of SB, SH, SW, SD, FSW, FSD, FSQ, or FSH, the transformed +instruction has the format shown in +<<transformedstoreinst>>. + +[[transformedstoreinst]] +.Transformed store instruction (SB, SH, SW, SD, FSW, FSD, FSQ, or FSH). Fields rs2, funct3, and opcode are the same as the trapping store instruction. +include::images/wavedrom/transformedstoreinst.edn[] + +For a standard atomic instruction (load-reserved, store-conditional, or AMO instruction), the transformed instruction has the format shown in <<transformedatomicinst>>. + +[[transformedatomicinst]] +.Transformed atomic instruction (load-reserved, store-conditional, or AMO instruction). All fields are the same as the trapping instruction except bits 19:15, Addr. Offset. +include::images/wavedrom/transformedatomicinst.edn[] + +For a standard virtual-machine load/store instruction (HLV, HLVX, or HSV), the transformed instruction has the format shown in <<transformedvmaccessinst>>. + +[[transformedvmaccessinst]] +.Transformed virtual-machine load/store instruction (HLV, HLVX, HSV). All fields are the same as the trapping instruction except bits 19:15, Addr. Offset +include::images/wavedrom/transformedvmaccessinst.edn[] + +In all the transformed instructions above, the Addr. Offset field that +replaces the instruction’s rs1 field in bits 19:15 is the positive +difference between the faulting virtual address (written to `mtval` or +`stval`) and the original virtual address. This difference can be +nonzero only for a misaligned memory access. Note also that, for basic +loads and stores, the transformations replace the instruction’s +immediate offset fields with zero. + +For a standard compressed instruction (16-bit size), the transformed +instruction is found as follows: + +. Expand the compressed instruction to its 32-bit equivalent. +. Transform the 32-bit equivalent instruction. +. Replace bit 1 with a `0`. + +Bits 1:0 of a transformed standard instruction will be binary `01` if +the trapping instruction is compressed and `11` if not. +[NOTE] +==== +In decoding the contents of `mtinst` or `htinst`, once software has +determined that the register contains the encoding of a standard basic +load (LB, LBU, LH, LHU, LW, LWU, LD, FLW, FLD, FLQ, or FLH) or basic +store (SB, SH, SW, SD, FSW, FSD, FSQ, or FSH), it is not necessary to +confirm also that the immediate offset fields (31:25, and 24:20 or 11:7) +are zeros. The knowledge that the register’s value is the encoding of a +basic load/store is sufficient to prove that the trapping instruction is +of the same kind. + +A future version of this standard may add information to the fields that +are currently zeros. However, for backwards compatibility, any such +information will be for performance purposes only and can safely be +ignored. +==== + +For guest-page faults, the trap instruction register is written with a +special pseudoinstruction value if: (a) the fault is caused by an +implicit memory access for VS-stage address translation, and (b) a +nonzero value (the faulting guest physical address) is written to +`mtval2` or `htval`. If both conditions are met, the value written to +`mtinst` or `htinst` must be taken from +<<pseudoinsts>>; zero is not allowed. + +[[pseudoinsts]] +.Special pseudoinstruction values for guest-page faults. The RV32 values are used when VSXLEN=32, and the RV64 values when VSXLEN=64. +[%autowidth,float="center",align="center",cols="<,<",options="header"] +|=== +|Value |Meaning +|`0x00002000` + +`0x00002020` +|32-bit read for VS-stage address translation (RV32) + +32-bit write for VS-stage address translation (RV32) + +|`0x00003000` + +`0x00003020` +|64-bit read for VS-stage address translation (RV64) + +64-bit write for VS-stage address translation (RV64) +|=== + +The defined pseudoinstruction values are designed to correspond closely +with the encodings of basic loads and stores, as illustrated by +<<pseudoinsts-basis>>. + +[[pseudoinsts-basis]] +.Standard instructions corresponding to the special pseudoinstructions of <<pseudoinsts>>. +[%autowidth,float="center",align="center",cols="<,<",options="header"] +|=== +|Encoding |Instruction +|`0x00002003` + +`0x00002023` +|`lw x0,0(x0)` + +`sw x0,0(x0)` + +|`0x00003003` + +`0x00003023` +|`ld x0,0(x0)` + +`sd x0,0(x0)` +|=== + +A _write_ pseudoinstruction (`0x00002020` or `0x00003020`) is used for +the case that the machine is attempting automatically to update bits A +and/or D in VS-level page tables. All other implicit memory accesses for +VS-stage address translation will be reads. If a machine never +automatically updates bits A or D in VS-level page tables (leaving this +to software), the _write_ case will never arise. The fact that such a +page table update must actually be atomic, not just a simple write, is +ignored for the pseudoinstruction. + +[NOTE] +==== +If the conditions that necessitate a pseudoinstruction value can ever +occur for M-mode, then `mtinst` cannot be entirely read-only zero; and +likewise for HS-mode and `htinst`. However, in that case, the trap +instruction registers may minimally support only values 0 and +`0x00002000` or `0x00003000`, and possibly `0x00002020` or `0x00003020`, +requiring as few as one or two flip-flops in hardware, per register. + +*** + +There is no harm here in ignoring the atomicity requirement for page +table updates, because a hypervisor is not expected in these +circumstances to emulate an implicit memory access that fails. Rather, +the hypervisor is given enough information about the faulting access to +be able to make the memory accessible (e.g. by restoring a missing page +of virtual memory) before resuming execution by retrying the faulting +instruction. +==== + +==== Trap Return + +The MRET instruction is used to return from a trap taken into M-mode. +MRET first determines what the new privilege mode will be according to +the values of MPP and MPV in `mstatus` or `mstatush`, as encoded in +<<h-mpp>>. MRET then in `mstatus`/`mstatush` sets +MPV=0, MPP=0, MIE=MPIE, and MPIE=1. Lastly, MRET sets the privilege mode +as previously determined, and sets `pc`=`mepc`. + +The SRET instruction is used to return from a trap taken into HS-mode or +VS-mode. Its behavior depends on the current virtualization mode. + +When executed in M-mode or HS-mode (i.e., V=0), SRET first determines +what the new privilege mode will be according to the values in +`hstatus`.SPV and `sstatus`.SPP, as encoded in +<<h-spp>>. SRET then sets `hstatus`.SPV=0, and in +`sstatus` sets SPP=0, SIE=SPIE, and SPIE=1. Lastly, SRET sets the +privilege mode as previously determined, and sets `pc`=`sepc`. + +When executed in VS-mode (i.e., V=1), SRET sets the privilege mode +according to <<h-vspp>>, in `vsstatus` sets SPP=0, +SIE=SPIE, and SPIE=1, and lastly sets `pc`=`vsepc`. + +If the Ssdbltrp extension is implemented, when `SRET` is executed in HS-mode, +if the new privilege mode is VU, the `SRET` instruction sets `vsstatus.SDT` +to 0. When executed in VS-mode, `vsstatus.SDT` is set to 0. |
