From 84fe233731dab8326b29c76af3141c40fb772bdc Mon Sep 17 00:00:00 2001 From: Ved Shanbhogue <91900059+ved-rivos@users.noreply.github.com> Date: Mon, 3 Jun 2024 16:32:22 -0500 Subject: Integrate Ssdbltrp and Smdbltrp into Priv spec (#1443) --- src/hypervisor.adoc | 24 ++++++++++-- src/machine.adoc | 92 +++++++++++++++++++++++++++++++++++++++++--- src/priv-preface.adoc | 6 +++ src/resources/riscv-spec.bib | 6 +++ src/riscv-privileged.adoc | 2 + src/smdbltrp.adoc | 17 ++++++++ src/ssdbltrp.adoc | 15 ++++++++ src/supervisor.adoc | 63 +++++++++++++++++++++++++++++- 8 files changed, 215 insertions(+), 10 deletions(-) create mode 100644 src/smdbltrp.adoc create mode 100644 src/ssdbltrp.adoc (limited to 'src') diff --git a/src/hypervisor.adoc b/src/hypervisor.adoc index 1e8f0b8..85cb67f 100644 --- a/src/hypervisor.adoc +++ b/src/hypervisor.adoc @@ -345,6 +345,7 @@ causes (codes 16 and above). 12 + 13 + 15 + +16 + 18 + 19 + 20 + @@ -366,6 +367,7 @@ Read-only 0 + Writable + Writable + Writable + +Read-only 0 + Writable + Writable + Read-only 0 + @@ -387,6 +389,7 @@ 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 + @@ -592,7 +595,9 @@ mode V=1. {bits: 1, name: 'CBZE'}, {bits: 24, name: 'WPRI'}, {bits: 2, name: 'PMM'}, - {bits: 27, name: 'WPRI'}, + {bits: 25, name: 'WPRI'}, + {bits: 1, name: 'DTE'}, + {bits: 1, name: 'WPRI'}, {bits: 1, name: 'ADUE'}, {bits: 1, name: 'PBMTE'}, {bits: 1, name: 'STCE'}, @@ -670,6 +675,10 @@ apply when `V=1`: * 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 @@ -915,6 +924,7 @@ modified, or if a VMID is reused, it may be necessary to execute an HFENCE.GVMA instruction (see <>) before or after writing `hgatp`. +[[vsstatus]] ==== Virtual Supervisor Status (`vsstatus`) Register The `vsstatus` register is a VSXLEN-bit read/write register that is @@ -945,7 +955,8 @@ normally read or modify `sstatus` actually access `vsstatus` instead. {bits: 1, name: 'MXR'}, {bits: 3, name: 'WPRI'}, {bits: 1, name: 'SPELP'}, - {bits: 7, name: 'WPRI'}, + {bits: 1, name: 'SDT'}, + {bits: 6, name: 'WPRI'}, {bits: 1, name: 'SD'}, ], config:{lanes: 2, hspace:1024}} .... @@ -971,7 +982,8 @@ normally read or modify `sstatus` actually access `vsstatus` instead. {bits: 1, name: 'MXR'}, {bits: 3, name: 'WPRI'}, {bits: 1, name: 'SPELP'}, - {bits: 8, name: 'WPRI'}, + {bits: 1, name: 'SDT'}, + {bits: 7, name: 'WPRI'}, {bits: 2, name: 'UXL[1:0]'}, {bits: 29, name: 'WPRI'}, {bits: 1, name: 'SD'}, @@ -1030,6 +1042,9 @@ 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 <>) in VS-mode. + ==== Virtual Supervisor Interrupt (`vsip` and `vsie`) Registers The `vsip` and `vsie` registers are VSXLEN-bit read/write registers that @@ -1549,6 +1564,9 @@ the instruction as indicated by the virtual address in `mtval`. capable of holding only an arbitrary subset of other 2-bit-shifted guest physical addresses, if any. +The Ssdbltrap extension (See <>) requires the implementation of +the `mtval2` CSR. + ==== Machine Trap Instruction (`mtinst`) Register The `mtinst` register is an MXLEN-bit read/write register formatted as diff --git a/src/machine.adoc b/src/machine.adoc index 79f6b32..1b8c2ff 100644 --- a/src/machine.adoc +++ b/src/machine.adoc @@ -430,7 +430,8 @@ S-level ISA. {bits: 1, name: 'MPV'}, {bits: 1, name: 'WPRI'}, {bits: 1, name: 'MPELP'}, - {bits: 21, name: 'WPRI'}, + {bits: 1, name: 'MDT'}, + {bits: 20, name: 'WPRI'}, {bits: 1, name: 'SD'}, ], config:{lanes: 4, hspace:1024}} .... @@ -446,8 +447,13 @@ shown in <>. Bits 30:4 of `mstatush` generally contain the same fie {bits: 4, name: 'WPRI'}, {bits: 1, name: 'SBE'}, {bits: 1, name: 'MBE'}, - {bits: 26, name: 'WPRI'}, -], config:{lanes: 1, hspace:1024}} + {bits: 1, name: 'GVA'}, + {bits: 1, name: 'MPV'}, + {bits: 1, name: 'WPRI'}, + {bits: 1, name: 'MPELP'}, + {bits: 1, name: 'MDT'}, + {bits: 21, name: 'WPRI'}, +], config:{lanes: 2, hspace:1024}} .... [[privstack]] @@ -539,6 +545,71 @@ If the machine provides only U and M modes, then only a single hardware storage bit is required to represent either 00 or 11 in MPP. ==== +[[machine-double-trap]] +===== Double Trap Control in `mstatus` Register + +A double trap typically arises during a sensitive phase in trap handling +operations -- when an exception or interrupt occurs while the trap handler (the +component responsible for managing these events) is in a non-reentrant state. +This non-reentrancy usually occurs in the early phase of trap handling, wherein +the trap handler has not yet preserved the necessary state to handle and resume +from the trap. The occurrence of a trap during this phase can lead to an +overwrite of critical state information, resulting in the loss of data needed to +recover from the initial trap. The trap that caused this critical error +condition is henceforth called the _unexpected trap_. Trap handlers are designed +to neither enable interrupts nor cause exceptions during this phase of handling. +However, managing Hardware-Error exceptions, which may occur unpredictably, +presents significant challenges in trap handler implementation due to the +potential risk of a double trap. + +The M-mode-disable-trap (`MDT`) bit is a WARL field introduced by the Smdbltrp +extension. Upon reset, the `MDT` field is set to 1. When the `MDT` bit is set to +1 by an explicit CSR write, the `MIE` (Machine Interrupt Enable) bit is cleared +to 0. For RV64, this clearing occurs regardless of the value written, if any, to +the `MIE` bit by the same write. The `MIE` bit can only be set to 1 by an +explicit CSR write if the `MDT` bit is already 0 or, for RV64, is being set to 0 +by the same write (For RV32, the `MDT` bit is in `mstatush` and the `MIE` bit in +`mstatus` register). + +When a trap is to be taken into M-mode, if the `MDT` bit is currently 0, it is +then set to 1, and the trap is delivered as expected. However, if `MDT` is +already set to 1, then this is an _unexpected trap_. Additionally, when the +Smrnmi extension is implemented, a trap that occurs when executing in M-mode +with the `mnstatus.NMIE` set to 0 is an _unexpected trap_. + +In the event of a _unexpected trap_, the handling is as follows: + +* When the Smrnmi extension is implemented and `mnstatus.NMIE` is 1, the hart + traps to the RNMI handler. To deliver this trap, the `mnepc` and `mncause` + registers are written with the values that the _unexpected trap_ would have + written to the `mepc` and `mcause` registers respectively. The privilege + mode information fields in the `mnstatus` register are written to indicate + M-mode and its `NMIE` field is set to 0. + +[NOTE] +==== +The consequence of this specification is that on occurrence of double trap the +RNMI handler is not provided with information that a trap would report in the +`mtval` and the `mtval2` registers. This information, if needed, may be obtained +by the RNMI handler by decoding the instruction at the address in `mnepc` and +examining its source register contents. +==== + +* When the Smrnmi extension is not implemented, or if the Smrnmi extension is + implemented and `mnstatus.NMIE` is 0, the hart enters a critical-error state + without updating any architectural state including the `pc`. This state + involves ceasing execution, disabling all interrupts (including NMIs), and + asserting a `critical-error` signal to the platform. + +[NOTE] +==== +The actions performed by the platform on assertion of a `critical-error` signal +by a hart are platform specific. The range of possible actions include restarting +the affected hart or restarting the entire platform among others. +==== + +An `MRET` instruction sets the `MDT` bit to 0. + [[xlen-control]] ===== Base ISA Control in `mstatus` Register @@ -1302,6 +1373,8 @@ For exceptions that cannot occur in less privileged modes, the corresponding `medeleg` bits should be read-only zero. In particular, `medeleg`[11] is read-only zero. +The `medeleg`[16] is read-only zero as double trap is not delegatable. + ==== Machine Interrupt (`mip` and `mie`) Registers The `mip` register is an MXLEN-bit read/write register containing @@ -1798,6 +1871,7 @@ _Designated for platform use_ 0 + 0 + 0 + +0 + 0 |0 + 1 + @@ -1815,7 +1889,8 @@ _Designated for platform use_ 13 + 14 + 15 + -16-17 + +16 + +17 + 18 + 19 + 20-23 + @@ -1839,6 +1914,7 @@ Instruction page fault + Load page fault + _Reserved_ + Store/AMO page fault + +Double trap + _Reserved_ + Software check + Hardware error + @@ -2095,7 +2171,8 @@ privileged than M. {bits: 1, name: 'CBZE'}, {bits: 24, name: 'WPRI'}, {bits: 2, name: 'PMM'}, - {bits: 26, name: 'WPRI'}, + {bits: 25, name: 'WPRI'}, + {bits: 1, name: 'DTE'}, {bits: 1, name: 'CDE'}, {bits: 1, name: 'ADUE'}, {bits: 1, name: 'PBMTE'}, @@ -2206,6 +2283,11 @@ the following rules apply to privilege modes that are less than M: * The `henvcfg.SSE` and `senvcfg.SSE` fields will read as zero and are read-only. * `SSAMOSWAP.W/D` raises an illegal-instruction exception. +The Ssdbltrp extension adds the double-trap-enable (`DTE`) field in `menvcfg`. +When `menvcfg.DTE` is zero, the implementation behaves as though Ssdbltrp is not +implemented. When Ssdbltrp is not implemented `sstatus.SDT`, `vsstatus.SDT`, and +`henvcfg.DTE` bits are read-only zero. + When XLEN=32, `menvcfgh` is a 32-bit read/write register that aliases bits 63:32 of `menvcfg`. The `menvcfgh` register does not exist when XLEN=64. diff --git a/src/priv-preface.adoc b/src/priv-preface.adoc index 936409c..c9a6def 100644 --- a/src/priv-preface.adoc +++ b/src/priv-preface.adoc @@ -17,6 +17,7 @@ modules: **Smcntrpmf* + *Smrnmi Extension* + *Smcdeleg* + +*Smdbltrp* + _Supervisor ISA_ + *Svade Extension* + *Svnapot Extension* + @@ -25,6 +26,7 @@ _Supervisor ISA_ + *Svadu Extension* + *Sstc* + *Sscofpmf* + +*Ssdbltrp* + *Hypervisor ISA* + _Shlcofideleg_ @@ -35,6 +37,7 @@ _Shlcofideleg_ *1.0* + *1.0* + *1.0* + +*1.0* + _1.13_ + *1.0* + *1.0* + @@ -44,6 +47,7 @@ _1.13_ + *1.0* + *1.0* + *1.0* + +*1.0* + _0.1_ |_Draft_ + @@ -54,6 +58,7 @@ _0.1_ *Ratified* + *Ratified* + _Draft_ + +_Draft_ + *Ratified* + *Ratified* + *Ratified* + @@ -61,6 +66,7 @@ _Draft_ + *Ratified* + *Ratified* + *Ratified* + +_Draft_ + *Ratified* + _Draft_ |=== diff --git a/src/resources/riscv-spec.bib b/src/resources/riscv-spec.bib index db5bb1b..16e6b38 100644 --- a/src/resources/riscv-spec.bib +++ b/src/resources/riscv-spec.bib @@ -1779,3 +1779,9 @@ pages={109-136} isbn = {978-1-4503-4139-4}, year = {2016} } +@electronic{DEBUG_SPEC, + title = {The RISC-V Debug Specification}, + url = {https://github.com/riscv/riscv-debug-spec}, + year = {} +} +~ diff --git a/src/riscv-privileged.adoc b/src/riscv-privileged.adoc index caff79a..0318802 100644 --- a/src/riscv-privileged.adoc +++ b/src/riscv-privileged.adoc @@ -89,11 +89,13 @@ include::smepmp.adoc[] include::smcntrpmf.adoc[] include::rnmi.adoc[] include::smcdeleg.adoc[] +include::smdbltrp.adoc[] include::supervisor.adoc[] include::sstc.adoc[] include::sscofpmf.adoc[] include::hypervisor.adoc[] include::priv-cfi.adoc[] +include::ssdbltrp.adoc[] include::priv-insns.adoc[] include::priv-history.adoc[] include::bibliography.adoc[] diff --git a/src/smdbltrp.adoc b/src/smdbltrp.adoc new file mode 100644 index 0000000..84df99f --- /dev/null +++ b/src/smdbltrp.adoc @@ -0,0 +1,17 @@ +[[smdbltrp]] +== "Smdbltrp" Double Trap Extension, Version 1.0 + +The Smdbltrp extension addresses a double trap (See <>) in +M-mode. When the Smrnmi extension (<>) is implemented, it enables +invocation of the RNMI handler on a double trap in M-mode to handle the +critical error. If the Smrnmi extension is not implemented or if a double trap +occurs during the RNMI handler's execution, this extension helps transition the +hart to a critical error state and enables signaling the critical error to the +platform. + +To improve error diagnosis and resolution, this extension supports debugging +harts in a critical error state. The extension introduces a mechanism to enter +Debug Mode instead of asserting a critical-error signal to the platform when the +hart is in a critical error state. See cite:[DEBUG_SPEC] for details. + +See <> for the operational details. diff --git a/src/ssdbltrp.adoc b/src/ssdbltrp.adoc new file mode 100644 index 0000000..e2b1127 --- /dev/null +++ b/src/ssdbltrp.adoc @@ -0,0 +1,15 @@ +[[ssdbltrp]] +== "Ssdbltrp" Double Trap Extension, Version 1.0 + +The Ssdbltrp extension addresses a double trap (See <>) +privilege modes lower than M. It enables HS-mode to invoke a critical error +handler in a virtual machine on a double trap in VS-mode. It also allows M-mode +to invoke a critical error handler in the OS/Hypervisor on a double trap in +S/HS-mode. + +The Ssdbltrp extension adds the `menvcfg`.DTE (See <>) and the +`sstatus`.SDT fields (See <>). If the hypervisor extension is +additionally implemented, then the extension adds the `henvcfg`.DTE (See +<>) and the `vstatus`.SDT fields (See <>). + +See <> for the operational details. diff --git a/src/supervisor.adoc b/src/supervisor.adoc index 1e26feb..b212620 100644 --- a/src/supervisor.adoc +++ b/src/supervisor.adoc @@ -64,7 +64,8 @@ register keeps track of the processor's current operating state. {bits: 1, name: 'MXR'}, {bits: 3, name: 'WPRI'}, {bits: 1, name: 'SPELP'}, - {bits: 7, name: 'WPRI'}, + {bits: 1, name: 'SDT'}, + {bits: 6, name: 'WPRI'}, {bits: 1, name: 'SD'}, ], config:{lanes: 2, hspace:1024}} .... @@ -90,7 +91,8 @@ register keeps track of the processor's current operating state. {bits: 1, name: 'MXR'}, {bits: 3, name: 'WPRI'}, {bits: 1, name: 'SPELP'}, - {bits: 8, name: 'WPRI'}, + {bits: 1, name: 'SDT'}, + {bits: 7, name: 'WPRI'}, {bits: 2, name: 'UXL[1:0]'}, {bits: 29, name: 'WPRI'}, {bits: 1, name: 'SD'}, @@ -224,6 +226,63 @@ Access to the `SPELP` field, added by Zicfilp, accesses the homonymous fields of `mstatus` when `V=0`, and the homonymous fields of `vsstatus` when `V=1`. +[[supv-double-trap]] +===== Double Trap Control in `sstatus` Register + +The S-mode-disable-trap (`SDT`) bit is a WARL field introduced by the Ssdbltrp +extension to address double trap (See <>) at privilege +modes lower than M. + +When the `SDT` bit is set to 1 by an explicit CSR write, the `SIE` (Supervisor +Interrupt Enable) bit is cleared to 0. This clearing occurs regardless of the +value written, if any, to the `SIE` bit by the same write. The `SIE` bit can +only be set to 1 by an explicit CSR write if the `SDT` bit is being set to 0 by +the same write or is already 0. + +When a trap is to be taken into S-mode, if the `SDT` bit is currently 0, +it is then set to 1, and the trap is delivered as expected. However, if `SDT` is +already set to 1, then this is an _unexpected trap_. In the event of an +_unexpected trap_, a double-trap exception trap is delivered into M-mode. To +deliver this trap, the hart writes registers, except `mcause` and `mtval2`, with +the same information that the _unexpected trap_ would have written if it was +taken into M-mode. The `mtval2` register is then set to what would be otherwise +written into the `mcause` register by the _unexpected trap_. The `mcause` +register is set to 16, the double-trap exception code. + +An `SRET` instruction sets the `SDT` bit to 0. + +[NOTE] +==== +A trap handler after saving the state needed for resuming from the trap, +including `scause`, `sepc`, and `stval` among others, should clear the `SDT` bit +when it is reentrant. + +Resetting of the `SDT` by an `SRET` enables the trap handler to detect double +trap occuring during the tail phase, where it restores critical state to return +from a trap. + +The consequence of this specification is that if a critical error condition was +caused by a guest page-fault, then the GPA will not be available in `mtval2` +when the double trap is delivered to M-mode. This condition arises if the +HS-mode invokes a hypervisor virtual-machine load or store instruction when +`SDT` is 1 and the instruction raises a guest page-fault. The use of such an +instruction in this phase of trap handling is not common. However, not recording +the GPA is considered benign because, if required, it can still be obtained +-- albeit with added effort -- through the process of walking the page tables. + +For a double trap originating in VS-mode, M-mode should redirect the exception +to HS-mode by copying the values of M-mode CSRs updated by the trap to HS-mode +CSRs and should use an `MRET` to resume execution at the address in `stvec`. + +Supervisor Software Events (SSE), an extension to the SBI, provide a +mechanism for supervisor software to register and service system events +emanating from an SBI implementation, such as firmware or a hypervisor. In the +event of a double trap, HS-mode and M-mode can utilize the SSE mechanism to +invoke a critical-error handler in VS-mode or S/HS-mode, respectively. +Additionally, the implementation of an SSE protocol can be considered as an +optional measure to aid in the recovery from such critical errors. +==== + ==== Supervisor Trap Vector Base Address (`stvec`) Register The `stvec` register is an SXLEN-bit read/write register that holds trap -- cgit v1.1