Skip to content

Latest commit

 

History

History
1287 lines (1048 loc) · 54.7 KB

riscv-integration.adoc

File metadata and controls

1287 lines (1048 loc) · 54.7 KB

Integrating {cheri_base_ext_name} with the RISC-V Base Integer Instruction Set

{cheri_base_ext_name} is an extension to the RISC-V ISA. The extension adds a carefully selected set of instructions and CSRs that are sufficient to implement new security features in the ISA. To ensure compatibility, {cheri_base_ext_name} also requires some changes to the primary base integer variants: RV32I, providing 32-bit addresses with 64-bit capabilities, and RV64I, providing 64-bit addresses with 128-bit capabilities. The remainder of this chapter describes these changes for both the unprivileged and privileged components of the base integer RISC-V ISAs.

Note
The changes described in this specification also ensure that {cheri_base_ext_name} is compatible with RV32E.
Note
RV128 is not currently supported by any CHERI extension.
Note
In line with the base RISC-V ISA, the unprivileged component with its corresponding {cheri_base_ext_name} changes as described in this chapter can be used with an entirely different privileged-level design. The changes for the privileged component described in this chapter are designed to support existing popular operating systems, and assume the standard privileged architecture specified in the RISC-V ISA.

Memory

A hart supporting {cheri_base_ext_name} has a single byte-addressable address space of 2XLEN bytes for all memory accesses. Each memory region capable of holding a capability also stores a tag bit for each naturally aligned CLEN bits (e.g. 16 bytes in RV64), so that capabilities with their tag set can only be stored in naturally aligned addresses. Tags must be atomically bound to the data they protect.

The memory address space is circular, so the byte at address 2XLEN - 1 is adjacent to the byte at address zero. A capability’s [section_cap_representable_check] described in [section_cap_encoding] is also circular, so address 0 is within the [section_cap_representable_check] of a capability where address 2MXLEN - 1 is within the bounds. However, the decoded top field of a capability is MXLEN + 1 bits wide and does not wrap, so a capability with base 2MXLEN - 1 and top 2MXLEN + 1 is not a subset of the [infinite-cap] capability and does not authorize access to the byte at address 0. Like malformed bounds (see [section_cap_malformed]), it is impossible for a CHERI core to generate a tagged capability with top > 2MXLEN. If such a capability exists then it must have been caused by a logic or memory fault. Unlike malformed bounds, the top overflowing is not treated as a special case in the architecture: normal bounds check rules should be followed.

Programmer’s Model for {cheri_base_ext_name}

For {cheri_base_ext_name}, the 32 unprivileged x registers of the base integer ISA are extended so that they are able to hold a capability as well as renamed to c registers. Therefore, each c register is CLEN bits wide and has an out-of-band tag bit. The x notation refers to the address field of the capability in an unprivileged register while the c notation is used to refer to the full capability (i.e. address, metadata and tag) held in the same unprivileged register.

The tag of the unprivileged c registers must be reset to zero. The reset values of the metadata and address fields are UNSPECIFIED for all unprivileged c registers except c0.

Register c0 is hardwired with all bits, including the capability metadata and tag, equal to 0. In other words, c0 is hardwired to the [null-cap] capability.

PCC - The Program Counter Capability

An authorizing capability with appropriate permissions is required to execute instructions in {cheri_base_ext_name}. Therefore, the unprivileged program counter (pc) register is extended so that it is able to hold a capability. The extended register is called the program counter capability (pcc). The pcc address field is effectively the pc in the base RISC-V ISA so that the hardware automatically increments as instructions are executed. The pcc's metadata and tag are reset to the [infinite-cap] capability metadata and tag with the address field set to the core boot address.

The hardware performs the following checks on pcc for each instruction executed in addition to the checks already required by the base RISC-V ISA. A failing check causes a CHERI exception.

  • The tag must be set

  • The capability must not be sealed

  • The capability must grant execute permission

  • All bytes of the instruction must be in bounds

Note
Operations that update pcc, such as changing privilege or executing jump instructions, unseal capabilities prior to writing. Therefore, implementations do not need to check that that pcc is unsealed when executing each instruction. However, this property has not yet been formally verified and may not hold if additional CHERI extensions beyond {cheri_base_ext_name} are implemented.
Note
It is common for implementations to not allow executing pc relative instructions, such as [AUIPC] or [JAL], in debug mode.
Program Counter Capability

img/pccreg.edn

pcc is an executable vector, so it need not be able to hold all possible invalid addresses.

Capability Instructions

{cheri_base_ext_name} introduces new instructions to the base RISC-V integer ISA to inspect and operate on capabilities held in registers.

Capability Inspection Instructions

These instructions allow software to inspect the fields of a capability held in a c register. The output is an integer value written to an x register representing the decoded field of the capability, such as the permissions or bounds. These instructions do not cause exceptions.

  • [GCTAG]: inspects the tag of the input capability. The output is 1 if the tag is set and 0 otherwise

  • [GCPERM]: outputs the architectural (AP) and software-defined (SDP) permission fields of the input capability

  • [GCTYPE]: outputs the type (e.g. unsealed or sentry) of the input capability

  • [GCBASE]: outputs the expanded base address of the input capability

  • [GCLEN]: outputs the length of the input capability. Length is defined as top - base. The output is 2MXLEN-1 when the capability’s length is 2MXLEN

  • [CRAM]: outputs the nearest bounds alignment that a valid capability can represent

  • [GCHI]: outputs the compressed capability metadata

  • [SCEQ]: compares two capabilities including tag, metadata and address

  • [SCSS]: tests whether the bounds and permissions of a capability are a subset of those from another capability

