Closed jhauser-us closed 5 years ago
Overall this approach looks good and it is much more detailed.
The existing instruction matching in OpenSBI, Xvisor and KVM can be easily adapted to the non-zero transformed value stored in htinst/mtinst CSR.
Is it intentional that hinst and htval are written during traps from U-mode -> HS-mode? If so, shouldn't they start with s- prefixes instead?
My understanding is that the hypervisor in HS-mode can fetch the faulting instruction (if it is not a instruction page fault) by setting the hstatus.sprv bit to 1 and performing a load with the faulting instruction address. Is that correct? If so, decoding the faulting instruction is relatively straightforward.
My understanding is that the hypervisor in HS-mode can fetch the faulting instruction (if it is not a instruction page fault) by setting the hstatus.sprv bit to 1 and performing a load with the faulting instruction address. Is that correct? If so, decoding the faulting instruction is relatively straightforward.
Please refer previous discussion at https://github.com/riscv/riscv-isa-manual/issues/394
Jonathan Behrens wrote:
Is it intentional that hinst and htval are written during traps from U-mode -> HS-mode? If so, shouldn't they start with s- prefixes instead?
We are proposing those CSRs for HS mode; they wouldn't exist for ordinary (non-hypervisor) S mode. As such, they are encoded in the space of hypervisor CSRs and have h- names the same as other hypervisor CSRs.
Yes, the fact that htinst
may be written with a nonzero value on traps from U mode to HS mode (or from HS mode to itself) means an OS running in HS mode could use the information for traps that have no connection to any guest running in a virtual machine. If that additional utility bothers people, we could suppress it by saying htinst
is written with a nonzero value only on transitions from VS or VU mode to HS mode. But I see nothing to be gained from ensuring HS mode gets no superfluous extra advantages over regular S mode.
Any updates on this ? Can we have a PR for this ?
Adopted with commit 899457caf7a9cdcb59a7d57421d249512b00de94.
This issue is a variation on #394. An earlier version of this proposal was #424.
There are reasons to suspect that hypervisor performance could substantially benefit if trap handlers received more information about page faults caused by guest-physical address translation (second-level translation).
To test this hypothesis, I propose adding two hypervisor CSRs,
htval
andhtinst
, plus two machine-level CSRs,mtval2
andmtinst
. The abbreviation "tinst" is short for "trap instruction". Although the hypervisor extension would require all four CSRs to exist, a minimal implementation would be free to hardwire all of them to zeros. Likemtval
andstval
,htval
andhtinst
must be written automatically on any trap into HS mode, andmtval2
andmtinst
must be written on any trap into M mode.When a guest-page fault trap is taken into HS mode,
htval
is automatically written either with zero or with the guest physical address that faulted, shifted right by 2 bits. For any other trap into HS mode,htval
must be written with zero.When a trap is taken into HS mode,
htinst
is automatically written with eitherExcept when a pseudoinstruction is required (described later), the value assigned to
htinst
may always be zero, indicating that the hardware isn't providing the transformed trapping instruction for this particular trap. For interrupts, and for the following synchronous exceptions, the value automatically written tohtinst
must be zero:For these synchronous exceptions,
htinst
may be automatically written with zero or with a transformation of the trapping instruction. If the trapping instruction is not a compressed instruction (it is 32-bit size or larger), the transformed instruction that may be written tohtinst
is as follows:If the trapping instruction is one of LB, LBU, LH, LHU, LW, LWU, LD, FLW, FLD, or FLQ, the transformed instruction has this structure:
If the trapping instruction is one of SB, SH, SW, SD, FSW, FSD, or FSQ, the transformed instruction has this structure:
If the trapping instruction is one of LR.x, SC.x, or AMO*, the transformed instruction has this structure:
Observe that in all cases the instruction's rs1 field (bits 19:15) is replaced by the difference between the faulting virtual address (written to
stval
) and the original virtual address. This can be nonzero only for an access or page fault that occurs for a misaligned memory access. Note also, for basic loads and stores, the instruction's immediate offset is replaced by zero bits.If the trapping instruction is a compressed instruction (16-bit size), the transformed instruction that may be written to
htinst
is found as follows:Bits 1:0 of a transformed instruction in
htinst
will be01
if the trapping instruction is compressed and11
if not.Traps for guest-page faults operate like regular page faults, except a special case applies. If a trap into HS mode is a guest-page fault, and
htval
is given a nonzero value (the faulting guest physical address), and furthermore if the guest memory access was for VS-level address translation, thenhtinst
must be written with one of these pseudoinstructions:For instruction guest-page faults,
htinst
is automatically written either with one of these pseudoinstructions or with zero. (No actual instruction is available, same as for regular instruction page faults.) For load or store/AMO guest-page faults,htinst
may be written with a pseudoinstruction, with zero, or with the same transformed trapping instruction as a regular page fault. Pseudoinstructions inhtinst
are distinguished by having bits 1:0 equal to00
.Note that, if an implementation uses
htval
to supply the faulting guest physical address to a trap handler, it cannot hardwirehtinst
entirely to zero. However, it may choose to support only values 0 and 0x00002000/0x00003000, and possibly 0x0x00002020/0x00003020. (A "write" pseudoinstruction, 0x0x00002020 or 0x00003020, is needed only if the hardware may automatically update bits A and D in VS-level page tables, else it won't arise.)With these new CSRs, a trap handler for guest-page faults will have this information available to it:
stval
, the original virtual address;htval
, if nonzero, the faulting guest physical address (shifted right by 2 bits); andhtinst
, either a special pseudoinstruction indicating that the fault occurred due to a read or write by VS-level address translation, or, if nonzero, a transformation of the faulting instruction.When maximally implemented, this should facilitate both the handling of guest-physical page faults and the emulation of I/O devices for a guest virtual machine.
Machine-level CSRs
mtval2
andmtinst
are of course defined identically tohtval
andhtinst
, except for M mode.