This document is in the Stable state
Assume anything could still change, but limited change should be expected. |
Copyright and license information
This specification is licensed under the Creative Commons Attribution 4.0 International License (CC-BY 4.0). The full license text is available at creativecommons.org/licenses/by/4.0/.
Copyright 2024 by RISC-V International.
Contributors
This RISC-V specification has been contributed to directly or indirectly by:
-
Thomas Aird <thomas.aird@codasip.com>
-
Hesham Almatary <hesham.almatary@cl.cam.ac.uk>
-
Andres Amaya Garcia <andres.amaya@codasip.com>
-
John Baldwin <jhb61@cl.cam.ac.uk>
-
Paul Buxton <paul.buxton@codasip.com>
-
David Chisnall <david.chisnall@cl.cam.ac.uk>
-
Jessica Clarke <jessica.clarke@cl.cam.ac.uk>
-
Brooks Davis <brooks.davis@sri.com>
-
Lawrence Esswood <lesswood@google.com>
-
Nathaniel Wesley Filardo <nwf20@cam.ac.uk>
-
Franz A. Fuchs <franz.fuchs@cl.cam.ac.uk>
-
Timothy Hutt <timothy.hutt@codasip.com>
-
Alexandre Joannou <alexandre.joannou@cl.cam.ac.uk>
-
Martin Kaiser <martin.kaiser@codasip.com>
-
Tariq Kurd <tariq.kurd@codasip.com>
-
Ben Laurie <benl@google.com>
-
Marno van der Maas <mvdmaas@lowrisc.org>
-
Maja Malenko <maja.malenko@codasip.com>
-
A. Theodore Markettos <theo.markettos@cl.cam.ac.uk>
-
David McKay <david.mckay@codasip.com>
-
Jamie Melling <jamie.melling@codasip.com>
-
Stuart Menefy <stuart.menefy@codasip.com>
-
Simon W. Moore <simon.moore@cl.cam.ac.uk>
-
Prashanth Mundkur <prashanth@riscv.org>
-
Peter G. Neumann <neumann@csl.sri.com>
-
Robert Norton <robert.norton@cl.cam.ac.uk>
-
Alexander Richardson <alexrichardson@google.com>
-
Michael Roe <mr101@cam.ac.uk>
-
Peter Rugg <peter.rugg@cl.cam.ac.uk>
-
Peter Sewell <peter.sewell@cl.cam.ac.uk>
-
Carl Shaw <carl.shaw@codasip.com>
-
Ricki Tura <ricki.tura@codasip.com>
-
Robert N. M. Watson <robert.watson@cl.cam.ac.uk>
-
Toby Wenman <toby.wenman@codasip.com>
-
Jonathan Woodruff <jonathan.woodruff@cl.cam.ac.uk>
-
Jason Zhijingcheng Yu <yu.zhi@comp.nus.edu.sg>
1. Introduction
This chapter is only included in the standalone CHERI spec and not part of the integrated document. |
1.1. CHERI Concepts and Terminology
Current CPU architectures (including RISC-V) allow memory access solely by specifying and dereferencing a memory address stored as an integer value in a register or in memory. Any accidental or malicious action that modifies such an integer value can result in unrestricted access to the memory that it addresses. Unfortunately, this weak memory protection model has resulted in the majority of software security vulnerabilities present in software today.
CHERI enables software to efficiently implement fine-grained memory protection and scalable software compartmentalization by providing strong, efficient hardware mechanisms to support software execution and enable it to prevent and mitigate vulnerabilities.
Design goals include incremental adoptability from current ISAs and software stacks, low performance overhead for memory protection, significant performance improvements for software compartmentalization, formal grounding, and programmer-friendly underpinnings. It has been designed to provide strong, non-probabilistic protection rather than depending on short random numbers or truncated cryptographic hashes that can be leaked and reinjected, or that could be brute forced.
1.2. CHERI Extensions to RISC-V
This specification is based on publicly available documentation including (Watson et al., 2023) and (Woodruff et al., 2019). It defines the following extensions to support CHERI alongside RISC-V
1.2.1. Extensions to the unprivileged specification
- RV32Y/RV64Y
-
Introduces key, minimal CHERI concepts and features to the RISC-V ISA. The resulting extended ISA is not backwards-compatible with RISC-V.
- Zcherihybrid
-
Extends RV32Y/RV64Y with features to ensure that the ISA extended with CHERI allows backwards binary compatibility with RISC-V.
- Zstid
-
Extension for supporting thread identifiers. This extension improves software compartmentalization on CHERI systems.
- Zcheri0lvl/Zcheri1lvl
-
Extension for supporting capability flow control. This extension allows limiting storing of capabilities to specific regions and can be used, e.g., for safer data sharing between compartments. Zcheri0lvl imposes no restrictions on capability flow, Zcheri1lvl enables a 1-bit flow control level.
The following two extensions are useful independent of CHERI:
1.2.2. Extensions to the privileged specification
The following extensions are added to the privleged specification
- Smcheri
-
Machine-Level Privileged extension to support CHERI.
- Sscheri
-
Supervisor-Level Privileged extension to support CHERI.
- Svcheri
-
Privileged extension for integrating CHERI with virtual memory.
- Sdcheri
-
Privileged extension for integrating CHERI with debug mode.
- Smcherire
-
Privileged extension to disable explicit access to CHERI registers and instructions.
- Smcherivarxlen
-
Privileged extension to allow dynamic XLEN and endianness changes.
- Svucrg
-
CHERI extension for capability revocation on RISC-V harts supporting page-based virtual-memory.
- Shcheri
-
Privileged extension to integrate CHERI with the Hypervisor extensions.
The extension names are provisional and subject to change. |
Extension | Status | Comment |
---|---|---|
Stable |
This extension is a candidate for freezing |
|
Stable |
This extension is a candidate for freezing |
|
Stable |
This extension is a candidate for freezing |
|
Stable |
This extension is a candidate for freezing |
|
Stable |
This extension is a candidate for freezing |
|
Stable |
This extension is a candidate for freezing |
|
Stable |
This extension is a candidate for freezing |
|
Stable |
This extension is a candidate for freezing |
|
Stable |
This extension is a candidate for freezing |
|
Stable |
This extension is a candidate for freezing |
|
Stable |
This extension is a candidate for freezing |
|
Stabilizing |
This extension is a candidate for freeze, software evaluation currently ongoing |
|
Stabilizing |
This extension is a candidate for freeze, software evaluation currently ongoing |
|
Stabilizing |
This extension is a candidate for freeze, software evaluation currently ongoing |
|
Stabilizing |
This extension is a candidate for freeze, software evaluation currently ongoing |
RV32Y/RV64Y is defined as the base extension which all CHERI RISC-V implementations must support. Zcherihybrid and Svucrg are optional extensions in addition to RV32Y/RV64Y.
We refer to software as purecap if it utilizes CHERI capabilities for all memory accesses — including loads, stores and instruction fetches — rather than integer addresses. Purecap software requires the CHERI RISC-V hart to support RV32Y/RV64Y. We refer to software as hybrid if it uses integer addresses or CHERI capabilities for memory accesses. Hybrid software requires the CHERI RISC-V hart to support RV32Y/RV64Y and Zcherihybrid.
See Appendix B for compatibility with other RISC-V extensions.
1.3. Risks and Known Uncertainty
-
All extensions could be divided up differently in the future, including after ratification
-
The RISC-V Architecture Review Committee (ARC) are likely to update all encodings
-
The ARC are likely to update all CSR addresses
-
Instruction mnemonics may be renamed
-
Any changes will affect assembly code, but assembler aliases can provide backwards compatibility
-
1.3.1. Partially Incompatible Extensions
There are RISC-V extensions in development that may duplicate some aspects of CHERI functionality or directly conflict with CHERI and should only be available in Integer Pointer Mode on a CHERI-enabled hart. These include:
-
RISC-V CFI specification
-
"J" Pointer Masking (see Chapter 11).
Chapters for the unprivileged specification
2. RV32Y and RV64Y Base Capability Instruction Sets, Version 1.0
This chapter will appear in the unpriv spec after the RV32I chapter. |
This chapter describes the RV32Y and RV64Y base capability instruction sets, that extend the RV32I and RV64I integer instruction sets with CHERI.
CHERI enhances the base ISA to add hardware memory access control. It has an additional memory access mechanism that protects references to code and data (pointers), rather than the location of code and data (integer addresses). This mechanism is implemented by providing a new primitive, called a capability, that software components can use to implement strongly protected pointers within an address space. Capabilities are unforgeable and delegatable tokens of authority that grant software the ability to perform a specific set of operations. In CHERI, integer-based pointers are replaced by capabilities to provide memory access control.
2.1. CHERI protection model
The CHERI model is motivated by the principle of least privilege, which argues that greater security can be obtained by minimizing the privileges accessible to running software. A second guiding principle is the principle of intentional use, which argues that, where many privileges are available to a piece of software, the privilege to use should be explicitly named rather than implicitly selected. While CHERI does not prevent the expression of vulnerable software designs, it provides strong vulnerability mitigation: attackers have a more limited vocabulary for attacks, and should a vulnerability be successfully exploited, they gain fewer rights, and have reduced access to further attack surfaces.
Protection properties for capabilities include the ISA ensuring that capabilities are always derived via valid manipulations of other capabilities (provenance), that corrupted in-memory capabilities cannot be dereferenced (integrity), and that rights associated with capabilities shall only ever be equal or less permissive (monotonicity). Tampering or modifying capabilities in an attempt to elevate their rights will yield an invalid capability as the valid tag will be cleared. Attempting to dereference via an invalid capability will result in a hardware exception.
CHERI capabilities may be held in registers or in memories, and are loaded, stored, and dereferenced using CHERI-aware instructions that expect capability operands rather than integer addresses. On system initialization, initial capabilities are made available to software by the execution environment via general purpose registers. All other capabilities will be derived from these initial valid capabilities through valid capability transformations.
Developers can use CHERI to build fine-grained spatial and temporal memory protection into their system software and applications and significantly improve their security.
2.2. General purpose registers
RV32Y/RV64Y extends the general purpose registers to 2*XLEN-bit
(hereafter referred to as CLEN), adding metadata to protect its integrity, limit how it is manipulated, and control its use.
In addition to widening to CLEN, each register also gains an out-of-band (hidden / hardware managed) one-bit valid tag.
The exact bitwise layout of capabilities as well as the precise encoding of each field for XLEN=32 and XLEN=64 is described in Appendix A, but always contain the fields listed in the following paragraphs.
2.2.1. Address
The lower XLEN-bits of a capability encode the address of where the capability points. This is also referred to as the integer part of the capability. For registers that are extended but (currently) only hold integer data, all other fields are zero.
2.2.2. Valid Tag
The valid tag is an additional hardware managed bit added to addressable memory and all c registers. It is stored separately and may be referred to as out of band or hidden. It indicates whether a c register or CLEN-aligned memory location contains a valid capability. If the valid tag is set, the capability is valid and can be dereferenced (contingent on checks such as permissions or bounds).
The capability is invalid if the valid tag is clear. Using an invalid capability to dereference memory or authorize any operation raises an exception. All capabilities derived from invalid capabilities are themselves invalid, i.e., their valid tags are 0.
All locations in registers or memory able to hold a capability are CLEN-bits wide including the valid tag bit. Those locations are referred as being CLEN-bit in this specification.
2.2.3. Bounds and Representability
Capabilities encode memory bounds, i.e. the lowest and highest byte in memory that it is permitted to access when dereferenced for data memory access, or for instruction execution.
Checking is on a byte-by-byte basis, so that it is possible for a memory access to be fully in-bounds, partially out-of-bounds or fully out-of-bounds.
All partially or fully out-of-bounds accesses cause an exception.
Every capability has two bounds - base and top.
The base is returned by the GCBASE instruction.
There is no equivalent instruction for the top, but there is for the length which is defined to be length = top - base
, and is returned by GCLEN.
-
The base is XLEN-bits and is inclusive.
-
The top is XLEN+1 bits and is exclusive.
-
The extra bit is required to allow the bounds to include the top byte of memory.
-
Inclusive top, with XLEN-bits, was considered but rejected in favor of the exclusive top. |
Therefore a memory location A
in the range base ≤ A < top
is within bounds, and so valid to access.
Checking every byte of every executed instruction and byte of every data memory access is fundamental to the memory safety which CHERI provides.
In a typical load/store unit, the expansion of the bounds from cs1 and bounds checking is in parallel with the address calculation, the memory translation and/or the PMA/PMP checking.
|
A compressed format is used to encode the bounds with a scheme similar to floating-point using an exponent and a mantissa. Therefore small exponents can allow byte granularity on the bounds, but larger exponents give coarser granularity.
The ISA only allows the bounds of a capability to be reduced. Therefore instructions cannot output any capability with the valid tag set which include bounds (or permissions) which are greater than any input capability which also has its valid tag set. On system initialization the Infinite is available which has bounds which cover all of memory, and maximum permissions set. All smaller capabilities are derived from this.
Bounds can be reduced using the SCBNDS/SCBNDSI instructions, which require the final bounds to be accurately encoded, clearing the valid tag if that is not possible due to the granularity constraints. The requested bounds can be rounded up to the nearest encodable value above the requested bounds using SCBNDSR and CRAM can be used to determine the granularity which is possible to encode.
Bounds can only be reduced with SCBNDS/SCBNDSI/SCBNDSR. If SCBNDSR rounds up the requested bounds, they must still be no larger than the initial bounds. |
The bounds are encoded relative to the address field, sharing some upper bits of the address. The number of shared bits depend on the exponent, see Section A.1.4.
Early versions of CHERI encoded the top and bottom bounds as full width addresses. This proved to be impractical for real systems, and so the CHERI-concentrate compressed system was developed to reduce the overhead. |
Because the upper bits of the address are shared with the bounds, the address of a capability cannot be arbitrary modified without risking changing the meaning of the bounds. Therefore whenever a capability address is updated, the semantics of the SCADDR instruction are required to check that the decoding of the bounds hasn’t changed. If they have changed, then the valid tag (if set) is cleared, so that the capability can no longer be used for dereferencing memory.
Capabilities allow the address pointer to be outside of the bounds by a small amount.
Behavior was observed in software which allows pointers to legitimately move outside of arrays, and then only come back into the valid range on dereference. |
The maximum range of address values that the pointer can take is defined by the representable region, which is checked on every update by SCADDR.
CHERI versions which use a different encoding scheme to the default may specify an alternative to the representable region check. Therefore the rest of the specification uses the phrase represented exactly |
The bounds and representable region (or space) are illustrated in Figure 2. E, MW and R in the figure are all introduced in Section A.1.4.2 along with the bounds decoding.
In the presence of memory corruption, fault injection, or hardware bugs, bounds can theoretically become malformed. Instructions which decode bounds will typically clear the valid tag of the output if the input is found to be malformed.
CHERI requires that the capability is correctly formed if the valid tag is set. Including handling of malformed bounds, and invalid settings of reserved bits, in the architecture allows the behavior to be clearly specified for all 2(CLEN+1) input values. |
2.2.4. Capability Type (CT)
This metadata field indicates the type of the capability. The type determines which operations the capability authorizes. The following capability types are defined in RV32Y/RV64Y:
Type | Hardware interpretation |
---|---|
0 |
Unsealed capability |
1 |
Sentry capability |
- Unsealed capabilities
-
When
CT=0
, the capability authorizes access to a region of memory as defined by the permissions and bounds.
- Sentry capabilities
-
Capabilities with
CT=1
describe function entry points, known as sealed entry (sentry) capabilities. They cannot be dereferenced to access memory and are only allow very limited changes to the fields in the capability, which is restricted to reducing the CL field using ACPERM. Modifying any other fields with ACPERM, or any other instruction, clears the valid tag of the output capability. However, control-flow instruction can be used to jump to a sentry capability to begin executing the instructions it references.Sentry capabilities can establish a form of control-flow integrity between mutually distrusting code. For example, the JALR (RV32Y/RV64Y) instruction with zero offset automatically unseals a sentry target capability and installs it in the program counter capability. The jump-and-link instructions also seal the return register, so the callee can return to the caller but cannot access the memory pointed at by the return register. In addition to using them for secure entry points, sentry capabilities can also be useful to software as secure software tokens. They can be converted to an unsealed capability by rebuilding via a superset capability with the CBLD instruction.
2.2.5. Architectural Permissions (AP)
This metadata field encodes architecturally defined permissions of the capability. Permissions grant access subject to the valid tag being set, the capability being unsealed, and bounds checks passing. Any operation is also contingent on requirements imposed by other RISC-V architectural features, such as virtual memory, PMP and PMAs, even if the capability grants sufficient permissions. The permissions currently defined in RV32Y/RV64Y are listed below.
Permissions can only be removed using ACPERM, they cannot be added.
- Read Permission (R)
-
Allow reading data from memory. Tags are always read as zero when reading non-capability data.
- Write Permission (W)
-
Allow writing data to memory. Valid tags are always written as zero when writing non-capability data. Every CLEN aligned word in memory has a valid tag, if any byte is overwritten with non-capability data then the valid tag for all CLEN-bits is cleared.
- Capability Permission (C)
-
Allow reading capability data from memory if the authorizing capability also grants R-permission. Allow writing capability data to memory if the authorizing capability also grants W-permission.
- Execute Permission (X)
-
Allow instruction execution.
- Load Mutable Permission (LM)
-
Allow preserving the W-permission of capabilities loaded from memory. If a capability grants R-permission and C-permission, but no LM-permission, then a capability loaded via this authorizing capability will have W-permission and LM-permission removed. The permission stripping behavior only applies to loaded capabilities that have their valid tag set and are not sealed; loaded capabilities that are sealed or invalid do not have their permissions changed. This ensures that capability loads/stores of non-capability data do not modify the stored value.
Clearing a capability’s LM-permission and W-permission allows sharing a read-only version of a data structure (e.g., a tree or linked list) without making a copy. |
- Access System Registers Permission (ASR)
-
Allow read and write access to privileged CSRs as well as some privileged instructions. In RV32Y/RV64Y, the only affected CSR is the unprivileged utidc CSR, which requires ASR-permission for writing (but not for reading).
This permission is important in privileged execution environments. Removing this permission allows constraining privileged software to a sandbox that cannot be subverted by changing privileged state. |
Extensions may add additional non-privileged CSRs that require ASR-permission. |
- Store Level Permission (SL)
-
This is a variable width field that allows limiting the propagation of capabilities using the following logic: capabilities with a Capability Level (CL) less than the inverse of the authorizing capability’s SL-permission will be stored with the valid tag cleared. With
LVLBITS=1
there is a single bit comparison, so it behaves as follows:-
If this field (as well as C-permission and W-permission) is set to 1 then capabilities may be stored via this capability regardless of their associated Capability Level (CL).
-
If this field is zero, then any capability with a Capability Level (CL) of zero (i.e., local), will be stored with the valid tag cleared.
-
- Elevate Level Permission (EL)
-
Any unsealed capability with its valid tag set to 1 that is loaded from memory has its EL-permission cleared and its Capability Level (CL) restricted to the authorizing capability’s Capability Level (CL) if the authorizing capability does not grant EL-permission. If sealed, then only CL is modified, EL-permission is unchanged. This permission is similar to the existing LM-permission, but instead of applying to the W-permission on the loaded capability it restricts the CL field.
2.2.6. Capability Level (CL)
The Capability Level (CL) is a variable width field that allows enforcing invariants on capability propagation. For example, the Capability Level can be used to ensure that a callee can only write a copy of the passed-in argument capability to specific locations in memory (e.g., the callee’s stack frame but not the heap). It can also be used to avoid sharing of compartment-local data (such as pointers to a stack object) between compartments.
This specification only defines the architectural mechanics of this feature, for further information on how this can be used by software please refer to (Watson et al., 2023). |
The width of this field depends on whether the Zcheri0lvl or Zcheri1lvl extension is implemented:
Zcheri0lvl
In this case the field is hardwired to 1 and all checks based on the Capability Level can be omitted (since they always pass).
Zcheri1lvl
The Capability Level can hold two values: when set to 1 the capability is global (in general allowing it to be stored using any authorizing capability), and when set to 0 the capability is local, and can only be stored by authorizing capabilities with the SL-permission set. Furthermore, the EL-permission can be used to restrict loading of global capabilities — causing the hardware to automatically set the level of loaded capabilities to local instead.
As with permissions, the capability level can only be decreased but never increased (without deriving from a capability with a higher level). But unlike architectural permissions, CL can be reduced even if the capability is sealed.
Auth cap field | Data cap field | |||
---|---|---|---|---|
W |
C |
SL |
CL |
Notes |
1 |
1 |
1 |
X |
Store data capability unmodified |
0 |
1 |
Store data capability unmodified ( |
||
0 |
Store data capability with valid tag cleared ( |
if W=0 or C=0 then SL is irrelevant |
Auth cap field | Data cap field | |||||
---|---|---|---|---|---|---|
R |
C |
EL |
CL |
Tag |
Sealed |
Action |
1 |
1 |
0 |
X |
1 |
Yes |
Load data capability with |
No |
Load data capability with |
|||||
All other cases |
Load data capability with EL, CL unmodified |
Future extensions are permitted to add more levels.
2.2.7. Software-Defined Permissions (SDP)
The metadata also contains an encoding-dependent number of software-defined permission (SDP) bits. They can be inspected by the kernel or application programs to enforce restrictions on API calls (e.g. permit/deny system calls, memory allocation, etc.). They can be cleared by ACPERM but are not interpreted by the CPU otherwise.
While these bits are not used by the hardware as architectural permissions, modification follows the same rules: SDP bits can only be cleared and never set.
This property is required to ensure restricted programs cannot forge capabilities that would pass the software-enforced checks. |
2.2.8. Special Capabilities
Infinite Capability
The Infinite capability grants all permissions while its bounds also cover the whole address space. All capability checks pass when performed against an Infinite capability. The in-memory encoding of the Infinite capability is described in Section A.2.2.
The Infinite capability is also known as 'default', 'almighty', or 'root' capability in other CHERI documentation. |
NULL Capability
A capability with all-zeroes metadata, an unset valid tag, and an address of zero is referred to as the NULL capability. This capability grants no permissions and any dereference results in a CHERI exception. The memory representation of the NULL capability is all zeroes.
2.3. Added State
A CHERI core adds state to allow capabilities to be used from within integer (X) registers, and to ensure they are not corrupted as they flow through the system. This means the following state is added by RV32Y/RV64Y:
2.3.1. Extended general purpose integer registers
The XLEN-wide integer registers (e.g., sp
, a0
) are all extended with another XLEN-bits of capability metadata plus a valid tag bit.
When referring to the extended register, the x
prefix is replaced with a c
: i.e. the capability extended version of x0
becomes c0
.
The existing integer register names refer to the address part of the capability.
For the ABI register names the c
prefix is added, i.e., csp
, ca0
.
The zero register is extended with zero metadata and a cleared valid tag: this is called the NULL capability.
Instruction encodings refer to c registers when they use cs1 , cd , etc. instead of rs1 , rd (which reads/writes the XLEN-bit subset of the register).
|
2.3.2. Extended CSRs
All registers that store addresses are extended to contain capabilities.
In the base RV32Y/RV64Y ISA, only the program counter (pc
) register is extended to become the Program Counter Capability (pcc).
All CSRs that hold pointers are extended to CLEN-bits, but since no CSRs are defined in the RV32I/RV64I base instruction set, any such change is described in the corresponding chapters. |
2.3.3. The Program Counter Capability (pcc
)
The pc
is extended to be the Program Counter Capability.
Extending the pc
allows the range of branches, jumps and linear execution for currently executing code to be restricted.
The pcc address field is the pc
in the base RISC-V ISA so that the
hardware automatically updates it as instructions are executed.
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.
ARC suggest that this become a software check exception, which would need a CHERI specific value in Xtval2 |
-
The valid 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
On startup pcc bounds and permissions must be set such that the program can run successfully (e.g., by setting it to Infinite to ensure all instructions are in bounds).
2.3.4. Valid tags in registers
Every register has a one-bit valid tag, indicating whether the capability in the register is valid to be dereferenced. This valid tag is cleared whenever an invalid capability operation is performed. Examples of such invalid operations include writing only the integer portion (the address field) of the register or attempting to increase bounds or permissions.
2.3.5. Valid tags in memory
The valid tags are tracked through the memory subsystem: every aligned CLEN-bit wide region has a non-addressable one-bit valid tag, which the hardware manages atomically with the data. The valid tag is cleared if any byte in the CLEN/8 aligned memory region is ever written using an operation other than a store of a capability operand with C-permission granted.
All system memory and caches that store capabilities must preserve this abstraction, handling the valid tags atomically with the data. |
2.4. Capability checks
With RV32Y/RV64Y, every memory access performed by a CHERI core must be authorized by a capability.
Instruction fetches, branches, jumps, and data memory accesses may result in a fatal exception if the access is out of bounds, or if the authorizing capability is missing the required permissions. I.e.:
-
all load instructions requires R-permission
-
all store instructions require W-permission
-
all indirect jumps require X-permission on the target capability
See CHERI Exception handling in the privileged specification for further details on the exception reporting mechanism.
Instruction fetch is also authorized by a capability: the program counter capability (pcc) which extends the PC. This allows code fetch to be bounded, preventing a wide range of attacks that subvert control flow with non-capability data.
The authorizing capability is either named explicitly (the base register of a load/store operation) or implicitly (when executing a branch, pcc is used for authorization).
E.g., lw t0, 16(csp)
loads a word from memory, getting the address, bounds, and permissions from the csp
(capability stack pointer) register.
No other exception paths are added by RV32Y/RV64Y: in particular, capability manipulations do not except, but may clear the valid tag on the result capability if the operation is not permitted.
Branches and jumps may raise exceptions, reusing the Instruction Address Misaligned exception path. |
2.5. Instructions Which Update The Capability Pointer
Updating the value of the pointer (i.e., the address field) of a capability requires specific instructions instead of integer ADD/ADDI. They all include a check that the result can be represented exactly.
Mnemonic | Description |
---|---|
Increment capability address by immediate, represented exactly check |
|
Increment capability address by register, represented exactly check |
|
Replace capability address, represented exactly check |
2.5.1. CADDI
See CADD.
2.5.2. CADD
- Synopsis
-
Capability pointer increment
- Mnemonic
-
cadd cd, cs1, rs2
caddi cd, cs1, imm
- Suggested assembly syntax
-
add cd, cs1, rs2
add cd, cs1, imm
The suggested assembly syntax distinguishes from integer add by operand type.
|
- Encoding
CADD with rs2=x0 is decoded as CMV instead, the key
difference being that capabilities cannot have their valid tag
cleared by CMV.
|
- Description
-
Copy the capability
cs1
tocd
.For CADD, increment
cd.address
by the value inrs2
.
For CADDI, incrementcd.address
by the immediate valueimm
.Set
cd.tag=0
ifcs1
is sealed.Set
cd.tag=0
if the resulting capability cannot be represented exactly.Set
cd.tag=0
ifcs1
's bounds are malformed, or if any of the reserved fields are set. - Operation for CADD
-
let cs1_val = C(cs1); let rs2_val = X(rs2); let newCap = incCapAddrChecked(cs1_val, rs2_val); C(cd) = newCap; RETIRE_SUCCESS
- Operation for CADDI
-
let cs1_val = C(cs1); let immBits : xlenbits = sign_extend(imm); let newCap = incCapAddrChecked(cs1_val, immBits); C(cd) = newCap; RETIRE_SUCCESS
2.5.3. SCADDR
- Synopsis
-
Capability set address
- Mnemonic
-
scaddr cd, cs1, rs2
- Encoding
- Description
-
Copy the capability
cs1
tocd
.Set
cd.address
tors2
.Set
cd.tag=0
ifcs1
is sealed.Set
cd.tag=0
if the resulting capability cannot be represented exactly.Set
cd.tag=0
ifcs1
's bounds are malformed, or if any of the reserved fields are set. - Operation
-
C(cd) = setCapAddrChecked(C(cs1), X(rs2)); RETIRE_SUCCESS
2.6. Instructions Which Manipulate Capability Data
For security, capabilities can only be modified in restricted ways. Special instructions are provided to copy capabilities or perform manipulations such as shrinking the bounds (SCBNDS), reducing the permissions (ACPERM) or authorizing a capability with another one which has a superset (or identical) bounds and permissions (CBLD).
Mnemonic | Description |
---|---|
AND capability permissions (expand to 1-bit per permission before ANDing) |
|
Move capability register |
|
Set metadata and clear valid tag |
|
Set immediate bounds on capability with rounding, clear valid tag if rounding is required |
|
Set register bounds on capability with rounding, clear valid tag if rounding is required |
|
Set bounds on capability with rounding up as required |
|
Seal capability |
|
Set cd to cs2 with its tag set after checking that cs2 is a subset of cs1 |
2.6.1. ACPERM
- Synopsis
-
Mask capability permissions
- Mnemonics
-
acperm cd, cs1, rs2
- Encoding
- Description
-
ACPERM performs the following operations:
-
Convert the AP and SDP fields of capability
cs1
into a bit field with the format shown in Figure 5. -
Calculate the bitwise AND of the bit field with the mask
rs2
.Some permission bits may be hardwired, in which case they are not included in this bitwise AND. -
Encode the resulting architectural permissions following the rules in Section A.1.1.1.
Depending on the base ISA and supported extensions, some combinations of permissions cannot be encoded or are not useful. In case the requested permissions combination falls into this category, ACPERM will return useful minimal sets of permissions, which may be no permissions. Therefore, it is possible that requesting to clear a permission also clears others, but ACPERM will never add new permissions. -
Copy
cs1
tocd
, and update the AP and SDP fields with the newly calculated versions. -
Set
cd.tag=0
ifcs1
is sealed and any permission bits were affected by ACPERM.-
Do not invalidate the tag on sealed capability if only the capability levels (CL) changed.
-
-
The EL, SL and CL fields are only modifiable if the implementation supports Zcheri1lvl, for Zcheri0lvl they are hardwired to 1. |
If a future extension adds a new permission that overlaps with an existing permission (e.g., finer-grained ASR-permission), then clearing the original must also clear the new permission. This ensures software forward-compatibility: for example, a kernel that does not know about finer-grained ASR-permission subsets must still be able to prevent all access to privileged instructions and CSRs by clearing ASR-permission. |
While capability levels (CL) are conceptually a label on the capability rather than a permission granted by the capability, they are still adjusted using the ACPERM instruction. This avoids the need for a dedicated instruction and allows reducing the level and removing EL-permission in a single instruction. |
- Operation
-
let cs1_val = C(cs1); let rs2_val = X(rs2); let cond = capIsSealed(cs1_val) | not(capReservedValid(cs1_val)); let inCap = clearTagIf(cs1_val, cond); let old_perms = packPerms(getArchPermsLegalized(inCap), inCap.sd_perms).bits; let new_perms = old_perms & rs2_val; let (new_arch_perms, new_sd_perms) = unpackPerms(struct {bits = new_perms}); let newCap = { setArchPerms(inCap, new_arch_perms) with sd_perms = new_sd_perms }; C(cd) = newCap; RETIRE_SUCCESS
2.6.2. CMV
- Synopsis
-
Capability move
- Mnemonic
-
cmv cd, cs1
- Suggested assembly syntax
-
mv cd, cs1
The suggested assembly syntax distinguishes from integer mv by operand type.
|
- Encoding
- Description
-
The contents of capability register
cs1
are written to capability registercd
. CMV unconditionally does a bit-wise copy fromcs1
tocd
.
This instruction can propagate tagged capabilities which have malformed bounds, have reserved bits set or have a permission field which cannot be produced by ACPERM.
- Operation
-
C(cd) = C(cs1); RETIRE_SUCCESS
2.6.3. SCHI
- Synopsis
-
Capability set metadata
- Mnemonic
-
schi cd, cs1, rs2
- Encoding
- Description
-
Copy
cs1
tocd
.Replace the capability metadata (i.e., bits [CLEN-1:MXLEN]) with
rs2
and setcd.tag
to 0.The value of cs1.tag
does not affect the result. - Operation
-
let capVal = C(cs1); let intVal = X(rs2); let newCap = bitsToCap(false, intVal @ capVal.address); C(cd) = newCap; RETIRE_SUCCESS
2.6.4. SCBNDSI
See SCBNDS.
2.6.5. SCBNDS
- Synopsis
-
Capability set bounds
- Mnemonics
-
scbnds cd, cs1, rs2
scbndsi cd, cs1, uimm
- Encoding
- Description
-
Capability register
cd
is set to capability registercs1
with the base address of its bounds replaced with the value ofcs1.address
and the length of its bounds set tors2
for SCBNDS, orimm
for SCBNDSI.Set
cd.tag=0
ifcs1.tag=0
,cs1
is sealed or ifcd
's bounds exceedcs1
's bounds.Set
cd.tag=0
if the requested bounds cannot be encoded exactly.Set
cd.tag=0
ifcs1
's bounds are malformed, or if any of the reserved fields are set.SCBNDSI uses the
s
bit to scale the immediate by 4 placesimmediate = ZeroExtend(s ? uimm<<4 : uimm)
The SCBNDSI encoding with s=1 and uimm ≤ 1 is RESERVED since these immediates can also be encoded with s=0 .
|
- Operation for SCBNDS
-
let cs1_val = C(cs1); let length = X(rs2); let newBase = cs1_val.address; let newTop : CapLenBits = zero_extend(newBase) + zero_extend(length); // inCapBoundsNoWrap returns false if the input bounds are malformed. let inBounds = inCapBoundsNoWrap(cs1_val, newBase, unsigned(length)); let (exact, newCap) : (bool, Capability) = setCapBounds(cs1_val, newBase, newTop); let cond = not(inBounds & exact) | boundsMalformed(newCap) | not(capReservedValid(newCap)) | capIsSealed(newCap); C(cd) = clearTagIf(newCap, cond); RETIRE_SUCCESS
- Operation for SCBNDSI
-
let cs1_val = C(cs1); let length = if s == 0b1 then uimm5 @ 0b0000 else 0b0000 @ uimm5; let newBase = cs1_val.address; let newTop : CapLenBits = zero_extend(newBase) + zero_extend(length); // inCapBoundsNoWrap returns false if the input bounds are malformed. let inBounds = inCapBoundsNoWrap(cs1_val, newBase, unsigned(length)); let (exact, newCap) : (bool, Capability) = setCapBounds(cs1_val, newBase, newTop); assert(exact, "SCBNDSI immediate too small for non-exact lengths"); let cond = not(inBounds) | boundsMalformed(newCap) | not(capReservedValid(newCap)) | capIsSealed(newCap); C(cd) = clearTagIf(newCap, cond); RETIRE_SUCCESS
2.6.6. SCBNDSR
- Synopsis
-
Capability set bounds, rounding up if necessary
- Mnemonic
-
scbndsr cd, cs1, rs2
- Encoding
- Description
-
Capability register
cd
is set to capability registercs1
with the base address of its bounds replaced with the value ofcs1.address
and the length of its bounds set tors2
.The base is rounded down and the top is rounded up by the smallest amounts needed to form a representable capability covering the requested base and top.
Set
cd.tag=0
ifcs1.tag=0
,cs1
is sealed or ifcd
's bounds exceedcs1
's bounds.Set
cd.tag=0
if the resulting capability cannot be represented exactly.Set
cd.tag=0
ifcs1
's bounds are malformed, or if any of the reserved fields are set. - Operation
-
let cs1_val = C(cs1); let length = X(rs2); let newBase = cs1_val.address; let newTop : CapLenBits = zero_extend(newBase) + zero_extend(length); // inCapBoundsNoWrap returns false if the input bounds are malformed. let inBounds = inCapBoundsNoWrap(cs1_val, newBase, unsigned(length)); let (_, newCap) : (bool, Capability) = setCapBounds(cs1_val, newBase, newTop); let cond = not(inBounds) | boundsMalformed(newCap) | not(capReservedValid(newCap)) | capIsSealed(newCap); C(cd) = clearTagIf(newCap, cond); RETIRE_SUCCESS
2.6.7. SENTRY
- Synopsis
-
Seal capability as sealed entry.
- Mnemonic
-
sentry cd, cs1
- Encoding
- Description
-
Copy
cs1
tocd
. Set the capability type ofcd
to sentry capability.Set
cd.tag=0
ifcs1
is sealed.The SENTRY instruction may give rise to an illegal instruction fault when the implementation does not support capability type 1 (unrestricted sentry; see Section 2.2.4). This is not the case when the implementation supports the capability encoding described in Appendix A. - Operation
-
let cs1_val = C(cs1); let inCap = clearTagIf(cs1_val, capIsSealed(cs1_val)); C(cd) = sealCap(inCap); RETIRE_SUCCESS
2.6.8. CBLD
- Synopsis
-
Capability build
- Mnemonic
-
cbld cd, cs1, cs2
- Encoding
- Description
-
Copy
cs2
tocd
.Set
cd.tag=1
if:-
cs1.tag
is set, and -
cs1
's bounds are not malformed, and all reserved fields are zero, and -
cs1
's permissions could have been legally produced by ACPERM, and -
cs1
is not sealed, and -
cs2
's permissions and bounds are equal to or a subset ofcs1
's, and -
cs2
's Capability Level (CL) is equal to or lower thancs1
's, andWith Zcheri0lvl this check always passes as the level is hardwired. -
cs2
's bounds are not malformed, and all reserved fields are zero, and -
cs2
's permissions could have been legally produced by ACPERM, and -
All reserved bits in
cs2
's metadata are 0;Otherwise, set
cd.tag=0
-
When cs1 is c0 this will copy cs2 to cd and clear cd.tag .
However this may change in future extensions, and so software should not
assume cs1==0 to be a pseudo-instruction for tag clearing.
|
- Operation
-
let cs1_val = C(cs1); let cs2_val = C(cs2); let tag = cs1_val.tag & not(capIsSealed(cs1_val)) & capIsSubset(cs2_val, cs1_val); /* Subset checks for malformed bounds, perms, and reserved bits */ C(cd) = { cs2_val with tag = tag }; RETIRE_SUCCESS
2.7. Instructions Which Inspect Capability Data
2.7.1. Instructions Which Decode Capability Bounds
The bounds describing the range of addresses the capability gives access to are stored in a compressed format. These instructions query the bounds and related information.
Mnemonic | Description |
---|---|
Get capability base |
|
Get capability length |
2.7.2. GCBASE
- Synopsis
-
Capability get base address
- Mnemonic
-
gcbase rd, cs1
- Encoding
- Description
-
Decode the base integer address from
cs1
's bounds and write the result tord
.If
cs1
's bounds are malformed then the bounds decode as zero, which causes this instruction to return zero.The value of cs1.tag
does not affect the result. - Operation
-
let capVal = C(cs1); X(rd) = match getCapBoundsBits(capVal) { None() => zeros(), Some(base, _) => base }; RETIRE_SUCCESS
2.7.3. GCLEN
- Synopsis
-
Capability get length
- Mnemonic
-
gclen rd, cs1
- Encoding
- Description
-
Calculate the length of
cs1
's bounds and write the result inrd
.The length is defined as the difference between the decoded bounds' top and base addresses, i.e.,
top - base
.Return the maximum length, 2MXLEN-1, if the length of
cs1
is 2MXLEN.If
cs1
's bounds are malformed then the bounds decode as zero, which causes this instruction to return zero.The value of cs1.tag
does not affect the result. - Operation
-
let capVal = C(cs1); // getCapLength returns 0 if the bounds are malformed let len = getCapLength(capVal); X(rd) = to_bits(xlen, if len > cap_max_addr then cap_max_addr else len); RETIRE_SUCCESS
2.7.4. Instructions Which Extract Capability Fields
These instructions either directly read bit fields from the metadata or valid tag, or only apply simple transformations on the metadata.
Mnemonic | Description |
---|---|
Get tag field |
|
Get hperm and uperm fields as 1-bit per permission, packed together |
|
Get capability type |
|
Get metadata |
2.7.5. GCTAG
- Synopsis
-
Capability get tag
- Mnemonic
-
gctag rd, cs1
- Encoding
- Description
-
Zero extend the value of
cs1.tag
and write the result tord
. - Operation
-
let capVal = C(cs1); X(rd) = zero_extend(bool_to_bits(capVal.tag)); RETIRE_SUCCESS
2.7.6. GCPERM
- Synopsis
-
Capability get permissions
- Mnemonic
-
gcperm rd, cs1
- Encoding
- Description
-
If MXLEN=32 unpack permissions from the format in Table 16.
Convert the unpacked AP permissions as well as the SDP fields of capability
cs1
into a bit field, with the format shown in Figure 6, and write the result tord
. A bit set to 1 in the bit field indicates thatcs1
grants the corresponding permission. All bits in the[0:23]
range that are reserved or assigned to extensions that are not implemented by the current hart always report 1.If the AP field cannot be produced by ACPERM then all architectural permission bits in
rd
are set to 0.Figure 6. Capability permissions bit fieldWhen Zcheri0lvl is implemented, the CL
,SL
, andEL
fields always report 1. This ensures forwards-compatibility with Zcheri1lvl since loads/stores on a core without dynamic levels behave as if these permissions are always present.Any future extension that defines new permission that are a refinement of existing permissions (e.g., finer-grained ASR-permission) must be allocated to the bits that are currently reported as 1 to ensure forward-compatibility. Completely new permissions (e.g., sealing) should use the bits that are reported as zero in the current specification. The value of cs1.tag
does not affect the result. - Operation
-
let capVal = C(cs1); X(rd) = packPerms(getArchPermsLegalized(capVal), capVal.sd_perms).bits; RETIRE_SUCCESS
2.7.7. GCTYPE
- Synopsis
-
Capability get type
- Mnemonic
-
gctype rd, cs1
- Encoding
- Description
-
Decode the architectural capability type from
cs1
and write the result tord
.The value of cs1.tag
does not affect the result.While the architectural capability type maps directly to the value of the CT
capability bit in RV32Y/RV64Y, future extensions may define an alternate mapping. Therefore, software should always use GCTYPE to obtain the capability type rather than directly reading the high bits of the capability using GCHI. - Operation
-
let capVal = C(cs1); X(rd) = zero_extend(bool_to_bits(capVal.sealed)); RETIRE_SUCCESS
2.7.8. GCHI
- Synopsis
-
Capability get metadata
- Mnemonic
-
gchi rd, cs1
- Encoding
- Description
-
Copy the metadata (bits [CLEN-1:MXLEN]) of capability
cs1
intord
.The value of cs1.tag
does not affect the result. - Operation
-
let capVal = C(cs1); X(rd) = capToMetadataBits(capVal).bits; RETIRE_SUCCESS
2.8. Miscellaneous Instructions Which Handle Capability Data
Mnemonic | Description |
---|---|
Full capability bitwise compare, set result true if both are fully equal |
|
Set result true if cs1 and cs1 tags match and cs2 bounds and permissions are a subset of cs1 |
|
Representable Alignment Mask: Return mask to apply to address to get the requested bounds |
2.8.1. SCEQ
- Synopsis
-
Set if Capabilities are EQual
- Mnemonic
-
sceq rd, cs1, cs2
- Encoding
- Description
-
Set
rd
to 1 if all bits (i.e., CLEN-bits and the valid tag) of capabilitiescs1
andcs2
are equal, otherwise setrd
to 0. - Operation
-
let cs1_val = C(cs1); let cs2_val = C(cs2); X(rd) = zero_extend(bool_to_bits(cs1_val == cs2_val)); RETIRE_SUCCESS
2.8.2. SCSS
- Synopsis
-
Set Capability Subset
- Mnemonic
-
scss rd, cs1, cs2
- Encoding
- Description
-
rd
is set to 1 if:-
the valid tag of capabilities
cs1
andcs2
are equal, and -
the bounds and permissions of
cs2
are a subset of those ofcs1
, and -
cs2
's Capability Level (CL) is equal to or lower thancs1
'sWith Zcheri0lvl this check always passes as the level is hardwired. -
neither
cs1
orcs2
have bounds which are malformed, and -
neither
cs1
orcs2
have any bits set in reserved fields, and -
neither
cs1
orcs2
have permissions that could not have been legally produced by ACPERM
-
Otherwise set rd
to 0.
The implementation of this instruction is similar to CBLD, although SCSS does not include the sealed bit in the check. |
- Operation
-
let cs1_val = C(cs1); let cs2_val = C(cs2); X(rd) = zero_extend(bool_bits( (cs1_val.tag == cs2_val.tag) & capIsSubset(cs2_val, cs1_val) /* capIsSubset returns false if either input has malformed bounds, perms, or non-zero reserved bits */ )); RETIRE_SUCCESS
2.8.3. CRAM
- Synopsis
-
Get Capability Representable Alignment Mask (CRAM)
- Mnemonic
-
cram rd, rs1
- Encoding
- Description
-
Integer register
rd
is set to a mask that can be used to round addresses down to a value that is sufficiently aligned to set exact bounds for the nearest representable length ofrs1
. See Section A.1.4 for the algorithm used to compute the next representable length. - Operation
-
let len = X(rs1); X(rd) = getRepresentableAlignmentMask(len); RETIRE_SUCCESS
2.9. Instructions Which Load and Store Capability Data
New loads and stores are introduced to handle capability data, LC and SC. They atomically access CLEN-bits of data and the associated valid tag.
All capability memory accesses check for C-permission in the authorizing capability in cs1
.
If C-permission is granted then:
If C-permission is not granted then:
All capability data memory access instructions require CLEN-aligned addresses, and will take a misaligned exception if this requirement is not met. They cannot be emulated.
ARC request that this become an access fault |
All memory accesses, of any type, require permission from the authorizing capability in cs1
.
-
All loads require R-permission, otherwise they raise an exception
-
All stores require W-permission, otherwise they raise an exception
Mnemonic | Description |
---|---|
Load capability |
|
Store capability |
2.9.1. LC
- Synopsis
-
Load capability
- Mnemonic
-
lc cd, offset(cs1)
- Encoding
Any instance of this instruction with a cs1 =c0 will trap (with a CHERI tag violation), as c0 is defined to always hold a NULL capability.
As such, the encodings with a cs1 =c0 are RESERVED for use by future extensions.
|
- Description
-
Calculate the effective address of the memory access by adding the address of
cs1
to the sign-extended 12-bit offset.Authorize the memory access with the capability in
cs1
.Load a naturally aligned CLEN-bit data value and the associated valid tag from memory.
Write the CLEN-bit data and the valid tag to
cd
and conditionally update them as specified below.This instruction can propagate tagged capabilities which have malformed bounds, have reserved bits set or have a permission field which cannot be produced by ACPERM.
Any instance of this instruction with a cs1
=c0
will trap (with a CHERI tag violation), asc0
is defined to always hold a NULL capability. As such, the encodings with acs1
=c0
are RESERVED for use by future extensions. - Determining the final value of
cd
-
If the valid tag of the memory location loaded is 0, or the authorizing capability (
cs1
) does not grant C-permission then setcd.tag=0
. In this case the steps below do not apply.If
cd.tag=1
,cd
is not sealed andcs1
does not grant LM-permission, then an implicit ACPERM is performed to clear W-permission and LM-permission fromcd
.If
cd.tag=1
,cd
is not sealed andcs1
does not grant EL-permission, then an implicit ACPERM is performed restricting the Capability Level (CL) ofcd
to the level ofcs1
and to remove EL-permission.If
cd.tag=1
,cd
is sealed andcs1
does not grant EL-permission, then an implicit ACPERM is performed restricting the Capability Level (CL) ofcd
to the level ofcs1
If Zcheri1lvl is implemented, then also see Table 4.
Missing EL-permission also affects the level of sealed capabilities since notionally the Capability Level (CL) of a capability is not a permission but rather a data flow label attached to the loaded value. While the implicit ACPERM introduces a dependency on the loaded data, implementations can avoid this by deferring the actual masking of permissions until the loaded capability is dereferenced or the metadata bits are inspected using GCPERM or GCHI. Additionally, metadata modifications are on naturally aligned data, and so on the read path from a data cache, the modification typically happens in parallel with data alignment multiplexers. ARC feedback: this is change relative to 0.9.5 so that the choice is removed. Choosing the other option would need to be a future extension
When sending load data to a trace interface, implementations trace the final value written to
cd
which may not match the value in memory. - Exceptions
-
ARC feedback: needs to be an access fault as it can’t be emulated
Misaligned address fault exception when the effective address is not aligned to CLEN/8.
ARC suggestion: consider software check fault
CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant R-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Operation
-
let offset : xlenbits = sign_extend(imm); let (auth_val, vaddr) = get_cheri_mode_cap_addr(rs1_cs1, offset); let aq : bool = false; let rl : bool = false; match check_and_handle_load_vaddr_for_triggers(vaddr, get_arch_pc()) { Some (ret) => return ret, None () => () }; if not(capTaggedAndReservedValid(auth_val)) then { handle_cheri_exception(CapCheckType_Data, CapEx_TagViolation); RETIRE_FAIL } else if capIsSealed(auth_val) then { handle_cheri_exception(CapCheckType_Data, CapEx_SealViolation); RETIRE_FAIL } else if not(canR(auth_val)) then { handle_cheri_exception(CapCheckType_Data, CapEx_PermissionViolation); RETIRE_FAIL } else if not(validAddrRange(vaddr, cap_size) | capBoundsInfinite(auth_val)) then { handle_cheri_exception(CapCheckType_Data, CapEx_InvalidAddressViolation); RETIRE_FAIL } else if not(inCapBounds(auth_val, vaddr, cap_size)) then { handle_cheri_exception(CapCheckType_Data, CapEx_LengthViolation); RETIRE_FAIL } else if not(is_aligned_addr(vaddr, cap_size)) then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL } else match translateAddr(vaddr, Read(Cap)) { TR_Failure(E_Extension(_)) => { internal_error(__FILE__, __LINE__, "unexpected cheri exception for cap load") }, TR_Failure(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }, TR_Address(addr, pbmt, ptw_info) => { let c = mem_read_cap(addr, pbmt, aq, aq & rl, false); match c { MemValue(v) => { let cr = clearTagIf(v, ptw_info.ptw_lc == PTW_LC_CLEAR | not(canC(auth_val))); C(cd) = legalizeLM(cr, auth_val); RETIRE_SUCCESS }, MemException(e) => {handle_mem_exception(vaddr, e); RETIRE_FAIL } } } }
2.9.2. SC
- Synopsis
-
Store capability
- Mnemonic
-
sc cs2, offset(cs1)
- Encoding
- Description
-
Calculate the effective address of the memory access by adding the address of
cs1
to the sign-extended 12-bit offset.Authorize the memory access with the capability in
cs1
.Store a naturally aligned CLEN-bit data value in
cs2
to memory and the associated valid tag incs2
.This instruction can propagate tagged capabilities which have malformed bounds, have reserved bits set or have a permission field which cannot be produced by ACPERM.
Any instance of this instruction with a cs1
=c0
will trap (with a CHERI tag violation), asc0
is defined to always hold a NULL capability. As such, the encodings with acs1
=c0
are RESERVED for use by future extensions. - Valid tag of the stored capability value
-
The stored valid tag is 0 if:
-
cs2.tag=0
, or -
cs1
does not grant C-permission, or -
cs1
does not grant SL-permission andcs2
has a Capability Level (CL) of 0 (local).
-
- Exceptions
-
ARC feedback: needs to be an access fault as it can’t be emulated
Misaligned address fault exception when the effective address is not aligned to CLEN/8 if Zam is supported, otherwise store access fault exception.
ARC suggestion: consider software check fault
CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant W-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Operation
-
let offset : xlenbits = sign_extend(imm); let (auth_val, vaddr) = get_cheri_mode_cap_addr(rs1_cs1, offset); let cs2_val = C(cs2); let aq : bool = false; let rl : bool = false; let cs2_val = clearTagIf(cs2_val, not(canC(auth_val))); match check_and_handle_store_vaddr_for_triggers(vaddr, get_arch_pc()) { Some (ret) => return ret, None () => () }; if not(capTaggedAndReservedValid(auth_val)) then { handle_cheri_exception(CapCheckType_Data, CapEx_TagViolation); RETIRE_FAIL } else if capIsSealed(auth_val) then { handle_cheri_exception(CapCheckType_Data, CapEx_SealViolation); RETIRE_FAIL } else if not(canW(auth_val)) then { handle_cheri_exception(CapCheckType_Data, CapEx_PermissionViolation); RETIRE_FAIL } else if not(validAddrRange(vaddr, cap_size) | capBoundsInfinite(auth_val)) then { handle_cheri_exception(CapCheckType_Data, CapEx_InvalidAddressViolation); RETIRE_FAIL } else if not(inCapBounds(auth_val, vaddr, cap_size)) then { handle_cheri_exception(CapCheckType_Data, CapEx_LengthViolation); RETIRE_FAIL } else if not(is_aligned_addr(vaddr, cap_size)) then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL } else match translateAddr(vaddr, Write(if cs2_val.tag then Cap else Data)) { TR_Failure(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }, TR_Address(addr, pbmt, _) => { let eares : MemoryOpResult(unit) = mem_write_ea_cap(addr, aq & rl, rl, false); match (eares) { MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }, MemValue(_) => { let res : MemoryOpResult(bool) = mem_write_cap(addr, pbmt, cs2_val, aq & rl, rl, false); match (res) { MemValue(true) => RETIRE_SUCCESS, MemValue(false) => internal_error(__FILE__, __LINE__, "store got false from mem_write_value"), MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL } } } } } }
2.10. Changes to Existing RISC-V Base ISA Instructions
RV32Y/RV64Y extend existing instructions which are used for handling addresses so that they manipulate a whole capability. The affected operands change type from x to c to represent this, and/or the PC is replaced by the pcc
In the base ISA this affects AUIPC (RV32Y/RV64Y) and all jumps and branches as well as all loads and stores.
The rules for modifying the behavior of such instructions are:
-
The result written to the target register is always unchanged.
-
The lower XLEN-bits are always written with the value from RV32I/RV64I.
-
-
Whenever the PC is handled, it is always the pcc.
-
Any instruction that has a base address register (generally
rs1
) reads the full capability register (cs1
) instead.-
This capability register is used to authorize the access.
-
-
Any instruction writes back an address (e.g., AUIPC (RV32Y/RV64Y)), writes a full capability register instead.
-
Whenever the address field of any capability (including the pcc) is modified, it is always updated using SCADDR semantics.
-
This includes adding an offset to the pcc from jumps and branches for both the target address and the link register. In this case, e.g.,
new_pcc = SCADDR(old_pcc, offset)
-
-
All jumps and branches check that a minimum sized instruction is in bounds of the target pcc.
-
An exception is taken by the branch or jump on failure.
-
-
JALR (RV32Y/RV64Y) copies all of
cs1
into the pcc. Ifcs1
is not suitable for execution then an exception is taken on the JALR (RV32Y/RV64Y) (see pcc for the definition of suitability). -
Any memory access instruction that has a base address register (generally
rs1
) reads the full capability register (cs1
) instead which is used to check whether the access is permitted, taking an exception if it is not. -
Whenever the address field of any capability (including the pcc) is modified, it is always updated using SCADDR semantics.
-
This includes adding an offset to the pcc from jumps and branches for both the target address and the link register. In this case, e.g.,
new_pcc = SCADDR(old_pcc, offset)
-
-
All jumps and branches check that a minimum sized instruction is in bounds of the target pcc.
-
An exception is taken by the branch or jump on failure.
-
-
JALR (RV32Y/RV64Y) copies all of
cs1
into the pcc. Ifcs1
is not suitable for execution then an exception is taken on the JALR (RV32Y/RV64Y) (see pcc for the definition of suitability).
These rules affect the following base ISA instructions listed in Table 11, and also apply to instructions added by other extensions (e.g. floating-point/vector loads/stores or the shift-and-add instruction from Zba).
These rules also apply to instructions added by other extensions (e.g., floating-point/vector loads/stores or the shift-and-add instruction from Zba). |
Exceptions are taken on the branch or jump which cause an exception, not at the target, to reduce the attack surface and also to aid with debugging. Therefore it is not possible to execute from a memory location without having already checked that execution of that location is authorized. |
Mnemonic | Description |
---|---|
Add immediate to PCC address, return capability |
|
Jump to PC+offset, bounds check minimum size target instruction, link to cd |
|
Indirect jump and link, bounds check minimum size target instruction. |
|
Conditional branches (checked by pcc) |
|
Integer loads (authorized by the capability in |
|
Integer stores (authorized by the capability in |
2.10.1. AUIPC (RV32Y/RV64Y)
- Synopsis
-
Add upper immediate to pcc
- Mnemonic
-
auipc cd, imm
- Integer Pointer Mode Mnemonic
-
auipc rd, imm
- Encoding
This instruction is extended from the version in the base ISA. |
- Description
-
Form a 32-bit offset from the 20-bit immediate filling the lowest 12 bits with zeros. Increment the address of the AUIPC instruction’s pcc by the 32-bit offset, then write the output capability to
cd
.Set
cd.tag=0
if the resulting capability cannot be represented exactly.
ARC review: we need to push the AUIPC instruction into the same extension as the capability encoding
- Operation
-
let off : xlenbits = sign_extend(imm @ 0x000); let (representable, newCap) = setCapAddr(PCC, PC + off); C(cd) = clearTagIf(newCap, not(representable)); RETIRE_SUCCESS
2.10.2. JAL (RV32Y/RV64Y)
- Synopsis
-
Jump and link
- Mnemonic
-
jal cd, offset
- Encoding
- Exceptions
-
CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Bounds violation
Minimum length instruction is not within the pcc's bounds.
- Operation
-
let off : xlenbits = sign_extend(imm); let newPC = PC + off; if not(validAddr(newPC) | capBoundsInfinite(PCC)) then { handle_cheri_exception(CapCheckType_JBr, CapEx_InvalidAddressViolation); RETIRE_FAIL } else if not(inCapBounds(PCC, newPC, min_instruction_bytes())) then { handle_cheri_exception(CapCheckType_JBr, CapEx_LengthViolation); RETIRE_FAIL } else if newPC[1] == bitone & not(extensionEnabled(Ext_Zca)) then { handle_mem_exception(newPC, E_Fetch_Addr_Align()); RETIRE_FAIL } else { let (success, linkCap) = setCapAddr(PCC, nextPC); /* Note that nextPC accounts for compressed instructions */ assert(success, "Link cap should always be representable."); assert(not(capIsSealed(linkCap)), "Link cap should always be unsealed"); C(cd) = sealCap(linkCap); set_next_pc(newPC); RETIRE_SUCCESS }
2.10.3. JALR (RV32Y/RV64Y)
- Synopsis
-
Jump and link register
- Mnemonic
-
jalr cd, cs1, offset
- Integer Pointer Mode Mnemonic
-
jalr rd, rs1, offset
- Encoding
This instruction is extended from the version in the base ISA. |
- Description
-
JALR allows unconditional, indirect jumps to a target capability in
cs1
. The target capability is unsealed if theoffset
is zero. The target address is obtained by adding the sign-extended 12-bitoffset
tocs1.address
, then setting the least-significant bit of the result to zero. The pcc of the next instruction following the jump is sealed and written tocd
.
- Exceptions
-
CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
cs1
has tag set to 0, or has any reserved bits setSeal violation
cs1
is sealed and the immediate is not 0Permission violation
cs1
does not grant X-permission, or the AP field could not have been produced by ACPERMBounds violation
Minimum length instruction is not within the target capability’s bounds
- Operation
-
let cs1_val = C(cs1); // Calculate new PC which may be offset from the capability address. let off : xlenbits = sign_extend(imm); let newPC = [cs1_val.address + off with 0 = bitzero]; /* clear bit zero as for RISCV JALR */ if not(capTaggedAndReservedValid(cs1_val)) then { handle_cheri_exception(CapCheckType_JBr, CapEx_TagViolation); RETIRE_FAIL } else if capIsSealed(cs1_val) & imm != zeros() then { handle_cheri_exception(CapCheckType_JBr, CapEx_SealViolation); RETIRE_FAIL } else if not(canX(cs1_val)) then { handle_cheri_exception(CapCheckType_JBr, CapEx_PermissionViolation); RETIRE_FAIL } else if not(validAddr(newPC) | capBoundsInfinite(cs1_val)) then { handle_cheri_exception(CapCheckType_JBr, CapEx_InvalidAddressViolation); RETIRE_FAIL } else if not(inCapBounds(cs1_val, newPC, min_instruction_bytes())) then { handle_cheri_exception(CapCheckType_JBr, CapEx_LengthViolation); RETIRE_FAIL } else if newPC[1] == bitone & not(extensionEnabled(Ext_Zca)) then { handle_mem_exception(newPC, E_Fetch_Addr_Align()); RETIRE_FAIL } else { let (success, linkCap) = setCapAddr(PCC, nextPC); /* Note that nextPC accounts for compressed instructions */ assert(success, "Link cap should always be representable."); assert(not(capIsSealed(linkCap)), "Link cap should always be unsealed"); C(cd) = sealCap(linkCap); set_next_pc(newPC); // Construct the new capability pointing to the address + offset. let (representable, newPCC) = setCapAddr(cs1_val, newPC); assert(representable, "If bounds checks passed then new PCC must be representable"); set_next_pcc(unsealCap(newPCC)); RETIRE_SUCCESS }
2.10.4. BEQ, BNE, BLT[U], BGE[U] (RV32Y/RV64Y)
- Synopsis
-
Conditional branches (BEQ, BNE, BLT[U], BGE[U])
- Mnemonics
-
beq rs1, rs2, imm
bne rs1, rs2, imm
blt rs1, rs2, imm
bge rs1, rs2, imm
bltu rs1, rs2, imm
bgeu rs1, rs2, imm
- Encoding
- Description
-
Execute as defined in the base ISA. The target address is written into the address field of pcc.
- Exceptions
-
CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Bounds violation
Minimum size instruction is not within the pcc's bounds.
2.10.5. Load and Store Instructions (RV32Y/RV64Y)
All load and store instructions behave as described in Load and Store Instructions with one fundamental difference:
-
For the base operand (
rs1
), the capability source operandcs1
is used to authorize the resulting memory access.
All load and store instructions authorized by cs1
cause CHERI exceptions if any of these checks fails:
-
cs1
must not bec0
1 -
The valid tag (
cs1.tag
) must be set, and there must be no reserved bits set incs1
-
cs1
must be unsealed -
All bytes of accessed memory must be inside
cs1’s
bounds, and the bounds can’t be malformed. -
For loads, the read permission must be set in
cs1
-
For stores, the write permission must be set in
cs1
1 All load/store encodings are reserved if cs1=c0
(since dereferencing NULL always faults).
This principle is extended to all loads and stores authorized by cs1
.
Load instructions, except for LC, always zero the valid tag and metadata of the result register.
Store instructions, except for SC, always write zero to the valid tag or tags associated with the memory locations that are written to.
Therefore, misaligned stores may clear up to two associated valid tag bits.
The changed interpretation of the base register also applies to all loads, stores and other memory operations defined in later chapters of this specification with a base operands of rs1
unless stated otherwise.
this applies to all existing loads and stores including integer, floating-point and vector. |
Under RV32Y/RV64Y all loads and stores are authorized by cs1
.
3. "Zcherihybrid" Extension for CHERI Integer Pointer Mode
This chapter will appear in the unpriv spec somewhere after the Zicsr chapter (since it depends on Zicsr). |
Zcherihybrid is an optional extension to the RV32Y/RV64Y base architectures. Zcherihybrid adds the ability to dynamically change the base ISA between using capability pointers for all memory references (RV32Y/RV64Y) and using integer pointers (RV32I/RV64I). The ability to choose between these two behaviors (referred to as CHERI Execution Modes) ensures CHERI can be fully compatible with the base RISC-V integers ISAs while saving instruction encoding space.
Additionally, Zcherihybrid adds a new unprivileged CSR: the default data capability, ddc, that is used to authorize all data memory accesses when treating pointers as integers.
Together with pcc, ddc allows confining code runs to a compartment (also called a sandbox), where all data memory and instruction memory accesses are bounded to fixed memory regions. |
The remainder of this section describes these features in detail as well as their integration with the primary base integer variants of the base RISC-V ISA.
Implementations that support both RV32Y/RV64Y and Zcherihybrid have full binary compatibility with all existing ratified RISC-V base architectures and extensions. |
3.1. CHERI Execution Mode
The two execution modes are:
- Integer Pointer Mode
-
Executing with RV32I/RV64I base ISA.
All RV32Y/RV64Y instructions and CSRs are also available in Zcherihybrid.
All instructions from existing RISC-V extensions can be run in Integer Pointer Mode. This execution mode is fully binary compatible with non-CHERI-aware programs. - Capability Pointer Mode
-
Executing with the RV32Y/RV64Y base ISA.
Some instructions in the RV32I/RV64I base ISA (and in some other extensions) use capabilities instead of integers for memory references (see Section 2.10). In these cases, such as SH1ADD (RV32Y/RV64Y), the lower XLEN-bits of the result is the same in either mode and the upper XLEN-bits, and valid tag, are either handled as capabilities in Capability Pointer Mode, or are ignored in the source and written to zero in Integer Pointer Mode
The CHERI Execution Mode impacts the instruction set in the following way:
-
The authorizing capability used to execute memory access instructions depends on the mode. In Integer Pointer Mode, ddc is implicitly used. In Capability Pointer Mode, the authorizing capability is supplied as an explicit c operand to the instruction.
The CHERI Execution Mode is key in providing backwards compatibility with the base RV32I/RV64I ISA. RISC-V software is able to execute unchanged in implementations supporting both RV32Y/RV64Y and Zcherihybrid provided that the privileged environment sets up ddc and pcc appropriately.
The CHERI execution mode is always Capability Pointer Mode on implementations that support RV32Y/RV64Y, but not Zcherihybrid. |
RV32Y/RV64Y implementations which support Zcherihybrid are typically referred to as CHERI Hybrid, whereas implementations which do not support Zcherihybrid are typically referred to as CHERI purecap. |
3.1.1. CHERI Execution Mode Effect On Existing Encodings
All RV32I/RV64I instructions are available in both CHERI execution modes.
3.1.2. CHERI Execution Mode Encoding
The CHERI Execution Mode is determined by a bit in the metadata of the pcc called the M-bit. Zcherihybrid adds a new CHERI Execution Mode field (M) to the capability format. Although always present, it only takes effect in code capabilities, i.e., when the X-permission is set. The exact location of the M-bit in the capability format for XLEN=32 and XLEN=64 is described in Appendix A.
-
Mode (M)=0 indicates Capability Pointer Mode.
-
Mode (M)=1 indicates Integer Pointer Mode.
While the M-bit only has a effect when installed in pcc, it needs to be encoded in all capabilities. Since indirect jumps copy the full target capability into pcc, it allows indirect jumps to change between modes (see Section 3.1.3). |
3.1.3. Changing CHERI Execution Mode
Mnemonic | From mode | Description |
---|---|---|
Capability Pointer Mode |
Install |
|
Capability Pointer Mode |
Switch to Integer Pointer Mode. |
|
Integer Pointer Mode |
Switch to Capability Pointer Mode. |
The mode can also be updated by setting the M-bit of a target capability using SCMODE followed by a JALR (RV32Y/RV64Y). |
3.1.4. Observing the CHERI Execution Mode
The effective CHERI execution mode cannot be determined just by reading the M-bit from pcc since it also depends on the execution environment.
The following code sequence demonstrate how a program can observe the current, effective CHERI execution mode.
It will write 0 for Capability Pointer Mode and 1 for Integer Pointer Mode to x1
:
auipc c1, 0
gctag x1, c1
3.2. Added State
Zcherihybrid adds the CLEN-wide CSRs shown in Table 13.
CLEN CSR | Address | Permissions | Description |
---|---|---|---|
0x416 |
RW |
User Default Data Capability |
3.2.1. Default Data Capability CSR (ddc)
ddc is a read-write, user mode accessible capability CSR. It does not require ASR-permission in pcc for writes or reads. Similarly to pcc authorizing all control flow and instruction fetches, this capability register is implicitly checked to authorize all data memory accesses when the current CHERI mode is Integer Pointer Mode. On startup ddc bounds and permissions must be set such that the program can run successfully (e.g., by setting it to Infinite to ensure all data references are in bounds).
CHERI register and instruction access is not required for the implicit access required by checking memory accesses against ddc. |
ddc is a data pointer, so it does not need to be able to hold all possible invalid addresses (see Invalid address conversion). |
3.3. Zcherihybrid Memory Accesses
In Capability Pointer Mode all memory accesses behave as defined by RV32Y/RV64Y and are authorised by the base register (cs1
), from which the bounds and permissions are taken. For example:
-
lw t0, 16(ca0)
In Integer Pointer Mode the lw
has the same behavior and assembly syntax as the RV32I/RV64I:
-
lw t0, 16(a0)
All memory accesses must still be checked, but now they are authorized by the capability in ddc instead.
3.4. Zcherihybrid Branches and Jumps
The rules from Section 2.10 are applied, so that all branch and jump targets are checked against pcc.
3.5. Zcherihybrid Instructions
Zcherihybrid introduces new instructions to switch CHERI execution modes. Additionally, Zcherihybrid makes all instructions defined by Zcherihybrid available.
Mnemonic | Description |
---|---|
Set capability CHERI execution mode (M-bit) |
|
Get capability CHERI execution mode (M-bit) |
|
Set current CHERI execution mode to Capability Pointer Mode |
|
Set current CHERI execution mode to Integer Pointer Mode |
3.5.1. SCMODE
- Synopsis
-
Capability set CHERI execution mode
- Mnemonic
-
scmode cd, cs1, rs2
- Encoding
- Description
-
Copy
cs1
tocd
.Clear
cd.tag
ifcs1
is sealed.If
cs1
grants X-permission andcs1
's permissions can be produced by ACPERM, then update the M-bit ofcd
to:-
Capability Pointer Mode if the least significant bit of
rs2
is 0, or, -
Integer Pointer Mode if the least significant bit of
rs2
is 1Otherwise do not update the M-bit.
The value of cs1.tag
does not affect the result.
-
- Operation
-
let cap = C(cs1); let mode = execution_mode_encdec(X(rs2)[0 .. 0]); let cap = clearTagIf(cap, capIsSealed(cap)); let hasMode = not(permsMalformed(cap)) & canX(cap); let newCap = if hasMode then setCapMode(cap, mode) else cap; C(cd) = newCap; RETIRE_SUCCESS
3.5.2. GCMODE
- Synopsis
-
Capability get CHERI execution mode
- Mnemonic
-
gcmode rd, cs1
- Encoding
- Description
-
Decode the CHERI execution mode from the capability in
cs1
and write the result tord
.Set
rd
to 0 ifcs1
does not grant X-permission, or, the AP field incs1
cannot be produced by ACPERM.Otherwise set
rd
according tocs1
's CHERI execution mode (M-bit):-
Set
rd
to 0 for Capability Pointer Mode, or, -
Set
rd
to 1 for Integer Pointer Mode.The value of cs1.tag
does not affect the result.
-
- Operation
-
let capVal = C(cs1); X(rd) = zero_extend(execution_mode_encdec(getCapMode(capVal))); RETIRE_SUCCESS
3.5.3. MODESW.INT
See MODESW.CAP.
3.5.4. MODESW.CAP
- Synopsis
-
Switch execution mode to Capability Pointer Mode (MODESW.CAP), or Integer Pointer Mode (MODESW.INT), 32-bit encodings
- Mnemonic
-
modesw.cap
modesw.int
- Encoding
- Description
-
Set the current CHERI execution mode in pcc.
- Operation
-
let mode : ExecutionMode = match effective_cheri_mode() { IntPtrMode => CapPtrMode, CapPtrMode => IntPtrMode, }; if debug_mode_active then dinfc = setCapMode(infinite_cap, mode); set_next_pcc(setCapMode(PCC, mode)); RETIRE_SUCCESS
3.6. Changes to RV32Y/RV64Y Instructions
The load and store capability instructions introduced in RV32Y/RV64Y change behavior depending on the CHERI execution mode although the instruction’s encoding remains unchanged.
3.6.1. LC
When the CHERI execution mode is Capability Pointer Mode; the instruction behaves as described in Section 2.9. In Integer Pointer Mode, the capability authorizing the memory access is ddc, so the effective address is obtained by adding the x register to the sign-extended offset.
3.6.2. SC
When the CHERI execution mode is Capability Pointer Mode; the instruction behaves as described in Section 2.9. In Integer Pointer Mode, the capability authorizing the memory access is ddc, so the effective address is obtained by adding the x register to the sign-extended offset.
3.7. Changes to Zicsr Instructions
RV32Y/RV64Y extends all RISC-V CSRs which hold addresses, to hold capabilities.
Therefore, such registers are extended to CLEN-bits in RV32Y/RV64Y and a c
suffix is added when referring to the entire CSR instead of the only the address field.
This assumes that the Zcmt CSR is extended to be a capability when the base architecture is RV32Y/RV64Y. |
For example, the jvt
CSR is extended to jvtc
, the c
suffix indicating that it’s a capability.
It is referred to as jvt
if only accessing the address or jvtc
if accessing the whole capability.
-
In Capability Pointer Mode CSRRW (RV32Y/RV64Y) always read/writes the entire CLEN-bits of all CLEN-width CSRs, i.e., it accesses
jvtc
. -
In Integer Pointer Mode CSRRW (RV32Y/RV64Y) only accesses XLEN-bits of extended CSRs (e.g.,
jvt
, for compatibility) and all CLEN-bits of CSRs added by CHERI extensions (e.g., ddc).-
CSRRW (RV32Y/RV64Y) in Integer Pointer Mode can only update the address field of
jvt
, but it can write a full value into ddc. -
Capability Pointer Mode always accesses
jvtc
, neverjvt
.
-
-
when only writing XLEN-bits to an extended CSR (e.g.,
jvt
), the CSR value is updated using SCADDR semantics.
need to resolve how to cross-reference the privileged spec to have a list of the new and extended CSRs |
When any CLEN-width CSR is accessed with another CSR instruction:
The following rules apply:
-
The final address is calculated according to the standard RISC-V CSR rules (set bits, clear bits etc).
-
The final address is updated as specified in the privileged specification for an XLEN write.
-
Unless specified otherwise, the update uses SCADDR semantics
-
-
When accessing an extended CSR:
-
In Integer Pointer Mode, XLEN-bits are read from the capability address field and written to an output x register.
-
In Capability Pointer Mode, CLEN-bits are read from the CSR and written to an output c register.
-
-
When accessing a CSR added by a CHERI extension:
-
CLEN-bits are read from the CSR and written to an output c register.
-
3.7.1. CSRRWI (RV32Y/RV64Y)
See CSRRCI (RV32Y/RV64Y).
3.7.2. CSRRS (RV32Y/RV64Y)
See CSRRCI (RV32Y/RV64Y).
3.7.3. CSRRSI (RV32Y/RV64Y)
See CSRRCI (RV32Y/RV64Y).
3.7.4. CSRRC (RV32Y/RV64Y)
See CSRRCI (RV32Y/RV64Y).
3.7.5. CSRRCI (RV32Y/RV64Y)
- Synopsis
-
CSR access (CSRRWI, CSRRS, CSRRSI, CSRRC, CSRRCI) 32-bit encodings for RV32Y/RV64Y
- Mnemonics for accessing CLEN-wide CSRs (RV32Y/RV64Y)
-
csrrs cd, csr, rs1
csrrc cd, csr, rs1
csrrwi cd, csr, imm
csrrsi cd, csr, imm
csrrci cd, csr, imm
- Mnemonics for accessing XLEN-wide CSRs or extended CSRs in Integer Pointer Mode
-
csrrs rd, csr, rs1
csrrc rd, csr, rs1
csrrwi rd, csr, imm
csrrsi rd, csr, imm
csrrci rd, csr, imm
- Encoding
- Description
-
These are standard RISC-V CSR instructions with extended functionality for accessing CLEN-wide CSRs (see Table 61), including extended CSRs with actions as shown in
For CLEN-wide CSRs, the full capability is read into
cd
in Capability Pointer Mode. In Integer Pointer Mode, the address field is instead read intord
.Unlike CSRRW (RV32Y/RV64Y), these instructions only update the address field and the valid tag as defined in Table 58 when writing CLEN-wide CSRs regardless of the execution mode. The final address to write to the capability CSR is determined as defined by RISC-V for these instructions.
See Table 57 for a list of CLEN-wide CSRs and Table 58 for the action taken on writing an XLEN-wide value to each one.
If
cd
isc0
(orrd
isx0
), then CSRRWI shall not read the CSR and and shall not cause any of the side effects that might occur on a CSR read. Ifrs1
isx0
for CSRRS and CSRRC, orimm
is 0 for CSRRSI and CSRRCI, then the instruction will not write to the CSR at all, and so shall not cause any of the side effects that might otherwise occur on a CSR write.The assembler pseudoinstruction to read a capability CSR in Capability Pointer Mode,
csrr cd, csr
, is encoded ascsrrs cd, csr, x0
.Access to XLEN-wide CSRs is as specified by RISC-V.
If the CSR accessed is a capability, and rs1 is x0 for CSRRS and CSRRC, or imm is 0 for CSRRSI and CSRRCI, then the CSR is not written so no representability check is needed in this case.
|
- Permissions
-
Accessing privileged CSRs may require ASR-permission, including existing RISC-V CSRs, as described in (RISC-V, 2023).
- Prerequisites for Capability Pointer Mode
-
RV32Y/RV64Y
- Prerequisites for Integer Pointer Mode
-
Zcherihybrid
- Operation
TBD
3.7.6. CSRRW (RV32Y/RV64Y)
- Synopsis
-
CSR access (CSRRW) 32-bit encodings for (RV32Y/RV64Y)
- Mnemonic for accessing CLEN-wide CSRs in Capability Pointer Mode
-
csrrw cd, csr, cs1
- Mnemonic for accessing XLEN-wide CSRs or extended CSRs in Integer Pointer Mode
-
csrrw rd, csr, rs1
- Encoding
- Description
-
These are standard RISC-V CSR instructions with extended functionality for accessing CLEN-wide CSRs (see Table 61).
See Table 57 for a list of CSRs extended to capabilities and Table 58 for the action taken on writing each one.
CLEN-wide CSRs and the action taken on accessing them is shown in Table 59.
CSRRW writes
cs1
to extended CSRs in Capability Pointer Mode, and reads a full capability intocd
.CSRRW writes
cs1
to CLEN-wide CSRs in both modes, and reads a full capability intocd
.CSRRW writes
rs1
to extended CSRs in Integer Pointer Mode, and reads the address field intord
.If
cd
isc0
(orrd
isx0
), then the instruction shall not read the CSR and shall not cause any of the side effects that might occur on a CSR read.The assembler pseudoinstruction to write a capability CSR
csrw csr, cs1
, is encoded ascsrrw c0, csr, cs1
.Access to XLEN-wide CSRs from other extensions is as specified by RISC-V.
When writing cs1 , if the bounds are malformed, any reserved bits are set,
or the permission could not have been produced by ACPERM then clear the valid tag before writing to the CSR.
|
- Permissions
-
Accessing privileged CSRs may require ASR-permission, including existing RISC-V CSRs, as described in (RISC-V, 2023).
- Prerequisites for Capability Pointer Mode
-
RV32Y/RV64Y
- Prerequisites for Integer Pointer Mode
-
Zcherihybrid
- Operation
TBD
4. "Zish4add" Extension for 16-byte pointer addition, Version 0.9
This chapter will appear in the unpriv spec (see github.com/riscv/riscv-isa-manual/pull/1923). |
The B-extension adds SH[1|2|3]ADD
instructions, and for RV64 all have an unsigned word *.UW
version.
Zish4add adds two new analogous instructions to RV64: SH4ADD and SH4ADD.UW.
Increment rs2
by rs1
shifted left by 4 bit positions and write the result to rd
.
Increment rs2
by the unsigned word in rs1
shifted left by 4 bit positions and write the result to rd
.
If the base architecture is RV32Y/RV64Y, and the CHERI execution mode is Capability Pointer Mode then both of these instructions use SCADDR semantics to update the output register.
5. "Zabhlrsc" Extension for Byte and Halfword Load Reserved/Store Conditional, Version 0.9
The Zalrsc extension offers LR/SC (load reserved/store conditional) instructions for words and doublewords. Zabhlrsc extends this by adding byte and halfword versions.
The absence of LR/SC operations for subword data types is problematic for CHERI software (RV32Y/RV64Y base architectures). Non-CHERI RISC-V software can use LR/SC on larger data types than are strictly required for the memory access to register the reservation set. RV32Y/RV64Y check memory bounds and so it not possible to round a subword access up to a word or larger to gain the reservation set. |
5.1. Byte and Halfword Atomic Load Reserved/Store Conditional Instructions
The Zabhlrsc extension provides the LR.[B|H]
and SC.[B|H]
instructions.
LR.[B|H] behave analogously to LR.[W|D].
SC.[B|H] behave analogously to SC.[W|D].
All Zabhlrsc instructions sign extend the result and write it to rd.
6. Integrating RV32Y/RV64Y and Zcherihybrid with the Vector Extension
This chapter should appear as a section in the vector chapter. Exact location TBD. |
The RISC-V vector (V) extension is orthogonal to CHERI because the vector registers only hold integer or floating-point data. The vector registers are not extended to hold capabilities.
A future extension may allow tags to be stored in vector registers.
Until that time, vector load and store instructions must not be used to implement generic
memory copying in software, such as the memcpy() standard C library function,
because the vector registers do not hold capabilities, so the valid tags of any
copied capabilities will be set to 0 in the destination memory.
|
Vector loads and stores all follow the behavior as described in Loads and Stores.
The assembly syntax of all vector loads and stores are updated in Capability Pointer Mode, so that the address operand becomes a c operand instead of an x operand.
According to the vector extension (RISC-V, 2021) only active elements are accessed or updated in memory. Therefore only active elements are subject to CHERI exception checks. If a vector load or store has no active elements then no CHERI fault will be taken.
This is consistent with other exceptions such as page faults which are only taken on active elements.
In the case of fault-only-first loads, a CHERI bounds violation is only taken if any bytes of element 0 are out of bounds, or if the CHERI bounds are malformed and there are any active elements. If another active element causes a CHERI bounds violation then it is treated the same way as other exceptions, the trap is not taken and instead vl is reduced. All other CHERI fault types, such as tag violations, are only taken if element zero is active.
Indexed loads in Capability Pointer Mode check the bounds of every access against
the authorizing capability in cs1 . Therefore the approach of having a zero base
register and treating every element as an absolute address may not work well
in this mode.
|
Appendix A: Anatomy of Capabilities in RV32Y/RV64Y
This chapter will appear as an appendix in the unpriv specification. |
RISC-V defines variants of the base integer instruction set characterized by the width of the integer registers and the corresponding size of the address space. There are two primary ISA variants, RV32I and RV64I, which provide 32-bit and 64-bit address spaces respectively. The term XLEN refers to the width of an integer register in bits (either 32 or 64). The value of XLEN may change dynamically at run-time depending on the values written to CSRs, so we define capability behavior in terms of MXLEN, which is the value of XLEN used in machine mode and the widest XLEN the implementation supports.
RV32Y/RV64Y assumes a version of the privileged architecture which defines MXLEN as constant and requires higher privilege modes to have at least the same XLEN as lower privilege modes; these changes are present in the current draft and expected to be part of privileged architecture 1.13. |
RV32Y/RV64Y defines capabilities of size CLEN corresponding to 2 * MXLEN without including the valid tag bit. The value of CLEN is always calculated based on MXLEN regardless of the effective XLEN value.
We briefly note that the capability encoding described in this section could be replaced with an entirely different design without changing how CHERI integrates with the RISC-V ISA. In particular, this capability encoding specification was designed to run software initially ported to CHERIv9 while providing spatial safety, temporal safety and compartmentalization support alongside a good measure of compatibility with RISC-V software that is not aware of CHERI. Alternative capability encoding specifications must provide key primitives, such as permissions and bounds, from this specification while using a different encoding that, for example, changes the granularity of bounds or adds new features. For simplicity of expression, the text is written as if this was the only possible capability encoding for CHERI RISC-V. |
A.1. Capability Encoding
The components of a capability, except the valid tag, are encoded as shown in Figure 8 for MXLEN=32 and Figure 9 for MXLEN=64. Each memory location or register able to hold a capability must also store the valid tag as out of band or hidden information that software cannot directly set or clear. The capability metadata is held in the most significant bits and the address is held in the least significant bits.
Reserved bits are available for future extensions to RV32Y/RV64Y.
Reserved bits must be 0 in tagged capabilities. |
The encoding of capabilities depends on the extensions supported by the current environment. The following extensions affect the capability encoding:
- Zcherihybrid
-
When Zcherihybrid is supported, capabilities include a M-bit. If not supported this field becomes reserved and reads as zero.
- Zcheri0lvl/Zcheri1lvl
-
Implementations of RV32Y/RV64Y may choose how many Capability Level (CL) bits (
LVLBITS
) to support. The CL field is variable width and depends on which of the mutually exclusive extensions Zcheri0lvl or Zcheri1lvl is supported.-
When Zcheri0lvl is supported, then
LVLBITS=0
and capability levels are not dynamically adjustable. Therefore, EL-permission, SL-permission and the Capability Level (CL) are hardwired to 1 and not encoded in the capability format. In this case, all capability checks related to levels always pass. -
When Zcheri1lvl is supported, then
LVLBITS=1
and capability levels are dynamically adjustable. All of EL-permission, SL-permission and the Capability Level (CL) are one bit wide and are encoded in the capability format memory.
-
Future extensions may increase the width of this field. |
A.1.1. Architectural Permissions (AP) Encoding
The bit width of the permissions field depends on the value of MXLEN as shown in Table 15. A 5-bit vector encodes the permissions when MXLEN=32. For this case, the legal encodings of permissions are listed in Table 16. Certain combinations of permissions are impractical. For example, C-permission is superfluous when the capability does not grant either R-permission or W-permission. Therefore, it is only possible to encode a subset of all combinations.
MXLEN | AP field width | Comment |
---|---|---|
32 |
5 |
Encodes some combinations of 6 permission bits, including the M-bit if Zcherihybrid is supported. |
64 |
6/81 |
Separate bits for each architectural permission. |
1 If Zcheri0lvl is supported this field is 6 bits wide, with Zcheri1lvl it uses 8 instead.
For MXLEN=32, the permissions encoding is split into four quadrants. The quadrant is taken from bits [4:3] of the permissions encoding. The meaning for bits [2:0] are shown in Table 16 for each quadrant.
Quadrants 2 and 3 are arranged to implicitly grant future permissions which may be added with the existing allocated encodings. Quadrant 0 does the opposite - the encodings are allocated not to implicitly add future permissions, and so granting future permissions will require new encodings. Quadrant 1 encodes permissions for executable capabilities and the M-bit.
Encoding[2:0] | R | W | C | LM | X | ASR | Mode1 | Notes |
---|---|---|---|---|---|---|---|---|
Quadrant 0: Non-capability data read/write |
||||||||
bit[2] - write, bit[1] - reserved (0), bit[0] - read |
||||||||
Reserved bits for future extensions are 0 so new permissions are not implicitly granted |
||||||||
0 |
N/A |
No permissions |
||||||
1 |
✔ |
N/A |
Data RO |
|||||
2-3 |
reserved |
|||||||
4 |
✔ |
N/A |
Data WO |
|||||
5 |
✔ |
✔ |
N/A |
Data RW |
||||
6-7 |
reserved |
|||||||
Quadrant 1: Executable capabilities |
||||||||
bit[0] - M-bit (0-Capability Pointer Mode, 1-Integer Pointer Mode) |
||||||||
0-1 |
✔ |
✔ |
✔ |
✔ |
✔ |
✔ |
Mode1 |
Execute + ASR (see Infinite) |
2-3 |
✔ |
✔ |
✔ |
✔ |
Mode1 |
Execute + Data & Cap RO |
||
4-5 |
✔ |
✔ |
✔ |
✔ |
✔ |
Mode1 |
Execute + Data & Cap RW |
|
6-7 |
✔ |
✔ |
✔ |
Mode1 |
Execute + Data RW |
|||
Quadrant 2: Restricted capability data read/write |
||||||||
R and C implicitly granted, LM dependent on W permission. |
||||||||
Reserved bits for future extensions must be 1 so they are implicitly granted |
||||||||
bit[2] is reserved to mean write for future encodings |
||||||||
0-2 |
reserved |
|||||||
3 |
✔ |
✔ |
N/A |
Data & Cap RO (no LM) |
||||
4-7 |
reserved |
|||||||
Quadrant 3: Capability data read/write |
||||||||
bit[2] - write, R and C implicitly granted. |
||||||||
Reserved bits for future extensions must be 1 so they are implicitly granted |
||||||||
0-2 |
reserved |
|||||||
3 |
✔ |
✔ |
✔ |
N/A |
Data & Cap RO |
|||
4-6 |
reserved |
|||||||
7 |
✔ |
✔ |
✔ |
✔ |
N/A |
Data & Cap RW |
1 Mode (M-bit) can only be set on a tagged capability when Zcherihybrid is supported. Despite being encoded here it is not an architectural permission.
When MXLEN=32 there are many reserved permission encodings (see Table 16). It is not possible for a tagged capability to have one of these values since ACPERM will never create it. It is possible for untagged capabilities to have reserved values. GCPERM will interpret reserved values as if it were 0b00000 (no permissions). Future extensions may assign meanings to the reserved bit patterns, in which case GCPERM is allowed to report a non-zero value. |
Mode is encoded with permissions for MXLEN=32, but is not a permission. It is orthogonal to permissions as it can vary arbitrarily using SCMODE. |
Bits[4:3] | R | W | C | LM | EL | SL | X | ASR | Mode1 | Notes |
---|---|---|---|---|---|---|---|---|---|---|
Quadrant 0: Non-capability data read/write |
||||||||||
bit[2] - write, bit[1] - reserved (0), bit[0] - read |
||||||||||
Reserved bits for future extensions are 0 so new permissions are not implicitly granted |
||||||||||
0 |
N/A |
No permissions |
||||||||
1 |
✔ |
N/A |
Data RO |
|||||||
2-3 |
reserved |
|||||||||
4 |
✔ |
N/A |
Data WO |
|||||||
5 |
✔ |
✔ |
N/A |
Data RW |
||||||
6-7 |
reserved |
|||||||||
Quadrant 1: Executable capabilities |
||||||||||
bit[0] - M-bit (0-Capability Pointer Mode, 1-Integer Pointer Mode) |
||||||||||
Bits[4:3] |
R |
W |
C |
LM |
EL |
SL |
X |
ASR |
Mode1 |
|
0-1 |
✔ |
✔ |
✔ |
✔ |
✔ |
∞ |
✔ |
✔ |
Mode1 |
Execute + ASR (see Infinite) |
2-3 |
✔ |
✔ |
✔ |
✔ |
∞2 |
✔ |
Mode1 |
Execute + Data & Cap RO |
||
4-5 |
✔ |
✔ |
✔ |
✔ |
✔ |
∞ |
✔ |
Mode1 |
Execute + Data & Cap RW |
|
6-7 |
✔ |
✔ |
02 |
✔ |
Mode1 |
Execute + Data RW |
||||
Quadrant 2: Restricted capability data read/write |
||||||||||
bit[2] = write, bit[1:0] = store level. R and C implicitly granted, LM dependent on W permission. |
||||||||||
Bits[4:3] |
R |
W |
C |
LM |
EL |
SL |
X |
ASR |
Mode1 |
|
0-2 |
reserved |
|||||||||
3 |
✔ |
✔ |
01 |
N/A |
Data & Cap R0 (without LM-permission) |
|||||
4 |
✔ |
✔ |
✔ |
✔ |
(3) |
N/A |
Reserved when |
|||
5 |
✔ |
✔ |
✔ |
✔ |
(2) |
N/A |
Reserved when |
|||
6 |
✔ |
✔ |
✔ |
✔ |
1 |
N/A |
Data & Cap RW (with store local, no EL-permission) |
|||
7 |
✔ |
✔ |
✔ |
✔ |
0 |
N/A |
Data & Cap RW (no store local, no EL-permission) |
|||
Quadrant 3: Capability data read/write |
||||||||||
bit[2] = write, bit[1:0] = store level. R and C implicitly granted. |
||||||||||
Reserved bits for future extensions must be 1 so they are implicitly granted |
||||||||||
Bits[4:3] |
R |
W |
C |
LM |
EL |
SL |
X |
ASR |
Mode1 |
|
0-2 |
reserved |
|||||||||
3 |
✔ |
✔ |
✔ |
✔ |
02 |
N/A |
Data & Cap R0 |
|||
4 |
✔ |
✔ |
✔ |
✔ |
✔ |
(3) |
N/A |
Reserved when |
||
5 |
✔ |
✔ |
✔ |
✔ |
✔ |
(2) |
N/A |
Reserved when |
||
6 |
✔ |
✔ |
✔ |
✔ |
✔ |
1 |
N/A |
Data & Cap RW (with store local) |
||
7 |
✔ |
✔ |
✔ |
✔ |
✔ |
0 |
N/A |
Data & Cap RW (no store local) |
1 Mode (M-bit) can only be set on a tagged capability when Zcherihybrid
is supported, otherwise such encodings are reserved. Despite being encoded here it is not an architectural permission.
2 SL isn’t applicable in these cases, but this value is reported by GCPERM to simplify the rules followed by ACPERM
3 These entries are reserved when LVLBITS=1
and in use when LVLBITS=2
When MXLEN=64, there is a bit per permission as shown in Table 18. A permission is granted if its corresponding bit is set, otherwise the capability does not grant that permission.
Bit | Encoded permission |
---|---|
0 |
|
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
EL-permission with Zcheri1lvl / reserved with Zcheri0lvl |
7 |
SL-permission with Zcheri1lvl / reserved with Zcheri0lvl |
The M-bit is only assigned meaning when the implementation supports Zcherihybrid and X-permission is set.
-
For MXLEN=64, the bit assigned to the M-bit must be zero if X-permission isn’t set.
-
For MXLEN=32, the M-bit is only encoded in quadrant 1 and does not exist in the other quadrants.
Permission Transitions
Executing ACPERM can result in sets of permissions which cannot be represented when MXLEN=32 (see Table 16) or permission combinations which are not useful for MXLEN=64, such as ASR-permission set without X-permission. These cases are defined to return useful minimal sets of permissions.
When removing permissions with ACPERM the following rules are followed in order:
Rule | Permission | Only valid if |
---|---|---|
1 (RV32 only) |
All other permissions are set. |
|
2 |
||
3 (RV32 only) |
||
4 (RV32 only) |
||
5 (RV32 only) |
not(C-permission) or LM-permission |
|
6 (RV32 only) |
||
7 |
||
8 (RV32 only) |
||
9 |
||
10 (RV32 only) |
||
11 |
||
12 (RV32 only) |
(LM-permission and (X-permission or W-permission)) |
|
13 (RV32 only) |
(C-permission and LM-permission and EL-permission and (SL-permission == ∞)) or |
|
14 |
||
152 |
X-permission and Zcherihybrid is implemented |
1 All the listed permissions in the set are either minimum or maximum.
2 For RV32, the encodings which have the M-bit set to 1 for Integer Pointer Mode
are only valid if Zcherihybrid is implemented. Otherwise those encodings represent invalid permissions.
Depending on the supported extensions and permissions encoding some referenced bits may have a hardwired value. In this case the rules are applied starting with this hardwired value, and proceed as if it had been modified but any change is discarded after following the final rule. For example, RV64 without Zcherihybrid, the M-bit is a reserved bit, and so is not relevant to ACPERM. Similarly, if Zcheri0lvl is implemented then EL-permission is initialized to 1, and SL-permission is initialized to the maximum value, but the resulting EL-permission and SL-permission is discarded at the end. |
Future extensions may allow more combinations of permissions, especially for MXLEN=64. |
A.1.2. Software-Defined Permissions (SDP) Encoding
The width of the SDP field depends on the underlying base architecture. The value of the SDP bits of the GCPERM result maps 1:1 to the SDP field in the capability.
MXLEN | SDPLEN |
---|---|
32 |
2 |
64 |
4 |
Software is completely free to define the usage of these bits. |
A.1.3. Capability Type (CT) Encoding
For RV32Y/RV64Y the CT field is one bit wide and maps 1:1 to the capability types listed in Table 2: it is a sentry capability if the bit is 1 or unsealed if it is 0.
A.1.4. Bounds (EF, T, TE, B, BE) Encoding
Concept
The bounds encode the base and top addresses that constrain memory accesses. The capability can be used to access any memory location A in the range base ≤ A < top. The bounds are encoded in compressed format, so it is not possible to encode any arbitrary combination of base and top addresses. An invalid capability with tag cleared is produced when attempting to construct a capability that is not representable because its bounds cannot be correctly encoded. The bounds are decoded as described in Section A.1.
The bounds field has the following components:
-
T: Value substituted into the capability’s address to decode the top address
-
B: Value substituted into the capability’s address to decode the base address
-
E: Exponent that determines the position at which B and T are substituted into the capability’s address
-
EF: Exponent format flag indicating the encoding for T, B and E
-
The exponent is stored in T and B if EF=0, so it is 'internal'
-
The exponent is zero if EF=1
-
The bit width of T and B are defined in terms of the mantissa width (MW) which is set depending on the value of MXLEN as shown in Table 21.
MXLEN | MW |
---|---|
32 |
10 |
64 |
14 |
The exponent E indicates the position of T and B within the capability’s address as described in Section A.1. The bit width of the exponent (EW) is set depending on the value of MXLEN. The maximum value of the exponent is calculated as follows:
CAP_MAX_E = MXLEN - MW + 2
The possible values for EW and CAP_MAX_E are shown in Table 22.
MXLEN | EW | CAP_MAX_E |
---|---|---|
32 |
5 |
24 |
64 |
6 |
52 |
The address and bounds must be representable in valid capabilities i.e. when the valid tag is set (see Section A.1.4.4). |
Decoding
The metadata is encoded in a compressed format (Woodruff et al., 2019). It uses a floating point representation to encode the bounds relative to the capability address. The base and top addresses from the bounds are decoded as shown below.
The pseudocode below does not have a formal notation.
It is a place-holder until the sail implementation has been integrated in the specification.
In this notation, / means "integer division", [] are the bit-select operators, and arithmetic is signed.
|
EW = (MXLEN == 32) ? 5 : 6
CAP_MAX_E = MXLEN - MW + 2
If EF = 1:
E = 0
T[EW / 2 - 1:0] = TE
B[EW / 2 - 1:0] = BE
LCout = (T[MW - 3:0] < B[MW - 3:0]) ? 1 : 0
LMSB = (MXLEN == 32) ? L8 : 0
else:
E = CAP_MAX_E - ( (MXLEN == 32) ? { L8, TE, BE } : { TE, BE } )
T[EW / 2 - 1:0] = 0
B[EW / 2 - 1:0] = 0
LCout = (T[MW - 3:EW / 2] < B[MW - 3:EW / 2]) ? 1 : 0
LMSB = 1
Reconstituting the top two bits of T:
T[MW - 1:MW - 2] = B[MW - 1:MW - 2] + LCout + LMSB
-
If E = 0 the lower section does not exist.
-
If E+MW=MXLEN then the top section is only the least signification bit of ct for the top bound, and top section doesn’t exist for the bottom bound.
-
If E+MW>MXLEN then neither top section exists, and so the bounds are calculated with no depending on the address field a.
The corrections ct and cb are calculated as as shown below using the definitions in Table 23 and Table 24.
A = a[E + MW - 1:E] R = B - 2MW-2
A < R | T < R | ct |
---|---|---|
false |
false |
0 |
false |
true |
+1 |
true |
false |
-1 |
true |
true |
0 |
A < R | B < R | cb |
---|---|---|
false |
false |
0 |
false |
true |
+1 |
true |
false |
-1 |
true |
true |
0 |
The base, b, and top, t, addresses are derived from the address by substituting a[E + MW - 1:E] with B and T respectively and clearing the lower E bits. The most significant bits of a may be adjusted up or down by 1 using corrections cb and ct to allow encoding memory regions that span alignment boundaries.
The EF bit selects between two cases:
-
EF = 1: The exponent is 0 for regions less than 2MW-2 bytes long. L8 is used to encode the MSB of the length and is added to B along with T[MW-3:0] to form the decoded top.
-
EF = 0: The exponent is internal with E stored in the lower bits of T and B along with L8 when MXLEN=32. E is chosen so that the most significant non-zero bit of the length of the region aligns with T[MW - 2] in the decoded top. Therefore, the most significant two bits of T can be derived from B using the equality
T = B + L
, where L[MW - 2] is known from the values of EF and E and a carry out is implied ifT[MW - 3:0] < B[MW - 3:0]
since it is guaranteed that the top is larger than the base.
The compressed bounds encoding allows the address to roam over a large representable region while maintaining the original bounds. This is enabled by defining a lower boundary R from the out-of-bounds values that allows us to disambiguate the location of the bounds with respect to an out-of-bounds address. R is calculated relative to the base by subtracting 2MW-2 from B. If B, T or a[E + MW - 1:E] is less than R, it is inferred that they lie in the 2E+MW aligned region above R labeled spaceU in Figure 2 and the corrections ct and cb are computed accordingly. The overall effect is that the address can roam 2E+MW/4 bytes below the base address and at least 2E+MW/4 bytes above the top address while still allowing the bounds to be correctly decoded.
Top bound MSB correction
A capability has infinite bounds if its bounds cover the entire address space such that the base address b=0 and the top address t≥2MXLEN, i.e., t is an MXLEN + 1 bit value. However, b is an MXLEN-bit value and the size mismatch introduces additional complications when decoding, so the following condition is required to correct t for capabilities whose Representable Range wraps the edge of the address space:D
if ( (E < (CAP_MAX_E - 1)) & (t[MXLEN: MXLEN - 1] - b[MXLEN - 1] > 1) )
t[MXLEN] = !t[MXLEN]
The comparison is unsigned. |
That is, invert the most significant bit of t if the decoded length of the capability is larger than E.
A capability has infinite bounds if E=CAP_MAX_E and it is not malformed (see Section A.1.4.4); this check is equivalent to b=0 and t≥2MXLEN. |
Malformed Capability Bounds
A capability is malformed if its bounds cannot be correctly decoded.
The following check
indicates whether a capability is malformed. enableL8
is true when MXLEN=32
and false otherwise, indicating whether the L8
bit is available for extra
precision when EF=1
.
malformedMSB = (E == CAP_MAX_E && B != 0)
|| (E == CAP_MAX_E - 1 && B[MW - 1] != 0)
malformedLSB = (E < 0) || (E == 0 && enableL8)
malformed = !EF && (malformedMSB || malformedLSB)
The check is for malformed bounds, so it does not include reserved bits! |
CHERI enforces the following invariants for all valid (i.e., tagged) capabilities:
-
The bounds are not malformed.
-
No reserved bit in the capability encoding is set.
-
The permissions can be legally produced by ACPERM.
A tagged capability that violates those invariants (i.e., a tagged but malformed capability or a tagged capability with any reserved bit set) can only possibly be caused by a logic or memory fault (e.g., bit flipping).
Capabilities with malformed bounds:
See specific instruction pages for full details of the effect of malformed capabilities.
A.2. Encoding of Special Capabilities
A.2.1. NULL Capability Encoding
The NULL capability is represented with 0 in all fields. This implies that it has no permissions and its exponent E is CAP_MAX_E (52 for MXLEN=64, 24 for MXLEN=32), so its bounds cover the entire address space such that the expanded base is 0 and top is 2MXLEN.
Field | Value | Comment |
---|---|---|
Tag |
zero |
Capability is not valid |
SDP |
zeros |
Grants no permissions |
AP |
zeros |
Grants no permissions |
M |
zero |
No meaning since non-executable (MXLEN=64 only) |
CL |
zero1 |
Local |
CT |
zero |
Unsealed |
EF |
zero |
Internal exponent format |
L8 |
zero |
Top address reconstruction bit (MXLEN=32 only) |
T |
zeros |
Top address bits |
TE |
zeros |
Exponent bits |
B |
zeros |
Base address bits |
BE |
zeros |
Exponent bits |
Address |
zeros |
Capability address |
Reserved |
zeros |
All reserved fields |
1 This field may be zero bits wide (i.e., omitted) if Zcheri0lvl is implemented.
A.2.2. Infinite Capability Encoding
The Infinite capability grants all permissions while its bounds also cover the whole address space. It includes X-permission and so includes the M-bit if Zcherihybrid is supported.
Future extension to the capability format may use a "multi-root" format where the infinite capability does not exist and instead have multiple roots with different permissions (e.g., one for code and one for data). |
Field | Value | Comment |
---|---|---|
Tag |
one |
Capability is valid |
SDP |
ones |
Grants all permissions |
AP (MXLEN=32) |
0x8/0x91 (see Table 16) |
Grants all permissions |
AP (MXLEN=64) |
0xFF (see Table 18) |
Grants all permissions |
CL |
one2 |
Global |
CT |
zero |
Unsealed |
EF |
zero |
Internal exponent format |
L8 |
zero |
Top address reconstruction bit (MXLEN=32 only) |
T |
zeros |
Top address bits |
TE |
zeros |
Exponent bits |
B |
zeros |
Base address bits |
BE |
zeros |
Exponent bits |
Address |
zeros |
Capability address |
Reserved |
zeros |
All reserved fields |
1If Zcherihybrid is supported, then the Infinite capability must represent Integer Pointer Mode for compatibility with standard RISC-V code. Therefore:
2 This field may be zero bits wide (i.e., omitted) if Zcheri0lvl is implemented.
A.3. Memory space
A hart supporting RV32Y/RV64Y 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 Representable Range described in Section A.1 is also circular, so address 0 is within the Representable Range 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 capability and does not authorize access to the byte at address 0. Like malformed bounds (see Section A.1.4.4), 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.
A.4. Representable Range Check
A.4.1. Concept
The new address, after updating the address of a capability, is within the representable range if decompressing the capability’s bounds with the original and new addresses yields the same base and top bounds.
In other words, given a capability with address a and the
new address a' = a + x
, the bounds b and t are decoded using a and the
new bounds b' and t' are decoded using a'. The new address is within the
capability’s representable range if b == b' && t == t'
.
Changing a capability’s address to a value outside the representable range unconditionally clears the capability’s tag. Examples are:
A.4.2. Practical Information
An artifact of the bounds encoding is that if an address is changed
such that t != t'
, then it is also the case that b != b'
.
The inverse is also true, if b != b'
then t != t'
.
Therefore, for representable range checking, it is acceptable
to either check t == t'
or b == b'
.
In the bounds encoding in this specification, the top and bottom capability bounds are formed of two or three sections:
-
Upper bits from the address
-
This is only if the other sections do not fill the available bits (E + MW < MXLEN)
-
-
Middle bits from T and B decoded from the metadata
-
Lower bits are set to zero
-
This is only if there is an internal exponent (EF=0)
-
Configuration | Upper Section (if E + MW < MXLEN) | Middle Section | Lower Section |
---|---|---|---|
EF=0 |
address[MXLEN-1:E + MW] + ct |
T[MW - 1:0] |
{E{1’b0}} |
EF=1, i.e., E=0 |
address[MXLEN-1:MW] + ct |
T[MW - 1:0] |
The representable range defines the range of addresses which do not corrupt the bounds encoding. The encoding was first introduced in Section A.1, and is repeated in a different form in Table 27 to aid this description.
For the address to be valid for the current bounds encoding, the value
in the Upper Section of Table 27 must
not change as this will change the meaning of the bounds. This
is because T
, B
and E
will be unchanged for the source and
destination capabilities. Therefore, the Middle and Lower sections
of the bounds calculation are also unchanged for source and
destination capabilities.
When E > CAP_MAX_E - 2, the calculation of the top bound is entirely derived
from T
and E
which will be identical for both the source and destination
capabilities, thus guaranteeing that t == t'
. Likewise, with such values of E, the
base bound is entirely derived from B
and E
and therefore b == b'
.
The calculation of the MSB of the top bound maybe inverted as specified
Section A.1.4.3.
Assuming (E < (CAP_MAX_E - 1))
, the truth-table for this inversion is as follows:
input_t[MXLEN:MXLEN-1] | b[MXLEN-1] | output_t[MXLEN:MXLEN-1] |
---|---|---|
00 |
0 |
00 |
01 |
0 |
01 |
10 |
0 |
00 |
11 |
0 |
01 |
00 |
1 |
10 |
01 |
1 |
01 |
10 |
1 |
10 |
11 |
1 |
01 |
Inspection of Table 28 shows
that output_t[MXLEN]
does not depend on input_t[MXLEN]
as:
-
output_t[MXLEN] = {input_t[MXLEN-1], b[MXLEN-1]} == 2’b01
.
This leads to the conclusions:
-
If
t[MXLEN-1] == t'[MXLEN-1]
andb[MXLEN-1] == b'[MXLEN-1]
, then it is guaranteedt[MXLEN] == t'[MXLEN]
. -
If
t[MXLEN-1] != t'[MXLEN-1]
orb[MXLEN-1] != b'[MXLEN-1]
, then the representable check will fail regardless of checkingt[MXLEN] == t'[MXLEN]
.
Therefore, for the purposed of representable range checking, it is not
required to check that t[MXLEN]==t'[XLEN]
.
Given that t[MXLEN]
is not part of the representable range check:
-
when
E == CAP_MAX_E - 2
,t[MXLEN-1:E] == T[MW-1:0]
andb[MXLEN-1:E] == B[MW-1:0]
.
Therefore, T
and B
are both derived from the capabilities metadata and are
therefore constant. Which means that in this case too, the representable
range check always passes.
As a result:
-
If E > CAP_MAX_E - 3, then the representability check always passes, even though the bounds are only infinite if E = CAP_MAX_E
This gives a range of s=2E+MW
, as shown in
Figure 2.
The gap between the object bounds and the bound of the representable range
is always guaranteed
to be at least 1/4 of s
. This is represented by R = B - 2MW-2
in
Section A.1.
This gives useful guarantees, such that if an executed instruction is in
pcc bounds, then it is also guaranteed that the next linear instruction
is representable.
A.5. Extending Zcheri1lvl to more than two levels
When LVLBITS > 1
, the behavior of ACPERM can no longer use masking to adjust the Capability Level (CL) or SL-permission, but instead must perform an integer minimum operation on those LVLBITS
-wide fields.
The CL field of the resulting capability is set to min(rs2[CL], cs1[CL])
(equivalent to rs2[CL] & cs1[CL]
for LVLBITS=1
).
Similarly, SL-permission is set to min(rs2[SL], cs1[SL])
(equivalent to rs2[SL] & cs1[SL]
for LVLBITS=1
).
When storing capabilities, the SL-permission checks need to perform a LVLBITS
-wide integer comparison instead of just testing a single bit.
Considering for an example LVLBITS=2
:
SL-permission | Permitted for levels | Resulting semantics |
---|---|---|
3 |
As low as |
Authorizes stores of capabilities with any level |
2 |
As low as |
Strip tag for level 0 (most local), keep for 1,2,3 |
1 |
As low as |
Strip tag for level 0&1, keep for 2&3 |
0 |
As low as |
Strip tag for level 0,1,2, i.e., only the most global can be stored |
While this extra negation is non-intuitive, it is required such that ACPERM can use a monotonically decreasing operation for both CL SL-permission. |
Chapters for the privileged specification
7. "Smcheri/Sscheri" Extensions, Version 1.0
This chapter will appear in the priv spec. Exact location TBD. |
This chapter describes integration of RV32Y/RV64Y with the RISC-V privileged architecture.
7.1. Machine-Level CSRs added or extended by Smcheri
RV32Y/RV64Y extends some M-mode CSRs to hold capabilities or otherwise add new functions. ASR-permission in the pcc is typically required for access.
7.1.1. Machine Trap Vector Base Address Capability Register (mtvecc)
The mtvecc register extends mtvec to hold a code capability. Its reset value is the Infinite capability.
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], which is a WARL field, meaning that the capability address can be legalized. If the MODE field is non-zero after any legalization, then the address used for the exception vector (which has mtvecc.address[1:0]=2’b00) will not match the value read by software from the CSR.
When updating the CSR all possible values of the address visible either by CSR read, or which are used as the pcc on exception launch, must be in the Representable Range, and the valid tag cleared if any are not.
The capability is always written using SCADDR semantics to update the address field, even when writing the full capability, and so sealed capabilities will always have their tags cleared.
Additionally, when MODE=Vectored the capability has its tag bit cleared if the
(capability address & ~3) + 4 * HICAUSE
is not within the Representable Range.
HICAUSE is the largest interrupt cause value that the implementation can write
to mcause or scause/vscause when an interrupt is taken.
When MODE=Vectored, it is only required that the capability address + 4 * HICAUSE is
within the Representable Range 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.
|
When MODE=Vectored, if either the capability address or the capability
address + 4 * HICAUSE are invalid then the Invalid address conversion rules
are followed which may require the valid tag to be cleared. In particular, if any part
of the range is in the invalid address space then clearing the valid tag is strongly
recommended.
|
As shown in Table 60, mtvecc is a code capability, so it does not need to be able to hold all possible invalid addresses (see Invalid address conversion).
7.1.2. Machine Scratch Capability Register (mscratchc)
The valid tag of the CSR must be reset to zero. The reset values of the metadata and address fields are UNSPECIFIED.
It is not WARL, all capability fields must be implemented.
7.1.3. Machine Exception Program Counter Capability (mepcc)
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 Representable Range or if the legalization changes the address and the capability is sealed.
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 Table 60, mepcc is a code capability, so it does not need to be able to hold all possible invalid addresses (see Invalid address conversion). Additionally, the capability in mepcc is unsealed when it is installed in pcc on execution of an MRET(RV32Y/RV64Y) instruction.
7.2. Machine-Level CSRs modified by Smcheri
7.2.1. Machine Status Registers (mstatus and mstatush)
The mstatus and mstatush registers operate as described in mstatus with two restrictions:
-
The SXL and UXL fields that control the value of XLEN for S-mode and U-mode must be read-only in implementations supporting RV32Y/RV64Y. Only 1 and 2 are supported values for SXL and UXL
-
The MBE, SBE, and UBE fields that control the memory system endianness for M-mode, S-mode, and U-mode must be read-only in implementations supporting RV32Y/RV64Y. 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.
Changing XLEN or endianness would change the interpretation of all in-memory capabilities, so allowing these fields to change at runtime is prohibited.
These restrictions are relaxed if a further privileged CHERI extension, Smcherivarxlen, optionally makes SXL, UXL, MBE, SBE, and UBE writeable, to support CHERI on implementations that support dynamic XLEN or endianness changes. |
- CAUTION
-
ARC-QUESTION: Doesif Smcherivarxlen need to be a separate extension or just a "if xME,xXL bits are writable, then this behavior is followed" note in Smcheri
7.2.2. Machine Cause Register (mcause)
RV32Y/RV64Y 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 Machine cause (mcause
) register values after trap and Synchronous exception priority in decreasing priority order respectively.
The behavior and usage of mcause otherwise remains as described in mcause.
The current specification uses the CHERI ISAv9 mcause value of 28, which is designated for custom extensions. |
- CAUTION
-
ARC-QUESTION: The exact code as well as the mechanism to report subcodes needs to be finalized: github.com/riscv/riscv-cheri/issues/536
If an instruction may raise multiple synchronous exceptions, the decreasing priority order of Table 29 indicates which exception is taken and reported in mcause
.
This table extends the existing priority order from Synchronous exception priority in decreasing priority order with new entries.
Once finalized this table should be merged with the main table. |
Priority | Exc.Code | Description |
---|---|---|
Highest |
3 |
Instruction address breakpoint |
28 |
Prior to instruction address translation: |
|
12, 1 |
During instruction address translation: |
|
1 |
With physical address for instruction: |
|
2 |
Illegal instruction |
|
28 |
CHERI faults due to: |
|
28 |
Prior to address translation for an explicit memory access: |
|
4,6 |
Load/store/AMO capability address misaligned |
|
13, 15, 5, 7 |
During address translation for an explicit memory access: |
|
5,7 |
With physical address for an explicit memory access: |
|
4,6 |
If not higher priority: |
|
Lowest |
13 |
If not higher priority: |
1 PCC bounds are intended to be checked against all the bytes of fetched instructions. In the case of variable length instruction encoding, and that the fetch has failed to return any data, then only a minimum length instruction is checked against the PCC bounds.
2 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.
3 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 page fault are both detected simultaneously, then both are recorded as shown in Table 32.
4 The lower priority CHERI PTE page fault only covers capability loads and atomics where the loaded tag is checked.
The full details of the CHERI exceptions with cause value 28 are in Table 34. |
7.2.3. 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.
7.2.4. Machine Trap Value Register (mtval)
The mtval register is an MXLEN-bit read-write register formatted as shown in Figure 15. When a data memory access causes 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. In this case the TYPE field of mtval2 shown in Table 30 is set to 1. For all other CHERI faults mtval is set to zero.
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.
7.2.5. 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 (RISC-V, 2023). RV32Y/RV64Y also requires the implementation of this CSR.
When a CHERI fault, or CHERI PTE page fault, is taken into M-mode, mtval2 is written with additional CHERI-specific exception information with the format shown in Figure 16 to assist software in handling the trap.
mtval2 is written to zero for all other exceptions, except as listed otherwise by the Hypervisor extension in (RISC-V, 2023), or by other future extensions.
the use of mtval2/stval2/vstval2 may be irregular as the Hypervisor uses mtval2 and htval for guest page addresses on guest page fault, and CHERI has no use for htval. |
If mtval is read-only zero for CHERI exceptions then mtval2 is also read-only zero for CHERI exceptions.
mtval2 values for CHERI faults
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 Figure 16 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 30 and Table 31 respectively.
CHERI Type Code | Description |
---|---|
0 |
CHERI instruction fetch fault |
1 |
CHERI data fault due to load, store or AMO |
2 |
CHERI jump or branch fault |
3-15 |
Reserved |
CHERI Cause Code | Description |
---|---|
0 |
Tag violation |
1 |
Seal violation |
2 |
Permission violation |
3 |
Invalid address violation |
4 |
Bounds violation |
5-15 |
Reserved |
CHERI violations have the following order in priority:
-
Tag violation (Highest)
-
Seal violation
-
Permission violation
-
Invalid address violation
-
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.
Fault | Value |
---|---|
RISC-V page fault |
0 |
1 |
|
RISC-V page fault and CHERI PTE page fault |
2 |
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. |
7.3. Supervisor-Level CSRs added or extended by Sscheri
RV32Y/RV64Y extends some of the existing RISC-V CSRs to be able to hold capabilities or with other new functions. ASR-permission in the pcc is typically required for access.
7.3.1. Supervisor Trap Vector Base Address Capability Register (stvecc)
The stvecc register extends stvec that is able to hold a capability. Its reset value is the Infinite capability.
7.3.2. Supervisor Scratch Capability Register (sscratchc)
The valid tag of the CSR must be reset to zero. The reset values of the metadata and address fields are UNSPECIFIED.
It is not WARL, all capability fields must be implemented.
7.3.3. Supervisor Exception Program Counter Capability (sepcc)
As shown in Table 60, sepcc is a code capability, so it does not need to be able to hold all possible invalid addresses (see Invalid address conversion). Additionally, the capability in sepcc is unsealed when it is installed in pcc on execution of an SRET (RV32Y/RV64Y) instruction. The handling of sepcc is otherwise identical to mepcc, but in supervisor mode.
7.3.4. Supervisor Trap Value Register 2 (stval2)
The stval2 register is an SXLEN-bit read-write register, which is added as part of Sscheri when the implementation supports S-mode. Its CSR address is 0x14b.
stval2 is updated following the same rules as mtval2 for CHERI exceptions and CHERI PTE page faults which are delegated to HS-mode or S-mode. It is written to zero for all other exceptions, except as listed otherwise by other future extensions.
The mechanism to report exception subcodes needs to be finalized: github.com/riscv/riscv-cheri/issues/536 |
7.4. Supervisor-Level CSRs modified by Sscheri
7.4.1. Supervisor Cause Register (scause)
RV32Y/RV64Y adds a new exception code for CHERI exceptions that scause must be able to represent.
The new exception code is listed in .Supervisor cause (scause
) register values after trap.
The behavior and usage of scause otherwise remains as described in scause.
See Section 7.2.2 for the new exceptions priorities when RV32Y/RV64Y is implemented.
7.4.2. Supervisor Trap Value Register (stval)
stval is updated following the same rules as Section 7.2.4 for CHERI exceptions and CHERI PTE page faults which are delegated to HS-mode or S-mode.
7.5. CHERI Exception handling
ARC-QUESTION: Need feedback whether to add this info to xcause or xtval2: github.com/riscv/riscv-cheri/issues/536 |
CHERI faults require additional information to be reported. The CSRs updated depend on the mode the trap is taken into, as shown in Table 33.
The additional information is written for CHERI faults and CHERI PTE page faults, and is otherwise written to zero for all other exceptions, except as listed otherwise by other future extensions.
Trap taken into | Faulting address | Additional CHERI fault information |
---|---|---|
M-mode |
||
HS-mode / S-mode |
||
VS-mode |
auth_cap is ddc for Integer Pointer Mode and cs1 for Capability Pointer Mode
|
Instructions | Xcause | Xtval2. TYPE | Xtval2. CAUSE | Description | Check |
---|---|---|---|---|---|
All instructions have these exception checks first |
|||||
All |
28 |
0 |
0 |
pcc tag |
not(pcc.tag) |
All |
28 |
0 |
1 |
pcc seal |
isCapSealed(pcc)1 |
All |
28 |
0 |
2 |
pcc permission |
not(pcc.X-permission) |
All |
28 |
0 |
3 |
pcc invalid address |
pcc holds an invalid address |
All |
28 |
0 |
4 |
pcc bounds |
Any byte of current instruction out of pcc bounds |
CSR/Xret additional exception check |
|||||
28 |
0 |
2 |
pcc permission |
not(pcc.ASR-permission) when required for CSR access or execution of MRET(RV32Y/RV64Y)/SRET (RV32Y/RV64Y) |
|
direct jumps additional exception check |
|||||
28 |
2 |
4 |
pcc bounds |
any byte of minimum length instruction at target out of pcc bounds |
|
indirect jumps additional exception checks |
|||||
indirect jumps |
28 |
2 |
0 |
|
not( |
indirect jumps |
28 |
2 |
1 |
|
isCapSealed( |
indirect jumps |
28 |
2 |
2 |
|
not( |
indirect jumps |
28 |
2 |
3 |
|
target address is an invalid address |
indirect jumps |
28 |
2 |
4 |
|
any byte of minimum length instruction at target out of |
Load additional exception checks |
|||||
all loads |
28 |
1 |
0 |
|
not( |
all loads |
28 |
1 |
1 |
|
isCapSealed( |
all loads |
28 |
1 |
2 |
|
not( |
all loads |
28 |
1 |
3 |
|
Address is invalid (see Invalid address conversion) |
all loads |
28 |
1 |
4 |
|
Any byte of load access out of |
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 |
28 |
1 |
0 |
|
not( |
all stores, all atomics, all cbos |
28 |
1 |
1 |
|
isCapSealed( |
all atomics, CBO.INVAL* |
28 |
1 |
2 |
|
not( |
all stores, all atomics, CBO.INVAL*, CBO.ZERO* |
28 |
1 |
2 |
|
not( |
CBO.CLEAN*, CBO.FLUSH* |
28 |
1 |
2 |
|
not( |
all stores, all atomics, all cbos |
28 |
1 |
3 |
|
Address is invalid (see Invalid address conversion) |
all stores, all atomics |
28 |
1 |
4 |
|
any byte of access out of |
CBO.ZERO*, CBO.INVAL* |
28 |
1 |
4 |
|
any byte of cache block out of |
CBO.CLEAN*, CBO.FLUSH* |
28 |
1 |
4 |
|
all bytes of cache block out of |
CBO.INVAL* |
28 |
0 |
2 |
pcc permission |
not(pcc.ASR-permission) |
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.
CBO.ZERO (RV32Y/RV64Y) 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-permission, W-permission, X-permission) 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. |
7.6. 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.
7.7. Physical Memory Attributes (PMA)
Typically, only parts of the entire memory space need to support CHERI valid tags. Therefore, it is desirable that harts supporting RV32Y/RV64Y extend PMAs with a CHERI taggable attribute indicating whether a memory region allows storing CHERI valid tags.
Data loaded from memory regions that are not CHERI taggable will always have the valid tag cleared. When the hart attempts to store data with the valid tag set to memory regions that are not taggable, the implementation may:
-
Cause an access fault exception
-
Implicitly set the stored tag to 0
8. "Smcherire" Extension, Version 1.0
ARC-QUESTION: The CBZE, CBIE etc. bits are specified by Zicbo*, can this be defined by Smcheri/Sscheri+Zcherihybrid instead of adding a new priv extension? |
When using a system with Zcherihybrid, it may be desirable to disabling CHERI register and instruction access to some (or all) privilege levels such that they operate as a RV32I/RV64I system without any observable presence of CHERI features.
Smcherire includes functions to disable explicit access to CHERI
registers and instructions.
The Smcherire extension makes the CRE
bit of mseccfg, menvcfg, and senvcfg writable.
If RV32Y/RV64Y is supported and Zcherihybrid is not supported, then Smcherire must also not be supported. In this case all CRE bits are hardwired to 1 and access to CHERI registers is always permitted. This allows implementing a hart that always runs in Capability Pointer Mode. |
CHERI register access is disabled if
-
XLEN in the current mode is less than MXLEN, or
-
the endianness in the current mode is not the reset value of mstatus.MBE, or
-
the effective CRE for the current privilege is 0.
The effective CRE for the current privilege is:
The effective CRE is always 1 in debug mode. |
On reset CHERI register access is disabled (mseccfg.CRE resets to zero). |
The following occurs when executing code in a privilege mode that has CHERI register access disabled:
-
Instructions that access c registers (implicitly or explicitly) cause illegal instruction exceptions
The only instruction added by RV32Y/RV64Y that does not access capability state is CRAM, all others are disabled. -
Executing CSR instructions accessing any CSR added by any CHERI extension (Zcherihybrid, Smcheri, Sscheri, Shcheri) causes an illegal instruction exception
-
Executing CSR instructions accessing any CSR extended to CLEN only allows XLEN access.
-
All allowed instructions execute as if the CHERI execution mode is Integer Pointer Mode.
Disabling CHERI register access has no effect on implicit accesses or security checks. The last capability installed in pcc and ddc before disabling CHERI register access will be used to authorize instruction execution and data memory accesses.
Disabling CHERI register access prevents low-privileged Integer Pointer Mode software from interfering with the correct operation of higher-privileged Integer Pointer Mode software that do not perform ddc switches on trap entry and return. Disabling CHERI register access allows harts supporting CHERI to be fully compatible with standard RISC-V, so CHERI instructions, such as CRAM, that do not change the state of CHERI CSRs raise exceptions when CRE=0. This is the default behavior on reset. |
Table 35 summarizes the behavior of a hart in connection with the CRE and the CHERI Execution Mode while in a privilege other than debug mode.
CRE=0, M-bit=X1 | CRE=1, M-bit=1 | CRE=1, M-bit=0 | |
---|---|---|---|
Authorizing capability for memory accesses |
Instruction’s capability operand |
||
New CHERI CSR Access Width |
✘ |
CLEN |
CLEN |
Extended CHERI CSR Access Width |
XLEN |
XLEN |
CLEN |
CHERI Instructions Allowed |
✘ |
✔ |
✔ |
Compressed Instructions Remapped |
No |
No |
Yes2 |
Summary |
Fully RISC-V compatible3 |
Integer Pointer Mode |
Capability Pointer Mode |
1 M-bit is irrelevant when CRE=0.
2 See Table 65 for a list of remapped
instructions.
3 The hart is fully compatible with standard RISC-V when CRE=0 provided that pcc, mtvecc, mepcc, stvecc, sepcc, vstvecc, vsepcc and ddc have not been changed from the default reset state (i.e., hold the Infinite capability).
9. "Smcherivarxlen" Extension, Version 1.0
Smcherivarxlen eliminates some restrictions for SXL and UXL imposed in Smcheri to allow implementations supporting multiple base ISAs. This extension allows the SXL, UXL, MBE, SBE, and UBE fields of mstatus/sstatus to be writable (which is prohibited by Smcheri otherwise).
ARC-QUESTION: Should this extension be folded into the Smcherire extension? |
- Changing XLEN
-
Setting the SXL or UXL field to a value that is not MXLEN disables most CHERI features and instructions, as described in Chapter 8, while in that privilege mode.
If CHERI register access must be disabled in a mode for security reasons, software should set CRE to 0 regardless of the SXL and UXL fields. Whenever XLEN in any mode is set to a value less than MXLEN, standard RISC-V rules from (RISC-V, 2023) are followed. This means that all operations must ignore source operand register bits above the configured XLEN, and must sign-extend results to fill all MXLEN-bits in the destination register. Similarly, pc bits above XLEN are ignored, and when the pc is written, it is sign-extended to fill MXLEN. The integer writing rule from CHERI is followed, so that every register write also zeroes the metadata and tag of the destination register.
However, CHERI operations and security checks will continue using the entire hardware register (i.e., CLEN-bits) to correctly decode capability bounds.
- Changing endianness
-
Setting the MBE, SBE, or UBE field to a value that is not the reset value of MBE disables most CHERI features and instructions, as described in Chapter 8, while in that privilege mode.
10. "Svcheri" Extension, Version 1.0
RISC-V’s page-based virtual-memory management is generally orthogonal to CHERI. In RV32Y/RV64Y, 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.
Svcheri requires that the pcc grants the ASR-permission to change the page-table root satp and other virtual-memory parameters as described in Section 7.3.
10.1. Capability Write (CW) Bit
Svcheri defines the Capability Write (CW) bit in Page Table Entries (PTEs) for Sv39, Sv48, and Sv57 virtual memory systems on RV64 harts. The CW bit controls whether capabilities with their valid tag set can be written to a virtual page.
Sv32 does not have any spare PTE bits, and so this bit does not exist for RV32. |
Any hart that supports RV32Y/RV64Y and at least one of the Sv39, Sv48, and Sv57 virtual memory translation schemes must also implement Svcheri. |
10.1.1. Limiting Capability Propagation
ARC-QUESTION: Is this too much rationale? Should it be trimmed down and just describe the mechanism? |
Page table enforcement can allow the operating system to limit the flow of capabilities between processes. It is highly desirable that a process should only possess capabilities that have been issued for that address space by the operating system. Unix processes may share memory for efficient communication, but capability pointers must not be shared across these channels into a foreign address space. An operating system might defend against this by only issuing a capability to the shared region that does not grant the load/store capability permission. However, there are circumstances where portions of general-purpose, mmapped* memory become shared, and the operating system must prevent future capability communication through those pages. This is not possible without restructuring software, as the capability for the original allocation, which spans both shared memory and private memory, would need to be deleted and replaced with a list of distinct capabilities with appropriate permissions for each range. Such a change would not be transparent to the program. Such sharing through virtual memory is on the page granularity, so preventing capability writes with a PTE permission is a natural solution.
* allocated using mmap
10.2. CHERI PTE page faults
CHERI adds the concept of CHERI PTE page faults. These reuse the load page fault and store/AMO page fault exception causes, and write additional information to mtval2/stval2/vstval2.
Page faults are considered to be CHERI PTE page faults if the Xtval2
register is written with a non-zero value.
It is possible for both a normal page fault and a CHERI PTE page fault to both trigger at once, as represented in the Xtval2 value, as shown in Table 32.
|
Where two stage translation is enabled, the CHERI PTE page fault is only raised when the second stage translation has completed, and so is prioritized below guest page faults. |
All RV64 harts with virtual memory can raise CHERI store/AMO PTE page faults. Only harts which implement Svcheri can raise CHERI load PTE page faults.
10.2.1. Extending the Page Table Entry Format
The page table entry format remains unchanged for Sv32. However, a new bit, Capability Write (CW), is added to leaf PTEs in Sv39, Sv48 and Sv57 as shown in Figure 21, Figure 22 and Figure 23 respectively. For non-leaf PTEs this bit remains reserved and must be cleared by software for forward compatibility, or else a page-fault exception is raised. Additionally, if the hypervisor extension is enabled this bit remains reserved for leaf and non-leaf PTEs used in guest address translation.
ARC-QUESTION: The current bit 60 has been allocated by Svrsw60t59b, should we use bit 58? |
The CW bit indicates whether reading or writing capabilities with the valid tag set to the virtual page is permitted. When the CW bit is set, capabilities are written as usual.
If the CW bit is clear then:
-
When a capability load or AMO instruction is executed, the implementation clears the valid tag bit of the capability read from the virtual page.
-
A CHERI store/AMO PTE page fault exception is raised when a capability store or AMO instruction is executed and the valid tag bit of the capability being written is set.
PTE.CW | Store/AMO |
---|---|
0 |
CHERI store/AMO PTE page fault if stored tag is set |
1 |
Normal operation |
The valid tag bit of the stored capability is checked after it is potentially cleared due to missing permissions. Therefore, the behavior in this section isn’t relevant if:
|
10.3. 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 Table 60) 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.
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. |
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 RV32Y/RV64Y 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 RV32Y/RV64Y when accessing CSRs, branching and jumping, and accessing memory.
10.3.1. 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 capability.
Some situations may require that a CSR may be updated to hold a capability with an invalid address:
-
executing instructions, such as CSRRW (RV32Y/RV64Y)
-
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:
-
If A’s address is invalid and A does not have infinite bounds (see Section A.1), then A’s tag is set to 0.
-
Write the final (potentially modified) version of capability A to the CSR e.g. mtvecc, mepcc, etc.
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. |
10.3.2. 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:
-
Calculate the effective target address T of the jump or branch as required by the instruction’s behavior.
-
If T is invalid and A does not have infinite bounds (see Section A.1), then the instruction causes 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, stval2 or vstval2.
-
If T is invalid and A has infinite bounds (see Section A.1), then A’s tag is unchanged and T is written into A’s address field. Attempting to execute the instruction at address T causes an instruction access fault or page fault as is usual in RISC-V.
-
Otherwise T is valid and the instruction behaves as normal.
RISC-V harts that do not support RV32Y/RV64Y normally raise an instruction access fault or page fault after jumping or branching to an invalid address. Therefore, RV32Y/RV64Y aims to preserve that behavior to ensure that harts supporting RV32Y/RV64Y and Zcherihybrid are fully compatible with RISC-V harts provided that pcc and ddc are set to the Infinite capability. |
10.3.3. 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:
-
Calculate the effective address range R of the memory access as required by the instruction’s behavior.
-
If any byte in R is invalid and A does not have infinite bounds (see Section A.1), then the instruction causes 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, stval2 or vstval2.
-
If any byte in R is invalid and A has infinite bounds (see Section A.1), the hart will raise an access fault or page fault as is usual in RISC-V.
-
Otherwise all bytes in R are valid and the instruction behaves as normal. === "Sdcheri", Integrating RV32Y/RV64Y with Sdext
This chapter will appear in the priv spec. Exact location TBD. |
This section describes changes to integrate the Sdext ISA and RV32Y/RV64Y. It must be implemented to make external debug compatible with RV32Y/RV64Y. Modifications to Sdext are kept to a minimum.
The following features, which are optional in Sdext, must be implemented for use with RV32Y/RV64Y:
-
The
hartinfo
register must be implemented. -
All harts which support RV32Y/RV64Y must provide
hartinfo.nscratch
of at least 1 and implement the dscratch0c register. -
All harts which support RV32Y/RV64Y must provide
hartinfo.datasize
of at least 1 andhartinfo.dataaccess
of 0. -
The program buffer must be implemented, with
abstractcs.progbufsize
of at least 4 ifdmstatus.impebreak
is 1, or at least 5 ifdmstatus.impebreak
is 0.
These requirements allow a debugger to read and write capabilities in integer
registers without disturbing other registers. These requirements may be
relaxed if some other means of accessing capabilities in integer registers,
such as an extension of the Access Register abstract command, is added. The
following sequences demonstrate how a debugger can read and write a capability
in # Read the high MXLEN-bits into data0-data1 csrrw c2, dscratch0c, c2 gchi x2, c1 csrw 0xBF0, x2 csrrw c2, dscratch0c, c2 ebreak # Read the valid tag into data0 csrrw c2, dscratch0c, c2 gctag x2, c1 csrw 0xBF0, x2 csrrw c2, dscratch0c, c2 ebreak # Write the high MXLEN-bits from data0-data1 csrrw c2, dscratch0c, c2 csrr x2, 0xBF0 schi c1, c1, x2 csrrw c2, dscratch0c, c2 ebreak # Write the valid tag (if nonzero) csrrw c2, dscratch0c, c2 csrr c2, dinfc cbld c1, c2, c1 csrrw c2, dscratch0c, c2 ebreak The low |
10.3.4. Debug Mode
When executing code due to an abstract command, the hart stays in debug mode and the rules outlined in Section 4.1 of (RISC-V, 2022) apply.
10.3.5. Core Debug Registers
RV32Y/RV64Y renames and extends debug CSRs that are designated to hold addresses to be able to hold capabilities. The renamed debug CSRs are listed in Table 49.
The pcc must grant ASR-permission to access debug CSRs. This permission is automatically provided when the hart enters debug mode as described in the dpcc section. The pcc metadata can only be changed if the implementation supports executing control transfer instructions from the program buffer — this is an optional feature according to (RISC-V, 2022).
10.3.6. Debug Program Counter (dpc)
The dpc register is as defined in (RISC-V, 2022). It is a DXLEN-bit register used as the PC saved when entering debug mode. dpc is extended into dpcc.
10.3.7. Debug Program Counter Capability (dpcc)
The valid tag of the CSR must be reset to zero. The reset values of the metadata and address fields are UNSPECIFIED.
Upon entry to debug mode, (RISC-V, 2022), does not specify how to update the PC, and says PC relative instructions may be illegal. This concept is extended to include any instruction which reads or updates pcc, which refers to all jumps, conditional branches and AUIPC (RV32Y/RV64Y). The exceptions are MODESW.CAP and MODESW.INT which are supported if Zcherihybrid is implemented, see dinfc for details.
As a result, the value of pcc is UNSPECIFIED in debug mode according to this specification. The pcc metadata has no architectural effect in debug mode. Therefore ASR-permission is implicitly granted for access to all CSRs and no CHERI instruction fetch faults are possible.
On debug mode entry dpcc (and consequently dpc) are updated with the capability in pcc whose address field is set to the address of the next instruction to be executed upon debug mode exit as described in (RISC-V, 2022).
10.3.8. Debug Scratch Register 0 (dscratch0)
The dscratch0 register is as defined in (RISC-V, 2022). It is an optional DXLEN-bit scratch register that can be used by implementations which need it. dscratch0 is extended into dscratch0c.
10.3.9. Debug Scratch Register 0 Capability (dscratch0c)
The dscratch0c register extends dscratch0 to hold a capability.
The valid tag of the CSR must be reset to zero. The reset values of the metadata and address fields are UNSPECIFIED.
10.3.10. Debug Scratch Register 1 (dscratch1)
The dscratch1 register is as defined in (RISC-V, 2022). It is an optional DXLEN-bit scratch register that can be used by implementations which need it. dscratch1 is extended into dscratch1c.
10.3.11. Debug Scratch Register 1 Capability (dscratch1c)
The dscratch1c register extends dscratch1 to hold a capability.
The valid tag of the CSR must be reset to zero. The reset values of the metadata and address fields are UNSPECIFIED.
10.3.12. Debug Infinite Capability Register (dinfc)
dinfc is a debug mode accessible capability CSR. The address and access details are shown in Table 13.
The reset value is the Infinite capability.
If Zcherihybrid is implemented:
-
The M-bit is reset to Integer Pointer Mode (1).
-
The debugger can set the M-bit to Capability Pointer Mode (0) by executing MODESW.CAP from the program buffer.
-
Executing MODESW.CAP causes subsequent instructions execution from the program buffer, starting from the next instruction, to be executed in Capability Pointer Mode. It also sets the CHERI execution mode to Capability Pointer Mode on future entry into debug mode.
-
Therefore to enable use of a CHERI debugger, a single MODESW.CAP only needs to be executed once from the program buffer after resetting the core.
-
The debugger can also execute MODESW.INT to change the mode back to Integer Pointer Mode, which also affects the execution of the next instruction in the program buffer, updates the M-bit of dinfc and controls which CHERI execution mode to enter on the next entry into debug mode.
-
The M-bit of dinfc is only updated by executing MODESW.CAP or MODESW.INT from the program buffer.
A future version of this specification may add writeable fields to allow creation of other capabilities, if, for example, a future extension requires multiple formats for the Infinite capability. |
10.4. Integrating Zcherihybrid with Sdext
Zcherihybrid allows MODESW.CAP and MODESW.INT to execute in debug mode.
When entering debug mode, whether the core enters Integer Pointer Mode or Capability Pointer Mode is controlled by the M-bit in dinfc.
The current mode can be read from dinfc.
The following sequence executed from the program buffer will write 0 for Capability Pointer Mode and 1 for Integer Pointer Mode to x1
:
csrr c1, dinfc
gcmode x1, c1
10.4.1. Debug Default Data Capability CSR (dddc)
The valid tag of the CSR must be reset to zero. The reset values of the metadata and address fields are UNSPECIFIED.
This CSR is only implemented if Zcherihybrid is implemented.
Upon entry to debug mode, ddc is saved in dddc. ddc's metadata is set to the Infinite capability’s metadata (with tag set) and ddc's address remains unchanged.
When debug mode is exited by executing DRET (RV32Y/RV64Y), the hart’s ddc is updated to the capability stored in dddc. A debugger may write dddc to change the hart’s context.
As shown in Table 60, dddc is a data pointer, so it does not need to be able to hold all possible invalid addresses (see Invalid address conversion).
10.5. Integrating RV32Y/RV64Y with Sdtrig
This chapter will appear in the priv spec. Exact location TBD. |
The Sdtrig extension is generally orthogonal to RV32Y/RV64Y. However, the priority of synchronous exceptions and where triggers fit is adjusted as shown in Table 37.
Priority | Exc. Code | Description | Trigger |
---|---|---|---|
Highest |
3 |
etrigger |
|
3 |
Instruction address breakpoint |
mcontrol/mcontrol6 execute address before |
|
28 |
Prior to instruction address translation: |
||
12, 1 |
During instruction address translation: |
||
1 |
With physical address for instruction: |
||
3 |
mcontrol/mcontrol6 execute data before |
||
2 |
Illegal instruction |
||
3 |
Load/store/AMO address breakpoint |
mcontrol/mcontrol6 load/store address before |
|
3 |
mcontrol/mcontrol6 store data before |
||
28 |
CHERI faults due to: |
||
28 |
Prior to address translation for an explicit memory access: |
||
4,6 |
Optionally: |
||
13, 15, 5, 7 |
During address translation for an explicit memory access: |
||
5,7 |
With physical address for an explicit memory access: |
||
4,6 |
If not higher priority: |
||
13 |
If not higher priority: |
||
Lowest |
3 |
mcontrol/mcontrol6 load data before |
See the notes beneath Synchronous exception priority in decreasing priority order for details about CHERI PTE page fault priority. |
11. Integrating RV32Y/RV64Y and Zcherihybrid with Pointer Masking
This chapter should appear as a section in the pointermasking chapter. Exact location TBD. |
The pointer masking extensions Smmpm, Smnpm, SSnpm, Sspm and Supm are compatible with both RV32Y/RV64Y and Zcherihybrid. Whenever pointer masking is enabled, all bounds decoding and bounds checks are affected.
The suggestion in this section is based on the pointer masking approach from Morello but with changes to sign extension and to address the dynamic nature of bit masking. Further evaluation on RISCV, especially for Capability Pointer Mode, is still required. |
When bounds are encoded or decoded, a masked but not sign extended address is used. Changing how many bits are masked can therefore change the interpretation of the bounds of a capability, both for the purpose of implicit accesses via bounds checks and any instructions that report the bounds of a capability. Apart from treating high address bits as 0, there are no other changes to bounds decode, which are still based on MXLEN, not the new effectively addressable space. That is, the maximum length of a capability does not change, and it is not invalid to have a capability that covers a longer range than could be actually be addressed with pointer masking enabled (such as one that covers the entire MXLEN address space). For the representable range check, both the original and new address are masked. Bounds setting instructions also mask the address in the same way.
Because dynamically changing the number of masked bits changes the interpretation of a capability, software must take the same care when sharing capabilities between address spaces with differing pointer masking as it generally must when sharing capabilities between address spaces with different page mappings. |
Any address that is checked against a capability (whether via loads/stores in Integer Pointer Mode or Capability Pointer Mode), is also first subject to the same masking as bounds decode (masking without extension). After any CHERI operations, the final access address is still subject to as much sign extension as the masking extensions mandate.
Chapters that still need review
Any chapter after this point still needs to be updated for the new document structure! |
12. "Svucrg" Extension, Version 1.0
This chapter will appear in the priv spec. Exact location TBD. |
This chapter needs additional updates before it is ready for ARC review |
Sv32 (for RV32) does not have any spare PTE bits, and so no features from this chapter can be implemented. |
The Svucrg extension adds the ability to perform capability revocation of user mode pages (see Section 12.1) by adding the PTE.CRG bit, and sstatus.UCRG as described below.
Svucrg depends on Svcheri also being supported. |
Svucrg is strongly recommended but not mandatory as a future version of this specification may specify an improved method. |
There is no explicit mechanism for enabling or disabling Svucrg. |
If software ignores the new PTE bits then there is no change in functionality unless capabilities are accessed. |
A future version of this specification may include kernel revocation which may require an sstatus.SCRG bit. |
The remainder of this chapter jointly specifies the behavior of PTE.CW, PTE.CRG and sstatus.UCRG.
The description below assumes that Svucrg has been implemented. If that is not the case then PTE.CRG and sstatus.UCRG should be taken as read-only-zero for purpose of the description in the remainder of this chapter only. PTE.CRG and sstatus.UCRG remain reserved in this case. |
The minimum level of PTE support is to set CW to 1 in all PTEs intended for storing capabilities (i.e., private anonymous mappings) and leave sstatus.UCRG and CRG in all PTEs set to 0, which will allow capabilities with their tags set to be loaded and stored successfully.
Hardware initiated memory accesses from the page-table walker are not checked by a capability. |
12.1. Capability Revocation
Page table enforcement can accelerate concurrent capability revocation for temporal safety. Without page table capability protection, a concurrent capability revocation sweep must begin by visiting all PTEs to mark them unreadable, henceforth trapping on any read to a new page to sweep it clean before proceeding. With a page-granularity generational capability read permission, we can eliminate the initial permission change of all PTEs. In addition, a page-granularity capability write control can eliminate many pages from the sweep that are known to not contain capabilities.
12.2. Extending the Page Table Entry Format
The page table entry format remains unchanged for Sv32. However, one new bit, Capability Read Generation (CRG), is added to leaf PTEs in Sv39, Sv48 and Sv57 as shown in Figure 32, Figure 33 and Figure 34 respectively. For non-leaf PTEs these bits remain reserved and must be cleared by software for forward compatibility, or else a page-fault exception is raised. Additionally, if the hypervisor extension is enabled these bits remain reserved for leaf and non-leaf PTEs used in guest address translation.
The behavior in this section isn’t relevant if: |
-
The authorizing capability doesn’t have C-permission, for loads, stores and AMOs.
-
Capability Level (CL) checks have cleared the stored tag, for stores and AMOs.
The CW bit indicates whether reading or writing capabilities with the valid tag set to the virtual page is permitted. When the CW bit is set, capabilities are written as usual, and capability reads are controlled by the CRG bit.
The valid tag bit of the stored capability is checked after it is potentially cleared due to lack of C-permission. |
If the CW bit is clear then:
-
When a capability load or AMO instruction is executed, the implementation clears the valid tag bit of the capability read from the virtual page.
-
When CRG is clear, the "no capability state", a CHERI store/AMO PTE page fault exception is raised when a capability store or AMO instruction is executed and the valid tag bit of the capability being written is set.
-
When CRG is set, the "pre-CW state", two schemes are permitted (also see Section 12.3):
-
The same behavior as when CRG is clear, allowing software interpretation of this state.
-
When a capability store or AMO instruction is executed and the valid tag bit of the capability being written is set, the implementation sets the CW bit and assigns the CRG bit equal to sstatus.UCRG.
The PTE update must be atomic with respect to other accesses to the PTE, and must atomically check that the PTE is valid and grants sufficient permissions. Updates to the CW bit and CRG bit must be exact (i.e., not speculative), and observed in program order by the local hart. Furthermore, the PTE update must appear in the global memory order no later than the explicit memory access, or any subsequent explicit memory access to that virtual page by the local hart. The ordering on loads and stores provided by FENCE instructions and the acquire/release bits on atomic instructions also orders the PTE updates associated with those loads and stores as observed by remote harts.
The PTE update is not required to be atomic with respect to the explicit memory access that caused the update, and the sequence is interruptible. However, the hart must not perform explicit memory access before the PTE update is globally visible.
-
When CW is set, the CRG bit indicates the current generation of the virtual memory page with regards to the ongoing capability revocation cycle. Two schemes are permitted:
-
A CHERI load PTE page fault exception is raised when a capability load or AMO instruction is executed with C-permission granted and the virtual page’s CRG bit does not equal sstatus.UCRG and PTE.U is set.
-
A CHERI load PTE page fault exception is raised when a capability load or AMO instruction is executed with C-permission granted and the virtual page’s CRG bit does not equal sstatus.UCRG and PTE.U is set and the capability read from memory has its tag set.
PTE.CW | PTE.U | PTE.CRG1 | Load/AMO |
---|---|---|---|
0 |
X |
X |
Clear loaded tag |
1 |
1 |
≠ sstatus.UCRG |
CHERI load PTE page fault, or CHERI load PTE page fault if tag is set2 |
1 |
1 |
= sstatus.UCRG1 |
Normal operation |
1 |
0 |
X |
Normal operation3 |
1 If Svucrg is not implemented then PTE.CRG and sstatus.UCRG are always both zero, and so always match. Therefore CHERI load PTE page fault are not possible.
2 The choice here is whether to take data dependent exceptions on loads or atomic operations. It is legal for the implementation to fault even if the valid tag is not set since this behavior is only an optimization for software. This means it is also legal to only check the valid tag under certain conditions and conservatively fault otherwise. Taking a trap when the valid tag is not set will introduce additional traps during revocation sweeps. Checking the loaded tag affects the exception priority, see Synchronous exception priority in decreasing priority order.
3 A future version of this specification may check an SCRG bit in sstatus for kernel revocation.
PTE.CW | PTE.CRG | Store/AMO |
---|---|---|
0 |
01 |
CHERI store/AMO PTE page fault if stored tag is set |
0 |
1 |
CHERI store/AMO PTE page fault if stored tag is set, or hardware CW and CRG update |
1 |
X |
Normal operation |
1 If Svucrg is not implemented then PTE.CRG is zero. Therefore CHERI store/AMO PTE page fault are possible.
12.3. Enabling Software or Hardware PTE updates
The decision about whether to take exceptions on capability stores with the valid tag set to a page with PTE.CW=0 and PTE.CRG=1 is determined by whether the Svade and Svadu extensions are enabled. These cause PTE Accessed and Dirty updates to be done in software, via the exception handler, or by a hardware mechanism respectively.
-
If only Svade is implemented, or enabled through henvcfg.ADUE or menvcfg.ADUE, then take a CHERI store/AMO PTE page fault.
-
If only Svadu is implemented, or enabled through henvcfg.ADUE or menvcfg.ADUE, then do the hardware update of setting PTE.CW=1 and setting PTE.CRG=sstatus.UCRG as described in Section 12.2.
12.4. Extending the Supervisor (sstatus) and Virtual Supervisor (vsstatus) Status Registers
The sstatus and vsstatus CSRs are extended to include the new Capability Read Generation (CRG) bit as shown.
When V=1 vsstatus.UCRG is in effect.
13. "Shcheri", Integrating RV32Y/RV64Y and Zcherihybrid with the Hypervisor Extension
This chapter will appear in the priv spec. Exact location TBD. |
The RISC-V hypervisor (H) extension virtualizes the supervisor-level architecture to support the efficient hosting of guest operating systems atop a type-1 or type-2 hypervisor (RISC-V, 2023). The hypervisor extension is generally orthogonal to CHERI; the main requirements, when integrating with RV32Y/RV64Y and Zcherihybrid, is that address CSRs added for hypervisors are extended to CLEN size. The remainder of this chapter describes these changes in detail.
13.1. Hypervisor Status Register (hstatus)
The hstatus register operates as described in (RISC-V, 2023) except for the VSXL field that controls the value of XLEN for VS-mode (known as VSXLEN).
The encoding of the VSXL field is the same as the MXL field of misa. Only 1 and 2 are supported values for VSXL. When the implementation supports RV32Y/RV64Y (but not Zcherihybrid), then hstatus's VSXL must be read-only as described in mstatus for mstatus.SXL. When the implementation supports both RV32Y/RV64Y and Zcherihybrid, then VSXL behaves as described in Section 7.2.1 for mstatus.SXL.
The VSBE field determines controls the endianness of explicit memory accesses from VS-mode and implicit memory accesses to VS-level memory management data structures. VSBE=0 indicates little endian and VSBE=1 is big endian. VSBE must be read-only and equal to MBE when the implementation only supports RV32Y/RV64Y. VSBE is optionally writeable when Zcherihybrid is also supported.
13.2. Hypervisor Environment Configuration Register (henvcfg)
The henvcfg register operates as described in the RISC-V Privileged Specification. A new enable bit is added to henvcfg when the implementation supports Zcherihybrid as shown in Figure 38.
The CHERI Register Enable (CRE) bit controls whether explicit access to CHERI registers is permitted when V=1. When henvcfg.CRE=1 and menvcfg.CRE=1 and mseccfg.CRE=1, CHERI registers can be read and written by VS-mode and VU-mode. When henvcfg.CRE=0, CHERI registers are disabled in VS-mode and VU-mode as described in Chapter 8.
The reset value is 0.
13.3. Hypervisor Exception Delegation Register (hedeleg)
Bit 28 of hedeleg now refers to a valid exception and so can be used to delegate CHERI exceptions to virtual supervisor mode.
13.4. Virtual Supervisor Status Register (vsstatus)
The vsstatus register operates as described in (RISC-V, 2023) except for the UXL field that controls the value of XLEN for VU-mode.
The encoding of the UXL field is the same as the MXL field of misa. Only 1 and 2 are supported values for UXL. When the implementation supports RV32Y/RV64Y (but not Zcherihybrid), then vsstatus.UXL must be read-only as described in mstatus for mstatus.UXL. When the implementation supports both RV32Y/RV64Y and Zcherihybrid, then UXL behaves as described in Section 7.2.1 for mstatus.UXL.
13.5. Virtual Supervisor Trap Vector Base Address Register (vstvec)
The vstvec register is as defined in (RISC-V, 2023). It is the VSXLEN-bit read/write register that is the VS mode’s version of the supervisor register stvec.
13.6. Virtual Supervisor Trap Vector Base Address Capability Register (vstvecc)
The vstvecc register extends vstvec to hold a capability. Its reset value is the Infinite capability.
13.7. Virtual Supervisor Scratch Register (vsscratch)
The vsscratch register is as defined in (RISC-V, 2023). It is a VSXLEN read/write register that is VS-mode’s version of supervisor register sscratch. vsscratch is extended into vsscratchc.
13.8. Virtual Supervisor Scratch Register (vsscratchc)
The vsscratchc register extends vsscratch to hold a capability.
The valid tag of the CSR must be reset to zero. The reset values of the metadata and address fields are UNSPECIFIED.
It is not WARL, all capability fields must be implemented.
13.9. Virtual Supervisor Exception Program Counter (vsepc)
The vsepc register is as defined in (RISC-V, 2023). It is extended into vsepcc.
13.10. Virtual Supervisor Exception Program Counter Capability (vsepcc)
As shown in Table 60, vsepcc is a code capability, so it does not need to be able to hold all possible invalid addresses (see Invalid address conversion). Additionally, the capability in vsepcc is unsealed when it is installed in pcc on execute of an SRET (RV32Y/RV64Y) instruction. The handling of vsepcc is otherwise identical to mepcc, but in virtual supervisor mode.
13.11. Virtual Supervisor Cause Register (vscause)
The vscause register is as defined in (RISC-V, 2023). It must additionally support the new exception code for CHERI exceptions that scause supports.
13.12. Virtual Supervisor Trap Value Register (vstval)
The vstval register is a VSXLEN-bit read-write register.
vstval is updated following the same rules as mtval for CHERI exceptions and CHERI PTE page faults which are delegated to VS-mode.
13.13. Virtual Supervisor Trap Value Register 2 (vstval2)
The vstval2 register is a VSXLEN-bit read-write register, which is added as part of RV32Y/RV64Y when the hypervisor extension is supported. Its CSR address is 0x24b.
vstval2 is updated following the same rules as mtval2 for CHERI exceptions and CHERI PTE page faults which are delegated to VS-mode. It is written to zero for all other exceptions, except as listed otherwise by other future extensions.
13.14. Hypervisor Load and Store Instructions For Capability Data
Hypervisor virtual-machine load ([HLV.C]) and store ([HSV.C]) instructions read or write CLEN-bits from memory as though V=1. These instructions change behavior depending on the CHERI execution mode although the instruction’s encoding remains unchanged.
When in Capability Pointer Mode, the hypervisor load and store capability instructions behave as described in Section 2.10. In Integer Pointer Mode, the instructions behave as rely on an x register operand providing the effective address for the memory access and the capability authorizing the memory access is ddc.
14. "Zstid" Extension for Software Thread Identification
This chapter needs to be split. |
Zstid is an optional extension to the RISC-V base ISA. Implementations that support RV32Y/RV64Y and Zstid define a variant of the CHERI ISA that allows for more efficient software compartmentalization of CHERI programs.
14.1. Control and Status Registers (CSRs)
Zstid adds new CSRs to implement a trusted software thread identifier (TID) used in compartmentalization. These CSRs are listed in Table 40, Table 41, Table 42 and Table 43.
Zstid CSR | Address | Prerequisites | Read-Permission | Write-Permission | Description |
---|---|---|---|---|---|
0x780 |
M-mode |
M |
Machine Thread Identifier |
Zstid CSR | Address | Prerequisites | Read-Permission | Write-Permission | Description |
---|---|---|---|---|---|
0x580 |
S-mode |
S |
Supervisor Thread Identifier |
Zstid CSR | Address | Prerequisites | Read-Permission | Write-Permission | Description |
---|---|---|---|---|---|
0xA80 |
VS-mode |
S |
Virtual Supervisor Thread Identifier |
Zstid CSR | Address | Prerequisites | Read-Permission | Write-Permission | Description |
---|---|---|---|---|---|
0x480 |
U-mode |
U |
User Thread Identifier |
14.2. Machine-Level, Supervisor-Level and Unprivileged CSRs
14.2.1. Machine Thread Identifier (mtid)
The mtid register is an MXLEN-bit read-write register. It is used to identify the current software thread in machine mode. The reset value of this register is UNSPECIFIED.
14.2.2. Supervisor Thread Identifier (stid)
The stid register is an SXLEN-bit read-write register. It is used to identify the current software thread in supervisor mode. The reset value of this register is UNSPECIFIED.
14.2.3. Virtual Supervisor Thread Identifier (vstid)
The vstid register is a VSLEN-bit read-write register. It is VS-mode’s version of supervisor register stid used to identify the current software thread in virtual supervisor mode. As other Virtual Supervisor registers when V=1, vstid substitutes for stid, so that instructions that normally read or modify stid actually access vstid instead. When V=0, vstid does not directly affect the behavior of the machine.
The reset value of this register is UNSPECIFIED.
14.2.4. User Thread Identifier (utid)
The utid register is an UXLEN-bit read-write register. It is used to identify the current software thread in user mode. The reset value of this register is UNSPECIFIED.
When RV32Y/RV64Y is implemented, the Zstid CSRs are extended as follows:
14.2.5. Machine Thread Identifier Capability (mtidc)
The mtidc register extends mtid to hold a capability. It is used to identify the current software thread in machine mode. On reset the valid tag of mtidc will be set to 0 and the remainder of the data is UNSPECIFIED.
14.2.6. Supervisor Thread Identifier Capability (stidc)
The stidc register extends stid to hold a capability. It is used to identify the current software thread in supervisor mode. On reset the valid tag of stidc will be set to 0 and the remainder of the data is UNSPECIFIED.
14.2.7. Virtual Supervisor Thread Identifier Capability (vstidc)
The vstidc register extends vstid to hold a capability. It is used to identify the current software thread in virtual supervisor mode. As other Virtual Supervisor registers when V=1, vstidc substitutes for stidc, so that instructions that normally read or modify stidc actually access vstidc instead. When V=0, vstidc does not directly affect the behavior of the machine. On reset the valid tag of vstidc will be set to 0 and the remainder of the data is UNSPECIFIED.
14.2.8. User Thread Identifier Capability (utidc)
The utidc register extends utid to hold a capability. It is used to identify the current software thread in user mode. On reset the valid tag of utidc will be set to 0 and the remainder of the data is UNSPECIFIED.
14.3. "Smstateen/Ssstateen" Integration
The TID bit controls access to the CSRs in Table 41, Table 42 and Table 43 provided by the Zstid extension.
mstateen0
)hstateen0
)sstateen0
)14.4. CHERI Compartmentalization
This section describes how this specification enables support for compartmentalization for CHERI systems. Compartmentalization seeks to separate the privileges between different protection units, e.g., two or more libraries. Code can be separated by sentries, which allow for giving out code capabilities to untrusted code where the untrusted code can only call the code capability, but not modify it. Sentries can be called from different software threads and thus there needs to be a way of identifying the current software thread. While identifying the current software thread can be done by privileged code, e.g., the kernel, the implied performance overhead of this is not bearable for CHERI systems with many compartments.
The RISC-V ABI includes a thread pointer (tp) register, which is not usable for the purpose of reliably identifying the current software thread because the tp register is a general purpose register and can be changed arbitrarily by untrusted code. Therefore, this specification offers additional CSRs that facilitate a trusted source for the thread ID. All registers are readable from their respective privilege levels and writeable with ASR-permission.
Appendix B: RISC-V Instructions with different behavior for RV32Y/RV64Y
This chapter needs to be refactored. It will appear as an appendix in the unpriv specification. |
These instruction pages are for the new CHERI instructions, and some existing RISC-V instructions where the effect of CHERI needs specific details.
For existing RISC-V instructions, note that:
-
In Integer Pointer Mode, every byte of each memory access is bounds checked against ddc
-
In Integer Pointer Mode, a minimum length instruction at the target of all indirect jumps is bounds checked against pcc
-
In Capability Pointer Mode a minimum length instruction at the target of all indirect jumps is bounds checked against
cs1
(e.g., JALR (RV32Y/RV64Y)) -
A minimum length instruction at the taken target of all jumps and conditional branches is bounds checked against pcc regardless of CHERI execution mode
Not all RISC-V extensions have been checked against CHERI. Compatible extensions will eventually be listed in a CHERI profile. |
B.1. RV32I/E and RV64I/E Base Integer Instruction Sets
There are a number of load and store instructions that are already in RISC-V that have modified behavior when CHERI is included (see Section 2.10).
B.1.1. Integer Loads (RV32Y/RV64Y)
LD
LWU
LW
LHU
LH
LBU
LB
- Synopsis
-
Integer Load (LD, LW[U], LH[U], LB[U])
- Capability Pointer Mode Mnemonics
-
ld rd, offset(cs1)
lw[u] rd, offset(cs1)
lh[u] rd, offset(cs1)
lb[u] rd, offset(cs1)
- Encoding
- Description
-
Load integer data of the indicated size (byte, halfword, word, double-word) from memory. The effective address of the load is obtained by adding the sign-extended 12-bit offset to the address of
cs1
. The authorizing capability for the operation iscs1
. A copy of the loaded value is written tord
.Any instance of this instruction with a cs1
=c0
will trap (with a CHERI tag violation), asc0
is defined to always hold a NULL capability. As such, the encodings with acs1
=c0
are RESERVED for use by future extensions. - Integer Pointer Mode Description
-
Load integer data of the indicated size (byte, halfword, word, double-word) from memory. The effective address of the load is obtained by adding the sign-extended 12-bit offset to
rs1
. The authorizing capability for the operation is ddc. A copy of the loaded value is written tord
. - Exceptions
-
ARC suggestion: consider software check fault
CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant R-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites for LD
-
RV64 or RV32 with Zilsd
B.1.2. Integer Stores (RV32Y/RV64Y)
SD
SW
SH
SB
- Synopsis
-
Integer Stores (SD, SW, SH, SB)
- Capability Pointer Mode Mnemonics
-
sd rs2, offset(cs1)
sw rs2, offset(cs1)
sh rs2, offset(cs1)
sb rs2, offset(cs1)
- Encoding
- Description
-
Store integer data of the indicated size (byte, halfword, word, double-word) to memory. The effective address of the store is obtained by adding the sign-extended 12-bit offset to the address of
cs1
. The authorizing capability for the operation iscs1
. A copy ofrs2
is written to memory at the location indicated by the effective address and the valid tag bit of each block of memory naturally aligned to CLEN/8 is cleared.Any instance of this instruction with a cs1
=c0
will trap (with a CHERI tag violation), asc0
is defined to always hold a NULL capability. As such, the encodings with acs1
=c0
are RESERVED for use by future extensions.
- Exceptions
-
ARC suggestion: consider software check fault
CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant W-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites for SD
-
RV64 or RV32 with Zilsd
B.2. RV32I/E and RV64I/E Privileged Instruction Sets
There are a number of instructions that are already in RISC-V that have modified behavior when CHERI is included.
B.2.1. SRET (RV32Y/RV64Y)
See MRET(RV32Y/RV64Y).
B.2.2. MRET (RV32Y/RV64Y)
- Synopsis
-
Trap Return (MRET, SRET)
- Mnemonics
-
mret
sret
- Encoding
- Description
-
Return from machine mode (MRET(RV32Y/RV64Y)) or supervisor mode (SRET (RV32Y/RV64Y)) trap handler as defined by (RISC-V, 2023). MRET unseals mepcc and writes the result into pcc. SRET unseals sepcc and writes the result into pcc.
- Exceptions
-
CHERI fault exceptions occur when pcc does not grant ASR-permission because MRET(RV32Y/RV64Y) and SRET (RV32Y/RV64Y) require access to privileged CSRs. When that exception occurs, CHERI instruction fetch fault is reported in the TYPE field and the Permission violation code is reported in the CAUSE field of mtval2, stval2 or vstval2.
- Operation
TBD
B.2.3. DRET (RV32Y/RV64Y)
- Synopsis
-
Debug Return (DRET)
- Mnemonic
-
dret
- Encoding
- Description
-
DRET (RV32Y/RV64Y) return from debug mode. It unseals dpcc and writes the result into pcc.
The DRET (RV32Y/RV64Y) instruction is the recommended way to exit debug mode. However, it is a pseudoinstruction to return that technically does not execute from the program buffer or memory. It currently does not require the pcc to grant ASR-permission so it never excepts. |
- Prerequisites
-
Sdext
- Operation
TBD
B.3. "A" Standard Extension for Atomic Instructions
Atomic instructions and their interactions with CHERI.
B.3.1. AMO<OP>.W
See AMO<OP>.D.
B.3.2. AMO<OP>.D
- Synopsis
-
Atomic Operations (AMO<OP>.W, AMO<OP>.D), 32-bit encodings
- Capability Pointer Mode Mnemonics (RV64)
-
amo<op>.[w|d] rd, rs2, 0(cs1)
- Capability Pointer Mode Mnemonics (RV32)
-
amo<op>.w rd, rs2, 0(cs1)
- Integer Pointer Mode Mnemonics (RV64)
-
amo<op>.[w|d] rd, rs2, 0(rs1)
- Integer Pointer Mode Mnemonics (RV32)
-
amo<op>.w rd, rs2, 0(rs1)
- Encoding
- Capability Pointer Mode Description
-
Standard atomic instructions, authorized by the capability in
cs1
.Any instance of this instruction with a cs1
=c0
will trap (with a CHERI tag violation), asc0
is defined to always hold a NULL capability. As such, the encodings with acs1
=c0
are RESERVED for use by future extensions. - Integer Pointer Mode Description
-
Standard atomic instructions, authorized by the capability in ddc.
- Permissions
-
Requires R-permission and W-permission in the authorizing capability.
Requires all bytes of the access to be in capability bounds.
- Exceptions
-
All misaligned atomics cause a store/AMO address misaligned exception to allow software emulation (if the Zam extension is supported, see (RISC-V, 2023)), otherwise they take a store/AMO access fault exception.
CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant R-permission or W-permission, or the AP field could not have been produced by ACPERM
Invalid address violation
The effective address is invalid according to Invalid address conversion
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
If virtual memory is enabled on an RV64 hart, then the state of PTE.CW, and, if Svucrg is implemented, PTE.CRG from the current virtual memory page may cause a CHERI PTE store/AMO page fault exception in addition to a normal RISC-V page fault when operating in user mode. See Table 32 for the exception reporting in this case.
- Prerequisites for Capability Pointer Mode AMO<OP>.W, AMO<OP>.D
-
RV32Y/RV64Y, and A
- Prerequisites for Integer Pointer Mode AMO<OP>.W, AMO<OP>.D
-
Zcherihybrid, and A
- Capability Pointer Mode Operation
TBD
- Integer Pointer Mode Operation
-
TODO
B.3.3. AMOSWAP.C
- Synopsis
-
Atomic Operation (AMOSWAP.C), 32-bit encoding
- Mnemonic
-
amoswap.c cd, cs2, 0(cs1)
- Encoding
- Description
-
Atomic swap of capability type, authorized by the capability in
cs1
.The operation is equivalent to an atomically executed sequence of:
lc cd, 0(cs1)
sc cs2, 0(cs1)
Any instance of this instruction with a cs1
=c0
will trap (with a CHERI tag violation), asc0
is defined to always hold a NULL capability. As such, the encodings with acs1
=c0
are RESERVED for use by future extensions.If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the base address is
rs1
and the authorizing capability is ddc. - Prerequisites
-
RV32Y/RV64Y, and A or Zaamo
- Operation
-
TODO
B.3.4. LR.D
See LR.B.
B.3.5. LR.W
See LR.B.
B.3.6. LR.H
See LR.B.
B.3.7. LR.B
- Synopsis
-
Load Reserved (LR.D, LR.W, LR.H, LR.B), 32-bit encodings
- Capability Pointer Mode Mnemonics (RV64)
-
lr.[d|w|h|b] rd, 0(cs1)
- Capability Pointer Mode Mnemonics (RV32)
-
lr.[w|h|b] rd, 0(cs1)
- Integer Pointer Mode Mnemonics (RV64)
-
lr.[d|w|h|b] rd, 0(rs1)
- Integer Pointer Mode Mnemonics (RV32)
-
lr.[w|h|b] rd, 0(rs1)
- Encoding
- Capability Pointer Mode Description
-
Load reserved instructions, authorized by the capability in
cs1
.Any instance of this instruction with a cs1
=c0
will trap (with a CHERI tag violation), asc0
is defined to always hold a NULL capability. As such, the encodings with acs1
=c0
are RESERVED for use by future extensions. - Integer Pointer Mode Description
-
Load reserved instructions, authorized by the capability in ddc.
- Exceptions
-
All misaligned load reservations cause a load address misaligned exception to allow software emulation (if the Zam extension is supported, see (RISC-V, 2023)), otherwise they take a load access fault exception.
ARC suggestion: consider software check fault
CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant R-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites for Capability Pointer Mode LR.D
-
RV64, RV32Y/RV64Y, and A
- Prerequisites for Capability Pointer Mode LR.W
-
RV32Y/RV64Y, and A
- Prerequisites for Capability Pointer Mode LR.H, LR.B
-
Zabhlrsc, and RV32Y/RV64Y
- Prerequisites for LR.D
-
RV64, Zcherihybrid, and A
- Prerequisites for LR.W
-
Zcherihybrid, and A
- Prerequisites for LR.H, LR.B
-
Zabhlrsc, Zcherihybrid
- Operation
TBD
B.3.8. LR.C
- Synopsis
-
Load Reserved Capability (LR.C), 32-bit encoding
- Mnemonic
-
lr.c cd, 0(cs1)
- Encoding
- Description
-
Calculate the effective address of the memory access by adding the address of
cs1
to the sign-extended 12-bit offset.Authorize the memory access with the capability in
cs1
.Load a naturally aligned CLEN-bit data value and the associated valid tag from memory.
Set the reservation as for LR.W/D.
Write the CLEN-bit data and the valid tag to
cd
and conditionally update them as specified below.Any instance of this instruction with a cs1
=c0
will trap (with a CHERI tag violation), asc0
is defined to always hold a NULL capability. As such, the encodings with acs1
=c0
are RESERVED for use by future extensions.If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the base address is
rs1
and the authorizing capability is ddc. - Determining the final value of
cd
-
If the valid tag of the memory location loaded is 0, or the authorizing capability (
cs1
) does not grant C-permission then setcd.tag=0
. In this case the steps below do not apply.If
cd.tag=1
,cd
is not sealed andcs1
does not grant LM-permission, then an implicit ACPERM is performed to clear W-permission and LM-permission fromcd
.If
cd.tag=1
,cd
is not sealed andcs1
does not grant EL-permission, then an implicit ACPERM is performed restricting the Capability Level (CL) ofcd
to the level ofcs1
and to remove EL-permission.If
cd.tag=1
,cd
is sealed andcs1
does not grant EL-permission, then an implicit ACPERM is performed restricting the Capability Level (CL) ofcd
to the level ofcs1
If Zcheri1lvl is implemented, then also see Table 4.
Missing EL-permission also affects the level of sealed capabilities since notionally the Capability Level (CL) of a capability is not a permission but rather a data flow label attached to the loaded value. While the implicit ACPERM introduces a dependency on the loaded data, implementations can avoid this by deferring the actual masking of permissions until the loaded capability is dereferenced or the metadata bits are inspected using GCPERM or GCHI. Additionally, metadata modifications are on naturally aligned data, and so on the read path from a data cache, the modification typically happens in parallel with data alignment multiplexers. ARC feedback: this is change relative to 0.9.5 so that the choice is removed. Choosing the other option would need to be a future extension
When sending load data to a trace interface, implementations trace the final value written to
cd
which may not match the value in memory. - Exceptions
-
All misaligned load reservations cause a load address misaligned exception to allow software emulation (if the Zam extension is supported, see (RISC-V, 2023)), otherwise they take a load access fault exception.
ARC suggestion: consider software check fault
CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant R-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites
-
RV32Y/RV64Y, and A or Zalrsc
- Operation
TBD
B.3.9. SC.D
See SC.B.
B.3.10. SC.W
See SC.B.
B.3.11. SC.H
See SC.B.
B.3.12. SC.B
- Synopsis
-
Store Conditional (SC.D, SC.W, SC.H, SC.B), 32-bit encodings
- Capability Pointer Mode Mnemonics (RV64)
-
sc.[d|w|h|b] rd, rs2, 0(cs1)
- Capability Pointer Mode Mnemonics (RV32)
-
sc.[w|h|b] rd, rs2, 0(cs1)
- Integer Pointer Mode Mnemonics (RV64)
-
sc.[d|w|h|b] rd, rs2, 0(rs1)
- Integer Pointer Mode Mnemonics (RV32)
-
sc.[w|h|b] rd, rs2, 0(rs1)
- Encoding
- Capability Pointer Mode Description
-
Store conditional instructions, authorized by the capability in
cs1
.Any instance of this instruction with a cs1
=c0
will trap (with a CHERI tag violation), asc0
is defined to always hold a NULL capability. As such, the encodings with acs1
=c0
are RESERVED for use by future extensions. - Integer Pointer Mode Description
-
Store conditional instructions, authorized by the capability in ddc.
- Exceptions
-
All misaligned store conditionals cause a store/AMO address misaligned exception to allow software emulation (if the Zam extension is supported, see (RISC-V, 2023)), otherwise they take a store/AMO access fault exception.
ARC suggestion: consider software check fault
CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant W-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites for Capability Pointer Mode SC.D
-
RV64, and RV32Y/RV64Y, and A
- Prerequisites for Integer Pointer Mode SC.D
-
RV64, and Zcherihybrid, and A
- Prerequisites for Capability Pointer Mode SC.W
-
RV32Y/RV64Y, and A
- Prerequisites for Integer Pointer Mode SC.W
-
Zcherihybrid, and A
- Prerequisites for Capability Pointer Mode SC.H, SC.B
-
RV32Y/RV64Y, and Zabhlrsc
- Prerequisites for Integer Pointer Mode SC.H, SC.B
-
Zcherihybrid, and Zabhlrsc
- Operation
TBD
B.3.13. SC.C
- Synopsis
-
Store Conditional (SC.C), 32-bit encoding
- Mnemonic
-
sc.c rd, cs2, 0(cs1)
- Encoding
- Description
-
Calculate the effective address of the memory access by adding the address of
cs1
to the sign-extended 12-bit offset.Authorize the memory access with the capability in
cs1
.Conditionally store, following the same rules as SC.W, a naturally aligned CLEN-bit data value in
cs2
to memory and the associated valid tag incs2
.Set rd to 1 for success or 0 for failure.
Any instance of this instruction with a cs1
=c0
will trap (with a CHERI tag violation), asc0
is defined to always hold a NULL capability. As such, the encodings with acs1
=c0
are RESERVED for use by future extensions. - Valid tag of the stored capability value
-
The stored valid tag is 0 if:
-
cs2.tag=0
, or -
cs1
does not grant C-permission, or -
cs1
does not grant SL-permission andcs2
has a Capability Level (CL) of 0 (local).If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the base address is
rs1
and the authorizing capability is ddc.
-
- Exceptions
-
ARC feedback: needs to be an access fault as it can’t be emulated
Misaligned address fault exception when the effective address is not aligned to CLEN/8 if Zam is supported, otherwise store access fault exception.
ARC suggestion: consider software check fault
CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant W-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites
-
RV32Y/RV64Y, and A or Zalrsc
- Operation
TBD
B.4. "Zfh", "Zfhmin", "F" and "D" Standard Extension for Floating-Point
Floating point instructions and how CHERI affects them.
B.4.1. FLD
See FLH.
B.4.2. FLW
See FLH.
B.4.3. FLH
- Synopsis
-
Floating point loads (FLD, FLW, FLH), 32-bit encodings
- Capability Pointer Mode Mnemonics
-
fld frd, offset(cs1)
flw frd, offset(cs1)
flh frd, offset(cs1)
- Integer Pointer Mode Mnemonics
-
fld rd, offset(rs1)
flw rd, offset(rs1)
flh rd, offset(rs1)
- Encoding
- Capability Pointer Mode Description
-
Standard floating point load instructions, authorized by the capability in
cs1
.Any instance of this instruction with a cs1
=c0
will trap (with a CHERI tag violation), asc0
is defined to always hold a NULL capability. As such, the encodings with acs1
=c0
are RESERVED for use by future extensions. - Integer Pointer Mode Description
-
Standard floating point load instructions, authorized by the capability in ddc.
- Exceptions
-
ARC suggestion: consider software check fault
CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant R-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites for Capability Pointer Mode FLD
-
RV32Y/RV64Y, and D
- Prerequisites for Integer Pointer Mode FLD
-
Zcherihybrid, and D
- Prerequisites for Capability Pointer Mode FLW
-
RV32Y/RV64Y, and F
- Prerequisites for Integer Pointer Mode FLW
-
Zcherihybrid, and F
- Prerequisites for Capability Pointer Mode FLH
-
RV32Y/RV64Y, and Zfhmin or Zfh
- Prerequisites for Integer Pointer Mode FLH
-
Zcherihybrid, and Zfhmin or Zfh
- Operation
-
TODO
B.4.4. FSD
See FSH.
B.4.5. FSW
See FSH.
B.4.6. FSH
- Synopsis
-
Floating point stores (FSD, FSW, FSH), 32-bit encodings
- Capability Pointer Mode Mnemonics
-
fsd fs2, offset(cs1)
fsw fs2, offset(cs1)
fsh fs2, offset(cs1)
- Integer Pointer Mode Mnemonics
-
fsd fs2, offset(rs1)
fsw fs2, offset(rs1)
fsh fs2, offset(rs1)
- Encoding
- Capability Pointer Mode Description
-
Standard floating point store instructions, authorized by the capability in
cs1
.Any instance of this instruction with a cs1
=c0
will trap (with a CHERI tag violation), asc0
is defined to always hold a NULL capability. As such, the encodings with acs1
=c0
are RESERVED for use by future extensions. - Integer Pointer Mode Description
-
Standard floating point store instructions, authorized by the capability in ddc.
- Exceptions
-
ARC suggestion: consider software check fault
CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant W-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites for Capability Pointer Mode FSD
-
RV32Y/RV64Y, and D
- Prerequisites for Integer Pointer Mode FSD
-
Zcherihybrid, and D
- Prerequisites for Capability Pointer Mode FSW
-
RV32Y/RV64Y, and F
- Prerequisites for Integer Pointer Mode FSW
-
Zcherihybrid, and F
- Prerequisites for Capability Pointer Mode FSH
-
RV32Y/RV64Y, and Zfh or Zfhmin
- Prerequisites for Integer Pointer Mode FSH
-
Zcherihybrid, and Zfh or Zfhmin
- Operation
TBD
B.5. "C" Standard Extension for Compressed Instructions
One group of 16-bit encodings are remapped to different instructions dependent upon the CHERI execution mode, MXLEN and which extensions are supported.
The following tables summarize the mappings.
Zcf and Zclsd are incompatible |
B.5.1. RV32
Encoding | Supported Extensions | |||||
---|---|---|---|---|---|---|
[15:13] |
[1:0] |
Zca |
Zcf |
Zcd |
Zcmp/ Zcmt |
Zclsd |
111 |
00 |
N/A |
C.FSW |
N/A |
N/A |
C.SD |
011 |
00 |
N/A |
C.FLW |
N/A |
N/A |
C.LD |
111 |
10 |
N/A |
C.FSWSP |
N/A |
N/A |
C.SDSP |
011 |
10 |
N/A |
C.FLWSP |
N/A |
N/A |
C.LDSP |
101 |
00 |
N/A |
N/A |
C.FSD |
reserved1 |
N/A |
001 |
00 |
N/A |
N/A |
C.FLD |
reserved1 |
N/A |
101 |
10 |
N/A |
N/A |
C.FSDSP |
N/A |
|
001 |
10 |
N/A |
N/A |
C.FLDSP |
reserved1 |
N/A |
1 reserved for future standard Zcm extensions
Encoding | Supported Extensions | |||||
---|---|---|---|---|---|---|
[15:13] |
[1:0] |
Zca |
Zcf |
Zcd |
Zcmp/ Zcmt |
Zclsd |
111 |
00 |
C.SC |
||||
011 |
00 |
C.LC |
||||
111 |
10 |
C.SCSP |
||||
011 |
10 |
C.LCSP |
||||
101 |
00 |
N/A |
N/A |
C.FSD |
reserved1 |
N/A |
001 |
00 |
N/A |
N/A |
C.FLD |
reserved1 |
N/A |
101 |
10 |
N/A |
N/A |
C.FSDSP |
N/A |
|
001 |
10 |
N/A |
N/A |
C.FLDSP |
reserved1 |
N/A |
1 reserved for future standard Zcm extensions
B.5.2. RV64 / RV64Y
Encoding | Supported Extensions | |||||
---|---|---|---|---|---|---|
[15:13] |
[1:0] |
Zca |
Zcf |
Zcd |
Zcmp/ Zcmt |
Zclsd |
111 |
00 |
C.SD |
N/A |
N/A |
N/A |
N/A |
011 |
00 |
C.LD |
N/A |
N/A |
N/A |
N/A |
111 |
10 |
C.SDSP |
N/A |
N/A |
N/A |
N/A |
011 |
10 |
C.LDSP |
N/A |
N/A |
N/A |
N/A |
101 |
00 |
N/A |
N/A |
C.FSD |
reserved1 |
N/A |
001 |
00 |
N/A |
N/A |
C.FLD |
reserved1 |
N/A |
101 |
10 |
N/A |
N/A |
C.FSDSP |
N/A |
|
001 |
10 |
N/A |
N/A |
C.FLDSP |
reserved1 |
N/A |
Encoding | Supported Extensions | |||||
---|---|---|---|---|---|---|
[15:13] |
[1:0] |
Zca |
Zcf |
Zcd |
Zcmp/ Zcmt |
Zclsd |
111 |
00 |
C.SD |
N/A |
N/A |
N/A |
N/A |
011 |
00 |
C.LD |
N/A |
N/A |
N/A |
N/A |
111 |
10 |
C.SDSP |
N/A |
N/A |
N/A |
N/A |
011 |
10 |
C.LDSP |
N/A |
N/A |
N/A |
N/A |
101 |
00 |
C.SC |
||||
001 |
00 |
C.LC |
||||
101 |
10 |
C.SCSP |
||||
001 |
10 |
C.LCSP |
B.5.3. C.BEQZ, C.BNEZ
- Synopsis
-
Conditional branches (C.BEQZ, C.BNEZ), 16-bit encodings
- Mnemonics
-
c.beqz rs1', offset
c.bnez rs1', offset
- Expansions
-
beq rs1′, x0, offset
bne rs1′, x0, offset
- Encoding
- Exceptions
-
A minimum sized instruction at the target address is not in pcc bounds.
- Prerequisites
-
C or Zca
- Operation (after expansion to 32-bit encodings)
B.5.4. C.MV (RV32Y/RV64Y)
- Synopsis
-
Capability move (C.MV), 16-bit encoding
- Mnemonic
-
c.mv cd, cs2
- Expansion
-
cmv cd, cs2
- Suggested assembly syntax
-
mv cd, cs2
The suggested assembly syntax distinguishes from integer c.mv by operand type.
|
- Encoding
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent. |
- Description
-
Capability register
cd
is replaced with the contents ofcs2
.
This instruction can propagate tagged capabilities which have malformed bounds, have reserved bits set or have a permission field which cannot be produced by ACPERM.
- Prerequisites
-
C or Zca, RV32Y/RV64Y
- Operation (after expansion to 32-bit encoding)
-
See CMV
B.5.5. C.ADDI16SP (RV32Y/RV64Y)
- Synopsis
-
Stack pointer increment in blocks of 16 (C.ADDI16SP), 16-bit encodings
- Mnemonic
-
c.addi16sp nzimm
- Expansion
-
caddi csp, csp, nzimm
The suggested assembly syntax distinguishes from integer c.addi16sp by operand type.
|
- Encoding
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent. |
- Description
-
Add the non-zero sign-extended 6-bit immediate to the value in the stack pointer (
csp=c2
), where the immediate is scaled to represent multiples of 16 in the range (-512,496).Set
csp.tag=0
ifcsp
is sealed.Set
cd.tag=0
if the resulting capability cannot be represented exactly.Set
cd.tag=0
ifcsp
's bounds are malformed, or if any of the reserved fields are set.
- Prerequisites
-
C or Zca, RV32Y/RV64Y
- Operation
-
execute(CADDI(sp, sp, sign_extend(nzimm)))
B.5.6. C.ADDI4SPN (RV32Y/RV64Y)
- Synopsis
-
Stack pointer increment in blocks of 4 (C.ADDI4SPN), 16-bit encoding
- Mnemonic
-
c.addi4spn cd', nzuimm
- Expansion
-
caddi cd', csp, nzuimm
The suggested assembly syntax distinguishes from integer c.addi4spn by operand type.
|
- Encoding
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent. |
- Description
-
Copy
csp
tocd'
. Add a zero-extended non-zero immediate, scaled by 4, tocd'.address
.Set
cd'.tag=0
ifcsp
is sealed.Set
cd'.tag=0
if the resulting capability cannot be represented exactly.Set
cd'.tag=0
ifcsp
's bounds are malformed, or if any of the reserved fields are set. - Integer Pointer Mode Description
-
Add a zero-extended non-zero immediate, scaled by 4, to the stack pointer,
sp
, and writes the result tord'
. This instruction is used to generate pointers to stack-allocated variables. - Prerequisites for C.ADDI4SPN
-
C or Zca, RV32Y/RV64Y
- Prerequisites for C.ADDI4SPN
-
C or Zca, Zcherihybrid
- Capability Pointer Mode Operation
-
let cd = creg2reg_idx(cdc) in execute(CADDI(cd, sp, zero_extend(nzuimm)))
B.5.7. C.JALR
- Synopsis
-
Jump register with link, 16-bit encodings
- Capability Pointer Mode Mnemonic
-
c.jalr c1, cs1
- Capability Pointer Mode Expansion
-
jalr c1, 0(cs1)
- Integer Pointer Mode Mnemonic
-
c.jalr x1, rs1
- Integer Pointer Mode Expansion
-
jalr x1, 0(rs1)
- Encoding
- Capability Pointer Mode Description
-
See JALR (RV32Y/RV64Y) for execution of the expanded instruction as shown above. Note that the
offset
is zero in the expansion. - Integer Pointer Mode Description
-
See JALR (RV32Y/RV64Y) for execution of the expanded instruction as shown above. Note that the
offset
is zero in the expansion. - Exceptions
- Prerequisites for Capability Pointer Mode
-
C or Zca, RV32Y/RV64Y
- Prerequisites for Integer Pointer Mode
-
C or Zca, Zcherihybrid
- Operation (after expansion to 32-bit encodings)
B.5.8. C.JR
- Synopsis
-
Jump register without link, 16-bit encodings
- Capability Pointer Mode Mnemonic
-
c.jr cs1
- Capability Pointer Mode Expansion
-
jalr c0, 0(cs1)
- Integer Pointer Mode Mnemonic
-
c.jr rs1
- Integer Pointer Mode Expansion
-
jalr x0, 0(rs1)
- Encoding
- Capability Pointer Mode Description
-
See JALR (RV32Y/RV64Y) for execution of the expanded instruction as shown above. Note that the
offset
is zero in the expansion. - Integer Pointer Mode Description
-
See JALR (RV32Y/RV64Y) for execution of the expanded instruction as shown above. Note that the
offset
is zero in the expansion. - Exceptions
- Prerequisites for Capability Pointer Mode
-
C or Zca, RV32Y/RV64Y
- Prerequisites for Integer Pointer Mode
-
C or Zca, Zcherihybrid
- Operation (after expansion to 32-bit encodings)
B.5.9. C.JAL
- Synopsis
-
Jump with link, 16-bit encodings
- Capability Pointer Mode Mnemonic (RV32)
-
c.jal c1, offset
- Capability Pointer Mode Expansion (RV32)
-
jal c1, offset
- Integer Pointer Mode Mnemonic (RV32)
-
c.jal x1, offset
- Integer Pointer Mode Expansion (RV32)
-
jal x1, offset
- Encoding (RV32)
- Capability Pointer Mode Description
-
Link the next linear pcc to
cd
and seal. Jump to pcc.address+offset. - Integer Pointer Mode Description
-
Set the next PC and link to
rd
according to the standard JAL (RV32Y/RV64Y) definition. - Exceptions
- Prerequisites for Capability Pointer Mode
-
C or Zca, RV32Y/RV64Y
- Prerequisites for Integer Pointer Mode
-
C or Zca, Zcherihybrid
- Operation (after expansion to 32-bit encodings)
B.5.10. C.J
- Synopsis
-
Jump without link, 16-bit encodings
- Mnemonic
-
c.j offset
- Capability Pointer Mode Expansion
-
jal c0, offset
- Integer Pointer Mode Expansion
-
jal x0, offset
- Encoding
- Description
-
Set the next PC following the standard JAL (RV32Y/RV64Y) definition.
There is no difference in Capability Pointer Mode or Integer Pointer Mode execution for this instruction.
- Exceptions
- Prerequisites for Capability Pointer Mode
-
C or Zca, RV32Y/RV64Y
- Prerequisites for Integer Pointer Mode
-
C or Zca, Zcherihybrid
- Operation (after expansion to 32-bit encodings)
B.5.11. C.LD
See C.LW.
B.5.12. C.LW
- Synopsis
-
Load (C.LD, C.LW), 16-bit encodings
- Capability Pointer Mode Mnemonics
-
c.ld rd', offset(cs1')
c.lw rd', offset(cs1')
- Capability Pointer Mode Expansions
-
ld rd', offset(cs1')
lw rd', offset(cs1')
- Integer Pointer Mode Mnemonics
-
c.ld rd', offset(rs1')
c.lw rd', offset(rs1')
- Integer Pointer Mode Expansions
-
ld rd', offset(rs1')
lw rd', offset(rs1')
- Encoding
- Capability Pointer Mode Description
-
Standard load instructions, authorized by the capability in
cs1
. - Integer Pointer Mode Description
-
Standard load instructions, authorized by the capability in ddc.
- Exceptions
-
ARC suggestion: consider software check fault
CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant R-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites for Capability Pointer Mode C.LD
-
RV64 or RV32 with Zclsd, and C or Zca, RV32Y/RV64Y
- Prerequisites for Integer Pointer Mode C.LD
-
RV64 or RV32 with Zclsd, C or Zca, Zcherihybrid
- Prerequisites Capability Pointer Mode C.LW
-
C or Zca, RV32Y/RV64Y
- Prerequisites Integer Pointer Mode C.LW
-
C or Zca, Zcherihybrid
- Operation (after expansion to 32-bit encodings)
B.5.13. C.LWSP
See C.LDSP.
B.5.14. C.LDSP
- Synopsis
-
Load (C.LWSP, C.LDSP), 16-bit encodings
- Capability Pointer Mode Mnemonics
-
c.ld/c.lw rd, offset(csp)
- Capability Pointer Mode Expansions
-
ld/lw rd, offset(csp)
- Integer Pointer Mode Mnemonics
-
c.ld/c.lw rd, offset(sp)
- Integer Pointer Mode Expansions
-
ld/lw rd, offset(sp)
- Encoding
- Capability Pointer Mode Description
-
Standard stack pointer relative load instructions, authorized by the capability in
csp
. - Integer Pointer Mode Description
-
Standard stack pointer relative load instructions, authorized by the capability in ddc.
- Exceptions
-
ARC suggestion: consider software check fault
CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant R-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites for Capability Pointer Mode C.LDSP
-
RV64 or RV32 with Zclsd, and C or Zca, RV32Y/RV64Y
- Prerequisites for Integer Pointer Mode C.LDSP
-
RV64 or RV32 with Zclsd, and C or Zca, Zcherihybrid
- Prerequisites for Capability Pointer Mode C.LWSP
-
C or Zca, RV32Y/RV64Y
- Prerequisites for Integer Pointer Mode C.LWSP
-
C or Zca, Zcherihybrid
- Operation (after expansion to 32-bit encodings)
B.5.15. C.FLW
See C.FLWSP.
B.5.16. C.FLWSP
- Synopsis
-
Floating point load (C.FLW, C.FLWSP), 16-bit encodings
- Integer Pointer Mode Mnemonics (RV32)
-
c.flw rd', offset(rs1'/sp)
- Integer Pointer Mode Expansions (RV32)
-
flw rd', offset(rs1'/sp)
- Encoding (RV32)
- Integer Pointer Mode Description
-
Standard floating point load instructions, authorized by the capability in ddc.
These instructions are available in RV32 Integer Pointer Mode only. In Capability Pointer Mode they are remapped to C.LC/C.LCSP. |
- Exceptions
-
ARC suggestion: consider software check fault
CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant R-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites for Integer Pointer Mode
-
C or Zca, Zcherihybrid, and Zcf or F
- Operation (after expansion to 32-bit encodings)
-
See FLW
B.5.17. C.FLD
See C.FLDSP
B.5.18. C.FLDSP
- Synopsis
-
Double precision floating point loads (C.FLD, C.FLDSP), 16-bit encodings
- Capability Pointer Mode Mnemonic (RV32)
-
c.fld frd', offset(cs1'/csp)
- Capability Pointer Mode Expansion (RV32)
-
fld frd', offset(csp)
- Integer Pointer Mode Mnemonic
-
c.fld fs2, offset(rs1'/sp)
- Integer Pointer Mode Expansion
-
fld fs2, offset(rs1'/sp)
- Encoding
- Integer Pointer Mode Description
-
Standard floating point stack pointer relative load instructions, authorized by the capability in ddc.
These instructions are available in RV64 Integer Pointer Mode only. In RV64 Capability Pointer Mode they are remapped to C.LC/C.LCSP. |
These encodings may be remapped by future code-size Zcm standard extensions, similar to [Zcmp] and [Zcmt]. The rule is that in RV64 Capability Pointer Mode they are always remapped to C.SC/C.SCSP. |
- Exceptions
-
ARC suggestion: consider software check fault
CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant R-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites for Capability Pointer Mode (RV32 only)
-
RV32Y/RV64Y, C and D; or
RV32Y/RV64Y, Zca and Zcd - Prerequisites for Integer Pointer Mode
-
Zcherihybrid, C and D; or
Zcherihybrid, Zca and Zcd - Operation (after expansion to 32-bit encodings)
-
See FLD
B.5.19. C.LC
see C.LCSP.
B.5.20. C.LCSP
- Synopsis
-
Capability loads (C.LC, C.LCSP), 16-bit encodings
These instructions have different encodings for RV64 and RV32. |
- Capability Pointer Mode Mnemonics
-
c.lc cd', offset(cs1')
c.lc cd', offset(csp)
- Capability Pointer Mode Expansions
-
lc cd', offset(cs1')
lc cd', offset(csp)
- Encoding
- Capability Pointer Mode Description
-
Load capability instruction, authorized by the capability in
cs1
. Take a load address misaligned exception if not naturally aligned.
These mnemonics do not exist in Integer Pointer Mode. |
- Exceptions
-
ARC suggestion: consider software check fault
CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant R-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites
-
C or Zca, RV32Y/RV64Y
- Operation (after expansion to 32-bit encodings)
-
See LC
B.5.21. C.SD
See C.SW.
B.5.22. C.SW
- Synopsis
-
Stores (C.SD, C.SW), 16-bit encodings
- Capability Pointer Mode Mnemonics
-
c.sd rs2', offset(cs1')
c.sw rs2', offset(cs1')
- Capability Pointer Mode Expansions
-
sd rs2', offset(cs1')
sw rs2', offset(cs1')
- Integer Pointer Mode Mnemonics
-
c.sd rs2', offset(rs1')
c.sw rs2', offset(rs1')
- Integer Pointer Mode Expansions
-
sd rs2', offset(rs1')
sw rs2', offset(rs1')
- Encoding
- Capability Pointer Mode Description
-
Standard store instructions, authorized by the capability in
cs1
. - Integer Pointer Mode Description
-
Standard store instructions, authorized by the capability in ddc.
- Exceptions
-
ARC suggestion: consider software check fault
CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant W-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites for Capability Pointer Mode C.SD
-
RV64 or RV32 with Zclsd, and C or Zca, RV32Y/RV64Y
- Prerequisites for Integer Pointer Mode C.SD
-
RV64 or RV32 with Zclsd, and C or Zca, Zcherihybrid
- Prerequisites for Capability Pointer Mode C.SW
-
C or Zca, RV32Y/RV64Y
- Prerequisites for Integer Pointer Mode C.SW
-
C or Zca, Zcherihybrid
- Operation (after expansion to 32-bit encodings)
B.5.23. C.SWSP
See C.SDSP.
B.5.24. C.SDSP
- Synopsis
-
Stack pointer relative stores (C.SWSP, C.SDSP), 16-bit encodings
- Capability Pointer Mode Mnemonics
-
c.sd rs2, offset(csp)
c.sw rs2, offset(csp)
- Capability Pointer Mode Expansions
-
sd rs2, offset(csp)
sw rs2, offset(csp)
- Integer Pointer Mode Mnemonics
-
c.sd rs2, offset(sp)
c.sw rs2, offset(sp)
- Integer Pointer Mode Expansions
-
sd rs2, offset(sp)
sw rs2, offset(sp)
- Encoding
- Capability Pointer Mode Description
-
Standard stack pointer relative store instructions, authorized by the capability in
csp
. - Integer Pointer Mode Description
-
Standard stack pointer relative store instructions, authorized by the capability in ddc.
- Exceptions
-
ARC suggestion: consider software check fault
CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant W-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites for Capability Pointer Mode C.SDSP
-
RV64 or RV32 with Zclsd, and C or Zca, RV32Y/RV64Y
- Prerequisites for Integer Pointer Mode C.SDSP
-
RV64 or RV32 with Zclsd, and C or Zca, Zcherihybrid
- Prerequisites for Capability Pointer Mode C.SWSP
-
C or Zca, RV32Y/RV64Y
- Prerequisites for Integer Pointer Mode C.SWSP
-
C or Zca, Zcherihybrid
- Operation (after expansion to 32-bit encodings)
B.5.25. C.FSW
See C.FSWSP.
B.5.26. C.FSWSP
- Synopsis
-
Floating point stores (C.FSW, C.FSWSP), 16-bit encodings
- Integer Pointer Mode Mnemonics (RV32)
-
c.fsw rs2', offset(rs1')
c.fsw rs2', offset(sp)
- Integer Pointer Mode Expansions (RV32)
-
fsw rs2', offset(rs1')
fsw rs2', offset(sp)
- Encoding (RV32)
- Integer Pointer Mode Description
-
Standard floating point store instructions, authorized by the capability in ddc.
These instructions are available in RV32 Integer Pointer Mode only. In Capability Pointer Mode they are remapped to C.SC/C.SCSP. |
- Exceptions
-
ARC suggestion: consider software check fault
CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant W-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites
-
C or Zca, Zcherihybrid, Zcf or F
- Operation (after expansion to 32-bit encodings)
-
See FSW
B.5.27. C.FSD
See C.FSDSP.
B.5.28. C.FSDSP
- Synopsis
-
Double precision floating point stores (C.FSD, C.FSDSP), 16-bit encodings
- Capability Pointer Mode Mnemonics (RV32)
-
c.fsd fs2, offset(cs1')
c.fsd fs2, offset(csp)
- Capability Pointer Mode Expansions (RV32)
-
fsd fs2, offset(cs1')
fsd fs2, offset(csp)
- Integer Pointer Mode Mnemonics
-
c.fsd fs2, offset(rs1')
c.fsd fs2, offset(sp)
- Integer Pointer Mode Expansions
-
fsd fs2, offset(rs1)
fsd fs2, offset(sp)
- Encoding
- Capability Pointer Mode Description
-
Standard floating point stack pointer relative store instructions, authorized by the capability in
cs1
orcsp
. - Integer Pointer Mode Description
-
Standard floating point stack pointer relative store instructions, authorized by the capability in ddc.
These instructions are available in RV64 Integer Pointer Mode only. In RV64 Capability Pointer Mode they are remapped to C.SC/C.SCSP. |
C.FSDSP may be remapped by the [Zcmp], [Zcmt] standard extensions. C.FSD may be remapped by future code-size reduction extensions. The rule is that in RV64 Capability Pointer Mode they are always remapped to C.LC/C.LCSP. |
- Exceptions
-
ARC suggestion: consider software check fault
CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant W-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites for Capability Pointer Mode C.FSD, C.FSDSP (RV32 only)
-
RV32Y/RV64Y, C and D; or
RV32Y/RV64Y, Zca and Zcd - Prerequisites for Integer Pointer Mode C.FSD, C.FSDSP
-
Zcherihybrid, C and D; or
Zcherihybrid, Zca and Zcd - Operation (after expansion to 32-bit encodings)
-
See FSD
B.5.29. C.SC
see C.SCSP.
B.5.30. C.SCSP
- Synopsis
-
Capability stores (C.SC, C.SCSP), 16-bit encodings
These instructions have different encodings for RV64 and RV32. |
- Capability Pointer Mode Mnemonics
-
c.sc cs2', offset(cs1')
c.sc cs2', offset(csp)
- Capability Pointer Mode Expansions
-
sc cs2', offset(cs1')
sc cs2', offset(csp)
- Encoding
- Capability Pointer Mode Description
-
Store the CLEN-bit value in
cs2'
to memory. The capability incs1/csp
authorizes the operation. The effective address of the memory access is obtained by adding the address ofcs1/csp
to the zero-extended offset.
These mnemonics do not exist in Integer Pointer Mode. |
- Tag of the written capability value
-
The capability written to memory has the valid tag set to 0 if the valid tag of
cs2'
is 0 or if the authorizing capability (cs1/csp
) does not grant C-permission.The stored tag is also set to zero if the authorizing capability does not have SL-permission set but the stored data has a Capability Level (CL) of 0 (local).
This instruction can propagate tagged capabilities which have malformed bounds, have reserved bits set or have a permission field which cannot be produced by ACPERM.
- Exceptions
-
ARC feedback: needs to be an access fault as it can’t be emulated
Misaligned address fault exception when the effective address is not aligned to CLEN/8 if Zam is supported, otherwise store access fault exception.
ARC suggestion: consider software check fault
CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant W-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites
-
C or Zca, RV32Y/RV64Y
- Operation (after expansion to 32-bit encodings)
-
See SC
B.6. "Zicbom", "Zicbop", "Zicboz" Standard Extensions for Base Cache Management Operations
Cache-related instructions and how CHERI affects them.
B.6.1. CBO.CLEAN (RV32Y/RV64Y)
- Synopsis
-
Perform a clean operation on a cache block
- Mnemonic
-
cbo.clean 0(cs1)
- Encoding
- Description
-
A CBO.CLEAN instruction performs a clean operation on the cache block whose effective address is the base address specified in
cs1
. The authorizing capability for this operation iscs1
.
If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the base address is rs1
and the authorizing capability is ddc.
- Exceptions
-
ARC suggestion: consider software check fault
CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant W-permission and R-permission, or the AP field could not have been produced by ACPERM
Bounds violation
None of the bytes accessed are within the bounds, or the capability has malformed bounds
- Prerequisites
-
Zicbom, RV32Y/RV64Y
- Operation
TBD
B.6.2. CBO.FLUSH (RV32Y/RV64Y)
- Synopsis
-
Perform a flush operation on a cache block
- Mnemonic
-
cbo.flush 0(cs1)
- Encoding
- Description
-
A CBO.FLUSH instruction performs a flush operation on the cache block whose effective address is the base address specified in
cs1
. The authorizing capability for this operation iscs1
.
If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the base address is rs1
and the authorizing capability is ddc.
- Exceptions
-
ARC suggestion: consider software check fault
CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant W-permission and R-permission, or the AP field could not have been produced by ACPERM
Bounds violation
None of the bytes accessed are within the bounds, or the capability has malformed bounds
- Prerequisites
-
Zicbom, RV32Y/RV64Y
- Operation
TBD
B.6.3. CBO.INVAL (RV32Y/RV64Y)
- Synopsis
-
Perform an invalidate operation on a cache block
- Mnemonic
-
cbo.inval 0(cs1)
- Encoding
- Description
-
A CBO.INVAL instruction performs an invalidate operation on the cache block whose effective address is the base address specified in
cs1
. The authorizing capability for this instruction iscs1
.
If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the base address is rs1
and the authorizing capability is ddc.
- Exceptions
-
ARC suggestion: consider software check fault
CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant W-permission, R-permission or ASR-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
CSR state controls whether CBO.INVAL performs cache block flushes instead of invalidations for less privileged modes.
Invalidating a cache block can re-expose capabilities previously stored to it after the most recent flush, not just secret values. As such, CBO.INVAL has stricter checks on its use than CBO.FLUSH, and should only be made available to, and used by, sufficiently-trusted software. Untrusted software should use CBO.FLUSH instead. |
- Prerequisites
-
Zicbom, RV32Y/RV64Y
- Operation
TBD
B.6.4. CBO.ZERO (RV32Y/RV64Y)
- Synopsis
-
Store zeros to the full set of bytes corresponding to a cache block
- Mnemonic
-
cbo.zero 0(cs1)
- Encoding
- Description
-
A
cbo.zero
instruction performs stores of zeros to the full set of bytes corresponding to the cache block whose effective address is the base address specified incs1
. An implementation may or may not update the entire set of bytes atomically although each individual write must atomically clear the valid tag bit of the corresponding aligned CLEN-bit location. The authorizing capability for this instruction iscs1
.
If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the base address is rs1
and the authorizing capability is ddc.
- Exceptions
-
ARC suggestion: consider software check fault
CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):
Kind Reason Tag violation
Authorizing capability valid tag set to 0, or has any reserved bits set
Seal violation
Authorizing capability is sealed
Permission violation
Authorizing capability does not grant W-permission, or the AP field could not have been produced by ACPERM
Bounds violation
At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds
- Prerequisites
-
Zicboz, RV32Y/RV64Y
- Operation
TBD
B.6.5. PREFETCH.I (RV32Y/RV64Y)
- Synopsis
-
Provide a HINT to hardware that a cache block is likely to be accessed by an instruction fetch in the near future
- Mnemonic
-
prefetch.i offset(cs1)
- Encoding
- Description
-
A PREFETCH.I instruction indicates to hardware that the cache block whose effective address is the sum of the base address specified in
cs1
and the sign-extended offset encoded in imm[11:0], where imm[4:0] equals 0b00000, is likely to be accessed by an instruction fetch in the near future. The encoding is only valid if imm[4:0]=0. The authorizing capability for this operation iscs1
. This instruction does not throw any exceptions. However, following the rules from Chapter 2, this instruction does not perform a prefetch if it is not authorized bycs1
.
If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the base address is rs1
and the authorizing capability is pcc.
PREFETCH.I does not perform a memory access if one or more of the following conditions of the authorizing capability are met:
-
The valid tag is not set
-
The sealed bit is set
-
No bytes of the cache line requested is in bounds
-
X-permission is not set
-
Any reserved bits are set
-
The permissions could not have been produced by ACPERM
-
The bounds are malformed
- Prerequisites
-
Zicbop, RV32Y/RV64Y
- Operation
TODO
B.6.6. PREFETCH.R (RV32Y/RV64Y)
- Synopsis
-
Provide a HINT to hardware that a cache block is likely to be accessed by a data read in the near future
- Mnemonic
-
prefetch.r offset(cs1)
- Encoding
- Description
-
A PREFETCH.R instruction indicates to hardware that the cache block whose effective address is the sum of the base address specified in
cs1
and the sign-extended offset encoded in imm[11:0], where imm[4:0] equals 0b00000, is likely to be accessed by a data read (i.e., load) in the near future. The encoding is only valid if imm[4:0]=0. The authorizing capability for this operation iscs1
. This instruction does not throw any exceptions. However, following the rules from Chapter 2, this instruction does not perform a prefetch if it is not authorized bycs1
.
If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the base address is rs1
and the authorizing capability is pcc.
PREFETCH.R does not perform a memory access if one or more of the following conditions of the authorizing capability are met:
-
The valid tag is not set
-
The sealed bit is set
-
No bytes of the cache line requested is in bounds
-
R-permission is not set
-
Any reserved bits are set
-
The permissions could not have been produced by ACPERM
-
The bounds are malformed
- Prerequisites
-
Zicbop, RV32Y/RV64Y
- Operation
TODO
B.6.7. PREFETCH.W (RV32Y/RV64Y)
- Synopsis
-
Provide a HINT to hardware that a cache block is likely to be accessed by a data write in the near future
- Mnemonic
-
prefetch.w offset(cs1)
- Encoding
- Description
-
A PREFETCH.W instruction indicates to hardware that the cache block whose effective address is the sum of the base address specified in
cs1
and the sign-extended offset encoded in imm[11:0], where imm[4:0] equals 0b00000, is likely to be accessed by a data write (i.e., store) in the near future. The encoding is only valid if imm[4:0]=0. The authorizing capability for this operation iscs1
. This instruction does not throw any exceptions. However, following the rules from Chapter 2, this instruction does not perform a prefetch if it is not authorized bycs1
.
If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the base address is rs1
and the authorizing capability is pcc.
PREFETCH.W does not perform a memory access if one or more of the following conditions of the authorizing capability are met:
-
The valid tag is not set
-
The sealed bit is set
-
No bytes of the cache line requested is in bounds
-
W-permission is not set
-
Any reserved bits are set
-
The permissions could not have been produced by ACPERM
-
The bounds are malformed
- Prerequisites
-
Zicbop, RV32Y/RV64Y
- Operation
TODO
B.7. "Zba" Extension for Bit Manipulation Instructions
Bit manipulation instruction reference.
B.7.1. ADD.UW (RV64Y)
- Synopsis
-
Add unsigned word for address generation
- Mnemonic
-
add.uw cd, rs1, cs2
- Encoding
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent. |
- Description
-
Copy the capability in
cs2
tocd
.Increment
cd.address
by the unsigned word inrs1
.Set
cd.tag=0
ifcs2
is sealed.Set
cd.tag=0
if the resulting capability cannot be represented exactly.Set
cd.tag=0
ifcs2
's bounds are malformed, or if any of the reserved fields are set. - Prerequisites
-
RV64, RV32Y/RV64Y, Zba
- Operation
-
let rs1_val = X(rs1); let cs2_val = C(cs2); let shamt : range(0,3) = match op { RISCV_ADDUW => 0, RISCV_SH1ADDUW => 1, RISCV_SH2ADDUW => 2, RISCV_SH3ADDUW => 3, }; let result = incCapAddrChecked(cs2_val, zero_extend(rs1_val[31..0]) << shamt); C(cd) = result; RETIRE_SUCCESS
B.7.2. SH1ADD (RV32Y/RV64Y)
See SH3ADD (RV32Y/RV64Y).
B.7.3. SH2ADD (RV32Y/RV64Y)
See SH3ADD (RV32Y/RV64Y).
B.7.4. SH3ADD (RV32Y/RV64Y)
- Synopsis
-
Shift by n and add for address generation (SH1ADD, SH2ADD, SH3ADD)
- Mnemonics (RV32Y/RV64Y)
-
sh[1|2|3]add cd, rs1, cs2
- Encoding
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent. |
- Description
-
Copy the capability in
cs2
tocd
.Increment
cd.address
byrs1
shifted left by n bit positions.Set
cd.tag=0
ifcs2
is sealed.Set
cd.tag=0
if the resulting capability cannot be represented exactly.Set
cd.tag=0
ifcs2
's bounds are malformed, or if any of the reserved fields are set.
- Exceptions
-
None
- Prerequisites
-
RV32Y/RV64Y, Zba
- Operation
-
let rs1_val = X(rs1); let cs2_val = C(cs2); let shamt : range(0,3) = match op { RISCV_SH1ADD => 1, RISCV_SH2ADD => 2, RISCV_SH3ADD => 3, }; let result = incCapAddrChecked(cs2_val, rs1_val << shamt); C(cd) = result; RETIRE_SUCCESS
B.7.5. SH1ADD.UW (RV64Y)
See SH3ADD.UW (RV64Y).
B.7.6. SH2ADD.UW (RV64Y)
See SH3ADD.UW (RV64Y).
B.7.7. SH3ADD.UW (RV64Y)
- Synopsis
-
Shift by n and add unsigned word for address generation (SH1ADD.UW, SH2ADD.UW, SH3ADD.UW)
- Mnemonics (RV64Y)
-
sh[1|2|3]add.uw cd, rs1, cs2
- Encoding
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent. |
- Description
-
Copy the capability in
cs2
tocd
.Increment
cd.address
by the unsigned wordrs1
shifted left by n bit positions.Set
cd.tag=0
ifcs2
is sealed.Set
cd.tag=0
if the resulting capability cannot be represented exactly.Set
cd.tag=0
ifcs2
's bounds are malformed, or if any of the reserved fields are set.
- Prerequisites
-
RV64, RV32Y/RV64Y, Zba
- Operation
-
let rs1_val = X(rs1); let cs2_val = C(cs2); let shamt : range(0,3) = match op { RISCV_ADDUW => 0, RISCV_SH1ADDUW => 1, RISCV_SH2ADDUW => 2, RISCV_SH3ADDUW => 3, }; let result = incCapAddrChecked(cs2_val, zero_extend(rs1_val[31..0]) << shamt); C(cd) = result; RETIRE_SUCCESS
B.8. "Zish4add" Extension
B.8.1. SH4ADD
- Synopsis
-
Shift by 4 and add for address generation (SH4ADD)
- Mnemonic (RV64Y)
-
sh4add cd, rs1, cs2
- Mnemonic (RV64I)
-
sh4add rd, rs1, rs2
- Encoding
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent. |
- RV64Y Description
-
Copy the capability in
cs2
tocd
.Increment
cd.address
byrs1
shifted left by 4 bit positions.Set
cd.tag=0
ifcs2
is sealed.Set
cd.tag=0
if the resulting capability cannot be represented exactly.Set
cd.tag=0
ifcs2
's bounds are malformed, or if any of the reserved fields are set. - RV64I Description
-
Increment
rs2
byrs1
shifted left by 4 bit positions and write the result tord
.
- Prerequisites for RV64Y
-
Zish4add
- Prerequisites for RV64I
-
Zish4add
- RV64Y Operation
-
let rs1_val = X(rs1); let cs2_val = C(cs2); let shamt = 4; let result = incCapAddrChecked(cs2_val, rs1_val << shamt); C(cd) = result; RETIRE_SUCCESS
- RV64I Operation
-
let rs1_val = X(rs1); let rs2_val = X(rs2); let shamt = 4; let result = (rs1_val << shamt) + rs2_val; X(rd) = result; RETIRE_SUCCESS
B.8.2. SH4ADD.UW
- Synopsis
-
Shift by 4 and add unsigned words for address generation (SH4ADD.UW)
- Mnemonic (RV64Y)
-
sh4add.uw cd, rs1, cs2
- Mnemonic (RV64I)
-
sh4add.uw rd, rs1, rs2
- Encoding
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent. |
- RV64Y Description
-
Copy the capability in
cs2
tocd
.Increment
cd.address
by the unsigned word inrs1
shifted left by 4 bit positions.Set
cd.tag=0
ifcs2
is sealed.Set
cd.tag=0
if the resulting capability cannot be represented exactly.Set
cd.tag=0
ifcs2
's bounds are malformed, or if any of the reserved fields are set. - RV64I Description
-
Increment
rs2
by the unsigned word inrs1
shifted left by 4 bit positions and write the result tord
.
- Prerequisites for RV64Y
-
RV64Y, Zish4add
- Prerequisites for RV64I
-
RV64, Zish4add
- RV64Y} Operation
-
let rs1_val = X(rs1); let cs2_val = C(cs2); let shamt = 4; let result = incCapAddrChecked(cs2_val, zero_extend(rs1_val[31..0]) << shamt); C(cd) = result; RETIRE_SUCCESS
- RV64I Operation
-
let rs1_val = X(rs1); let rs2_val = X(rs2); let shamt = 4; let result : xlenbits = (zero_extend(rs1_val[31..0]) << shamt) + rs2_val; X(rd) = result; RETIRE_SUCCESS
B.9. "Zcmp" Standard Extension For Code-Size Reduction
The push (CM.PUSH (RV32Y)) and pop (CM.POP ({cheri_base32ext_name}), CM.POPRET (RV32Y), CM.POPRETZ (RV32Y)) instructions are redefined in Capability Pointer Mode to save/restore capability data.
The double move instructions (CM.MVSA01 (RV32Y), CM.MVA01S (RV32Y)) are redefined in Capability Pointer Mode to move capability data between registers. The saved register mapping is as shown in Table 48.
saved register specifier | xreg | integer ABI | CHERI ABI |
---|---|---|---|
0 |
x8 |
s0 |
cs0 |
1 |
x9 |
s1 |
cs1 |
2 |
x18 |
s2 |
cs2 |
3 |
x19 |
s3 |
cs3 |
4 |
x20 |
s4 |
cs4 |
5 |
x21 |
s5 |
cs5 |
6 |
x22 |
s6 |
cs6 |
7 |
x23 |
s7 |
cs7 |
All instructions are defined in (RISC-V, 2023).
B.9.1. CM.PUSH (RV32Y)
- Synopsis
-
Create stack frame (CM.PUSH): store the return address register and 0 to 12 saved registers to the stack frame, optionally allocate additional stack space. 16-bit encoding.
- Mnemonic
-
cm.push {creg_list}, -stack_adj
- Encoding
NOTE: For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent. |
rlist values 0 to 3 are reserved for a future EABI variant
- Description
-
Create stack frame, store capability registers as specified in creg_list using SC semantics.
Optionally allocate additional multiples of 16-byte stack space in
csp
.All accesses are authorized against
csp
.
This encoding is not available in RV64Y, it is remapped to C.SCSP |
If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the table access is checked against pcc bounds.
- Prerequisites
-
C or Zca, RV32Y/RV64Y, Zcmp
- Operation
TBD
B.9.2. CM.POP (RV32Y)
- Synopsis
-
Destroy stack frame (CM.POP): load the return address register and 0 to 12 saved registers from the stack frame, deallocate the stack frame. 16-bit encodings.
- Mnemonic
-
cm.pop {creg_list}, -stack_adj
- Encoding
rlist values 0 to 3 are reserved for a future EABI variant |
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent. |
- Description
-
Load capability registers as specified in creg_list using LC semantics.
Deallocate stack frame.
All accesses are authorized by
csp
.
This encoding is not available in RV64Y, it is remapped to C.SCSP |
If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the table access is checked against pcc bounds.
- Prerequisites
-
C or Zca, RV32Y/RV64Y, Zcmp
- Operation
TBD
B.9.3. CM.POPRET (RV32Y)
- Synopsis
-
Destroy stack frame (CM.POPRET): load the return address register and 0 to 12 saved registers from the stack frame, deallocate the stack frame. Return through the return address register. 16-bit encodings.
- Mnemonic
-
cm.popret {creg_list}, -stack_adj
- Encoding
rlist values 0 to 3 are reserved for a future EABI variant |
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent. |
- Description
-
Load capability registers as specified in creg_list using LC semantics.
Deallocate stack frame.
Return by calling JALR (RV32Y/RV64Y) to
cra
.All data accesses are authorized by
csp
.The return destination is authorized by
cra
.
This encoding is not available in RV64Y, it is remapped to C.SCSP |
If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the table access is checked against pcc bounds.
- Prerequisites
-
C or Zca, RV32Y/RV64Y, Zcmp
- Operation
TBD
B.9.4. CM.POPRETZ (RV32Y)
- Synopsis
-
Destroy stack frame (CM.POPRETZ): load the return address register and register 0 to 12 saved registers from the stack frame, deallocate the stack frame. Move zero into argument register zero. Return through the return address register. 16-bit encoding.
- Mnemonic
-
cm.popretz {creg_list}, -stack_adj
- Encoding
rlist values 0 to 3 are reserved for a future EABI variant |
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent. |
- Description
-
Load capability registers as specified in creg_list using LC semantics.
Deallocate stack frame.
Move zero into
ca0
.Return by calling JALR (RV32Y/RV64Y) to
cra
.All data accesses are authorized by
csp
.The return destination is authorized by
cra
.
This encoding is not available in RV64Y, it is remapped to C.SCSP |
If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the table access is checked against pcc bounds.
- Prerequisites
-
C or Zca, RV32Y/RV64Y, Zcmp for Capability Pointer Mode
- Operation
TBD
B.9.5. CM.MVSA01 (RV32Y)
- Synopsis
-
CM.MVSA01: Move argument registers 0 and 1 into two saved registers. 16-bit encoding.
- Mnemonic
-
cm.mvsa01 c1s', c2s'
- Encoding
The encoding uses sreg number specifiers instead of xreg number specifiers to save encoding space. The saved register encoding is shown in Table 48. |
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent. |
- Description
-
Atomically move two saved capability registers
cs0-cs7
intoca0
andca1
.
This encoding is not available in RV64Y, it is remapped to C.SCSP |
If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the table access is checked against pcc bounds.
- Prerequisites
-
C or Zca, RV32Y/RV64Y, Zcmp
- Operation
TBD
B.9.6. CM.MVA01S (RV32Y)
- Synopsis
-
Move two saved registers into argument registers 0 and 1. 16-bit encoding.
- Mnemonic
-
cm.mva01s c1s', c2s'
- Encoding
The encoding uses sreg number specifiers instead of xreg number specifiers to save encoding space. The saved register encoding is shown in Table 48. |
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent. |
- Description
-
Atomically move two capability registers
ca0
andca1
intocs0-cs7
.
This encoding is not available in RV64Y, it is remapped to C.SCSP |
If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the table access is checked against pcc bounds.
- Prerequisites
-
C or Zca, RV32Y/RV64Y, Zcmp
- Operation
TBD
B.10. "Zcmt" Standard Extension For Code-Size Reduction
The table jump instructions (CM.JT (RV32Y), CM.JALT (RV32Y)) defined in (RISC-V, 2023) are not redefined in Capability Pointer Mode to have capabilities in the jump table. This is to prevent the code-size growth caused by doubling the size of the jump table.
In the future, new jump table modes or new encodings can be added to have capabilities in the jump table.
The jump vector table CSR jvt (RV32Y/RV64Y) has a capability alias jvtc so that it can only be configured to point to accessible memory. All accesses to the jump table are checked against jvtc in Capability Pointer Mode, and against pcc bounds in Integer Pointer Mode. This allows the jump table to be accessed when the pcc bounds are set narrowly to the local function only in Capability Pointer Mode.
In Capability Pointer Mode the instruction fetch bounds check is authorized by two different capabilities - jvtc for the table access and pcc for the CM.JALT (RV32Y)/CM.JT (RV32Y) instruction, and target instruction. |
In Capability Pointer Mode the implementation doesn’t need to expand and bounds check against jvtc on every access, it is sufficient to decode the valid accessible range of entries after every write to jvtc, and then check that the accessed entry is in that range. |
B.10.1. Jump Vector Table CSR (jvt) (RV32Y/RV64Y)
The JVT CSR is exactly as defined by (RISC-V, 2023). It is extended to jvtc.
B.10.2. Jump Vector Table CSR (jvtc)
jvtc extends the Zcmt jvt (RV32Y/RV64Y) CSR to be CLEN-bits.
All instruction fetches from the jump vector table are checked against jvtc in Capability Pointer Mode. In Integer Pointer Mode the address field gives the base address of the table, and the access is checked against pcc bounds.
See CM.JALT (RV32Y), CM.JT (RV32Y).
If the access to the jump table succeeds, then the instructions execute as follows:
-
CM.JT (RV32Y) executes as J or AUIPC+JR
-
CM.JALT (RV32Y) executes as JAL or AUIPC+JALR
As a result the capability metadata is retained in pcc during execution.
B.10.3. CM.JALT (RV32Y)
- Synopsis
-
Jump via table with link (CM.JALT), 16-bit encodings
- Mnemonic (RV32)
-
cm.jalt index
- Encoding
For this encoding to decode as CM.JALT (RV32Y), index≥32, otherwise it decodes as CM.JT (RV32Y). |
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent. |
- Description (RV32Y)
-
Redirect instruction fetch via the jump table defined by the indexing via
jvtc.address+ index*XLEN/8
, checking every byte of the jump table access against jvtc bounds (not against pcc) and requiring X-permission. Link tocra
.
This encoding is not available in RV64Y, it is remapped to C.SCSP |
If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the table access is checked against pcc bounds.
- Permissions (RV32Y)
-
Requires jvtc to have its valid tag set, not be sealed, have X-permission and for the full XLEN-wide table access to be in jvtc bounds.
- Exceptions (RV32Y)
-
CHERI instruction fetch fault can be caused for one the following reasons:
Kind Tag violation
✔
Seal violation
✔
Permission violation
✔
Bounds violation
✔
- Prerequisites for (RV32Y)
-
C or Zca, RV32Y/RV64Y, Zcmt
- Operation
TBD
B.10.4. CM.JT (RV32Y)
- Synopsis
-
Jump via table with link (CM.JT), 16-bit encodings
- Mnemonic (RV32)
-
cm.jt index
- Encoding
For this encoding to decode as CM.JT (RV32Y), index<32, otherwise it decodes as CM.JALT (RV32Y). |
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent. |
- Description (RV32Y)
-
Redirect instruction fetch via the jump table defined by the indexing via
jvtc.address+ index*XLEN/8
, checking every byte of the jump table access against jvtc bounds (not against pcc) and requiring X-permission.
This encoding is not available in RV64Y, it is remapped to C.SCSP |
If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the table access is checked against pcc bounds.
- Permissions (RV32Y)
-
Requires jvtc to have its valid tag set, not be sealed, have X-permission and for the full XLEN-wide table access to be in jvtc bounds.
- Exceptions (RV32Y)
-
CHERI instruction fetch fault can be caused for one the following reasons:
Kind Tag violation
✔
Seal violation
✔
Permission violation
✔
Bounds violation
✔
- Prerequisites for (RV32Y)
-
C or Zca, RV32Y/RV64Y, Zcmt
- Operation
TBD
Appendix C: Control and Status Registers (CSRs) overview
Smcheri and Sscheri extend the CSRs listed in Table 49, Table 50, Table 51, Table 52 and Table 53 from the base RISC-V ISA and its extensions. The CSRs are renamed to reflect the fact that they are extended to CLEN-bits wide, as the x registers are renamed to c registers. Even though the CSR is extended, the CSR index remains identical.
If Zcherihybrid is supported then the CHERI Execution Mode determines whether CLEN or XLEN-bits are returned (see CSRRW (RV32Y/RV64Y)). |
RV32Y/RV64Y CSR | Address | Extended CSR | Prerequisites | Permissions | Description |
---|---|---|---|---|---|
0x7b1 |
Sdext |
DRW |
Debug Program Counter Capability |
||
0x7b2 |
Sdext |
DRW |
Debug Scratch Capability 0 |
||
0x7b3 |
Sdext |
DRW |
Debug Scratch Capability 1 |
RV32Y/RV64Y CSR | Address | Extended CSR | Prerequisites | Permissions | Description |
---|---|---|---|---|---|
0x305 |
M-mode |
MRW, ASR-permission |
Machine Trap-Vector Base-Address Capability |
||
0x340 |
M-mode |
MRW, ASR-permission |
Machine Scratch Capability |
||
0x341 |
M-mode |
MRW, ASR-permission |
Machine Exception Program Counter Capability |
||
0x780 |
Zstid |
Read: M, Write: M, ASR-permission |
Machine thread ID |
RV32Y/RV64Y CSR | Address | Extended CSR | Prerequisites | Permissions | Description |
---|---|---|---|---|---|
0x105 |
S-mode |
SRW, ASR-permission |
Supervisor Trap-Vector Base-Address Capability |
||
0x140 |
S-mode |
SRW, ASR-permission |
Supervisor Scratch Capability |
||
0x141 |
S-mode |
SRW, ASR-permission |
Supervisor Exception Program Counter Capability |
||
0x580 |
Zstid |
Read: S, Write: S, ASR-permission |
Supervisor thread ID |
RV32Y/RV64Y CSR | Address | Extended CSR | Prerequisites | Permissions | Description |
---|---|---|---|---|---|
0x205 |
H |
HRW, ASR-permission |
Virtual Supervisor Trap-Vector Base-Address Capability |
||
0x240 |
H |
HRW, ASR-permission |
Virtual Supervisor Scratch Capability |
||
0x241 |
H |
HRW, ASR-permission |
Virtual Supervisor Exception Program Counter Capability |
RV32Y/RV64Y CSR | Address | Extended CSR | Prerequisites | Permissions | Description |
---|---|---|---|---|---|
0x017 |
Zcmt |
URW |
Jump Vector Table Capability |
||
0x480 |
Zstid |
Read: U, Write: U, ASR-permission |
User thread ID |
Appendix D: CHERI System Implications
Unclear if this chapter will appear in the priv spec. May just be in the standalone spec. |
CHERI processors need memory systems which support the capability valid tags in memory.
There are, or will soon be, a wide range of CHERI systems in existence from tiny IoT devices up to server chips.
There are two types of bus connections used in SoCs which contain CHERI CPUs:
-
Tag-aware busses, where the bus protocol is extended to carry the valid tag along with the data. This is typically done using user defined bits in the protocol.
-
These busses will read tags from memory (if tags are present in the target memory) and return them to the requestor.
-
These busses will write the valid tag to memory as an extension of the data write.
-
-
Non-tag aware busses, i.e., current non-CHERI aware busses.
-
Reads of tagged memory will not read the valid tag.
-
Writes to tagged memory will clear the valid tag of any CLEN-aligned CLEN-wide memory location where any byte matches the memory write.
-
The fundamental rule for any CHERI system is that the valid tag and data are always accessed atomically. For every naturally aligned CLEN-wide memory location, it must never be possible to:
-
Update any data bytes without also writing the valid tag
-
This implies clearing the valid tag if a non-CHERI aware bus master overwrites a capability in memory
-
-
Read a tagged value with mismatched (stale or newer) data
-
Set the valid tag without also writing the data.
Clearing tags in memory does not necessarily require updating the associated data. |
D.1. Small CHERI system example
This example shows a minimum sized system where only the local memory is extended to support capability valid tags. The valid tag-aware region is highlighted. All tags are created by the CHERI CPU, and only stored locally. The memory is shared with the system, probably via a secure DMA, which is not tag aware.
Therefore the connection between CPU and memory is tag-aware, and the connection to the system is not tag aware.
All writes from the system port to the memory must clear any memory tags to follow the rules from above.
D.2. Large CHERI system example
In the case of a large CHERI SoC with caches, all the cached memory visible to the CHERI CPUs must support tags. All memory is backed up by DRAM, and standard DRAM does not offer the extra bit required for CHERI valid tag storage and so a typical system will have a tag cache IP.
A region of DRAM is typically reserved for CHERI valid tag storage.
The valid tag cache sits on the boundary of the valid tag-aware and non-tag-aware memory domains, and it provides the bridge between the two. It stores tags locally in its cache, and if there is a miss, it will create an extra bus request to access the region of DRAM reserved for tag storage. Therefore in the case of a miss a single access is split into two - one to access the data and one to access the valid tag.
The key property of the valid tag cache is to preserve the atomic access of data and tags in the memory system so that all CPUs have a consistent view of tags and data.
The region of DRAM reserved for tag storage must be only accessible by the valid tag cache, therefore no bus initiators should be able to write to the DRAM without the transactions passing through the valid tag cache.
Therefore the GPUs and peripherals cannot write to the valid tag storage in the DRAM, or the valid tagged memory data storage region. These constraints will be part of the design of the network-on-chip. It is possible for the GPU and peripherals to read the valid tagged memory data storage region of the DRAM, if required.
It would be possible to allow a DMA to access the valid tagged memory region of the DRAM directly to allow swap to/from DRAM and external devices such as flash. This will require the highest level of security in the SoC, as the CHERI protection model relies on the integrity of the valid tags, and so the root-of-trust will need to authenticate and encrypt the transfer, with anti-rollback protection. |
For further information on the valid tag cache see (Efficient Tagged Memory, 2017).
D.3. Large CHERI pure-capability system example
In this example every DRAM access passes through the valid tag cache, and so all bus masters are tag-aware and can access the valid tagged memory if permitted by the network-on-chip.
The system topology is simpler than in Figure 60.
There is likely to be a performance difference between the two systems. The main motivation for Figure 60 is to avoid the GPU DRAM traffic needing to look-up every tag in the valid tag cache, potentially adding overhead to every transaction.
Appendix E: Extension summary
E.1. Zabhlrsc
Zabhlrsc is a separate extension independent of CHERI, but is required for CHERI software.
Mnemonic | Zabhlrsc | Function |
---|
E.2. RV32Y/RV64Y
RV32Y/RV64Y defines the set of instructions supported by a core when in Capability Pointer Mode.
Some instructions depend on the presence of other extensions, as listed in Table 55.
Mnemonic | RV32 | RV64 | A | Zabhlrsc | Zicbo[mpz] | C or Zca | Zba | Zcb | Zcmp | Zcmt | Zfh | F | D | V | Function |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
✔ |
✔ |
Load capability |
|||||||||||||
✔ |
✔ |
Store capability |
|||||||||||||
✔ |
✔ |
✔ |
Load capability, SP relative |
||||||||||||
✔ |
✔ |
✔ |
Store capability, SP relative |
||||||||||||
✔ |
✔ |
✔ |
Load capability |
||||||||||||
✔ |
✔ |
✔ |
Store capability |
||||||||||||
✔ |
✔ |
✔ |
Load word, SP relative |
||||||||||||
✔ |
✔ |
✔ |
Store word, SP relative |
||||||||||||
✔ |
✔ |
✔ |
Load word |
||||||||||||
✔ |
✔ |
✔ |
Store word |
||||||||||||
✔ |
✔ |
Load double |
|||||||||||||
✔ |
✔ |
Store double |
|||||||||||||
✔ |
✔ |
Load double, SP relative |
|||||||||||||
✔ |
✔ |
Store double, SP relative |
|||||||||||||
✔ |
✔ |
Add immediate to PCC address |
|||||||||||||
✔ |
✔ |
Increment capability address by register, representability check |
|||||||||||||
✔ |
✔ |
Increment capability address by immediate, representability check |
|||||||||||||
✔ |
✔ |
Replace capability address, representability check |
|||||||||||||
✔ |
✔ |
Get valid tag field |
|||||||||||||
✔ |
✔ |
Get hperm and uperm fields as 1-bit per permission, packed together |
|||||||||||||
✔ |
✔ |
Move capability register |
|||||||||||||
✔ |
✔ |
AND capability permissions (expand to 1-bit per permission before ANDing) |
|||||||||||||
✔ |
✔ |
Get metadata |
|||||||||||||
✔ |
✔ |
Set metadata and clear valid tag |
|||||||||||||
✔ |
✔ |
Full capability bitwise compare, set result true if both are fully equal |
|||||||||||||
✔ |
✔ |
Seal capability |
|||||||||||||
✔ |
✔ |
Set result true if cs1 and cs1 valid tags match and cs2 bounds and permissions are a subset of cs1 |
|||||||||||||
✔ |
✔ |
Set cd to cs2 with its valid tag set after checking that cs2 is a subset of cs1 |
|||||||||||||
✔ |
✔ |
Set register bounds on capability with rounding, clear valid tag if rounding is required |
|||||||||||||
✔ |
✔ |
Set immediate bounds on capability with rounding, clear valid tag if rounding is required |
|||||||||||||
✔ |
✔ |
Set bounds on capability with rounding up as required |
|||||||||||||
✔ |
✔ |
Representable Alignment Mask: Return mask to apply to address to get the requested bounds |
|||||||||||||
✔ |
✔ |
Get capability base |
|||||||||||||
✔ |
✔ |
Get capability length |
|||||||||||||
✔ |
✔ |
Get capability type |
|||||||||||||
✔ |
✔ |
✔ |
ADD immediate to stack pointer in Integer Pointer Mode, CADD |
||||||||||||
✔ |
✔ |
✔ |
ADD immediate to stack pointer in Integer Pointer Mode, CADD |
||||||||||||
✔ |
✔ |
✔ |
Integer register move in Integer Pointer Mode, capability register move |
||||||||||||
✔ |
✔ |
✔ |
Jump to PC+offset, bounds check minimum size target instruction |
||||||||||||
✔ |
✔ |
Jump to PC+offset, bounds check minimum size target instruction, link to cd |
|||||||||||||
✔ |
✔ |
✔ |
Jump to PC+offset, bounds check minimum size target instruction, link to cd |
||||||||||||
✔ |
✔ |
Indirect jump and link, bounds check minimum size target instruction. set PCC=unseal(cs1),cd=seal(nextPCC) |
|||||||||||||
✔ |
✔ |
✔ |
Indirect jump and link, bounds check minimum size target instruction. set PCC=unseal(cs1),cd=seal(nextPCC) |
||||||||||||
✔ |
✔ |
✔ |
Indirect jump, bounds check minimum size target instruction. set PCC=unseal(cs1) |
||||||||||||
✔ |
✔ |
Return from debug mode, sets ddc from dddc and pcc from dpcc |
|||||||||||||
✔ |
✔ |
Return from machine mode handler, sets pcc from mtvecc , needs ASR-permission |
|||||||||||||
✔ |
✔ |
Return from supervisor mode handler, sets pcc from stvecc, needs ASR-permission |
|||||||||||||
✔ |
✔ |
CSR write - can also read/write a full capability through an address alias |
|||||||||||||
✔ |
✔ |
CSR set - can also read/write a full capability through an address alias |
|||||||||||||
✔ |
✔ |
CSR clear - can also read/write a full capability through an address alias |
|||||||||||||
✔ |
✔ |
CSR write - can also read/write a full capability through an address alias |
|||||||||||||
✔ |
✔ |
CSR set - can also read/write a full capability through an address alias |
|||||||||||||
✔ |
✔ |
CSR clear - can also read/write a full capability through an address alias |
|||||||||||||
✔ |
✔ |
✔ |
Cache block invalidate (implemented as clean) |
||||||||||||
✔ |
✔ |
✔ |
Cache block clean |
||||||||||||
✔ |
✔ |
✔ |
Cache block flush |
||||||||||||
✔ |
✔ |
✔ |
Cache block zero |
||||||||||||
✔ |
✔ |
✔ |
Prefetch instruction cache line, always valid |
||||||||||||
✔ |
✔ |
✔ |
Prefetch read-only data cache line |
||||||||||||
✔ |
✔ |
✔ |
Prefetch writeable data cache line |
||||||||||||
✔ |
✔ |
✔ |
Load reserved capability |
||||||||||||
✔ |
✔ |
✔ |
Store conditional capability |
||||||||||||
✔ |
✔ |
✔ |
Atomic swap of cap |
||||||||||||
✔ |
✔ |
Load floating point double |
|||||||||||||
✔ |
✔ |
Load floating point double, sp relative |
|||||||||||||
✔ |
✔ |
Store floating point double |
|||||||||||||
✔ |
✔ |
Store floating point double, sp relative |
|||||||||||||
✔ |
✔ |
✔ |
Push integer stack frame |
||||||||||||
✔ |
✔ |
✔ |
Pop integer stack frame |
||||||||||||
✔ |
✔ |
✔ |
Pop integer stack frame and return |
||||||||||||
✔ |
✔ |
✔ |
Pop integer stack frame and return zero |
||||||||||||
✔ |
✔ |
✔ |
Move two integer registers |
||||||||||||
✔ |
✔ |
✔ |
Move two integer registers |
||||||||||||
✔ |
✔ |
✔ |
Table jump and link |
||||||||||||
✔ |
✔ |
✔ |
Table jump |
||||||||||||
✔ |
✔ |
add unsigned words, representability check |
|||||||||||||
✔ |
✔ |
✔ |
shift and add, representability check |
||||||||||||
✔ |
✔ |
shift and add unsigned words, representability check |
|||||||||||||
✔ |
✔ |
✔ |
shift and add, representability check |
||||||||||||
✔ |
✔ |
shift and add unsigned words, representability check |
|||||||||||||
✔ |
✔ |
✔ |
shift and add, representability check |
||||||||||||
✔ |
✔ |
shift and add unsigned words, representability check |
|||||||||||||
✔ |
shift and add, representability check |
||||||||||||||
✔ |
shift and add unsigned words, representability check |
||||||||||||||
✔ |
✔ |
Hypervisor virtual machine load capability |
|||||||||||||
✔ |
✔ |
Hypervisor virtual machine store capability |
E.3. Zcherihybrid
Zcherihybrid defines the set of instructions added by the Integer Pointer Mode, in addition to RV32Y/RV64Y.
Zcherihybrid implies RV32Y/RV64Y |
Mnemonic | RV32 | RV64 | A | Zabhlrsc | Zicbo[mpz] | C or Zca | Zba | Zcb | Zcmp | Zcmt | Zfh | F | D | V | Function |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
✔ |
✔ |
Set the mode bit of a capability, no permissions required |
|||||||||||||
✔ |
✔ |
Get the mode bit of a capability, no permissions required |
|||||||||||||
✔ |
✔ |
Directly switch mode into Capability Pointer Mode |
|||||||||||||
✔ |
✔ |
Directly switch mode into Integer Pointer Mode |
|||||||||||||
✔ |
✔ |
Load floating point word capability |
|||||||||||||
✔ |
✔ |
Load floating point word, sp relative |
|||||||||||||
✔ |
✔ |
Store floating point word capability |
|||||||||||||
✔ |
✔ |
Store floating point word, sp relative |
|||||||||||||
✔ |
✔ |
Load floating point double |
|||||||||||||
✔ |
✔ |
Load floating point double, sp relative |
|||||||||||||
✔ |
✔ |
Store floating point double |
|||||||||||||
✔ |
✔ |
Store floating point double, sp relative |
Appendix F: Capability Width CSR Summary
CLEN CSR | Alias | Prerequisites |
---|---|---|
Sdext |
||
Sdext |
||
Sdext |
||
M-mode |
||
M-mode |
||
M-mode |
||
S-mode |
||
S-mode |
||
S-mode |
||
H |
||
H |
||
H |
||
Zcmt |
||
Zstid |
||
Zstid |
||
Zstid |
||
Zstid |
CLEN CSR | Action on XLEN write | Action on CLEN write |
---|---|---|
Apply Invalid address conversion. Always update the CSR with SCADDR even if the address didn’t change. |
Apply Invalid address conversion and update the CSR with the result if the address changed, direct write if address didn’t change |
|
Update the CSR using SCADDR. |
direct write |
|
Update the CSR using SCADDR. |
direct write |
|
Apply Invalid address conversion. Always update the CSR with SCADDR even if the address didn’t change, including the MODE field in the address for simplicity. Vector range check * if vectored mode is programmed. |
Apply Invalid address conversion. Always update the CSR with SCADDR even if the address didn’t change, including the MODE field in the address for simplicity. Vector range check * if vectored mode is programmed. |
|
Update the CSR using SCADDR. |
direct write |
|
Apply Invalid address conversion. Always update the CSR with SCADDR even if the address didn’t change. |
Apply Invalid address conversion and update the CSR with the result if the address changed, direct write if address didn’t change |
|
Apply Invalid address conversion. Always update the CSR with SCADDR even if the address didn’t change, including the MODE field in the address for simplicity. Vector range check * if vectored mode is programmed. |
Apply Invalid address conversion. Always update the CSR with SCADDR even if the address didn’t change, including the MODE field in the address for simplicity. Vector range check * if vectored mode is programmed. |
|
Update the CSR using SCADDR. |
direct write |
|
Apply Invalid address conversion. Always update the CSR with SCADDR even if the address didn’t change. |
Apply Invalid address conversion and update the CSR with the result if the address changed, direct write if address didn’t change |
|
Apply Invalid address conversion. Always update the CSR with SCADDR even if the address didn’t change, including the MODE field in the address for simplicity. Vector range check * if vectored mode is programmed. |
Apply Invalid address conversion. Always update the CSR with SCADDR even if the address didn’t change, including the MODE field in the address for simplicity. Vector range check * if vectored mode is programmed. |
|
Update the CSR using SCADDR. |
direct write |
|
Apply Invalid address conversion. Always update the CSR with SCADDR even if the address didn’t change. |
Apply Invalid address conversion and update the CSR with the result if the address changed, direct write if address didn’t change |
|
Apply Invalid address conversion. Always update the CSR with SCADDR even if the address didn’t change. |
Apply Invalid address conversion and update the CSR with the result if the address changed, direct write if address didn’t change |
|
Update the CSR using SCADDR. |
direct write |
|
Update the CSR using SCADDR. |
direct write |
|
Update the CSR using SCADDR. |
direct write |
|
Update the CSR using SCADDR. |
direct write |
* The vector range check is to ensure that vectored entry to the handler
is within bounds of the capability written to Xtvecc
. The check on writing
must include the lowest (0 offset) and highest possible offset (e.g., 64 * MXLEN-bits where HICAUSE=16).
XLEN-bits of extended CLEN-wide CSRs are written when executing CSRRWI (RV32Y/RV64Y), CSRRC (RV32Y/RV64Y), CSRRS (RV32Y/RV64Y), CSRRCI (RV32Y/RV64Y) or CSRRSI (RV32Y/RV64Y) regardless of the CHERI execution mode. When using CSRRW (RV32Y/RV64Y), CLEN-bits are written when the CHERI execution mode is Capability Pointer Mode and XLEN-bits are written when the mode is Integer Pointer Mode; therefore, writing XLEN-bits with CSRRW (RV32Y/RV64Y) is only possible when Zcherihybrid is implemented.
CLEN CSR | Action on XLEN write | Action on CLEN write |
---|---|---|
Apply Invalid address conversion. Always update the CSR with SCADDR even if the address didn’t change. |
Apply Invalid address conversion and update the CSR with the result if the address changed, direct write if address didn’t change |
|
Apply Invalid address conversion. Always update the CSR with SCADDR even if the address didn’t change. |
Apply Invalid address conversion and update the CSR with the result if the address changed, direct write if address didn’t change |
|
Ignore |
Ignore |
XLEN-bits of CLEN-wide CSRs added in Zcherihybrid are written when executing CSRRWI (RV32Y/RV64Y), CSRRC (RV32Y/RV64Y), CSRRS (RV32Y/RV64Y), CSRRCI (RV32Y/RV64Y) or CSRRSI (RV32Y/RV64Y) regardless of the CHERI execution mode. CLEN-bits are always written when using CSRRW (RV32Y/RV64Y) regardless of the CHERI execution mode.
Implementations which allow misa.C to be writable need to legalize Xepcc on reading if the misa.C value has changed since the value was written as this can cause the read value of bit [1] to change state. |
CLEN CSR | Code Pointer | Data Pointer | Unseal On Execution |
---|---|---|---|
✔ |
✔ |
||
✔ |
|||
✔ |
✔ |
||
✔ |
|||
✔ |
✔ |
||
✔ |
|||
✔ |
✔ |
||
✔ |
|||
✔ |
|||
✔ |
Some CSRs store code pointers or data pointers as shown in Table 60. These are WARL CSRs that do not need to store full 64-bit addresses on RV64, and so need not be capable of holding all possible invalid addresses. Prior to writing an invalid address to these CSRs, the address must be converted to another invalid address that the CSR is capable of holding. CSRs that store fewer address bits are also subject to the invalid address check in Invalid address conversion on writing.
Table 61 shows all CLEN-wide CSRs.
CLEN CSR | Prerequisites | Address | Permissions | Reset Value | Description |
---|---|---|---|---|---|
Sdext |
0x7b1 |
DRW |
tag=0, otherwise undefined |
Debug Program Counter Capability |
|
Sdext |
0x7b2 |
DRW |
tag=0, otherwise undefined |
Debug Scratch Capability 0 |
|
Sdext |
0x7b3 |
DRW |
tag=0, otherwise undefined |
Debug Scratch Capability 1 |
|
M-mode |
0x305 |
MRW, ASR-permission |
Machine Trap-Vector Base-Address Capability |
||
M-mode |
0x340 |
MRW, ASR-permission |
tag=0, otherwise undefined |
Machine Scratch Capability |
|
M-mode |
0x341 |
MRW, ASR-permission |
Machine Exception Program Counter Capability |
||
S-mode |
0x105 |
SRW, ASR-permission |
Supervisor Trap-Vector Base-Address Capability |
||
S-mode |
0x140 |
SRW, ASR-permission |
tag=0, otherwise undefined |
Supervisor Scratch Capability |
|
S-mode |
0x141 |
SRW, ASR-permission |
Supervisor Exception Program Counter Capability |
||
H |
0x205 |
HRW, ASR-permission |
Virtual Supervisor Trap-Vector Base-Address Capability |
||
H |
0x240 |
HRW, ASR-permission |
tag=0, otherwise undefined |
Virtual Supervisor Scratch Capability |
|
H |
0x241 |
HRW, ASR-permission |
Virtual Supervisor Exception Program Counter Capability |
||
Zcmt |
0x017 |
URW |
tag=0, otherwise undefined |
Jump Vector Table Capability |
|
Zcherihybrid, Sdext |
0x7bc |
DRW |
tag=0, otherwise undefined |
Debug Default Data Capability (saved/restored on debug mode entry/exit) |
|
Zcherihybrid |
0x416 |
URW |
User Default Data Capability |
||
Sdext |
0x7bd |
DRW |
Source of Infinite capability in debug mode, writes are ignored |
||
Zstid |
0x480 |
Read: U, Write: U, ASR-permission |
tag=0, otherwise undefined |
User thread ID |
|
Zstid |
0x580 |
Read: S, Write: S, ASR-permission |
tag=0, otherwise undefined |
Supervisor thread ID |
|
Zstid |
0xA80 |
Read: VS, Write: VS, ASR-permission |
tag=0, otherwise undefined |
Virtual supervisor thread ID |
|
Zstid |
0x780 |
Read: M, Write: M, ASR-permission |
tag=0, otherwise undefined |
Machine thread ID |
Appendix G: Instructions and CHERI Execution Mode
Table 62, Table 63 and Table 64 summarize on which CHERI Execution Mode each instruction may be executed in.
Mnemonic | Zcherihybrid | RV32Y/RV64Y | Function |
---|---|---|---|
✔ |
Load capability, SP relative |
||
✔ |
Store capability, SP relative |
||
✔ |
Load capability |
||
✔ |
Store capability |
Mnemonic | Zcherihybrid | RV32Y/RV64Y | Function |
---|---|---|---|
✔ |
Load floating point word capability |
||
✔ |
Load floating point word, sp relative |
||
✔ |
Store floating point word capability |
||
✔ |
Store floating point word, sp relative |
||
✔ |
Load floating point double |
||
✔ |
Load floating point double, sp relative |
||
✔ |
Store floating point double |
||
✔ |
Store floating point double, sp relative |
Mnemonic | Zcherihybrid | RV32Y/RV64Y | Function |
---|---|---|---|
✔ |
✔ |
Load capability |
|
✔ |
✔ |
Store capability |
|
✔ |
✔ |
Load word, SP relative |
|
✔ |
✔ |
Store word, SP relative |
|
✔ |
✔ |
Load word |
|
✔ |
✔ |
Store word |
|
✔ |
✔ |
Load double |
|
✔ |
✔ |
Store double |
|
✔ |
✔ |
Load double, SP relative |
|
✔ |
✔ |
Store double, SP relative |
|
✔ |
✔ |
Add immediate to PCC address |
|
✔ |
✔ |
Increment capability address by register, representability check |
|
✔ |
✔ |
Increment capability address by immediate, representability check |
|
✔ |
✔ |
Replace capability address, representability check |
|
✔ |
✔ |
Get valid tag field |
|
✔ |
✔ |
Get hperm and uperm fields as 1-bit per permission, packed together |
|
✔ |
✔ |
Move capability register |
|
✔ |
✔ |
AND capability permissions (expand to 1-bit per permission before ANDing) |
|
✔ |
✔ |
Get metadata |
|
✔ |
✔ |
Set metadata and clear valid tag |
|
✔ |
✔ |
Full capability bitwise compare, set result true if both are fully equal |
|
✔ |
✔ |
Seal capability |
|
✔ |
✔ |
Set result true if cs1 and cs1 valid tags match and cs2 bounds and permissions are a subset of cs1 |
|
✔ |
✔ |
Set cd to cs2 with its valid tag set after checking that cs2 is a subset of cs1 |
|
✔ |
✔ |
Set register bounds on capability with rounding, clear valid tag if rounding is required |
|
✔ |
✔ |
Set immediate bounds on capability with rounding, clear valid tag if rounding is required |
|
✔ |
✔ |
Set bounds on capability with rounding up as required |
|
✔ |
✔ |
Representable Alignment Mask: Return mask to apply to address to get the requested bounds |
|
✔ |
✔ |
Get capability base |
|
✔ |
✔ |
Get capability length |
|
✔ |
✔ |
Get capability type |
|
✔ |
Set the mode bit of a capability, no permissions required |
||
✔ |
Get the mode bit of a capability, no permissions required |
||
✔ |
Directly switch mode into Capability Pointer Mode |
||
✔ |
Directly switch mode into Integer Pointer Mode |
||
✔ |
✔ |
ADD immediate to stack pointer in Integer Pointer Mode, CADD |
|
✔ |
✔ |
ADD immediate to stack pointer in Integer Pointer Mode, CADD |
|
✔ |
✔ |
Integer register move in Integer Pointer Mode, capability register move |
|
✔ |
✔ |
Jump to PC+offset, bounds check minimum size target instruction |
|
✔ |
✔ |
Jump to PC+offset, bounds check minimum size target instruction, link to cd |
|
✔ |
✔ |
Jump to PC+offset, bounds check minimum size target instruction, link to cd |
|
✔ |
✔ |
Indirect jump and link, bounds check minimum size target instruction. set PCC=unseal(cs1),cd=seal(nextPCC) |
|
✔ |
✔ |
Indirect jump and link, bounds check minimum size target instruction. set PCC=unseal(cs1),cd=seal(nextPCC) |
|
✔ |
✔ |
Indirect jump, bounds check minimum size target instruction. set PCC=unseal(cs1) |
|
✔ |
✔ |
Return from debug mode, sets ddc from dddc and pcc from dpcc |
|
✔ |
✔ |
Return from machine mode handler, sets pcc from mtvecc , needs ASR-permission |
|
✔ |
✔ |
Return from supervisor mode handler, sets pcc from stvecc, needs ASR-permission |
|
✔ |
✔ |
CSR write - can also read/write a full capability through an address alias |
|
✔ |
✔ |
CSR set - can also read/write a full capability through an address alias |
|
✔ |
✔ |
CSR clear - can also read/write a full capability through an address alias |
|
✔ |
✔ |
CSR write - can also read/write a full capability through an address alias |
|
✔ |
✔ |
CSR set - can also read/write a full capability through an address alias |
|
✔ |
✔ |
CSR clear - can also read/write a full capability through an address alias |
|
✔ |
✔ |
Cache block invalidate (implemented as clean) |
|
✔ |
✔ |
Cache block clean |
|
✔ |
✔ |
Cache block flush |
|
✔ |
✔ |
Cache block zero |
|
✔ |
✔ |
Prefetch instruction cache line, always valid |
|
✔ |
✔ |
Prefetch read-only data cache line |
|
✔ |
✔ |
Prefetch writeable data cache line |
|
✔ |
✔ |
Load reserved capability |
|
✔ |
✔ |
Store conditional capability |
|
✔ |
✔ |
Atomic swap of cap |
|
✔ |
✔ |
Load floating point double |
|
✔ |
✔ |
Load floating point double, sp relative |
|
✔ |
✔ |
Store floating point double |
|
✔ |
✔ |
Store floating point double, sp relative |
|
✔ |
✔ |
Push integer stack frame |
|
✔ |
✔ |
Pop integer stack frame |
|
✔ |
✔ |
Pop integer stack frame and return |
|
✔ |
✔ |
Pop integer stack frame and return zero |
|
✔ |
✔ |
Move two integer registers |
|
✔ |
✔ |
Move two integer registers |
|
✔ |
✔ |
Table jump and link |
|
✔ |
✔ |
Table jump |
|
✔ |
✔ |
add unsigned words, representability check |
|
✔ |
✔ |
shift and add, representability check |
|
✔ |
✔ |
shift and add unsigned words, representability check |
|
✔ |
✔ |
shift and add, representability check |
|
✔ |
✔ |
shift and add unsigned words, representability check |
|
✔ |
✔ |
shift and add, representability check |
|
✔ |
✔ |
shift and add unsigned words, representability check |
|
✔ |
✔ |
shift and add, representability check |
|
✔ |
✔ |
shift and add unsigned words, representability check |
|
✔ |
✔ |
Hypervisor virtual machine load capability |
|
✔ |
✔ |
Hypervisor virtual machine store capability |
Mnemonic | Integer Pointer Mode mnemonic RV32 | Integer Pointer Mode mnemonic RV64 |
---|---|---|
Mnemonic | Function |
---|---|
Load capability, SP relative |
|
Store capability, SP relative |
|
Load capability |
|
Store capability |
MODESW.CAP, MODESW.INT and SCMODE only exist in Capability Pointer Mode if Integer Pointer Mode is also present. A hart does not support the M-bit if it does not implement the Zcherihybrid extension. |
Mnemonic | illegal insn if (1) | OR illegal insn if (2) | OR illegal insn if (3) |
---|---|---|---|
MODE==D (optional) |
|||
MODE==D (optional) |
|||
MODE==D (optional) |
|||
MODE==D (optional) |
|||
MODE==D (optional) |
|||
MODE==D (optional) |
|||
MODE<D |
|||
MODE<M |
PCC.ASR==0 |
||
MODE<S |
PCC.ASR==0 |
mstatus.TSR==1 AND MODE==S |
|
CSR permission fault |
|||
CSR permission fault |
|||
CSR permission fault |
|||
CSR permission fault |
|||
CSR permission fault |
|||
CSR permission fault |
|||
MODE<M AND menvcfg.CBIE[0]==0 |
MODE<S AND senvcfg.CBIE[0]==0 |
||
MODE<M AND menvcfg.CBIE[0]==0 |
MODE<S AND senvcfg.CBIE[0]==0 |
||
MODE<M AND menvcfg.CBIE[0]==0 |
MODE<S AND senvcfg.CBIE[0]==0 |
||
MODE<M AND menvcfg.CBIE[0]==0 |
MODE<S AND senvcfg.CBIE[0]==0 |
||
Xstatus.fs==0 |
|||
Xstatus.fs==0 |
|||
Xstatus.fs==0 |
|||
Xstatus.fs==0 |
|||
Xstatus.fs==0 |
|||
Xstatus.fs==0 |
|||
Xstatus.fs==0 |
|||
Xstatus.fs==0 |
|||
Xstatus.fs==0 |
|||
Xstatus.fs==0 |
|||
Xstatus.fs==0 |
|||
Xstatus.fs==0 |
|||
V=1 |
MODE==U AND hstatus.HU=0 |
||
V=1 |
MODE==U AND hstatus.HU=0 |
Appendix H: Placeholder references to unprivileged spec
To allow building this document both as an extension to the RISC-V ISA documents and standalone, the following references point to the appropriate chapter in the (un)privileged specification:
- RV32I
-
See Chapter RV32I Base Integer Instruction Set in (RISC-V, 2023).
- General purpose registers
-
See Chapter RV32I Base Integer Instruction Set in (RISC-V, 2023).
- Load and Store Instructions
-
See Chapter RV32I Base Integer Instruction Set in (RISC-V, 2023).
- Integer Register-Immediate Instructions
-
See Chapter RV32I Base Integer Instruction Set in (RISC-V, 2023).
- Control Transfer Instructions
-
See Chapter RV32I Base Integer Instruction Set in (RISC-V, 2023).
- Atomics
-
See Chapter "A" Extension for Atomic Instructions in (RISC-V, 2023).
- Zba
-
See Chapter "B" Extension for Bit Manipulation in (RISC-V, 2023).
Appendix I: Placeholder references to privileged spec
This chapter only exists for the standalone document to allow references to resolve. |
- Control and Status Registers (CSRs) overview
-
See Chapter Control and Status Registers (CSRs) in (RISC-V, 2023).
- Machine Status Registers (mstatus and mstatush)
- Base ISA Control in
mstatus
Register - Endianness Control in
mstatus
andmstatush
Registers -
See
mtatus
in Chapter Machine-Level ISA, Version 1.13 in (RISC-V, 2023).
- Machine Scratch Register (mscratch)
-
See
mscratch
in Chapter Machine-Level ISA, Version 1.13 in (RISC-V, 2023).
- Machine Cause (
mcause
) Register - Synchronous exception priority in decreasing priority order
- Machine cause (
mcause
) register values after trap -
See
mcause
in Chapter Machine-Level ISA, Version 1.13 in (RISC-V, 2023).
mcause
) register.- Machine Trap-Vector Base-Address (
mtvec
) Register -
See
mtvec
in Chapter Machine-Level ISA, Version 1.13 in (RISC-V, 2023).
- Machine Exception Program Counter (mepc)
-
See
mepc
in Chapter Machine-Level ISA, Version 1.13 in (RISC-V, 2023).
- Machine Trap Delegation Register (medeleg)
-
See
medeleg
in Chapter Machine-Level ISA, Version 1.13 in (RISC-V, 2023).
- Machine Trap Value Register (mtval)
-
See
mtval
in Chapter Machine-Level ISA, Version 1.13 in (RISC-V, 2023).
- Machine Security Configuration (
mseccfg
) Register -
See
mseccfg
in Chapter Machine-Level ISA, Version 1.13 in (RISC-V, 2023). Smcheri adds a new CRE bit.
- Machine Environment Configuration (
menvcfg
) Register -
See
menvcfg
in Chapter Machine-Level ISA, Version 1.13 in (RISC-V, 2023). Smcheri adds a new CRE bit.
- Supervisor Trap Vector Base Address (
stvec
) Register -
See
stvec
in Chapter Supervisor-Level ISA, Version 1.13 in (RISC-V, 2023).
stvec
) register.- Supervisor Scratch (
sscratch
) Register -
See
sscratch
in Chapter Supervisor-Level ISA, Version 1.13 in (RISC-V, 2023).
- Supervisor Exception Program Counter (
sepc
) Register -
See
sepc
in Chapter Supervisor-Level ISA, Version 1.13 in (RISC-V, 2023).
- Supervisor Trap Value (
stval
) Register -
See
stval
in Chapter Supervisor-Level ISA, Version 1.13 in (RISC-V, 2023).
- Supervisor Cause (
scause
) Register - .Supervisor cause (
scause
) register values after trap -
See
scause
in Chapter Supervisor-Level ISA, Version 1.13 in (RISC-V, 2023).
scause
) register.- Supervisor Environment Configuration (
senvcfg
) Register -
See
senvcfg
in Chapter Supervisor-Level ISA, Version 1.13 in (RISC-V, 2023). Sscheri adds a new CRE bit.
- Supervisor Status (
sstatus
) Register -
See
sstatus
in Chapter Supervisor-Level ISA, Version 1.13 in (RISC-V, 2023).
Index
Bibliography
Efficient Tagged Memory. (2017). www.cl.cam.ac.uk/research/security/ctsrd/pdfs/201711-iccd2017-efficient-tags.pdf
RISC-V. (2021). RISC-V "V" Vector Extension. github.com/riscv/riscv-v-spec/releases/download/v1.0/riscv-v-spec-1.0.pdf
RISC-V. (2022). RISC-V Debug Specification. github.com/riscv/riscv-debug-spec/raw/c93823ef349286dc71a00928bddb7254e46bc3b5/riscv-debug-stable.pdf
RISC-V. (2023). RISC-V Privileged Specification. github.com/riscv/riscv-isa-manual/releases/download/riscv-isa-release-056b6ff-2023-10-02/priv-isa-asciidoc.pdf
RISC-V. (2023). RISC-V Unprivileged Specification. github.com/riscv/riscv-isa-manual/releases/download/riscv-isa-release-056b6ff-2023-10-02/unpriv-isa-asciidoc.pdf
RISC-V. (2023). RISC-V Code-size Reduction Specification. github.com/riscv/riscv-code-size-reduction/releases/download/v1.0.4-3/Zc-1.0.4-3.pdf
Watson, R. N. M., Neumann, P. G., Woodruff, J., Roe, M., Almatary, H., Anderson, J., Baldwin, J., Barnes, G., Chisnall, D., Clarke, J., Davis, B., Eisen, L., Filardo, N. W., Fuchs, F. A., Grisenthwaite, R., Joannou, A., Laurie, B., Markettos, A. T., Moore, S. W., … Xia, H. (2023). Capability Hardware Enhanced RISC Instructions: CHERI Instruction-Set Architecture (Version 9) (UCAM-CL-TR-987; Issue UCAM-CL-TR-987). University of Cambridge, Computer Laboratory. doi.org/10.48456/tr-987
Woodruff, J., Joannou, A., Xia, H., Fox, A., Norton, R. M., Chisnall, D., Davis, B., Gudka, K., Filardo, N. W., Markettos, A. T., & others. (2019). Cheri concentrate: Practical compressed capabilities. IEEE Transactions on Computers, 68(10), 1455–1469. doi.org/10.1109/TC.2019.2914037