Note
[GCBASE] and [GCLEN] output 0 when a capability with malformed bounds is provided as an input (see [section_cap_malformed]).

Capability Manipulation Instructions

These instructions allow software to manipulate the fields of a capability held in a c register. The output is a capability written to a c register with its fields modified. The output capability has its tag set to 0 if the input capability did not have a tag set, the output capability has more permissions or larger bounds compared to the input capability, or the operation results in a capability with malformed bounds. These instructions do not give rise to exceptions.

  • [SCADDR]: set the address of a capability to an arbitrary address

  • [CADD], [CADDI]: increment the address of the input capability by an arbitrary offset

  • [SCHI]: replace a capability’s metadata with an arbitrary value. The output tag is always 0

  • [ACPERM]: bitwise AND of a mask value with a bit map representation of the architectural (AP) and software-defined (SDP) permissions fields

  • [SCBNDS]: set the base and length of a capability. The tag is cleared, if the encoding cannot represent the bounds exactly

  • [SCBNDSR]: set the base and length of a capability. The base will be rounded down and/or the length will be rounded up if the encoding cannot represent the bounds exactly

  • [SENTRY]: seal capability as a sentry capability

  • [CBLD]: replace the base, top, address, permissions and mode fields of a capability with the fields from another capability

  • [CMV]: move a capability from a c register to another c register

Capability Load and Store Instructions

A load capability instruction, [LC], reads CLEN bits from memory together with its tag and writes the result to a c register. The capability authorizing the memory access is provided in a c source register, so the effective address is obtained by incrementing that capability with the sign-extended 12-bit offset.

A store capability instruction, [SC], writes CLEN bits and the tag in a c register to memory. The capability authorizing the memory access is provided in a c source register, so the effective address is obtained by incrementing that capability with the sign-extended 12-bit offset.

[LC] and [SC] instructions cause CHERI exceptions if the authorizing capability fails any of the following checks:

  • The tag is zero

  • The capability is sealed

  • At least one byte of the memory access is outside the capability’s bounds

  • For loads, the read permission must be set in AP

  • For stores, the write permission must be set in AP

Capability load and store instructions also cause load or store/AMO address misaligned exceptions if the address is not naturally aligned to a CLEN boundary.

Misaligned capability loads and stores are errors. Implementations must generate exceptions for misaligned capability loads and stores even if they allow misaligned integer loads and stores to complete normally. Execution environments must report misaligned capability loads and stores as errors and not attempt to emulate them using byte access. The Zicclsm extension does not affect capability loads and stores. Software which uses capability loads and stores to copy data other than capabilities must ensure that addresses are aligned.

Note
Since there is only one tag per aligned CLEN bit block in memory, it is not possible to represent a capability value complete with its tag at an address not aligned to CLEN. Therefore, [LC] and [SC] give rise to misaligned address fault exceptions when the effective address to access is misaligned, even if the implementation supports Zicclsm. To transfer CLEN misaligned bits without a tag, use integer loads and stores.

For loads, the tag of the capability loaded from memory is cleared if the authorizing capability does not grant permission to read capabilities (i.e. both [r_perm] and [c_perm] must be set in AP). For stores, the tag of the capability written to memory is cleared if the authorizing capability does not grant permission to write capabilities (i.e. both [w_perm] and [c_perm] must be set in AP).

Warning
TODO: these cases may cause exceptions in the future - we need a way for software to discover and/or control the behavior

Existing RISC-V Instructions

The operands or behavior of some instructions in the base RISC-V ISA changes in {cheri_base_ext_name}.

Integer Computational Instructions

Most integer computational instructions operate on XLEN bits of values held in x registers. Therefore, these instructions only operate on the address field if the input register of the instruction holds a capability. The output is XLEN bits written to an x register; the tag and capability metadata of that register are zeroed.

The add upper immediate to pcc instruction ([AUIPC]) is used to build pcc-relative capabilities. [AUIPC] forms a 32-bit offset from the 20-bit immediate and filling the lowest 12 bits with zeros. The pcc address is then incremented by the offset and a representability check is performed so the capability’s tag is cleared if the new address is outside the pcc's [section_cap_representable_check]. The resulting CLEN value along with the new tag are written to a c register.

Control Transfer Instructions

Control transfer instructions operate as described in the base RISC-V ISA. They also may cause metadata updates and/or cause exceptions in addition to the base behavior as described below.

Unconditional Jumps

[JAL] sign-extends the offset and adds it to the address of the jump instruction to form the target address. The target address is installed in the address field of pcc. The capability with the address of the instruction following the jump is sealed and written to a c register.

[JALR] allows unconditional, indirect jumps to a target capability. The target capability is obtained by incrementing the capability in the c register operand by the sign-extended 12-bit offset, then setting the least significant bit of the result to zero. The target capability is unsealed if it is a sentry with zero offset. The capability with the address of the instruction following the jump is sealed and written to a c register.

All jumps cause CHERI exceptions when a minimum sized instruction at the target address is not within the bounds of the pcc.

[JALR] causes a CHERI exception when:

  • The target capability’s tag is zero

  • The target capability is sealed and the immediate is not zero

  • A minimum sized instruction at the target capability’s address is not within bounds

  • The target capability does not grant execute permission

[JAL] and [JALR] can also cause instruction address misaligned exceptions following the standard RISC-V rules.

