diff --git a/cfi_backward.adoc b/cfi_backward.adoc index fcf4ab6..2d5e32c 100644 --- a/cfi_backward.adoc +++ b/cfi_backward.adoc @@ -132,11 +132,9 @@ S-mode. If S-mode isn't supported but U-mode is, then with the SSE field set to When `SSE` field is 0, the following rules apply to privilege modes that are less than M: -* Any attempt to access the `ssp` CSR will result in an illegal instruction - exception. * 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 S-stage page tables becomes reserved. +* The `pte.xwr=010b` encoding in VS/S-stage page tables becomes reserved. * The `henvcfg.SSE` and `senvcfg.SSE` fields will read as zero and are read-only. ==== Supervisor environment configuration registers (`senvcfg`) @@ -157,11 +155,9 @@ less than M: Zicfiss extension introduces the `SSE` field (bit 3) in `senvcfg`. If the `SSE` field is set to 1, the Zicfiss extension is activated in VU/U-mode. When -the `SSE` field is 0, the Zicfiss extension remains inactive in VS/U-mode, and +the `SSE` field is 0, the Zicfiss extension remains inactive in VU/U-mode, and the following rules apply: -* Any attempts to access the `ssp` CSR will result in an illegal instruction - exception. * 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. @@ -189,8 +185,6 @@ Zicfiss extension introduces the `SSE` field (bit 3) in `henvcfg`. If the the `SSE` field is 0, the Zicfiss extension remains inactive in VS-mode, and the following rules apply when `V=1`: -* Any attempts to access the `ssp` CSR will result in an illegal instruction - exception. * 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. @@ -204,6 +198,20 @@ The `ssp` CSR is an unprivileged read-write (URW) CSR that reads and writes of the current privilege mode. The bits 1:0 of `ssp` are read-only zero. If the UXLEN or SXLEN may never be 32, then the bit 2 is also read-only zero. +Attempts to access the `ssp` CSR may result in either an illegal instruction +exception or a virtual instruction exception, contingent upon the state of the +`__x__envcfg.SSE` fields. The conditions are specified as follows: + +* If the privilege mode is less than M and `menvcfg.SSE` is 0, an illegal + instruction exception is raised. +* Otherwise, if in U-mode and `senvcfg.SSE` is 0, an illegal instruction + exception is raised. +* Otherwise, if in VS-mode and `henvcfg.SSE` is 0, a virtual instruction + exception is raised. +* Otherwise, if in VU-mode and either `henvcfg.SSE` or `senvcfg.SSE` is 0, + a virtual instruction exception is raised. +* Otherwise, the access is allowed. + ==== Machine Security Configuration (`mseccfg`) .Machine security configuration register (`mseccfg`) when `MXLEN=64` @@ -339,9 +347,9 @@ The `SSPUSH` and `C.SSPUSH` instructions require the virtual address in `ssp` to have a shadow stack attribute (see <>). Correct execution of `SSPUSH` and `C.SSPUSH` requires that `ssp` refers to idempotent memory. If the memory referenced by `ssp` is not idempotent, then the `SSPUSH`/`C.SSPUSH` instructions -cause a store/AMO access fault exception. If the virtual address in `ssp` is not +cause a store/AMO access-fault exception. If the virtual address in `ssp` is not `XLEN` aligned, then the `SSPUSH`/`C.SSPUSH` instructions cause a store/AMO -access fault exception. +access-fault exception. The operation of the `SSPUSH` and `C.SSPUSH` instructions is as follows: @@ -492,14 +500,14 @@ The `SSPOPCHK` and `C.SSPOPCHK` instructions require the virtual address in `ssp` to have a shadow stack attribute (see <>). Correct execution of `SSPOPCHK` and `C.SSPOPCHK` requires that `ssp` refers to idempotent memory. If the memory reference by `ssp` is not idempotent, then the instructions cause a -load access fault exception. If the virtual address in `ssp` is not `XLEN` +load access-fault exception. If the virtual address in `ssp` is not `XLEN` aligned, then `SSPOPCHK` and `C.SSPOPCHK` instructions cause a load access fault exception [NOTE] ==== Misaligned accesses to shadow stack are not required and enforcing alignment is -more secure to detect errors in the program. An access fault exception is raised +more secure to detect errors in the program. An access-fault exception is raised instead of address misaligned exception in such cases to indicate fatality and that the instruction must not be emulated by a trap handler. @@ -536,7 +544,7 @@ endif If the value loaded from the address in `ssp` does not match the value in `rs1`, a software error exception (cause=18) is raised with `__x__tval` set to "shadow stack fault (code=3)". The software error exception caused by `SSPOPCHK`/ -`C.SSPOPCHK` is lower in priority than a load access fault exception. +`C.SSPOPCHK` is lower in priority than a load access-fault exception. The `ssp` is incremented by `SSPOPCHK` and `C.SSPOPCHK` only if the load from the shadow stack completes successfully and no software error exception is @@ -707,18 +715,40 @@ operation is then stored into the register specified in the `dst` operand. The `SSAMOSWAP` instruction requires the virtual address in `addr` to have a shadow stack attribute (see <>). If the virtual address is not XLEN -aligned, then `SSAMOSWAP` causes a store/AMO access fault exception. If the +aligned, then `SSAMOSWAP` causes a store/AMO access-fault exception. If the memory reference by the `ssp` is not idempotent, then `SSAMOSWAP` causes a -store/AMO access fault exception. The operation of the `SSAMOSWAP` instructions +store/AMO access-fault exception. The operation of the `SSAMOSWAP` instructions is as follows: .`SSAMOSWAP` operation [listing] ---- - X(rd) = mem[X(rs1)] - mem[X(rs1)] = X(rs2) + if privilege_mode != M && menvcfg.SSE == 0 + raise illegal instruction exception + else if privilege_mode == M && senvcfg.SSE == 0 + raise illegal instruction exception + else if privilege_mode == VS && henvcfg.SSE == 0 + raise virtual instruction exception + else if privilege_mode == VU && senvcfg.SSE == 0 + raise virtual instruction exception + else + X(rd) = mem[X(rs1)] + mem[X(rs1)] = X(rs2) + endif ---- +Just as for AMOs in the A extension, `SSAMOSWAP` requires that the address +held in `rs1` be naturally aligned to the size of the operand (i.e., 16-byte +aligned for __quadwords__, eight-byte aligned for __doublewords__, and four-byte +aligned for __words__). And the same exception options apply if the address is +not naturally aligned. + +Just as for AMOs in the A extension, the `SSAMOSWAP` optionally provide release +consistency semantics, using the `aq` and `rl` bits, to help implement +multiprocessor synchronization. The memory operation performed by an +`SSAMOSWAP`, has acquire semantics if `aq` bit is 1 and has release semantics if +`rl` bit is 1. + [NOTE] ==== Stack switching is a common operation in user programs as well as supervisor @@ -767,7 +797,6 @@ pointer to be switched using the process outlined in this note. The `SSAMOSWAP` instruction can be used to store this checkpoint. When the old value at the memory location operated on by `SSAMOSWAP` is not required, `rd` can be set to `x0`. - ==== [[SSMP]] @@ -782,16 +811,26 @@ enhanced to support a shadow stack memory region for use by M-mode. ==== Virtual-Memory system extension for Shadow Stack The shadow stack memory is protected using page table attributes such that it -cannot be stored to by instructions other than `SSPUSH`, and `C.SSPUSH`. The -`SSPOPCHK` and `C.SSPOPCHk` instructions can only load from shadow stack memory. +cannot be stored to by instructions other than `SSAMOSWAP`, `SSPUSH`, and +`C.SSPUSH`. The `SSPOPCHK` and `C.SSPOPCHK` instructions can only load from +shadow stack memory. -The `SSPUSH` and `C.SSPUSH` instructions perform a store. The `SSPOPCHK` and -`C.SSPOPCHK` instructions perfom a load. +The `SSAMOSWAP`, `SSPUSH`, and `C.SSPUSH` instructions perform a store. The +`SSPOPCHK` and `C.SSPOPCHK` instructions perform a load. -The shadow stack can be read using all instructions that load from memory. +When the value of `satp.MODE` (or `vsatp.MODE` when `V=1`) is set to `Bare` +and the effective privilege mode is less than M, shadow stack memory accesses +are disallowed. Under these conditions: +* The `SSPUSH`, `SSAMOSWAP`, and `C.SSPUSH` instructions will result in a + store/AMO access-fault exception. +* The `SSPOPCHK` and `C.SSPOPCHK` instructions will result in a load access + fault exception. + +Implicit accesses, including an instruction fetch, to the shadow stack page are +not allowed. Such memory accesses cause an access-fault exception corresponding +to the original access type. -Attempting to fetch an instruction from a shadow stack page raises an -instruction page fault exception. +The shadow stack can be read using all instructions that load from memory. The encoding `R=0`, `W=1`, and `X=0`, is defined to represent a shadow stack page. When `menvcfg.SSE=0`, this encoding remains reserved. When `V=1` and @@ -800,42 +839,41 @@ page. When `menvcfg.SSE=0`, this encoding remains reserved. When `V=1` and The following faults may occur: . If the accessed page is a shadow stack page: -.. Stores other than `SSPUSH` and `C.SSPUSH` cause store/AMO access fault. -.. Instruction fetches cause an instruction page fault. +.. Stores other than `SSAMOSWAP`, `SSPUSH`, and `C.SSPUSH` cause store/AMO + access-fault exception. +.. Implicit accesses cause an access-fault exception corresponding to the + original access type. . If the accessed page is not a shadow stack page or if the page is in non-idempotent memory: -.. `C.SSPUSH` and `SSPUSH` cause a store/AMO access fault. -.. `C.SSPOPCHK` and `SSPOPCHK` cause a load access fault. +.. `SSAMOSWAP`, `C.SSPUSH`, and `SSPUSH` cause a store/AMO access-fault. +.. `C.SSPOPCHK` and `SSPOPCHK` cause a load access-fault. [NOTE] ==== -Stores to shadow stack by instructions other than `SSPUSH`, and `C.SSPUSH` -cause a store/AMO access fault exception, rather than a store/AMO page fault -exception, to indicate fatality. +Stores to shadow stack by instructions other than `SSAMOSWAP`, `SSPUSH`, and +`C.SSPUSH` cause a store/AMO access-fault exception, rather than a store/AMO +page fault exception, to indicate fatality. If a store/AMO page fault was triggered, it would suggest that the operating system should service that fault and correct the condition. Correcting the condition is not possible in this case. The page fault handler would have to resort to decoding the opcode of the instruction that caused the page fault to determine if it was caused by non-shadow-stack-stores to shadow stack pages -(which is a fatal condition) vs. a page fault caused by an `SSPUSH` or -`C.SSPUSH` to a non-resident page (which is a recoverable condition). Since +(which is a fatal condition) vs. a page fault caused by an `SSAMOSWAP, `SSPUSH` +or `C.SSPUSH` to a non-resident page (which is a recoverable condition). Since the operating system page fault handler is typically performance-critical, -causing an access fault instead of a page fault enables the operating system to +causing an access-fault instead of a page fault enables the operating system to easily distinguish between the fatal/non-recoverable conditions and recoverable page faults. On implementations where address misaligned exception is prioritized higher than -access fault exception, a trap handler handler that emulates misaligned stores -must cause an access fault exception if the store is not `SSPUSH` or `C.SSPUSH`, -and the store is being made to a shadow stack page. +access-fault exception, a trap handler handler that emulates misaligned stores +must cause an access-fault exception if the store is not `SSAMOSWAP`, `SSPUSH` +or `C.SSPUSH`, and the store is being made to a shadow stack page. -Shadow stack instructions cause an access fault if the accessed page is not a +Shadow stack instructions cause an access-fault if the accessed page is not a shadow stack page or if the page is in non-idempotent memory to similarly indicate fatality. - -Instruction fetch from a shadow stack page causes a page fault because this -condition is clearly distinguished by a unique cause code and is non-recoverable. ==== To support these rules, the virtual address translation process specified in @@ -856,14 +894,15 @@ follows: 5. A leaf PTE has been found. If the memory access is by a shadow stack instruction and `pte.xwr != 010b`, then cause an access-violation exception - corresponding to the access type. If the memory access is a store/AMO and - `pte.xwr == 010b`, then cause a store/AMO access-violation. If the requested - memory access is not allowed by the `pte.r`, `pte.w`, `pte.x`, and `pte.u` - bits, given the current privilege mode and the value of the `SUM` and `MXR` - fields of the `mstatus` register, stop and raise a page fault exception - corresponding to the original access type. - -The PMA checks are extended to require memory referenced by `SSPUSH`, + corresponding to the access type. If the memory access is either a + non-shadow-stack store/AMO or an implicit access, and `pte.xwr == 010b`, then + an access-fault exception is raised, corresponding to the original access type. + If the requested memory access is not allowed by the `pte.r`, `pte.w`, `pte.x`, + and `pte.u` bits, given the current privilege mode and the value of the `SUM` + and `MXR` fields of the `mstatus` register, stop and raise a page fault + exception corresponding to the original access type. + +The PMA checks are extended to require memory referenced by `SSAMOSWAP`, `SSPUSH`, `C.SSPUSH`, `C.SSPOPCHK`, and `SSPOPCHK` to be idempotent. The `U` and `SUM` bit enforcement is performed normally for shadow stack @@ -891,14 +930,15 @@ a guard page for a stack is a page that is inaccessible to the process owning the stack. For shadow stacks, the guard page may also be a non-shadow-stack page that is otherwise accessible to the process owning the shadow stack because shadow stack loads and stores to non-shadow-stack pages cause an -access fault exception. +access-fault exception. ==== The G-stage address translation and protections remain unaffected by Zicfiss extension. When G-stage page tables are active, the `C.SSPOPCHK` and `SSPOPCHK` instructions require the G-stage page table to have read permission for the -accessed memory, whereas the `C.SSPUSH` and `SSPUSH` instructions require write -permission. The `xwr == 010b` encoding in the G-stage PTE remains reserved. +accessed memory, whereas the `SSAMOSWAP`, `C.SSPUSH` and `SSPUSH` instructions +require write permission. The `xwr == 010b` encoding in the G-stage PTE remains +reserved. [NOTE] ==== @@ -910,32 +950,32 @@ its guests. [[PMP_SS]] ==== PMP extension for shadow stack -When privilege mode is less than M, the PMP region accessed by `SSPUSH` and -`C.SSPUSH` must provide write permission and the PMP region accessed by -`C.SSPOPCHK` and `SSPOPCHK` must provide read permission. - -The M-mode memory accesses by `SSPUSH` and `C.SSPUSH` instructions test for -write permission in the matching PMP entry when permission checking is -required. - -The M-mode memory accesses by `C.SSPOPCHK` and `SSPOPCHK` instructions test for -read permission in the matching PMP entry when permission checking is required. +The PMP region accessed by `SSAMOSWAP`, `SSPUSH` and `C.SSPUSH` must provide +write permission and the PMP region accessed by `C.SSPOPCHK` and `SSPOPCHK` must +provide read permission when permission checking is required. A new WARL field `SSPMP` is defined in the `mseccfg` CSR to identify a PMP entry -as the shadow stack memory region for M-mode accesses. +as the shadow stack memory region for M-mode accesses. When `mseccfg.MML` is 1, the +`SSPMP` field is read-only else it may be written. -When `mseccfg.MML` is 1, the `SSPMP` field is read-only else it may be written. +When the `SSPMP` field is set to zero, the `SSAMOSWAP`, `SSPUSH`, and `C.SSPUSH` +instructions raise a store/AMO access-fault exception, and the `SSPOPCHK` and +`C.SSPOPCHK` instructions raise a load access-fault exception if the effective +privilege mode is M. When the `SSPMP` field is not zero, the following rules are additionally -enforced for M-mode memory accesses: +enforced for memory accesses performed when effective privilege mode is M: -* `SSPUSH`, `C.SSPUSH`, `SSPOPCHK`, and `C.SSPOPCHK` instructions must match the - PMP entry identified by `SSPMP` else an access fault exception corresponding - to the access type occurs. +* `SSAMOSWAP`, `SSPUSH`, `C.SSPUSH`, `SSPOPCHK`, and `C.SSPOPCHK` instructions + must match the PMP entry identified by `SSPMP` else an access-fault exception + corresponding to the access type occurs. + +* Write by instructions other than `SSAMOSWAP`, `SSPUSH` and `C.SSPUSH` that + match the PMP entry identified by `SSPMP` cause an store/AMO access-fault + exception. -* Write by instructions other than `SSPUSH` and `C.SSPUSH` that - match the PMP entry identified by `SSPMP` cause an store/AMO - access fault exception. +* All implicit memory accesses that match the PMP entry identified by `SSPMP` + cause an access-fault exception corresponding to the original access type. [NOTE] ====