hgatp
Hypervisor guest address translation and protection
The hgatp register is an HSXLEN-bit read/write register
which controls G-stage address translation and protection, the second stage of two-stage
translation for guest virtual addresses.
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 IllegalInstruction
exception.
Encoding of hgatp MODE field. 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, the remaining fields in hgatp must be set to zeros.
HSXLEN=32 | ||
---|---|---|
Value |
Name |
Description |
0 |
Bare |
No translation or protection. |
HSXLEN=64 |
||
Value |
Name |
Description |
0 |
Bare + — +
Sv39x4 |
No translation or protection. |
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.
This definition simplifies the implementation of speculative execution
of |
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.
Attributes
Defining Extension |
|
||||
---|---|---|---|---|---|
CSR Address |
0x680 |
||||
Length |
|
||||
Privilege Mode |
S |
Software write
This CSR may store a value that is different from what software attempts to write.
When a software write occurs (e.g., through csrrw), the following determines the written value:
MODE = if (csr_value.MODE == $bits(HgatpMode::Bare)) { if (!GSTAGE_MODE_BARE) { return UNDEFINED_LEGAL_DETERMINISTIC; } } if (csr_value.MODE == $bits(HgatpMode::Sv32x4)) { if (!SV32X4_TRANSLATION) { return UNDEFINED_LEGAL_DETERMINISTIC; } } if (csr_value.MODE == $bits(HgatpMode::Sv39x4)) { if (!SV39X4_TRANSLATION) { return UNDEFINED_LEGAL_DETERMINISTIC; } } if (csr_value.MODE == $bits(HgatpMode::Sv48x4)) { if (!SV48X4_TRANSLATION) { return UNDEFINED_LEGAL_DETERMINISTIC; } } if (csr_value.MODE == $bits(HgatpMode::Sv57x4)) { if (!SV57X4_TRANSLATION) { return UNDEFINED_LEGAL_DETERMINISTIC; } } # mode is supported return csr_value.MODE; VMID = if (csr_value.MODE == $bits(HgatpMode::Bare)) { # when MODE == Bare, PPN and VMID must be 0 if (csr_value.VMID == 0) { return 0; } else { return UNDEFINED_LEGAL_DETERMINISTIC; } } return csr_value.VMID[VMID_WIDTH-1:0]; PPN = if (csr_value.MODE == $bits(HgatpMode::Bare)) { # when MODE == Bare, PPN and VMID must be 0 if (csr_value.PPN == 0) { return 0; } else { return UNDEFINED_LEGAL_DETERMINISTIC; } } return csr_value.PPN;
Software read
This CSR may return a value that is different from what is stored in hardware.
if ((CSR[hgatp].MODE == $bits(HgatpMode::Sv32x4)) || (CSR[hgatp].MODE == $bits(HgatpMode::Sv39x4)) || (CSR[hgatp].MODE == $bits(HgatpMode::Sv48x4)) || (CSR[hgatp].MODE == $bits(HgatpMode::Sv57x4))) {
return $bits(CSR[hgatp]) & ~64'h3;
} else {
return $bits(CSR[hgatp]);
}