Conditional Branches

Branch instructions (see [insns-conbr-32bit]) encode signed offsets in multiples of 2 bytes. The offset is sign-extended and added to the address of the branch instruction to form the target address.

Branch instructions compare two x registers as described in the base RISC-V ISA, so the metadata and tag values are disregarded in the comparison if the operand registers hold capabilities. If the comparison evaluates to true, then the target address is installed in the pcc's address field. These instructions cause CHERI exceptions when a minimum sized instruction at the target address is not within the pcc's bounds.

Integer Load and Store Instructions

Integer load and store instructions transfer the amount of integer data described in the base RISC-V ISA between the registers and memory. For example, [LD] and [LW] load 64-bit and 32-bit values respectively from memory into an x register. However, the address operands for load and store instructions are interpreted differently in {cheri_base_ext_name}: the capability authorizing the access is in the c register operand and the memory address is given by incrementing the address of that capability by the sign-extended 12-bit immediate offset.

All load and store instructions cause CHERI exceptions if the authorizing capability fails any of the following checks:

  • The tag is set

  • The capability is unsealed

  • All bytes of accessed memory are inside the capability’s bounds

  • For loads, the read permission must be set in AP

  • For stores, the write permission must be set in AP

Integer load instructions always zero the tag and metadata of the result register.

Integer stores write zero to the tag associated with the memory locations that are naturally aligned to CLEN. Therefore, misaligned stores may clear up to two tag bits in memory.

Zicsr, Control and Status Register (CSR) Instructions

{cheri_base_ext_name} requires that RISC-V CSRs intended to hold addresses, like mtvec, are now able to hold capabilities. Therefore, such registers are renamed and extended to CLEN-bit in {cheri_base_ext_name}.

Reading or writing any part of a CLEN-bit CSR may cause side effects. For example, the CSR’s tag bit may be cleared if a new address is outside the [section_cap_representable_check] of a CSR capability being written.

This section describes how the CSR instructions operate on these CSRs in {cheri_base_ext_name}.

The CLEN-bit CSRs are summarized in [clen_csr_summary].

CSR Instructions

All CSR instructions atomically read-modify-write a single CSR. If the CSR accessed is of capability size then the capability’s tag, metadata and address are all accessed atomically.

When the [CSRRW] instruction is accessing a capability width CSR, then the source and destination operands are c registers and it atomically swaps the values in the whole CSR with the CLEN width register operand.

There are special rules for updating specific CLEN-wide CSRs as shown in [extended_CSR_writing].

When [CSRRS] and [CSRRC] instructions are accessing a capability width CSR, such as mtvecc, then the destination operand is a c register and the source operand is an x register. Therefore, the instructions atomically read CLEN bits from the CSR, calculate the final address using standard RISC-V behavior (set bits, clear bits, etc.), and that final address is written to the CSR capability’s address field. The update typically uses the semantics of a [SCADDR] instruction which clears the tag if the capability is sealed, or if the updated address is not representable. [extended_CSR_writing] shows the exact action taken for each capability width CSR.

The [CSRRWI], [CSRRSI] and [CSRRCI] variants are similar to [CSRRW], [CSRRS], and [CSRRC] respectively, when accessing a capability width CSR except that they update the capability’s address only using an XLEN-bit value obtained by zero-extending a 5-bit unsigned immediate field.

All CSR instructions cause CHERI exceptions if the pcc does not grant [asr_perm] and the CSR accessed is privileged.

Control and Status Registers (CSRs)

{cheri_base_ext_name} extends the CSRs listed in Table 1, Table 2, Table 3, Table 4 and Table 5 from the base RISC-V ISA and its extensions. The CSRs are renamed to reflect the fact that they are extended to CLEN+1 bits wide, as the x registers are renamed to c registers.

Table 1. Renamed debug-mode CSRs in {cheri_base_ext_name}
Table 2. Renamed machine-mode CSRs in {cheri_base_ext_name}
Table 3. Renamed supervisor-mode CSRs in {cheri_base_ext_name}
Table 4. Renamed virtual supervisor-mode CSRs in {cheri_base_ext_name}
Table 5. Renamed user-mode CSRs in {cheri_base_ext_name}

Machine-Level CSRs

{cheri_base_ext_name} extends some M-mode CSRs to hold capabilities or otherwise add new functions. [asr_perm] in the pcc is typically required for access.

Machine Status Registers (mstatus and mstatush)

The mstatus and mstatush registers operate as described in cite:[riscv-priv-spec] except for the SXL and UXL fields that control the value of XLEN for S-mode and U-mode, respectively, and the MBE, SBE, and UBE fields that control the memory system endianness for M-mode, S-mode, and U-mode, respectively.

The encoding of the SXL and UXL fields is the same as the MXL field of misa. Only 1 and 2 are supported values for SXL and UXL and the fields must be read-only in implementations supporting {cheri_base_ext_name}. The effective XLEN in S-mode and U-mode are termed SXLEN and UXLEN, respectively.

The MBE, SBE, and UBE fields determine the endianness of memory accesses other than instruction fetches performed from M-mode, S-mode, or U-mode, respectively. xBE=0 indicates little endian and xBE=1 is big endian. MBE must be read-only. SBE and UBE must be read only and equal to MBE, if S-mode or U-mode, respectively, is implemented, or read-only zero otherwise.

Note
A further CHERI extension, {cheri_default_ext_name}, optionally makes SXL, UXL, MBE, SBE, and UBE writeable, so implementations that support multiple base ISAs must support both {cheri_base_ext_name} and {cheri_default_ext_name}.

Machine Trap Vector Base Address Register (mtvec)

The mtvec register is as defined in cite:[riscv-priv-spec]. It is an MXLEN-bit register used as the executable vector jumped to when taking traps into machine mode. It is extended into mtvecc.

Machine-mode trap-vector base-address register

img/mtvecreg.edn

Machine Trap Vector Base Address Capability Register (mtvecc)

The mtvecc register is a renamed extension of mtvec that holds a capability. Its reset value is the [infinite-cap] capability. The capability represents an executable vector.

Machine-mode trap-vector base-capability register

img/mtveccreg.edn

The metadata is WARL as not all fields need to be implemented, for example the reserved fields will always read as zero.

When interpreting mtvecc as a capability, as for mtvec, address bits [1:0] are always zero (as they are reused by the MODE field).

When MODE=Vectored, all synchronous exceptions into machine mode cause the pcc to be set to the capability, whereas interrupts cause the pcc to be set to the capability with its address incremented by four times the interrupt cause number.

Capabilities written to mtvecc also include writing the MODE field in mtvecc.address[1:0]. As a result, a representability and sealing check is performed on the capability with the legalized (WARL) MODE field included in the address. The tag of the capability written to mtvecc is cleared if either check fails.

Additionally, when MODE=Vectored the capability has its tag bit cleared if the capability address + 4 x HICAUSE is not within the representable bounds. HICAUSE is the largest exception cause value that the implementation can write to mcause when an interrupt is taken.

Note
When MODE=Vectored, it is only required that address + 4 x HICAUSE is within representable bounds instead of the capability’s bounds. This ensures that software is not forced to allocate a capability granting access to more memory for the trap-vector than necessary to handle the trap causes that actually occur in the system.

Machine Scratch Register (mscratch)

The mscratch register is as defined in cite:[riscv-priv-spec]. It is an MXLEN-bit read/write register dedicated for use by machine mode. Typically, it is used to hold a pointer to a machine-mode hart-local context space and swapped with a user register upon entry to an M-mode trap handler. mscratch is extended into mscratchc.

Machine-mode scratch register

img/mscratchreg.edn

Machine Scratch Capability Register (mscratchc)

The mscratchc register is a renamed extension of mscratch that is able to hold a capability.

{TAG_RESET_CSR}

It is not WARL, all capability fields must be implemented.

Machine-mode scratch capability register

img/mscratchcreg.edn

Machine Exception Program Counter (mepc)

The mepc register is as defined in cite:[riscv-priv-spec]. It is extended into mepcc.

Machine exception program counter register

img/mepcreg.edn

Machine Exception Program Counter Capability (mepcc)

The mepcc register is a renamed extension of mepc that is able to hold a capability. Its reset value is the [infinite-cap] capability.

Machine exception program counter capability register

img/mepccreg.edn

Capabilities written to mepcc must be legalized by implicitly zeroing bit mepcc[0]. Additionally, if an implementation allows IALIGN to be either 16 or 32, then whenever IALIGN=32, the capability read from mepcc must be legalized by implicitly zeroing mepcc[1]. Therefore, the capability read or written has its tag bit cleared if the legalized address is not within the [section_cap_representable_check] or if the legalization changes the address and the capability is sealed.

Note
When reading or writing a sealed capability in mepcc, the tag is not cleared if the original address equals the legalized address.

When a trap is taken into M-mode, mepcc is written with the pcc including the virtual address of the instruction that was interrupted or that encountered an exception. Otherwise, mepcc is never written by the implementation, though it may be explicitly written by software.

As shown in [CSR_exevectors], mepcc is an executable vector, so it does not need to be able to hold all possible invalid addresses. Additionally, the capability in mepcc is unsealed when it is installed in pcc on execution of an [MRET] instruction.

Machine Cause Register (mcause)

{cheri_base_ext_name} adds a new exception code for CHERI exceptions that mcause must be able to represent. The new exception code and its priority are listed in Table 6 and Table 7 respectively. The behavior and usage of mcause otherwise remains as described in cite:[riscv-priv-spec].

Machine cause register

img/mcausereg.edn

Table 6. Machine cause register (mcause) values after trap. Entries added in {cheri_base_ext_name} are in bold
Interrupt Exception Code Description

1
1
1
1

0
1
2
3

Reserved
Supervisor software interrupt
Reserved
Machine software interrupt

1
1
1
1

4
5
6
7

Reserved
Supervisor timer interrupt
Reserved
Machine timer interrupt

1
1
1
1

8
9
10
11

Reserved
Supervisor external interrupt
Reserved
Machine external interrupt

1
1

12-15
≥16

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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16-23
24-27
{cheri_excep_mcause}
29-31
32-47
48-63
≥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
Environment call from S-mode
Reserved
Environment call from M-mode
Instruction page fault
Load page fault
Reserved
Store/AMO page fault
Reserved
Designated for custom use
CHERI fault
Designated for custom use
Reserved
Designated for custom use
Reserved

Table 7. Synchronous exception priority in decreasing priority order. Entries added in {cheri_base_ext_name} are in bold
Priority Exc.Code Description

Highest

3

Instruction address breakpoint

{cheri_excep_mcause}

Prior to instruction address translation:
CHERI fault due to PCC checks (tag, execute permission, invalid address and bounds)

12, 1

During instruction address translation:
First encountered page fault or access fault

1

With physical address for instruction:
Instruction access fault

2
0
8,9,11
3
3

Illegal instruction
Instruction address misaligned
Environment call
Environment break
Load/store/AMO address breakpoint

{cheri_excep_mcause}

CHERI faults due to:
PCC [asr_perm] clear
Branch/jump target address checks (tag, execute permissions, invalid address and bounds)

{cheri_excep_mcause}

Prior to address translation for an explicit memory access:
CHERI fault due to capability checks (tag, permissions, invalid address and bounds)

4,6

Load/store/AMO capability address misaligned
Optionally:
Load/store/AMO address misaligned

13, 15, 5, 7

During address translation for an explicit memory access:
First encountered CHERI PTE page fault12, page fault or access fault

5,7

With physical address for an explicit memory access:
Load/store/AMO access fault

4,6

If not higher priority:

Lowest

13

If not higher priority:
CHERI load PTE fault3

1 The higher priority CHERI PTE page fault covers capability loads or atomics where the loaded tag is not checked, and all capability stores and atomics where the stored tag is set.

2 CHERI PTE page fault exceptions have the same priority against access faults as normal RISC-V page faults. If a normal RISC-V page fault and a CHERI PTE fault are both detected simultaneously, then both are recorded as shown in mtval2 for page faults.

3 The lower priority PTE fault only covers capability loads and atomics where the loaded tag is checked.

Note
The full details of the CHERI exceptions with cause value {cheri_excep_mcause} are in Table 12.

Machine Trap Delegation Register (medeleg)

Bit 28 of medeleg now refers to a valid exception and so can be used to delegate CHERI exceptions to supervisor mode.

Machine Trap Value Register (mtval)

The mtval register is an MXLEN-bit read-write register formatted as shown in Machine trap value register. When a data memory access gives rise to a CHERI fault taken into M-mode, mtval is written with the MXLEN-bit effective address which caused the fault according to the existing rules for reporting load/store addresses from cite:[riscv-priv-spec]. In this case the TYPE field of mtval2 shown in Table 8 is set to {cheri_excep_type_data}. For all other CHERI faults mtval is set to zero.

The behavior of mtval is otherwise as described in cite:[riscv-priv-spec].

If the hardware platform specifies that no exceptions set mtval to a non-zero value, then mtval is read-only zero for all CHERI exceptions.

Machine trap value register

img/mtvalreg.edn

Machine Trap Value Register 2 (mtval2)

The mtval2 register is an MXLEN-bit read-write register, which is added as part of the Hypervisor extension cite:[riscv-priv-spec]. {cheri_base_ext_name} also requires the implementation of this CSR.

When a CHERI fault is taken into M-mode, mtval2 is written with additional CHERI-specific exception information with the format shown in Machine trap value register 2 format for CHERI Faults to assist software in handling the trap.

If mtval is read-only zero for CHERI exceptions then mtval2 is also read-only zero for CHERI exceptions.

mtval2 values for CHERI faults
Machine trap value register 2 format for CHERI Faults

img/mtval2reg.edn

Note
mtval2 is also used for Hypervisor guest physical addresses, and so the implemented bits must also cover that use case. If Hypervisor is not implemented then all WPRI fields in Machine trap value register 2 format for CHERI Faults are read-only-zero.

TYPE is a CHERI-specific fault type that caused the exception while CAUSE is the cause of the fault. The possible CHERI types and causes are encoded as shown in Table 8 and Table 9 respectively.

Table 8. Encoding of TYPE field for CHERI Faults
CHERI Type Code Description

{cheri_excep_type_pcc}

CHERI instruction fetch fault

{cheri_excep_type_data}

CHERI data fault due to load, store or AMO

{cheri_excep_type_jump}

CHERI jump or branch fault

3-15

Reserved

Table 9. Encoding of CAUSE field
CHERI Cause Code Description

{cheri_excep_cause_tag}

Tag violation

{cheri_excep_cause_seal}

Seal violation

{cheri_excep_cause_perm}

Permission violation

{cheri_excep_cause_inv_addr}

Invalid address violation

{cheri_excep_cause_bounds}

Bounds violation

5-15

Reserved

CHERI violations have the following order in priority:

  1. Tag violation (Highest)

  2. Seal violation

  3. Permission violation

  4. Invalid address violation

  5. Bounds violation (Lowest)

mtval2 values for Load/Store/AMO Page Faults

Page faults can be caused by normal RISC-V page faults and also by CHERI PTE faults. If both are detected at once, then both are recorded.

Table 10. mtval2 for page faults
Fault Value

RISC-V page fault

0

CHERI PTE fault

1

RISC-V page fault and CHERI PTE fault

2

Note
Reporting both allows the software the choice about which action to take first, for example a write to a page with no write permission, and the incorrect value of PTE.CRG requires two actions. Software can then decide whether to prioritize the copy-on-write procedure to fix the lack of write permission, or to sweep the page.

Supervisor-Level CSRs

{cheri_base_ext_name} extends some of the existing RISC-V CSRs to be able to hold capabilities or with other new functions. [asr_perm] in the pcc is typically required for access.

Supervisor Trap Vector Base Address Register (stvec)

The stvec register is as defined in cite:[riscv-priv-spec]. It is an SXLEN-bit register used as the executable vector jumped to when taking traps into supervisor mode. It is extended into stvecc.

Supervisor trap-vector base-address register

img/stvecreg.edn

Supervisor Trap Vector Base Address Capability Register (stvecc)

The stvec register is an SXLEN-bit WARL read/write register that holds the trap vector configuration, consisting of a vector base address (BASE) and a vector mode (MODE). The stvecc register is a renamed extension of stvec that is able to hold a capability. Its reset value is the [infinite-cap] capability.

Supervisor trap-vector base-capability register

img/stveccreg.edn

The handling of stvecc is otherwise identical to mtvecc, but in supervisor mode.

Supervisor Scratch Register (sscratch)

The sscratch register is as defined in cite:[riscv-priv-spec]. It is an MXLEN-bit read/write register dedicated for use by supervisor mode. Typically, it is used to hold a pointer to a supervisor-mode hart-local context space and swapped with a user register upon entry to an S-mode trap handler. sscratch is extended into sscratchc.

Supervisor-mode scratch register

img/sscratchreg.edn

Supervisor Scratch Capability Register (sscratchc)

The sscratchc register is a renamed extension of sscratch that is able to hold a capability.

{TAG_RESET_CSR}

It is not WARL, all capability fields must be implemented.

Supervisor scratch capability register

img/sscratchcreg.edn

Supervisor Exception Program Counter (sepc)

The sepc register is as defined in cite:[riscv-priv-spec]. It is extended into sepcc.

Supervisor exception program counter register

img/sepcreg.edn

Supervisor Exception Program Counter Capability (sepcc)

The sepcc register is a renamed extension of sepc that is able to hold a capability. Its reset value is the [infinite-cap] capability.

As shown in [CSR_exevectors], sepcc is an executable vector, so it need not be able to hold all possible invalid addresses. Additionally, the capability in sepcc is unsealed when it is installed in pcc on execution of an [SRET] instruction. The handling of sepcc is otherwise identical to mepcc, but in supervisor mode.

Supervisor exception program counter capability register

img/sepccreg.edn

Supervisor Cause Register (scause)

{cheri_base_ext_name} adds a new exception code for CHERI exceptions that scause must be able to represent. The new exception code and its priority are listed in Table 11 and Table 7 respectively. The behavior and usage of scause otherwise remains as described in cite:[riscv-priv-spec].

Supervisor cause register

img/scausereg.edn

Table 11. Supervisor cause register (scause) values after trap. Causes added in {cheri_base_ext_name} are in bold
Interrupt Exception Code Description

1
1
1
1
1
1
1
1

0
1
2-4
5
6-8
9
10-15
≥16

Reserved
Supervisor software interrupt
Reserved
Supervisor timer interrupt
Reserved
Supervisor external 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
1
2
3
4
5
6
7
8
9
10-11
12
13
14
15
16-23
24-27
28
29-31
32-47
48-63
≥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
Environment call from S-mode
Reserved
Instruction page fault
Load page fault
Reserved
Store/AMO page fault
Reserved
Designated for custom use
CHERI fault
Designated for custom use
Reserved
Designated for custom use
Reserved

Supervisor Trap Value Register (stval)

The stval register is an SXLEN-bit read-write register formatted as shown in Supervisor trap value register.

stval is updated following the same rules as mtval for CHERI exceptions which are delegated to S-mode.

Supervisor trap value register

img/stvalreg.edn

Supervisor Trap Value Register 2 (stval2)

The stval2 register is an SXLEN-bit read-write register, which is added as part of {cheri_base_ext_name} when the implementation supports S-mode. Its CSR address is 0x14b.

stval2 is updated following the same rules as mtval2 for CHERI exceptions which are delegated to S-mode.

The fields are identical to mtval2 for CHERI exceptions, and for load and store/AMO page fault exceptions if {cheri_pte_ext_name} is implemented.

Note
stval2 is not a standard RISC-V CSR, but mtval2 is.
Supervisor trap value register 2

img/stval2reg.edn

Unprivileged CSRs

In {cheri_base_ext_name}, the only register that requires [asr_perm] is [utidc] (for updates but not for reads), and all other unprivileged CSRs do not require pcc to grant [asr_perm] to access unprivileged CSRs.

CHERI Exception handling

Note
auth_cap is [ddc] for {cheri_int_mode_name} and cs1 for {cheri_cap_mode_name}
Table 12. Valid CHERI exception combination description
Instructions Xcause Xtval2. TYPE Xtval2. CAUSE Description Check

All instructions have these exception checks first

All

{cheri_excep_mcause}

{cheri_excep_type_pcc}

{cheri_excep_cause_tag}

pcc tag

not(pcc.tag)

All

{cheri_excep_mcause}

{cheri_excep_type_pcc}

{cheri_excep_cause_seal}

pcc seal

isCapSealed(pcc)1

All

{cheri_excep_mcause}

{cheri_excep_type_pcc}

{cheri_excep_cause_perm}

pcc permission

not(pcc.[x_perm])

All

{cheri_excep_mcause}

{cheri_excep_type_pcc}

{cheri_excep_cause_inv_addr}

pcc invalid address

pcc holds an invalid address

All

{cheri_excep_mcause}

{cheri_excep_type_pcc}

{cheri_excep_cause_bounds}

pcc bounds

Any byte of current instruction out of pcc bounds

CSR/Xret additional exception check

CSR*, [MRET], [SRET]

{cheri_excep_mcause}

{cheri_excep_type_pcc}

{cheri_excep_cause_perm}

pcc permission

not(pcc.[asr_perm]) when required for CSR access or execution of [MRET]/[SRET]

direct jumps additional exception check

[JAL], [insns-conbr-32bit]

{cheri_excep_mcause}

{cheri_excep_type_jump}

{cheri_excep_cause_bounds}

pcc bounds

any byte of minimum length instruction at target out of pcc bounds

indirect jumps additional exception checks

indirect jumps

{cheri_excep_mcause}

{cheri_excep_type_jump}

{cheri_excep_cause_tag}

cs1 tag

not(cs1.tag)

indirect jumps

{cheri_excep_mcause}

{cheri_excep_type_jump}

{cheri_excep_cause_seal}

cs1 seal

isCapSealed(cs1) and imm12 != 0

indirect jumps

{cheri_excep_mcause}

{cheri_excep_type_jump}

{cheri_excep_cause_perm}

cs1 permission

not(cs1.[x_perm])

indirect jumps

{cheri_excep_mcause}

{cheri_excep_type_jump}

{cheri_excep_cause_inv_addr}

cs1 invalid address

target address is an invalid address

indirect jumps

{cheri_excep_mcause}

{cheri_excep_type_jump}

{cheri_excep_cause_bounds}

cs1 bounds

any byte of minimum length instruction at target out of cs1 bounds

Load additional exception checks

all loads

{cheri_excep_mcause}

{cheri_excep_type_data}

{cheri_excep_cause_tag}

auth_cap tag

not(auth_cap.tag)

all loads

{cheri_excep_mcause}

{cheri_excep_type_data}

{cheri_excep_cause_seal}

auth_cap seal

isCapSealed(auth_cap)

all loads

{cheri_excep_mcause}

{cheri_excep_type_data}

{cheri_excep_cause_perm}

auth_cap permission

not(auth_cap.[r_perm])

all loads

{cheri_excep_mcause}

{cheri_excep_type_data}

{cheri_excep_cause_inv_addr}

auth_cap invalid address

Address is invalid (see Invalid address conversion)

all loads

{cheri_excep_mcause}

{cheri_excep_type_data}

{cheri_excep_cause_bounds}

auth_cap bounds

Any byte of load access out of auth_cap bounds

capability loads

4

N/A

N/A

load address misaligned

Misaligned capability load

Store/atomic/cache-block-operation additional exception checks

all stores, all atomics, all cbos

{cheri_excep_mcause}

{cheri_excep_type_data}

{cheri_excep_cause_tag}

auth_cap tag

not(auth_cap.tag)

all stores, all atomics, all cbos

{cheri_excep_mcause}

{cheri_excep_type_data}

{cheri_excep_cause_seal}

auth_cap seal

isCapSealed(auth_cap)

all atomics, CBO.INVAL*

{cheri_excep_mcause}

{cheri_excep_type_data}

{cheri_excep_cause_perm}

auth_cap permission

not(auth_cap.[r_perm])

all stores, all atomics, CBO.INVAL*, CBO.ZERO*

{cheri_excep_mcause}

{cheri_excep_type_data}

{cheri_excep_cause_perm}

auth_cap permission

not(auth_cap.[w_perm])

CBO.CLEAN*, CBO.FLUSH*

{cheri_excep_mcause}

{cheri_excep_type_data}

{cheri_excep_cause_perm}

auth_cap permission

not(auth_cap.[r_perm]) and not(auth_cap.[w_perm])

all stores, all atomics, all cbos

{cheri_excep_mcause}

{cheri_excep_type_data}

{cheri_excep_cause_inv_addr}

auth_cap invalid address

Address is invalid (see Invalid address conversion)

all stores, all atomics

{cheri_excep_mcause}

{cheri_excep_type_data}

{cheri_excep_cause_bounds}

auth_cap bounds

any byte of access out of auth_cap bounds

CBO.ZERO*, CBO.INVAL*

{cheri_excep_mcause}

{cheri_excep_type_data}

{cheri_excep_cause_bounds}

auth_cap bounds

any byte of cache block out of auth_cap bounds

CBO.CLEAN*, CBO.FLUSH*

{cheri_excep_mcause}

{cheri_excep_type_data}

{cheri_excep_cause_bounds}

auth_cap bounds

all bytes of cache block out of auth_cap bounds

CBO.INVAL*

{cheri_excep_mcause}

{cheri_excep_type_pcc}

{cheri_excep_cause_perm}

pcc permission

not(pcc.[asr_perm])

capability stores

6

N/A

N/A

capability alignment

Misaligned capability store

1 This check is architecturally required, but is impossible to encounter so may not required in an implementation.

Note
Indirect branches are [JALR], conditional branches are [insns-conbr-32bit].
Note
[CBO.ZERO] issues as a cache block wide store. All CMOs operate on the cache block which contains the address. Prefetches check that the capability is tagged, not sealed, has the permission ([r_perm], [w_perm], [x_perm]) corresponding to the instruction, and has bounds which include at least one byte of the cache block; if any check fails, the prefetch is not performed but no exception is generated.

CHERI Exceptions and speculative execution

CHERI adds architectural guarantees that can prove to be microarchitecturally useful. Speculative-execution attacks can — among other factors — rely on instructions that fail CHERI permission checks not to take effect. When implementing any of the extensions proposed here, microarchitects need to carefully consider the interaction of late-exception raising and side-channel attacks.

Physical Memory Attributes (PMA)

Typically, the entire memory space need not support tagged data. Therefore, it is desirable that harts supporting {cheri_base_ext_name} extend PMAs with a taggable attribute indicating whether a memory region allows storing tagged data.

Data loaded from memory regions that are not taggable will always have the tag cleared. When the hart attempts to store data with the tag set to memory regions that are not taggable, the implementation may:

  • Cause an access fault exception

  • Implicitly set the stored tag to 0

Page-Based Virtual-Memory Systems

RISC-V’s page-based virtual-memory management is generally orthogonal to CHERI. In {cheri_base_ext_name}, capability addresses are interpreted with respect to the privilege level of the processor in line with RISC-V’s handling of integer addresses. In machine mode, capability addresses are generally interpreted as physical addresses; if the mstatus MPRV flag is asserted, then data accesses (but not instruction accesses) will be interpreted as if performed by the privilege mode in mstatus’s MPP. In supervisor and user modes, capability addresses are interpreted as dictated by the current satp configuration: addresses are virtual if paging is enabled and physical if not.

{cheri_base_ext_name} requires that the pcc grants the [asr_perm] to change the page-table root satp and other virtual-memory parameters as described in Supervisor-Level CSRs.

Invalid Address Handling

When address translation is in effect and XLEN=64, the upper bits of virtual memory addresses must match for the address to be valid:

  • For Sv39, bits [63:39] must equal bit 38

  • For Sv48, bits [63:48] must equal bit 47

  • For Sv57, bits [63:57] must equal bit 56

RISC-V permits that CSRs holding addresses, such as mtvec and mepc (see [CSR_exevectors]) as well as pc, need not hold all possible invalid addresses. Implementations may convert an invalid address into some other invalid address that the register is capable of holding. Therefore, implementations often support area and power optimizations by compressing invalid addresses in a lossy fashion.

Where compressed addresses are implemented, there must be also sufficient address bits to represent all valid physical addresses. The following description is for both virtual and physical addresses.

Note
Compressing invalid addresses allows implementations to reduce the number of flip-flops required to hold some CSRs, such as mtvec. In CHERI, invalid addresses may also be used to reduce the number of bits to compare during a bounds check, for example, to 40 bits if using Sv39, assuming that this also covers all valid physical addresses.
Note
Care needs to be taken not to truncate physical addresses to the implemented number of physical addresses bits without also checking that the capability is still valid following the rules in this section, as the capability bounds and representable range always cover the entire MXLEN-bit address bits, but the address is likely not to.

However, the bounds encoding of capabilities in {cheri_base_ext_name} depends on the address value, so implementations must not convert invalid addresses to other arbitrary invalid address in an unrestricted manner. The remainder of this section describes how invalid address handling must be supported in {cheri_base_ext_name} when accessing CSRs, branching and jumping, and accessing memory.

Updating CSRs

Some capability-holding CSRs need not be able to hold all invalid virtual addresses. Prior to writing to those CSRs, implementations may convert an invalid address into some other invalid address that the CSR is capable of holding. This is problematic for CHERI as updating the address may invalidate the bounds as a result, if the bounds are not those of the [infinite-cap] capability.

Some situations may require that a CSR may be updated to hold a capability with an invalid address:

  • executing instructions, such as [CSRRW]

  • hardware updates to CSRs such as storing the pcc (which becomes capability A) into mepcc/sepcc etc. when taking an exception.

In order to satisfy the definitions of such CSRs and preserve capability system invariants, the following procedure must be used as part of write-back to the CSR:

  1. If A’s address is invalid and A does not have infinite bounds (see [section_cap_encoding]), then A’s tag is set to 0.

  2. Write the final (potentially modified) version of capability A to the CSR e.g. mtvecc, mepcc, etc.

Note
When A’s address is invalid and happens to match an invalid address which the CSR can hold, then it is implementation defined whether to clear A’s tag.
Branches and Jumps

Control transfer instructions jump or branch to a capability A which can be:

The following procedure must be used when jumping or branching to the target capability A if the pcc cannot hold all invalid addresses:

  1. Calculate the effective target address T of the jump or branch as required by the instruction’s behavior.

  2. If T is invalid and A does not have infinite bounds (see [section_cap_encoding]), then the instruction gives rise to a CHERI fault; the CHERI jump or branch fault is reported in the TYPE field and invalid address violation is reported in the CAUSE field of mtval2 or stval2.

  3. If T is invalid and A has infinite bounds (see [section_cap_encoding]), then A’s tag is unchanged and T is written into A’s address field. Attempting to execute the instruction at address T gives rise to an instruction access fault or page fault as is usual in RISC-V.

  4. Otherwise T is valid and the instruction behaves as normal.

Note
RISC-V harts that do not support {cheri_base_ext_name} normally raise an instruction access fault or page fault after jumping or branching to an invalid address. Therefore, {cheri_base_ext_name} aims to preserve that behavior to ensure that harts supporting {cheri_base_ext_name} and {cheri_default_ext_name} are fully compatible with RISC-V harts provided that pcc and [ddc] are set to the [infinite-cap] capability.
Memory Accesses

The following procedure must be used while loading or storing to memory with a capability A when the implementation supports invalid address optimizations:

  1. Calculate the effective address range R of the memory access as required by the instruction’s behavior.

  2. If any byte in R is invalid and A does not have infinite bounds (see [section_cap_encoding]), then the instruction gives rise to a CHERI fault; the CHERI data fault is reported in the TYPE field and invalid address violation is reported in the CAUSE field of mtval2 or stval2.

  3. If any byte in R is invalid and A has infinite bounds (see [section_cap_encoding]), the hart will raise an access fault or page fault as is usual in RISC-V.

  4. Otherwise all bytes in R are valid and the instruction behaves as normal.