This document is in the Stable state

Assume anything could still change, but limited change should be expected.

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:

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.

The following two extensions are useful independent of CHERI:

Zish4add

Addition of SH4ADD and SH4ADD.UW for RV64 only, as CHERI capabilities are 16 bytes when XLEN=64

Zabhlrsc

Addition of LR.B, LR.H, SC.B, SC.H for more accurate atomic locking as the memory ranges are restricted by using bounds, therefore precise locking is needed.

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.
Table 1. Extension status and summary
Extension Status Comment

RV32Y/RV64Y

Stable

This extension is a candidate for freezing

Zcherihybrid

Stable

This extension is a candidate for freezing

Zish4add

Stable

This extension is a candidate for freezing

Zabhlrsc

Stable

This extension is a candidate for freezing

Smcheri

Stable

This extension is a candidate for freezing

Sscheri

Stable

This extension is a candidate for freezing

Smcherire

Stable

This extension is a candidate for freezing

Smcherivarxlen

Stable

This extension is a candidate for freezing

Svcheri

Stable

This extension is a candidate for freezing

Sdcheri

Stable

This extension is a candidate for freezing

Shcheri

Stabilizing

This extension is a candidate for freeze, software evaluation currently ongoing

Svucrg

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 10).

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 (or RV32E/RV64E) integer instruction sets with CHERI. If the hart supports RV32E/RV64E instead of RV32I/RV64I, RV32Y/RV64Y the restrictions from [rv32e] apply and 16 general purpose registers instead of 32 — but all other RV32Y/RV64Y changes are identical so the remainder of this chaper only refers to extending RV32I/RV64I behavior.

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 corrupted1 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. Attempting to dereference via an invalid capability will result in a hardware exception.

1 Not all possible corrupted states are detected, see Section A.2, “Integrity of Capabilities”.

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

ARC note - CLEN will become YLEN

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 one-bit valid tag which is defined below.

RV32Y/RV64Y specify the fields which the capability format supports, and how those fields behave for XLEN=32 and XLEN=64.

The exact encoding format of the capability is described in Appendix A.

Future extensions may redefine the capability format providing they follow the rules defined by the RV32Y/RV64Y base ISA.
Diagram
Figure 1. CHERI Capability structure

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 data, all other fields are zero.

2.2.2. Valid Tag

ARC note C registers will become Y registers

The valid tag is an additional bit added to addressable memory and all CLEN-bit registers. It is stored separately and may be referred to as out of band or hidden, and is hardware managed. It indicates whether a CLEN-bit 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).

All registers or memory locations able to hold a capability are CLEN bits wide with an additional hidden valid tag bit. These are referred as being CLEN-bit in this specification.

The valid tag cannot be directly set to 1 by software, it is not a conventionally accessible bit of state. If the tag valid is set then it shows that the capability has been derived correctly according to the principles listed above (provenance, integrity, monotonicity). If the rules are followed then the valid tag will propagate through the instructions that modify, load or store the capability.

Therefore, for capability manipulation in registers:

  • Any instruction that wrote the capability to a register had at least one valid tag set in its input operands.

    • This is the provenance check.

  • Any instruction that wrote the capability to a register requested a legal operation that does not increase bounds or permissions, and set the valid tag on the output.

    • This is the monotonicity check.

  • Any instruction that wrote the capability to a register detected corrupted values.

    • This is the integrity check.

Capability load/store require the provenance check:

  • Any store that wrote the capability to memory was correctly authorized

  • Any load that read the capability from memory was correctly authorized

When an operation fails a check, either due to software error or malicious intent, then the operation raises an exception or sets the resulting valid tag to zero.

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 zero.

When the valid tag is zero, the register or memory location may be used to store non-capability data.

2.2.3. Capability Bounds

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.

It is not permitted to make any partially or fully out-of-bounds memory accesses.

Every capability has two memory address bounds: base representing the lowest accessible byte, and top representing one byte above the highest accessible byte.

  • 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.

  • The length is XLEN+1-bits and is defined to be top - base.

Therefore a memory location A in the range base ≤ A < top is within bounds, and so valid to access.

Inclusive top, with XLEN bits, was considered but rejected in favor of the exclusive top.
Checking every byte of every executed instruction and every 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 bounds encoding format is defined in Section A.1.4.

Future extensions may redefine the bounds encoding format.

Software can query the capability bounds:

  • The base is returned by GCBASE.

  • The length is returned by GCLEN.

    • GCLEN saturates the length to XLEN bits

  • The top can be calculated via GCBASE+GCLEN

A future extension may add an instruction to directly read the top if needed for performance.

2.2.4. Updating The Bounds

On system initialization the Infinite capability is available which has bounds which cover all of memory, and maximum permissions set. All smaller capabilities are derived from this.

The ISA does not allow the bounds (and permissions) of a capability with its valid tag set to be increased (monotonicity).

Bounds can be programmed using the SCBNDS, SCBNDSI and SCBNDSR instructions, which set the current address to be the base bound and the length to be the operand (rs1 or imm) value. The granularity constraints means that not all requested combinations of top and base bounds can be encoded exactly.

  • SCBNDS sets the base to cs1.address, and the length to rs1. Set the valid tag to zero if the bounds cannot be encoded exactly.

  • SCBNDSI sets the base to cs1.address, and the length to the immediate value. Set the valid tag to zero if the bounds cannot be encoded exactly.

  • SCBNDSR sets the base to cs1.address, and the length to rs1. The bounds may be rounded up if they cannot be encoded exactly.

    • If SCBNDSR rounds up the requested bounds, they must still be no larger than the initial bounds.

  • CRAM can be used to calculate the nearest precisely encodable length and base values for a given size.

The bounds are encoded relative to the address field, sharing some upper bits of the address. The number of shared bits depends 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 CHERI concentrate encoding scheme shares the upper bits of the address with the bounds, the address of a capability cannot be arbitrary modified without risking changing the meaning of the bounds. This means that 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 the interpretation of bounds has changed, then the valid tag is set to zero, so that the capability is invalid for use.

SCADDR updates the address field of a capability and then checks that the updated capability is still valid.

2.2.5. Representability

Due to the encoding of capability bounds, not all out-of-bounds pointers can be represented. 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.

Existing software sometimes temporarily moves pointers outside of arrays, and then only come back into the valid range on dereference, so the encoding was designed to allow valid capabilities to be out-of-bounds.
RV32Y/RV64Y implementations that use a different encoding scheme to the default (e.g., for accellerators or specific micro-controllers) may specify an alternative to the representable region check, and may never allow the address to be out of bounds. Therefore, the rest of the specification uses the phrase represented exactly for the check performed by SCADDR.

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.

cap bounds map
Figure 2. Memory address bounds encoded within a capability

2.2.6. 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:

Table 2. Capability types in RV32Y/RV64Y
Type Hardware interpretation

0

Unsealed capability

1

Sealed entry (sentry) capability

Future extensions are likely to add more types of sealed capabilities by extending the width of the CT-field. In the base ISA, sentries are the only type of sealed capability and the CT field is only 1-bit.
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≠0 are sealed against modification. They cannot be dereferenced to access memory and it is not permitted to change the address, bounds or permissions. Modifications are restricted to reducing the CL field using ACPERM.

Sentries describe secure function entry points. They are used as the target of JALR (RV32Y/RV64Y), which must have a zero offset for the use of a sentry to be valid.

Sentry capabilities can establish a form of control-flow integrity between mutually distrusting code. JALR (RV32Y/RV64Y) with zero offset automatically unseals a sentry target capability and installs it in the program counter capability.

JALR (RV32Y/RV64Y) also seals the return register, so the callee can return to the caller but cannot access the memory pointed at by the return register, and cannot return elsewhere.

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 extracting the metadata with GCHI, zeroing the CT field, reapplying it with SCHI and then rebuilding via a superset capability with the CBLD instruction. A future extension may add an unseal instruction for performance.

2.2.7. 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 on valid capabilities, they cannot be added.

The encoding of permissions varies with MXLEN and is described in AP-field encoding.
Read Permission (R)

Allow reading data from memory. Valid 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/8-byte aligned location in memory has an associated valid tag. If any byte is overwritten with non-capability data then the associated valid tag or tags are set to zero.

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. This ensures that capability loads of non-capability data do not modify the loaded value, and that sealed capabilities are not modified.

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 field that allows limiting the propagation of capabilities using the following logic: capabilities with a Capability Level (CL) (see below) less than the inverse of the authorizing capability’s SL-permission will be stored with a zero valid tag.

In the base ISA this is a single bit comparison, behaving 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.

Future extensions may make this field wider to enable more use cases.
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.8. Capability Level (CL)

The Capability Level (CL) field 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 Capability Level can hold two values:

  • 1: the capability is global, in general allowing it to be stored using any authorizing capability.

  • 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 of a valid capability can only be decreased but never increased (without deriving from a capability with a higher level). But unlike architectural permissions, the Capability Level can be reduced even if the capability is sealed.

Table 3. SL-permission effects for stored capabilities
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 (CL ≥ ~SL)

0

Store data capability with valid tag cleared (CL < ~SL)

if W=0 or C=0 then SL is irrelevant
Table 4. EL-permission effects for loading capabilities
Auth cap field Data cap field

R

C

EL

CL

Tag

Sealed

Action

1

1

0

X

1

Yes

Load data capability with CL=min(auth.CL, data.CL), EL unchanged

No

Load data capability with EL=0, CL=min(auth.CL, data.CL)

All other cases

Load data capability with EL, CL unmodified

2.2.9. 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 on valid capabilities.

This property is required to ensure restricted programs cannot forge capabilities that would pass the software-enforced checks.

2.2.10. Special Capabilities

Infinite Capability

The Infinite capability grants all permissions, has the maximum CL-field, and its bounds cover the whole 2^MXLEN address space. The address field can hold any value.

All capability checks pass when performed against a valid Infinite capability. The in-memory encoding of the Infinite capability is described in Section A.3.2.

The Infinite capability is also known as 'default', 'almighty', or 'root' capability in other CHERI documentation.
NULL Capability

A capability with all-zero metadata, a zero valid tag, and an address of zero is referred to as the NULL capability. This capability grants no permissions and any dereference results in raising an exception.

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:

Diagram
Figure 3. Extended registers in RV32Y/RV64Y
Diagram
Figure 4. New CLEN CSRs added in RV32Y/RV64Y

2.3.1. Extended registers

All registers that can contain addresses are extended with another XLEN bits of capability metadata and a valid tag bit.

General Purpose Registers

The XLEN-wide integer registers (e.g., sp, a0) are all extended in this way.

When referring to the extended registers, the x prefix is replaced with a c: i.e. the extended version of x1 becomes c1. The register can be referred to either way - as c1 accessing all CLEN bits or as x1 accessing only the address field (i.e., the lower XLEN bits). For the ABI register names the c prefix is added, e.g., csp to refer to all CLEN bits, and so the assembler can refer to wither sp or csp.

The zero register is extended with zero metadata and a zero 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).
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 raises 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 system initialization the pc 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).

Diagram
Figure 5. Program Counter Capability

2.3.2. Added CSRs

RV32Y and RV64Y add the CLEN-bit CSR shown in Table 5.

Table 5. Unprivileged capability CSRs added in RV32Y/RV64Y
CLEN CSR Permissions Description

utidc

RW, ASR-permission required for writes, not reads

User Thread ID Capability

User Thread Identifier Capability (utidc)

The utidc register is used to identify the current software thread in user mode. Any operations that modifies utidc raises an exception unless the ASR-permission is set in the current pcc.

While the RISC-V ABI includes a thread pointer (tp) register, it 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 an additional CSR that facilitates a trusted source for identifying software threads.
Diagram
Figure 6. User thread identifier capability register

The following should probably move to a programmers guide

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. The utidc register supports a model where untrusted code is separated by trusted code and each call from one piece of untrusted code to another piece of untrusted piece of code goes through trusted code. Often, the trusted code is referred to as a trampoline. 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 utidc register is designed to hold a capability, which can only be used for memory accesses by trusted code. In a commonly used model on CHERI systems, the trusted code’s responsibility is only to switch between compartments, but not to switch threads. This responsibility is usually taken over by more privileged code, e.g., an operating system kernel running on a different privilege level. The privileged code switches software threads and writes the utidc register.

Every piece of code in the user space (and more privileged levels) can read the content of the utidc register. However, the memory authorized by the capability in utidc must not be accessible to untrusted code, but only to trusted code. In order to protect this capability, it can be made a sentry (thus being sealed). The trusted code will be given a capability large enough so that it can recover the sentry stored in utidc. For the untrusted code, the sentry stored in utidc is inaccessible. The sentry itself is no secret, but the memory pointed to by the sentry is a secret and must not be accessed by any untrusted code.

Trusted code can use the sentry in utidc to implement secure compartment switches. Often, the sentry is used to implement a trusted stack. Whenever a compartment switch happens, the trusted code can pass arguments between the caller and callee compartment avoid capability leaks between the two compartments. The trusted code can store capabilities on the trusted stack when calling out of a compartment and can install them when returning the same compartment.

2.3.3. Extended CSRs

All CSRs that can hold addresses are extended to CLEN bits.

RV32Y/RV64Y has three classes of CSR:

  1. XLEN-bit CSRs, which do not contain addresses

    1. e.g., fcsr from the "F" extension

  2. XLEN-bit CSRs extended to CLEN bits, which are able to contain addresses (referred to as extended CSRs)

    1. e.g., jvt from the "Zcmt" extension

  3. CLEN-bit CSRs, which are added by RV32Y/RV64Y and contain addresses

    1. e.g., utidc

When accessing CSRs these rules are followed:

  1. Accesses to XLEN-bit CSRs are as specified by Zicsr

  2. Accesses to CLEN-bit CSRs and extended CSRs, using CSRRW will:

    1. Read CLEN bits

    2. Write CLEN bits, and will write the valid tag to zero if:

      1. any integrity check fails

  3. Accesses to CLEN-bit CSRs and extended CSRs, using encodings other than CSRRW will:

    1. Read CLEN bits

    2. Write an XLEN-bit to the address field, and use SCADDR semantics to determine the final written value

Any CLEN-bit or extended CSR may have additional rules defined to determine the final written value of the metadata and/or to write zero to the valid tag.

The assembler pseudoinstruction to read a capability CSR csrr cd, csr, is encoded as csrrs cd, csr, c0.

Table 6. CLEN-bit CSR and Extended CSR access summary for RV32Y/RV64Y
Instruction Read Width Write Width

CSRRW rd==x0

CLEN

CSRRW rd!=x0

CLEN

CLEN

CSRR[C|S] rs1==x0

CLEN

CSRR[C|S] rs1!=x0

CLEN

XLEN

CSRRWI rd==x0

XLEN

CSRRWI rd!=x0

CLEN

XLEN

CSRR[C|S]I uimm==x0

CLEN

CSRR[C|S]I uimm!=x0

CLEN

XLEN

In Table 6 and Table 17, when there is no read or write width shown, the CSR access is not made and there are no side-effects following standard Zicsr rules.

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.:

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 set valid tag of the resulting capability to zero if the operation is not permitted.

Branches and jumps may raise exceptions, reusing the Instruction Address Misaligned exception path.

2.5. Instructions to 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.

Table 7. Instructions which update the address field summary in RV32Y/RV64Y
Mnemonic Description

CADDI

Increment capability address by immediate, represented exactly check

CADD

Increment capability address by register, represented exactly check

SCADDR

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
Diagram
Diagram
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 to cd.

For CADD, increment cd.address by the value in rs2 .
For CADDI, increment cd.address by the immediate value imm.

Set cd.tag=0 if cs1 is sealed.

Set cd.tag=0 if the resulting capability cannot be represented exactly.

Set cd.tag=0 if cs1 '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
Diagram
Description

Copy the capability cs1 to cd.

Set cd.address to rs2.

Set cd.tag=0 if cs1 is sealed.

Set cd.tag=0 if the resulting capability cannot be represented exactly.

Set cd.tag=0 if cs1 '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 to 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).

Table 8. Other instructions which manipulate capability data summary in RV32Y/RV64Y
Mnemonic Description

ACPERM

AND capability permissions (expand to 1-bit per permission before ANDing)

CMV

Move capability register

SCHI

Set metadata and clear valid tag

SCBNDSI

Set immediate bounds on capability with rounding, clear valid tag if rounding is required

SCBNDS

Set register bounds on capability with rounding, clear valid tag if rounding is required

SCBNDSR

Set bounds on capability with rounding up as required

SENTRY

Seal capability

CBLD

Set cd to cs2 with its tag set after checking that cs2 is a subset of cs1

2.6.1. ACPERM

Synopsis

Reduce capability permissions and level by bitwise ANDing with a mask

Mnemonics

acperm cd, cs1, rs2

Encoding
Diagram
Description

ACPERM performs the following operations:

  1. Convert the AP-field, CL-field and SDP-field of capability cs1 into a bit field with the format shown in Figure 7.

  2. Calculate the bitwise AND of the bit field with the mask in rs2.

    Future extensions may include hardwired permission bits, in which case they are not included in this bitwise AND.
  3. 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 these cases, ACPERM will return a 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.
  4. Copy cs1 to cd, and update the AP-field, CL-field and SDP-field with the newly calculated versions.

  5. Set cd.tag=0 if cs1 is sealed and any bits in the AP-field or SDP-field were affected by ACPERM.

    1. Do not set the valid tag to zero on a sealed capability if only the CL-field changed.

Diagram
Figure 7. Capability permissions bit field
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
Diagram
CMV is encoded as CADD with rs2=x0.
Description

The contents of capability register cs1 are written to capability register cd. CMV unconditionally does a bit-wise copy from cs1 to cd .

This instruction can propagate valid capabilities which fail integrity checks.

Operation
C(cd) = C(cs1);
RETIRE_SUCCESS

2.6.3. SCHI

Synopsis

Capability set metadata

Mnemonic

schi cd, cs1, rs2

Encoding
Diagram
Description

Copy cs1 to cd.

Replace the capability metadata (i.e., bits [CLEN-1:MXLEN]) with rs2 and set cd.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
Diagram
Diagram
Description

Capability register cd is set to capability register cs1 with the base address of its bounds replaced with the value of cs1.address and the length of its bounds set to rs2 for SCBNDS, or imm for SCBNDSI.

Set cd.tag=0 if cs1.tag=0, cs1 is sealed or if cd 's bounds exceed cs1 's bounds.

Set cd.tag=0 if the requested bounds cannot be encoded exactly.

Set cd.tag=0 if cs1 's bounds are malformed, or if any of the reserved fields are set.

SCBNDSI uses the s bit to scale the immediate by 4 places

immediate = 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
Diagram
Description

Capability register cd is set to capability register cs1 with the base address of its bounds replaced with the value of cs1.address and the length of its bounds set to rs2.

The base is rounded down and the top is rounded up by the smallest amounts needed to form a capability covering the requested base and top.

Set cd.tag=0 if cs1.tag=0, cs1 is sealed or if cd 's bounds exceed cs1 's bounds.

Set cd.tag=0 if the requested bounds cannot be encoded exactly.

Set cd.tag=0 if cs1 '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
Diagram
Description

Copy cs1 to cd. Set the capability type of cd to sentry capability.

Set cd.tag=0 if cs1 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.6). 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
Diagram
Description

Copy cs2 to cd.

Set cd.tag=1 if:

  1. cs1.tag is set, and

  2. cs1 passes all integrity checks, and

  3. cs1 is not sealed, and

  4. cs2 's permissions and bounds are equal to or a subset of cs1 's, and

  5. cs2 's Capability Level (CL) is equal to or lower than cs1 's, and

  6. cs2 passes all integrity checks, and

    Otherwise, set cd.tag=0

CBLD is typically used alongside SCHI to build capabilities from integer values.
When cs1 is c0 CBLD will copy cs2 to cd and clear cd.tag. However future extensions may add additional behavior to update currently reserved fields, 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 to Inspect Capability Data

2.7.1. Instructions to 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.

Table 9. Instructions which decode capability bounds summary in RV32Y/RV64Y
Mnemonic Description

GCBASE

Get capability base

GCLEN

Get capability length

2.7.2. GCBASE

Synopsis

Capability get base address

Mnemonic

gcbase rd, cs1

Encoding
Diagram
Description

Decode the base integer address from cs1 's bounds and write the result to rd.

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
Diagram
Description

Calculate the length of cs1 's bounds and write the result in rd.

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 to Extract Capability Fields

These instructions either directly read bit fields from the metadata or valid tag, or only apply simple transformations on the metadata.

Table 10. Instructions which extract capability fields summary in RV32Y/RV64Y
Mnemonic Description

GCTAG

Get capability tag

GCPERM

Get capability architectural and software permissions

GCTYPE

Get capability type

GCHI

Get capability metadata

2.7.5. GCTAG

Synopsis

Capability get tag

Mnemonic

gctag rd, cs1

Encoding
Diagram
Description

Zero extend the value of cs1.tag and write the result to rd.

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
Diagram
Description

If MXLEN=32 unpack the AP-field from the format in Table 19.

Convert the unpacked AP-field as well as the SDP-field and CL-field of capability cs1 into a bit field, with the format shown in Figure 8, and write the result to rd. All bits in the [23:0] range that are reserved or assigned to extensions that are not implemented by the current hart always report 1.

If the AP-field could not have been produced by ACPERM then all architectural permission bits in rd are set to 0.

Diagram
Figure 8. Capability permissions bit field
Any future extension that defines new permissions 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
Diagram
Description

Decode the architectural capability type (Section 2.2.6) from cs1 and write the result to rd.

The value of cs1.tag does not affect the result.
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
Diagram
Description

Copy the metadata (bits [CLEN-1:MXLEN]) of capability cs1 into rd.

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 to Handle Capability Data

Table 11. Miscellaneous capability instruction summary in RV32Y/RV64Y
Mnemonic Description

SCEQ

Full capability bitwise compare, set result true if both are fully equal

SCSS

Set result true if cs1 and cs1 tags match and cs2 bounds and permissions are a subset of cs1

CRAM

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
Diagram
Description

Set rd to 1 if all bits (i.e., CLEN bits and the valid tag) of capabilities cs1 and cs2 are equal, otherwise set rd 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
Diagram
Description

rd is set to 1 if:

  1. the valid tag of capabilities cs1 and cs2 are equal, and

  2. the bounds and permissions of cs2 are a subset of those of cs1, and

  3. cs2 's Capability Level (CL) is equal to or lower than cs1 's

  4. neither cs1 or cs2 fail any integrity checks, and

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
Diagram
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 of rs1. 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 to 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:

  • LC reads CLEN bits of data from memory, and returns the associated valid tag.

  • SC writes CLEN bits of data to memory, and writes the associated valid tag.

If C-permission is not granted then:

  • LC reads CLEN bits from memory, but does not return the associated valid tag, instead zero is returned.

  • SC writes CLEN bits to memory, and writes zero to the associated valid tag.

All capability data memory access instructions require CLEN-aligned addresses, and will take an access fault exception if this requirement is not met. They cannot be emulated.

An access fault is raised instead of a misaligned exceptions since these instructions cannot be emulated since there is one hidden valid tag per CLEN-aligned memory region.
This is a change in behavior relative to v0.9.5 (previously a misaligned exception was taken)

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

Under some circumstances LC will modify the data loaded from memory before writing it back to the destination register. See LC for details.

Table 12. Capability load/store instruction summary in RV32Y/RV64Y
Mnemonic Description

LC

Load capability

SC

Store capability

2.9.1. LC

Synopsis

Load capability

Mnemonic

lc cd, offset(cs1)

Encoding
Diagram
Any instance of this instruction with a cs1=c0 will raise an exception, 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 cs1.address 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 valid capabilities which fail integrity checks.

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 set cd.tag=0. In this case the steps below do not apply.

If cd.tag=1, cd is not sealed and cs1 does not grant LM-permission, then an implicit ACPERM is performed to clear W-permission and LM-permission from cd.

If cd.tag=1, cd is not sealed and cs1 does not grant EL-permission, then an implicit ACPERM is performed restricting the Capability Level (CL) of cd to the level of cs1 and to remove EL-permission.

If cd.tag=1, cd is sealed and cs1 does not grant EL-permission, then an implicit ACPERM is performed restricting the Capability Level (CL) of cd to the level of cs1

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.

When sending load data to a trace interface, implementations trace the final value written to cd which may not match the value in memory.

ARC note: this is change relative to 0.9.5 (either memory value or register value were legal). The choice is now removed. Choosing the other option would need to be a future extension

Exceptions

Load access fault exception when the effective address is not aligned to CLEN/8.

This is a change in behavior relative to v0.9.5 (previously a misaligned exception was raised)

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
Diagram
Any instance of this instruction with a cs1=c0 will raise an exception, 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 cs1.address 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 in cs2.

This instruction can propagate valid capabilities which fail integrity checks.

Valid tag of the stored capability value

The stored valid tag is 0 if:

  1. cs2.tag=0, or

  2. cs1 does not grant C-permission, or

  3. cs1 does not grant SL-permission and cs2 has a Capability Level (CL) of 0 (local).

Exceptions

Store access fault exception when the effective address is not aligned to CLEN/8.

This is a change in behavior relative to v0.9.5 (previously a misaligned exception was raised)

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 that 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), 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 destination x register is always unchanged. I.e., the lower XLEN bits are always written with the value from RV32I/RV64I.

  • Whenever the PC is handled, it is always the CLEN-bit pcc.

  • Any memory instruction that has rs1 as a base address register reads the full capability register (cs1) instead. The base address is unchanged, i.e., using the value from rs1. The metadata and valid tag are used to authorize the access.

  • Any instruction that writes back an address (e.g., AUIPC (RV32Y/RV64Y) or CSRRW (RV32Y/RV64Y)) to the destination register, 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 raised on the branch or jump on failure.

  • JALR (RV32Y/RV64Y) updates pcc.address as expected, but also copies the metadata and valid tag from cs1 into the pcc. If cs1 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 13, and also apply to instructions added by other extensions, e.g.:

Exceptions are raised on the branch or jump that cause an exception, not at the target, primarily to reduce the attack surface but also to aid with debugging. Therefore, it is impossible to execute from a memory location without having already checked that execution of that location is authorized.
Table 13. Changed RISC-V base ISA instructions summary in RV32Y/RV64Y
Mnemonic Description

AUIPC (RV32Y/RV64Y)

Add immediate to PCC address, return capability

JAL (RV32Y/RV64Y)

Jump to PC+offset, bounds check minimum size target instruction, link to cd

JALR (RV32Y/RV64Y)

Indirect jump and link, bounds check minimum size target instruction.

BEQ, BNE, BLT[U], BGE[U]

Conditional branches (checked by pcc)

LD, LW[U], LH[U], LB[U]

Integer loads (authorized by the capability in cs1)

SD, SW, SH, SB

Integer stores (authorized by the capability in cs1)

2.10.1. AUIPC (RV32Y/RV64Y)

Synopsis

Add upper immediate to pcc

Mnemonic

auipc cd, imm

Integer Pointer Mode Mnemonic

auipc rd, imm

Encoding
Diagram
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 may need to push the AUIPC instruction into the same extension as the capability encoding, for CHERIoT

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
Diagram
Description

Jump to the target pcc.

Increment pcc.address by the sign-extended offset to form the target pcc. The pcc of the next instruction is sealed and written to cd.

Exceptions
Kind Reason

Bounds violation

Minimum length instruction at the target 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
Diagram
This instruction is extended from the version in the base ISA.
Description

Jump to the target capability in cs1.

The target capability is unsealed if the offset is zero. Increment cs1.address by the sign-extended 12-bit offset and set the least-significant bit of the result to zero. The pcc of the next instruction is sealed and written to cd.

Exceptions
Kind Reason

Tag violation

cs1 has tag set to 0, or has any reserved bits set

Seal violation

cs1 is sealed and the immediate is not 0

Permission violation

cs1 does not grant X-permission, or the AP-field could not have been produced by ACPERM

Bounds violation

Minimum length instruction at the target 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
Diagram
Description

Execute as defined in the base ISA. The target address is written into pcc.address.

Exceptions
Kind Reason

Bounds violation

Minimum size instruction at the target 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:

  • Where the base operand is rs1, the capability source operand cs1 is used to authorize the resulting memory access.

All load and store instructions authorized by cs1 raise exceptions if any of these checks fail:

  • cs1 must not be c01

  • The valid tag (cs1.tag) must be set

  • cs1 must be unsealed

  • For loads, read permission must be set in cs1

  • For stores, write permission must be set in cs1

  • All integrity checks on cs1 must pass

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.

Under RV32Y/RV64Y all loads and stores are authorized by cs1.

3. "Zcherihybrid" Extension for CHERI Integer Pointer Mode

ARC-QUESTION: Should the name be something like Zyhybrid/Zycompat/Zyi? WARNING: 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).

The M-bit of the pcc, may be overridden by the execution environment which may not grant permission to enter Capability Pointer Mode.

3.1.3. Changing CHERI Execution Mode

The M-bit of pcc can be updated by the instructions listed in Table 14:

Table 14. Zcherihybrid instructions that can perform mode changes
Mnemonic From mode Description

JALR (RV32Y/RV64Y)

Capability Pointer Mode

Install cs1 in the pcc and so update pcc.M

MODESW.INT

Capability Pointer Mode

Switch to Integer Pointer Mode.

MODESW.CAP

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

ARC question: should misa.Y be 1 when in Capability Pointer Mode and 0 when in Integer Pointer Mode?

Implementations that support Zcherihybrid will typically boot into Integer Pointer Mode so that non-CHERI aware software can run unmodified. CHERI aware software can observe and switch the mode as required.

3.2. Added State

Zcherihybrid adds the CLEN-wide CSRs shown in Table 15.

Table 15. Unprivileged CLEN-wide CSRs added in Zcherihybrid
CLEN CSR Address Permissions Description

ddc

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).

Diagram
Figure 9. Unprivileged default data capability register

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.

In Integer Pointer Mode JALR does not copy the target capability register cs1 into pcc, instead it updates the address of pcc with the target value. The only difference to RV32I/RV64I without Zcherihybrid, is that the target address is checked against the bounds of pcc.

3.5. Zcherihybrid Instructions

Zcherihybrid introduces new instructions to switch CHERI execution modes. Additionally, Zcherihybrid makes all instructions defined by Zcherihybrid available.

Table 16. Instructions summary for Zcherihybrid
Mnemonic Description

SCMODE

Set capability CHERI execution mode (M-bit)

GCMODE

Get capability CHERI execution mode (M-bit)

MODESW.CAP

Set current CHERI execution mode to Capability Pointer Mode

MODESW.INT

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
Diagram
Description

Copy cs1 to cd.

Clear cd.tag if cs1 is sealed.

If cs1 grants X-permission and cs1 's AP-field could have been produced by ACPERM, then update the M-bit of cd to:

  1. Capability Pointer Mode if the least significant bit of rs2 is 0, or,

  2. Integer Pointer Mode if the least significant bit of rs2 is 1

    Otherwise 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
Diagram
Description

Decode the CHERI execution mode from the capability in cs1 and write the result to rd.

Set rd to 0 if cs1 does not grant X-permission, or, the AP-field in cs1 could not have been produced by ACPERM.

Otherwise set rd according to cs1 's CHERI execution mode (M-bit):

  1. Set rd to 0 for Capability Pointer Mode, or,

  2. 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
Diagram
Description

Set the current CHERI execution mode in pcc.

  • MODESW.CAP: If the current mode in pcc is Integer Pointer Mode (1), then the M-bit in pcc is set to Capability Pointer Mode (0). Otherwise no effect.

  • MODESW.INT: If the current mode in pcc is Capability Pointer Mode (0), then the M-bit in pcc is set to Integer Pointer Mode (1). Otherwise no effect.

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

When in Integer Pointer Mode, there is a special rule for updating extended CSRs (e.g., jvtc/jvt (RV32Y/RV64Y))

  • Writing an extended CSR writes the address field (XLEN bits) only, and the full CSR is updated using SCADDR semantics.

  • Reading an extended CSR reads the address field (XLEN bits) only

For this purpose the assembly syntax will refer to jvt (RV32Y/RV64Y). Accesses to extended CSRs in Integer Pointer Mode must only access XLEN bits for compatibility, and so use SCADDR semantics to determine the final written value.

Table 17. CLEN-bit CSR and Extended CSR access summary for Zcherihybrid
CLEN-bit CSR1 Extended CSR2

Instruction

Read Width

Write Width

Read Width

Write Width

CSRRW rd==x0

CLEN

XLEN

CSRRW rd!=x0

CLEN

CLEN

XLEN

XLEN

CSRR[C|S] rs1==x0

CLEN

XLEN

CSRR[C|S] rs1!=x0

CLEN

XLEN

XLEN

XLEN

CSRRWI rd==x0

XLEN

XLEN

CSRRWI rd!=x0

CLEN

XLEN

XLEN

XLEN

CSRR[C|S]I uimm==x0

CLEN

XLEN

CSRR[C|S]I uimm!=x0

CLEN

XLEN

XLEN

XLEN

1 e.g., utidc 2 e.g., jvt (RV32Y/RV64Y)

3.7.1. CSRRWI (RV32Y/RV64Y)

3.7.2. CSRRS (RV32Y/RV64Y)

3.7.3. CSRRSI (RV32Y/RV64Y)

3.7.4. CSRRC (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-bit CSRs

csrrs cd, csr, rs1
csrrc cd, csr, rs1
csrrwi cd, csr, imm
csrrsi cd, csr, imm
csrrci cd, csr, imm

Mnemonics for accessing extended CSRs in Capability Pointer Mode

csrrs cd, csr, rs1
csrrc cd, csr, rs1
csrrwi cd, csr, imm
csrrsi cd, csr, imm
csrrci cd, csr, imm

Mnemonics for accessing 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
Diagram
Description

These CSR instructions have extended functionality for accessing CLEN-bit CSRs, and XLEN-bit CSRs extended to CLEN bits (Extended CSRs).

Access to XLEN-bit CSRs is as defined in Zicsr.

Zicsr rules are followed when determining whether to read or write the CSR.

Suppressed read or write actions have no side-effects on the CSR.

All writes are XLEN bits only, as determined by Zicsr, and use SCADDR semantics to determine the final write data.

Read data from extended CSRs is CLEN bits in Capability Pointer Mode or XLEN bits in Integer Pointer Mode.

Read data from CLEN-bit CSRs is always CLEN bits.

Permissions

Accessing CSRs may require ASR-permission.

Prerequisites for Capability Pointer Mode

RV32Y/RV64Y, Zicsr

Prerequisites for Integer Pointer Mode

Zcherihybrid, Zicsr

Operation
TBD

3.7.6. CSRRW (RV32Y/RV64Y)

Synopsis

CSR access (CSRRW) 32-bit encodings for (RV32Y/RV64Y)

Mnemonic for accessing CLEN-wide CSRs

csrrw cd, csr, cs1

Mnemonic for accessing extended CSRs in Capability Pointer Mode

csrrw cd, csr, cs1

Mnemonic for accessing extended CSRs in Integer Pointer Mode

csrrw rd, csr, rs1

Encoding
Diagram
Description

CSRRW has extended functionality for accessing CLEN-bit CSRs, and XLEN-bit CSRs extended to CLEN bits (Extended CSRs).

Access to XLEN-bit CSRs is as defined in Zicsr.

CSRRW accesses to CLEN-bit CSRs read CLEN bits into cd and write cs1 into the CSR.

CSRRW accesses to extended CSRs in Capability Pointer Mode read CLEN bits into cd and write cs1 into the CSR.

CSRRW accesses to extended CSRs in Integer Pointer Mode read XLEN bits into rd and write rs1 into the CSR. The final write data is determined using SCADDR semantics.

In all cases, when writing cs1, if any integrity check fails then set the valid tag to zero before writing to the CSR.

Permissions

Accessing CSRs may require ASR-permission.

Prerequisites for Capability Pointer Mode

RV32Y/RV64Y, Zicsr

Prerequisites for Integer Pointer Mode

Zcherihybrid, Zicsr

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.

sh4add wavedrom reg

Increment rs2 by rs1 shifted left by 4 bit positions and write the result to rd.

sh4adduw wavedrom reg

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.

zabhlrsc lr ext wavedrom reg
zabhlrsc sc ext wavedrom reg

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.

5.2. Vector with RV32Y/RV64Y

This chapter should appear as a section in the vector chapter. Exact location TBD.

The Vector extension is orthogonal to RV32Y/RV64Y because the vector registers do not support valid tags.

A future extension may allow valid 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.

Under RV32Y/RV64Y, vector loads and stores follow the standard rules for active elements:

  • Only active elements are subject to CHERI exception checks.

  • If there are no active elements then no CHERI exceptions will be raised.

  • CHERI exceptions are only raised on fault-only-first loads if element 0 is both active and fails any exception checks.

Indexed loads 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 10 for MXLEN=32 and Figure 11 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.

Diagram
Figure 10. Capability encoding for MXLEN=32
Diagram
Figure 11. Capability encoding for MXLEN=64

Reserved bits are available for future extensions to RV32Y/RV64Y.

Reserved bits must be 0 in valid 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.

A.1.1. Architectural Permissions (AP) Encoding

The bit width of the permissions field depends on the value of MXLEN as shown in Table 18. A 5-bit vector encodes the permissions when MXLEN=32. For this case, the legal encodings of permissions are listed in Table 19. 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.

Table 18. Permissions widths depending on MXLEN
MXLEN AP-field width Comment

32

5

Encodes some combinations of 8 permission bits, including the M-bit if Zcherihybrid is supported.

64

8

Separate bits for each architectural permission.

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 19 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.

Table 19. Encoding of architectural permissions for MXLEN=32
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

Reserved3

5

(2)

N/A

Reserved3

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

Reserved3

5

(2)

N/A

Reserved3

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 valid 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 for adding additional levels in a future extension

When MXLEN=64, there is a bit per permission as shown in Table 20. A permission is granted if its corresponding bit is set, otherwise the capability does not grant that permission.

Table 20. Encoding of architectural permissions for MXLEN=64
Bit Encoded permission

0

C-permission

1

W-permission

2

R-permission

3

X-permission

4

ASR-permission

5

LM-permission

6

EL-permission

7

SL-permission

The M-bit is only assigned meaning when the implementation supports Zcherihybrid and X-permission is set.

  1. For MXLEN=64, the bit assigned to the M-bit must be zero if X-permission isn’t set.

  2. 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 19) 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:

Table 21. ACPERM common rules
Rule Permission Only valid if

1 (RV32 only)

ASR-permission

All other permissions are set.

2

C-permission

R-permission or W-permission

3 (RV32 only)

C-permission

R-permission

4 (RV32 only)

X-permission

R-permission

5 (RV32 only)

W-permission

not(C-permission) or LM-permission

6 (RV32 only)

X-permission

W-permission or C-permission

7

EL-permission

C-permission and R-permission

8 (RV32 only)

EL-permission

LM-permission

9

LM-permission

C-permission and R-permission

10 (RV32 only)

LM-permission

(W-permission or EL-permission)

11

SL-permission

C-permission

12 (RV32 only)

SL-permission

(LM-permission and (X-permission or W-permission))

13 (RV32 only)

X-permission

(C-permission and LM-permission and EL-permission and (SL-permission == ∞)) or
(not(C-permission and not(LM-permission) and not(EL-permission) and (SL-permission==0)))1

14

ASR-permission

X-permission

152

M-bit

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.

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-field bits of the GCPERM result maps 1:1 to the SDP-field in the capability.

Table 22. SDP widths depending on MXLEN
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 23.

Table 23. Mantissa width (MW) values depending on MXLEN
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 24.

Table 24. Exponent widths and CAP_MAX_E depending on MXLEN
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

The bounds are decoded as shown in Figure 12 and Figure 13.

Diagram
Figure 12. Decoding of the MXLEN+1 wide top (t) bound
Diagram
Figure 13. Decoding of the MXLEN wide base (b) bound

Figure 12 and Figure 13 include ranges which may not be present when the bounds are decoded:

  • 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 25 and Table 26.

A = a[E + MW - 1:E]
R = B - 2MW-2
The comparisons in Table 25 and Table 26 are unsigned.
Table 25. Calculation of top address correction
A < R T < R ct

false

false

0

false

true

+1

true

false

-1

true

true

0

Table 26. Calculation of base address correction
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:

  1. 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.

  2. 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 if T[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)

Capabilities with malformed bounds:

  1. Return both base and top bounds as zero, which affects instructions like GCBASE.

  2. Cause certain manipulation instructions like CADDI to always set the valid tag of the result to zero.

A.2. Integrity of Capabilities

CHERI enforces the following rules for all valid capabilities:

  1. The bounds are not malformed.

  2. No reserved bit in the capability encoding is set.

  3. The permissions can be legally produced by ACPERM.

In all cases the capability could not have been legally created, and so either:

  • There has been a corruption of capability state due to memory or logic faults

  • There is an incompatible or faulty CHERI IP within the system

These checks are much less rigorous than parity or ECC protection, and are only used to detect simple problems with the capability metadata.
Even though valid capabilities which fail the integrity check could not have been legally generated, defining the handling in the architecture allows the behavior to be precisely specified for all 2(CLEN+1) input values.

A.3. Encoding of Special Capabilities

A.3.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.

Table 27. Field values of the NULL capability
Field Value Comment

Valid 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 and Zcherihybrid only)

CL

zero

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

A.3.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).
Table 28. Field values of the Infinite capability
Field Value Comment

Tag

one

Capability is valid

SDP

ones

Grants all permissions

AP (MXLEN=32)

0x8/0x91 (see Table 19)

Grants all permissions

AP (MXLEN=64)

0xFF (see Table 20)

Grants all permissions

CL

one

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:

  • For MXLEN=32, the M-bit is set to 1 in the AP-field, giving the value 0x9

  • For MXLEN=64, the M-bit is set to 1 in a separate M field which is not shown in the table above.

A.4. 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 valid 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.5. Representable Range Check

A.5.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:

  • Instructions such as CADD which include pointer arithmetic.

  • The SCADDR instruction which updates the capability address field.

A.5.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)

Table 29. Composition of the decoded top address bound
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 29 to aid this description.

For the address to be valid for the current bounds encoding, the value in the Upper Section of Table 29 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:

Table 30. Top bound MSB inversion truth table
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 30 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] and b[MXLEN-1] == b'[MXLEN-1], then it is guaranteed t[MXLEN] == t'[MXLEN].

  • If t[MXLEN-1] != t'[MXLEN-1] or b[MXLEN-1] != b'[MXLEN-1], then the representable check will fail regardless of checking t[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] and b[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.

Chapters for the privileged specification

6. "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.

6.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.

6.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.

Diagram
Figure 14. Machine-mode trap-vector base-capability register

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 zeroed. In particular, if any part of the range is in the invalid address space then setting the valid tag to zero is strongly recommended.

As shown in Table 58, mtvecc is a code capability, so it does not need to be able to hold all possible invalid addresses (see Invalid address conversion).

6.1.2. Machine Scratch Capability Register (mscratchc)

The mscratchc register extends mscratch 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.

Diagram
Figure 15. Machine-mode scratch capability register

6.1.3. Machine Exception Program Counter Capability (mepcc)

The mepcc register extends mepc to hold a capability. Its reset value is the Infinite capability.

Diagram
Figure 16. Machine exception program counter capability register

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 58, 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.

6.1.4. Machine Thread Identifier Capability (mtidc)

The mtidc register 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.

Diagram
Figure 17. Machine thread identifier capability register

6.2. Machine-Level CSRs modified by Smcheri

6.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: Does Smcherivarxlen need to be a separate extension or just a "if xME,xXL bits are writable, then this behavior is followed" note in Smcheri

6.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 31 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.
Table 31. Synchronous exception priority in decreasing priority order. Entries added in RV32Y/RV64Y are in bold
Priority Exc.Code Description

Highest

3

Instruction address breakpoint

28

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

12, 1

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

1

With physical address for instruction:
Instruction access fault

2
0
8,9,11
3
3

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

28

CHERI faults due to:
PCC ASR-permission clear
Branch/jump target address checks (tag, execute permissions, invalid address and bounds)

28

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

4,6

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

13, 15, 5, 7

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

5,7

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

4,6

If not higher priority:
Load/store/AMO address misaligned

Lowest

13

If not higher priority:
CHERI load PTE page fault4

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 34.

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 36.

6.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.

6.2.4. Machine Trap Value Register (mtval)

The mtval register is an MXLEN-bit read-write register formatted as shown in Figure 18. 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 32 is set to 1. For all other CHERI faults mtval is set to zero.

The behavior of mtval is otherwise as described in mtval.

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.

Diagram
Figure 18. Machine trap value register

6.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 19 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
Diagram
Figure 19. Machine trap value register 2 format 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 19 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 32 and Table 33 respectively.

Table 32. Encoding of TYPE field for CHERI Faults
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

Table 33. Encoding of CAUSE field
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:

  1. Tag violation (Highest)

  2. Seal violation

  3. Permission violation

  4. Invalid address violation

  5. Bounds violation (Lowest)

mtval2 values for Load/Store/AMO Page Faults

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

Table 34. mtval2 for page faults
Fault Value

RISC-V page fault

0

CHERI PTE page fault

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.

6.2.6. "Smstateen/Ssstateen" Integration

The new TID bit in mstateen0 controls access to the stidc CSR.

Diagram
Figure 20. Machine State Enable 0 Register (mstateen0)

6.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.

6.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.

Diagram
Figure 21. Supervisor trap-vector base-capability register

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

6.3.2. Supervisor Scratch Capability Register (sscratchc)

The sscratchc register extends sscratch 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.

Diagram
Figure 22. Supervisor scratch capability register

6.3.3. Supervisor Exception Program Counter Capability (sepcc)

The sepcc register extends sepc to hold a capability. Its reset value is the Infinite capability.

As shown in Table 58, 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.

Diagram
Figure 23. Supervisor exception program counter capability register

6.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.

Unlike mtval2, stval2 is a new a CSR added by Sscheri.
The mechanism to report exception subcodes needs to be finalized: github.com/riscv/riscv-cheri/issues/536
Diagram
Figure 24. Supervisor trap value register 2

6.3.5. Supervisor Thread Identifier Capability (stidc)

The stidc register 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.

Diagram
Figure 25. Supervisor thread identifier capability register

6.4. Supervisor-Level CSRs modified by Sscheri

6.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 6.2.2 for the new exceptions priorities when RV32Y/RV64Y is implemented.

6.4.2. Supervisor Trap Value Register (stval)

stval is updated following the same rules as Section 6.2.4 for CHERI exceptions and CHERI PTE page faults which are delegated to HS-mode or S-mode.

6.4.3. "Smstateen/Ssstateen" Integration

The new TID bit in sstateen0 controls access to the utidc CSR. .Supervisor State Enable 0 Register (sstateen0)

Diagram

6.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 35.

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.

Table 35. CHERI fault reporting
Trap taken into Faulting address Additional CHERI fault information

M-mode

mtval

mtval2

HS-mode / S-mode

stval

stval2

VS-mode

vstval

vstval2

auth_cap is ddc for Integer Pointer Mode and cs1 for Capability Pointer Mode
Table 36. Valid CHERI exception combination description
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

CSR*, MRET(RV32Y/RV64Y), SRET (RV32Y/RV64Y)

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

JAL (RV32Y/RV64Y), conditional branches

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

cs1 tag

not(cs1.tag)

indirect jumps

28

2

1

cs1 seal

isCapSealed(cs1) and imm12 != 0

indirect jumps

28

2

2

cs1 permission

not(cs1.X-permission)

indirect jumps

28

2

3

cs1 invalid address

target address is an invalid address

indirect jumps

28

2

4

cs1 bounds

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

Load additional exception checks

all loads

28

1

0

auth_cap tag

not(auth_cap.tag)

all loads

28

1

1

auth_cap seal

isCapSealed(auth_cap)

all loads

28

1

2

auth_cap permission

not(auth_cap.R-permission)

all loads

28

1

3

auth_cap invalid address

Address is invalid (see Invalid address conversion)

all loads

28

1

4

auth_cap bounds

Any byte of load access out of auth_cap bounds

capability loads

4

N/A

N/A

load address misaligned

Misaligned capability load

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

all stores, all atomics, all cbos

28

1

0

auth_cap tag

not(auth_cap.tag)

all stores, all atomics, all cbos

28

1

1

auth_cap seal

isCapSealed(auth_cap)

all atomics, CBO.INVAL*

28

1

2

auth_cap permission

not(auth_cap.R-permission)

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

28

1

2

auth_cap permission

not(auth_cap.W-permission)

CBO.CLEAN*, CBO.FLUSH*

28

1

2

auth_cap permission

not(auth_cap.R-permission) and not(auth_cap.W-permission)

all stores, all atomics, all cbos

28

1

3

auth_cap invalid address

Address is invalid (see Invalid address conversion)

all stores, all atomics

28

1

4

auth_cap bounds

any byte of access out of auth_cap bounds

CBO.ZERO*, CBO.INVAL*

28

1

4

auth_cap bounds

any byte of cache block out of auth_cap bounds

CBO.CLEAN*, CBO.FLUSH*

28

1

4

auth_cap bounds

all bytes of cache block out of auth_cap bounds

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.

6.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.

6.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

7. "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 37 summarizes the behavior of a hart in connection with the CRE and the CHERI Execution Mode while in a privilege other than debug mode.

Table 37. Hart’s behavior depending on the effective CRE and CHERI Execution Mode
CRE=0, M-bit=X1 CRE=1, M-bit=1 CRE=1, M-bit=0

Authorizing capability for memory accesses

ddc or pcc

ddc or pcc

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 63 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).

8. "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 7, 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 7, while in that privilege mode.

9. "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 6.3.

9.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.

9.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

9.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 34.
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.

9.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 26, Figure 27 and Figure 28 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?
Diagram
Figure 26. Sv39 page table entry
Diagram
Figure 27. Sv48 page table entry
Diagram
Figure 28. Sv57 page table entry

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.

Table 38. Summary of Store CW behavior in the PTEs
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:

  • The authorizing capability doesn’t have C-permission.

  • Insufficient SL-permission has cleared the valid tag of the to-be-stored capability.

9.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 58) 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.

9.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:

  1. 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.

  2. 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.

9.3.2. Branches and Jumps

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

  • pcc for branches, direct jumps and any branch when in Integer Pointer Mode (see Chapter 3).

  • The capability in the c input register of a jump when in Capability Pointer Mode (see Chapter 3).

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

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

  2. If T is invalid and A does not have infinite bounds (see Section 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.

  3. 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.

  4. 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.

9.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:

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

  2. If any byte in R is invalid and A does not have infinite bounds (see Section 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.

  3. 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.

  4. 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 and hartinfo.dataaccess of 0.

  • The program buffer must be implemented, with abstractcs.progbufsize of at least 4 if dmstatus.impebreak is 1, or at least 5 if dmstatus.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 c1 if MXLEN is 64, hartinfo.dataaccess is 0, hartinfo.dataaddr is 0xBF0, hartinfo.datasize is 1, dmstatus.impebreak is 0, and abstractcs.progbufsize is 5:

# 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 MXLEN bits of a capability are read and written using normal Access Register abstract commands. If dscratch0c were known to be preserved between abstract commands, it would be possible to remove the requirements on hartinfo.datasize, hartinfo.dataaccess, and abstractcs.progbufsize, however there is no way to discover the former property.

9.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.

9.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 47.

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).

9.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.

Diagram
Figure 29. Debug program counter

9.3.7. Debug Program Counter Capability (dpcc)

The dpcc register extends dpc 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.

Diagram
Figure 30. Debug program counter capability

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).

When leaving debug mode, the capability in dpcc is unsealed and written into pcc. A debugger may write dpcc to change where the hart resumes and its mode, permissions, sealing or bounds.

The legalization of dpcc follows the same rules described for mepcc.

9.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.

Diagram
Figure 31. Debug scratch 0 register

9.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.

Diagram
Figure 32. Debug scratch 0 capability register

9.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.

Diagram
Figure 33. Debug scratch 1 register

9.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.

Diagram
Figure 34. Debug scratch 1 capability register

9.3.12. Debug Infinite Capability Register (dinfc)

dinfc is a debug mode accessible capability CSR. The address and access details are shown in Table 15.

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.
Diagram
Figure 35. Debug infinite capability register

9.4. Integrating Zcherihybrid with Sdext

A new debug default data capability (dddc) CSR is added at the CSR number shown in Table 15.

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

9.4.1. Debug Default Data Capability CSR (dddc)

dddc is a debug mode accessible capability CSR. The address is shown in Table 15.

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.

Diagram
Figure 36. Debug default data capability

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 58, dddc is a data pointer, so it does not need to be able to hold all possible invalid addresses (see Invalid address conversion).

9.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 39.

Table 39. Synchronous exception priority (including triggers) in decreasing priority order. Entries added in RV32Y/RV64Y are in bold
Priority Exc. Code Description Trigger

Highest

3
3
3
3

etrigger
icount
itrigger
mcontrol/mcontrol6 after (on previous instruction)

3

Instruction address breakpoint

mcontrol/mcontrol6 execute address before

28

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

12, 1

During instruction address translation:
First encountered CHERI PTE page fault, page fault or access fault

1

With physical address for instruction:
Instruction access fault

3

mcontrol/mcontrol6 execute data before

2
0
8,9,11
3

Illegal instruction
Instruction address misaligned
Environment call
Environment break

3

Load/store/AMO address breakpoint

mcontrol/mcontrol6 load/store address before

3

mcontrol/mcontrol6 store data before

28

CHERI faults due to:
PCC ASR-permission clear
Branch/jump target address checks (tag, execute permissions, invalid address and bounds)

28

Prior to address translation for an explicit memory access:
Load/store/AMO capability address misaligned
CHERI fault due to capability checks (tag, sealed, permissions, invalid address and bounds)

4,6

Optionally:
Load/store/AMO address misaligned

13, 15, 5, 7

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

5,7

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

4,6

If not higher priority:
Load/store/AMO address misaligned

13

If not higher priority:
CHERI PTE load page fault

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.

10. 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!

11. "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 11.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.

11.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.

11.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 37, Figure 38 and Figure 39 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.

Diagram
Figure 37. Sv39 page table entry
Diagram
Figure 38. Sv48 page table entry
Diagram
Figure 39. Sv57 page table entry
The behavior in this section isn’t relevant if:
  1. The authorizing capability doesn’t have C-permission, for loads, stores and AMOs.

  2. 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 11.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.

Table 40. Summary of Load CW and CRG behavior in the PTEs
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.

Table 41. Summary of Store CW and CRG behavior in the PTEs
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.

11.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 11.2.

11.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.

mstatus.UCRG also exists. Reading or writing it is equivalent to reading or writing sstatus.UCRG.

Diagram
Figure 40. Machine-mode status (mstatus) register when MXLEN=64
Diagram
Figure 41. Supervisor-mode status (sstatus) register when SXLEN=64
Diagram
Figure 42. Virtual Supervisor-mode status (vsstatus) register when VSXLEN=64

12. "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.

12.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 6.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.

12.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 43.

Diagram
Figure 43. Hypervisor environment configuration register (henvcfg)

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 7.

The reset value is 0.

12.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.

12.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 6.2.1 for mstatus.UXL.

12.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.

Diagram
Figure 44. Virtual supervisor trap vector base address register

12.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.

Diagram
Figure 45. Virtual supervisor trap vector base address capability register

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

12.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.

Diagram
Figure 46. Virtual supervisor scratch register

12.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.

Diagram
Figure 47. Virtual supervisor scratch capability register

12.9. Virtual Supervisor Exception Program Counter (vsepc)

The vsepc register is as defined in (RISC-V, 2023). It is extended into vsepcc.

Diagram
Figure 48. Virtual supervisor exception program counter

12.10. Virtual Supervisor Exception Program Counter Capability (vsepcc)

The vsepcc register extends vsepc to hold a capability. Its reset value is the Infinite capability.

As shown in Table 58, 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.

Diagram
Figure 49. Virtual supervisor exception program counter capability

12.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.

12.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.

Diagram
Figure 50. Virtual supervisor trap value register

12.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.

vstval2 is not a standard RISC-V CSR, but mtval2 is.
Diagram
Figure 51. Virtual supervisor trap value register 2

12.14. Virtual Supervisor Thread Identifier Capability (vstidc)

The vstidc register is used to identify the current software thread in virtual supervisor mode. It is used to identify the current software thread in 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.

Diagram
Figure 52. Virtual supervisor thread identifier capability register

12.15. "Smstateen/Ssstateen" Integration

The new TID bit controls access to the vstidc CSR.

Diagram
Figure 53. Hypervisor State Enable 0 Register (hstateen0)

12.16. 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.

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:

  1. In Integer Pointer Mode, every byte of each memory access is bounds checked against ddc

  2. In Integer Pointer Mode, a minimum length instruction at the target of all indirect jumps is bounds checked against pcc

  3. 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))

  4. 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
Diagram
Description

Load 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 cs1.address. The authorizing capability for the operation is cs1. A copy of the loaded value is written to rd.

Any instance of this instruction with a cs1=c0 will raise an exception, 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.
Integer Pointer Mode Description

Load 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 to rd.

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
Diagram
Description

Store 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 cs1.address. The authorizing capability for the operation is cs1. A copy of rs2 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 raise an exception, 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.
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)

B.2.2. MRET (RV32Y/RV64Y)

Synopsis

Trap Return (MRET, SRET)

Mnemonics

mret
sret

Encoding
Diagram
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
Diagram
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
Diagram
Capability Pointer Mode Description

Standard atomic instructions, authorized by the capability in cs1.

Any instance of this instruction with a cs1=c0 will raise an exception, 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.
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 34 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
Diagram
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 raise an exception, 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.
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
Diagram
Capability Pointer Mode Description

Load reserved instructions, authorized by the capability in cs1.

Any instance of this instruction with a cs1=c0 will raise an exception, 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.
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
Diagram
Description

Calculate the effective address of the memory access by adding cs1.address 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 raise an exception, 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.

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.

This instruction can propagate valid capabilities which fail integrity checks.

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 set cd.tag=0. In this case the steps below do not apply.

If cd.tag=1, cd is not sealed and cs1 does not grant LM-permission, then an implicit ACPERM is performed to clear W-permission and LM-permission from cd.

If cd.tag=1, cd is not sealed and cs1 does not grant EL-permission, then an implicit ACPERM is performed restricting the Capability Level (CL) of cd to the level of cs1 and to remove EL-permission.

If cd.tag=1, cd is sealed and cs1 does not grant EL-permission, then an implicit ACPERM is performed restricting the Capability Level (CL) of cd to the level of cs1

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.

When sending load data to a trace interface, implementations trace the final value written to cd which may not match the value in memory.

ARC note: this is change relative to 0.9.5 (either memory value or register value were legal). The choice is now removed. Choosing the other option would need to be a future extension

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
Diagram
Capability Pointer Mode Description

Store conditional instructions, authorized by the capability in cs1.

Any instance of this instruction with a cs1=c0 will raise an exception, 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.
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
Diagram
Description

Calculate the effective address of the memory access by adding cs1.address 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 in cs2.

Set rd to 1 for success or 0 for failure.

Any instance of this instruction with a cs1=c0 will raise an exception, 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.
Valid tag of the stored capability value

The stored valid tag is 0 if:

  1. cs2.tag=0, or

  2. cs1 does not grant C-permission, or

  3. cs1 does not grant SL-permission and cs2 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.

    This instruction can propagate valid capabilities which fail integrity checks.

Exceptions

Store access fault exception when the effective address is not aligned to CLEN/8.

This is a change in behavior relative to v0.9.5 (previously a misaligned exception was raised)

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
Diagram
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 raise an exception, 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.
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
Diagram
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 raise an exception, 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.
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
Zcd and Zcmp/Zcmt incompatible

B.5.1. RV32

Table 42. 16-bit instruction remapping in Integer Pointer Mode
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

Zcmp/Zcmp

N/A

001

10

N/A

N/A

C.FLDSP

reserved1

N/A

1 reserved for future standard Zcm extensions

Table 43. 16-bit instruction remapping in Capability Pointer Mode
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

Zcmp/Zcmp

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

Table 44. 16-bit instruction remapping in Integer Pointer Mode
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

Zcmp/Zcmp

N/A

001

10

N/A

N/A

C.FLDSP

reserved1

N/A

Table 45. 16-bit instruction remapping in Capability Pointer Mode
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
Diagram
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)

See Conditional branches

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
Diagram
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent.
Description

Capability register cd is replaced with the contents of cs2.

This instruction can propagate valid capabilities which fail integrity checks.

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
Diagram
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 if csp is sealed.

Set cd.tag=0 if the resulting capability cannot be represented exactly.

Set cd.tag=0 if csp '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
Diagram
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent.
Description

Copy csp to cd'. Add a zero-extended non-zero immediate, scaled by 4, to cd'.address.

Set cd'.tag=0 if csp is sealed.

Set cd'.tag=0 if the resulting capability cannot be represented exactly.

Set cd'.tag=0 if csp '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 to rd'. 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
Diagram
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

See JALR (RV32Y/RV64Y)

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)

See JALR (RV32Y/RV64Y)

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
Diagram
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

See JALR (RV32Y/RV64Y)

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)

See JALR (RV32Y/RV64Y)

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)
Diagram
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

See JAL (RV32Y/RV64Y)

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)

See JAL (RV32Y/RV64Y)

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
Diagram
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

See JAL (RV32Y/RV64Y)

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)

See JAL (RV32Y/RV64Y)

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
Diagram
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)

See LD, LW

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
Diagram
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)

See LW, LD

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)
Diagram
Diagram
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
Diagram
Diagram
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
Diagram
Diagram
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
Diagram
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)

See SD, SW

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
Diagram
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)

See SD, SW

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)
Diagram
Diagram
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
Diagram
Diagram
Capability Pointer Mode Description

Standard floating point stack pointer relative store instructions, authorized by the capability in cs1 or csp.

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
Diagram
Diagram
Capability Pointer Mode Description

Store the CLEN-bit value in cs2' to memory. The capability in cs1/csp authorizes the operation. The effective address of the memory access is obtained by adding the address of cs1/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 valid capabilities which fail integrity checks.

Exceptions

Store access fault exception when the effective address is not aligned to CLEN/8.

This is a change in behavior relative to v0.9.5 (previously a misaligned exception was raised)

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
Diagram
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 is cs1.

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
Diagram
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 is cs1.

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
Diagram
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 is cs1.

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
Diagram
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 in cs1. 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 is cs1.

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
Diagram
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 is cs1. 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 by cs1.

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 integrity check fails

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
Diagram
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 is cs1. 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 by cs1.

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 integrity check fails

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
Diagram
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 is cs1. 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 by cs1.

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 integrity check fails

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
Diagram
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent.
Description

Copy the capability in cs2 to cd.

Increment cd.address by the unsigned word in rs1.

Set cd.tag=0 if cs2 is sealed.

Set cd.tag=0 if the resulting capability cannot be represented exactly.

Set cd.tag=0 if cs2 '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)

B.7.3. SH2ADD (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
Diagram
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent.
Description

Copy the capability in cs2 to cd.

Increment cd.address by rs1 shifted left by n bit positions.

Set cd.tag=0 if cs2 is sealed.

Set cd.tag=0 if the resulting capability cannot be represented exactly.

Set cd.tag=0 if cs2 '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)

B.7.6. SH2ADD.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
Diagram
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent.
Description

Copy the capability in cs2 to cd.

Increment cd.address by the unsigned word rs1 shifted left by n bit positions.

Set cd.tag=0 if cs2 is sealed.

Set cd.tag=0 if the resulting capability cannot be represented exactly.

Set cd.tag=0 if cs2 '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
Diagram
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent.
RV64Y Description

Copy the capability in cs2 to cd.

Increment cd.address by rs1 shifted left by 4 bit positions.

Set cd.tag=0 if cs2 is sealed.

Set cd.tag=0 if the resulting capability cannot be represented exactly.

Set cd.tag=0 if cs2 's bounds are malformed, or if any of the reserved fields are set.

RV64I Description

Increment rs2 by rs1 shifted left by 4 bit positions and write the result to rd.

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
Diagram
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent.
RV64Y Description

Copy the capability in cs2 to cd.

Increment cd.address by the unsigned word in rs1 shifted left by 4 bit positions.

Set cd.tag=0 if cs2 is sealed.

Set cd.tag=0 if the resulting capability cannot be represented exactly.

Set cd.tag=0 if cs2 's bounds are malformed, or if any of the reserved fields are set.

RV64I Description

Increment rs2 by the unsigned word in rs1 shifted left by 4 bit positions and write the result to rd.

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 (RV32Y), 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 46.

Table 46. saved register mapping for Zcmp
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
Diagram
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
Diagram
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
Diagram
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
Diagram
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
Diagram
The encoding uses sreg number specifiers instead of xreg number specifiers to save encoding space. The saved register encoding is shown in Table 46.
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent.
Description

Atomically move two saved capability registers cs0-cs7 into ca0 and ca1.

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
Diagram
The encoding uses sreg number specifiers instead of xreg number specifiers to save encoding space. The saved register encoding is shown in Table 46.
For implementations that support Zcherihybrid, the behavior of this instruction is CHERI Execution Mode dependent.
Description

Atomically move two capability registers ca0 and ca1 into cs0-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.

Diagram
Figure 54. Jump Vector Table Capability register

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.

If the access to the jump table succeeds, then the instructions execute as follows:

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
Diagram
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 to 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.

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
Diagram
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

B.11. "H" Extension for Hypervisor Support

Hypervisor load and store instructions and the RV32Y/RV64Y extensions.

B.11.1. HLV.C

Synopsis

Hypervisor virtual-machine load capability

Mnemonic

hlv.c cd, cs1

Encoding
Diagram
Description

Execute LC as though V=1; i.e., with the address translation and protection, and endianness, that apply to memory accesses in either VS-mode or VU-mode.

The effective address is cs1.address.

The authorizing capability for the operation is cs1.

The loaded value is written to cd.

Any instance of this instruction with a cs1=c0 will raise an exception, 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.
Prerequisites

RV32Y/RV64Y, H

Operation

TBD

B.11.2. HSV.C

Synopsis

Hypervisor virtual-machine store capability

Mnemonic

hsv.c cs2, cs1

Encoding
Diagram
Description

Execute SC as though V=1; i.e., with the address translation and protection, and endianness, that apply to memory accesses in either VS-mode or VU-mode.

The effective address is cs1.address.

The authorizing capability for the operation is cs1.

Capability Pointer Mode

RV32Y/RV64Y, H

Operation

TBD

Appendix C: Control and Status Registers (CSRs) overview

Smcheri and Sscheri extend the CSRs listed in Table 47, Table 48, Table 49, Table 50 and Table 51 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)).
Table 47. Renamed debug-mode CSRs in RV32Y/RV64Y
RV32Y/RV64Y CSR Address Extended CSR Prerequisites Permissions Description

dpcc

0x7b1

dpc

Sdext

DRW

Debug Program Counter Capability

dscratch0c

0x7b2

dscratch0

Sdext

DRW

Debug Scratch Capability 0

dscratch1c

0x7b3

dscratch1

Sdext

DRW

Debug Scratch Capability 1

Table 48. Renamed machine-mode CSRs in RV32Y/RV64Y
RV32Y/RV64Y CSR Address Extended CSR Prerequisites Permissions Description

mtvecc

0x305

mtvec

M-mode

MRW, ASR-permission

Machine Trap-Vector Base-Address Capability

mscratchc

0x340

mscratch

M-mode

MRW, ASR-permission

Machine Scratch Capability

mepcc

0x341

mepc

M-mode

MRW, ASR-permission

Machine Exception Program Counter Capability

Table 49. Renamed supervisor-mode CSRs in RV32Y/RV64Y
RV32Y/RV64Y CSR Address Extended CSR Prerequisites Permissions Description

stvecc

0x105

stvec

S-mode

SRW, ASR-permission

Supervisor Trap-Vector Base-Address Capability

sscratchc

0x140

sscratch

S-mode

SRW, ASR-permission

Supervisor Scratch Capability

sepcc

0x141

sepc

S-mode

SRW, ASR-permission

Supervisor Exception Program Counter Capability

Table 50. Renamed virtual supervisor-mode CSRs in RV32Y/RV64Y
RV32Y/RV64Y CSR Address Extended CSR Prerequisites Permissions Description

vstvecc

0x205

vstvec

H

HRW, ASR-permission

Virtual Supervisor Trap-Vector Base-Address Capability

vsscratchc

0x240

vsscratch

H

HRW, ASR-permission

Virtual Supervisor Scratch Capability

vsepcc

0x241

vsepc

H

HRW, ASR-permission

Virtual Supervisor Exception Program Counter Capability

Table 51. Renamed user-mode CSRs in RV32Y/RV64Y
RV32Y/RV64Y CSR Address Extended CSR Prerequisites Permissions Description

jvtc

0x017

jvt (RV32Y/RV64Y)

Zcmt

URW

Jump Vector Table Capability

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:

  1. 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.

    1. These busses will read tags from memory (if tags are present in the target memory) and return them to the requestor.

    2. These busses will write the valid tag to memory as an extension of the data write.

  2. Non-tag aware busses, i.e., current non-CHERI aware busses.

    1. Reads of tagged memory will not read the valid tag.

    2. Writes to tagged memory will set the valid tag to zero 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:

  1. Update any data bytes without also writing the valid tag

    1. This implies setting the valid tag to zero if a non-CHERI aware bus master overwrites a capability in memory

  2. Read a valid tag value with mismatched (stale or newer) data

  3. 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

small cheri system.drawio
Figure 55. Example small CHERI system with local capability valid tag storage

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

large cheri system.drawio
Figure 56. Example large CHERI system with tag cache

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

large cheri purecap system.drawio
Figure 57. Example large CHERI system with only tag-aware bus masters

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 56.

There is likely to be a performance difference between the two systems. The main motivation for Figure 56 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.

These instructions are not controlled by the CRE bits in mseccfg, menvcfg or senvcfg.

Table 52. Zabhlrsc instruction extension
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 53.

Table 53. RV32Y/RV64Y instruction extension - Pure Capability Pointer Mode instructions
Mnemonic RV32 RV64 A Zabhlrsc Zicbo[mpz] C or Zca Zba Zcb Zcmp Zcmt Zfh F D V Function

LC

Load capability

SC

Store capability

C.LCSP

Load capability, SP relative

C.SCSP

Store capability, SP relative

C.LC

Load capability

C.SC

Store capability

C.LWSP

Load word, SP relative

C.SWSP

Store word, SP relative

C.LW

Load word

C.SW

Store word

C.LD

Load double

C.SD

Store double

C.LDSP

Load double, SP relative

C.SDSP

Store double, SP relative

AUIPC (RV32Y/RV64Y)

Add immediate to PCC address

CADD

Increment capability address by register, representability check

CADDI

Increment capability address by immediate, representability check

SCADDR

Replace capability address, representability check

GCTAG

Get valid tag field

GCPERM

Get hperm and uperm fields as 1-bit per permission, packed together

CMV

Move capability register

ACPERM

AND capability permissions (expand to 1-bit per permission before ANDing)

GCHI

Get metadata

SCHI

Set metadata and clear valid tag

SCEQ

Full capability bitwise compare, set result true if both are fully equal

SENTRY

Seal capability

SCSS

Set result true if cs1 and cs1 valid tags match and cs2 bounds and permissions are a subset of cs1

CBLD

Set cd to cs2 with its valid tag set after checking that cs2 is a subset of cs1

SCBNDS

Set register bounds on capability with rounding, clear valid tag if rounding is required

SCBNDSI

Set immediate bounds on capability with rounding, clear valid tag if rounding is required

SCBNDSR

Set bounds on capability with rounding up as required

CRAM

Representable Alignment Mask: Return mask to apply to address to get the requested bounds

GCBASE

Get capability base

GCLEN

Get capability length

GCTYPE

Get capability type

C.ADDI16SP (RV32Y/RV64Y)

ADD immediate to stack pointer in Integer Pointer Mode, CADD

C.ADDI4SPN (RV32Y/RV64Y)

ADD immediate to stack pointer in Integer Pointer Mode, CADD

C.MV (RV32Y/RV64Y)

Integer register move in Integer Pointer Mode, capability register move

C.J

Jump to PC+offset, bounds check minimum size target instruction

C.JAL

Jump to PC+offset, bounds check minimum size target instruction, link to cd

JAL (RV32Y/RV64Y)

Jump to PC+offset, bounds check minimum size target instruction, link to cd

JALR (RV32Y/RV64Y)

Indirect jump and link, bounds check minimum size target instruction. set PCC=unseal(cs1),cd=seal(nextPCC)

C.JALR

Indirect jump and link, bounds check minimum size target instruction. set PCC=unseal(cs1),cd=seal(nextPCC)

C.JR

Indirect jump, bounds check minimum size target instruction. set PCC=unseal(cs1)

DRET (RV32Y/RV64Y)

Return from debug mode, sets ddc from dddc and pcc from dpcc

MRET(RV32Y/RV64Y)

Return from machine mode handler, sets pcc from mtvecc , needs ASR-permission

SRET (RV32Y/RV64Y)

Return from supervisor mode handler, sets pcc from stvecc, needs ASR-permission

CSRRW (RV32Y/RV64Y)

CSR write - can also read/write a full capability through an address alias

CSRRS (RV32Y/RV64Y)

CSR set - can also read/write a full capability through an address alias

CSRRC (RV32Y/RV64Y)

CSR clear - can also read/write a full capability through an address alias

CSRRWI (RV32Y/RV64Y)

CSR write - can also read/write a full capability through an address alias

CSRRSI (RV32Y/RV64Y)

CSR set - can also read/write a full capability through an address alias

CSRRCI (RV32Y/RV64Y)

CSR clear - can also read/write a full capability through an address alias

CBO.INVAL (RV32Y/RV64Y)

Cache block invalidate (implemented as clean)

CBO.CLEAN (RV32Y/RV64Y)

Cache block clean

CBO.FLUSH (RV32Y/RV64Y)

Cache block flush

CBO.ZERO (RV32Y/RV64Y)

Cache block zero

PREFETCH.R (RV32Y/RV64Y)

Prefetch instruction cache line, always valid

PREFETCH.W (RV32Y/RV64Y)

Prefetch read-only data cache line

PREFETCH.I (RV32Y/RV64Y)

Prefetch writeable data cache line

LR.C

Load reserved capability

SC.C

Store conditional capability

AMOSWAP.C

Atomic swap of cap

C.FLD

Load floating point double

C.FLDSP

Load floating point double, sp relative

C.FSD

Store floating point double

C.FSDSP

Store floating point double, sp relative

CM.PUSH (RV32Y)

Push integer stack frame

CM.POP (RV32Y)

Pop integer stack frame

CM.POPRET (RV32Y)

Pop integer stack frame and return

CM.POPRETZ (RV32Y)

Pop integer stack frame and return zero

CM.MVSA01 (RV32Y)

Move two integer registers

CM.MVA01S (RV32Y)

Move two integer registers

CM.JALT (RV32Y)

Table jump and link

CM.JT (RV32Y)

Table jump

ADD.UW (RV64Y)

add unsigned words, representability check

SH1ADD (RV32Y/RV64Y)

shift and add, representability check

SH1ADD.UW (RV64Y)

shift and add unsigned words, representability check

SH2ADD (RV32Y/RV64Y)

shift and add, representability check

SH2ADD.UW (RV64Y)

shift and add unsigned words, representability check

SH3ADD (RV32Y/RV64Y)

shift and add, representability check

SH3ADD.UW (RV64Y)

shift and add unsigned words, representability check

SH4ADD

shift and add, representability check

SH4ADD.UW

shift and add unsigned words, representability check

HLV.C

Hypervisor virtual machine load capability

HSV.C

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
Table 54. Zcherihybrid instruction extension - Integer Pointer Mode instructions
Mnemonic RV32 RV64 A Zabhlrsc Zicbo[mpz] C or Zca Zba Zcb Zcmp Zcmt Zfh F D V Function

SCMODE

Set the mode bit of a capability, no permissions required

GCMODE

Get the mode bit of a capability, no permissions required

MODESW.CAP

Directly switch mode into Capability Pointer Mode

MODESW.INT

Directly switch mode into Integer Pointer Mode

C.FLW

Load floating point word capability

C.FLWSP

Load floating point word, sp relative

C.FSW

Store floating point word capability

C.FSWSP

Store floating point word, sp relative

C.FLD

Load floating point double

C.FLDSP

Load floating point double, sp relative

C.FSD

Store floating point double

C.FSDSP

Store floating point double, sp relative

Appendix F: Capability Width CSR Summary

Table 55. CSRs aliased and extended to capability width
CLEN CSR Alias Prerequisites

dpcc

dpc

Sdext

dscratch0c

dscratch0

Sdext

dscratch1c

dscratch1

Sdext

mtvecc

mtvec

M-mode

mscratchc

mscratch

M-mode

mepcc

mepc

M-mode

stvecc

stvec

S-mode

sscratchc

sscratch

S-mode

sepcc

sepc

S-mode

vstvecc

vstvec

H

vsscratchc

vsscratch

H

vsepcc

vsepc

H

jvtc

jvt (RV32Y/RV64Y)

Zcmt

Table 56. Action taken on writing to extended CSRs
CLEN CSR Action on XLEN write Action on CLEN write

dpcc

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

dscratch0c

Update the CSR using SCADDR.

direct write

dscratch1c

Update the CSR using SCADDR.

direct write

mtvecc

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.

mscratchc

Update the CSR using SCADDR.

direct write

mepcc

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

stvecc

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.

sscratchc

Update the CSR using SCADDR.

direct write

sepcc

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

vstvecc

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.

vsscratchc

Update the CSR using SCADDR.

direct write

vsepcc

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

jvtc

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

* 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.

Table 57. Action taken on writing to CLEN-wide CSRs
CLEN CSR Action on XLEN write Action on CLEN write

dddc

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

ddc

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

dinfc

Ignore

Ignore

utidc

Update the CSR using SCADDR.

direct write

stidc

Update the CSR using SCADDR.

direct write

vstidc

Update the CSR using SCADDR.

direct write

mtidc

Update the CSR using SCADDR.

direct write

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.
Table 58. CLEN-wide CSRs storing code pointers or data pointers
CLEN CSR Code Pointer Data Pointer Unseal On Execution

dpcc

mtvecc

mepcc

stvecc

sepcc

vstvecc

vsepcc

jvtc

dddc

ddc

Some CSRs store code pointers or data pointers as shown in Table 58. 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 59 shows all CLEN-wide CSRs.

Table 59. All CLEN-wide CSRs.
CLEN CSR Prerequisites Address Permissions Reset Value Description

dpcc

Sdext

0x7b1

DRW

tag=0, otherwise undefined

Debug Program Counter Capability

dscratch0c

Sdext

0x7b2

DRW

tag=0, otherwise undefined

Debug Scratch Capability 0

dscratch1c

Sdext

0x7b3

DRW

tag=0, otherwise undefined

Debug Scratch Capability 1

mtvecc

M-mode

0x305

MRW, ASR-permission

Infinite

Machine Trap-Vector Base-Address Capability

mscratchc

M-mode

0x340

MRW, ASR-permission

tag=0, otherwise undefined

Machine Scratch Capability

mepcc

M-mode

0x341

MRW, ASR-permission

Infinite

Machine Exception Program Counter Capability

stvecc

S-mode

0x105

SRW, ASR-permission

Infinite

Supervisor Trap-Vector Base-Address Capability

sscratchc

S-mode

0x140

SRW, ASR-permission

tag=0, otherwise undefined

Supervisor Scratch Capability

sepcc

S-mode

0x141

SRW, ASR-permission

Infinite

Supervisor Exception Program Counter Capability

vstvecc

H

0x205

HRW, ASR-permission

Infinite

Virtual Supervisor Trap-Vector Base-Address Capability

vsscratchc

H

0x240

HRW, ASR-permission

tag=0, otherwise undefined

Virtual Supervisor Scratch Capability

vsepcc

H

0x241

HRW, ASR-permission

Infinite

Virtual Supervisor Exception Program Counter Capability

jvtc

Zcmt

0x017

URW

tag=0, otherwise undefined

Jump Vector Table Capability

dddc

Zcherihybrid, Sdext

0x7bc

DRW

tag=0, otherwise undefined

Debug Default Data Capability (saved/restored on debug mode entry/exit)

ddc

Zcherihybrid

0x416

URW

Infinite

User Default Data Capability

dinfc

Sdext

0x7bd

DRW

Infinite

Source of Infinite capability in debug mode, writes are ignored

utidc

RV32Y/RV64Y

0x480

Read: U, Write: U, ASR-permission

tag=0, otherwise undefined

User thread ID

stidc

RV32Y/RV64Y

0x580

Read: S, Write: S, ASR-permission

tag=0, otherwise undefined

Supervisor thread ID

vstidc

RV32Y/RV64Y

0xA80

Read: VS, Write: VS, ASR-permission

tag=0, otherwise undefined

Virtual supervisor thread ID

mtidc

RV32Y/RV64Y

0x780

Read: M, Write: M, ASR-permission

tag=0, otherwise undefined

Machine thread ID

Appendix G: Instructions and CHERI Execution Mode

Table 60, Table 61 and Table 62 summarize on which CHERI Execution Mode each instruction may be executed in.

Table 60. Instructions valid for execution in Capability Pointer Mode only
Mnemonic Zcherihybrid RV32Y/RV64Y Function

C.LCSP

Load capability, SP relative

C.SCSP

Store capability, SP relative

C.LC

Load capability

C.SC

Store capability

Table 61. Instructions valid for execution in Integer Pointer Mode only
Mnemonic Zcherihybrid RV32Y/RV64Y Function

C.FLW

Load floating point word capability

C.FLWSP

Load floating point word, sp relative

C.FSW

Store floating point word capability

C.FSWSP

Store floating point word, sp relative

C.FLD

Load floating point double

C.FLDSP

Load floating point double, sp relative

C.FSD

Store floating point double

C.FSDSP

Store floating point double, sp relative

Table 62. Instructions valid for execution in both Integer Pointer Mode and Capability Pointer Mode
Mnemonic Zcherihybrid RV32Y/RV64Y Function

LC

Load capability

SC

Store capability

C.LWSP

Load word, SP relative

C.SWSP

Store word, SP relative

C.LW

Load word

C.SW

Store word

C.LD

Load double

C.SD

Store double

C.LDSP

Load double, SP relative

C.SDSP

Store double, SP relative

AUIPC (RV32Y/RV64Y)

Add immediate to PCC address

CADD

Increment capability address by register, representability check

CADDI

Increment capability address by immediate, representability check

SCADDR

Replace capability address, representability check

GCTAG

Get valid tag field

GCPERM

Get hperm and uperm fields as 1-bit per permission, packed together

CMV

Move capability register

ACPERM

AND capability permissions (expand to 1-bit per permission before ANDing)

GCHI

Get metadata

SCHI

Set metadata and clear valid tag

SCEQ

Full capability bitwise compare, set result true if both are fully equal

SENTRY

Seal capability

SCSS

Set result true if cs1 and cs1 valid tags match and cs2 bounds and permissions are a subset of cs1

CBLD

Set cd to cs2 with its valid tag set after checking that cs2 is a subset of cs1

SCBNDS

Set register bounds on capability with rounding, clear valid tag if rounding is required

SCBNDSI

Set immediate bounds on capability with rounding, clear valid tag if rounding is required

SCBNDSR

Set bounds on capability with rounding up as required

CRAM

Representable Alignment Mask: Return mask to apply to address to get the requested bounds

GCBASE

Get capability base

GCLEN

Get capability length

GCTYPE

Get capability type

SCMODE

Set the mode bit of a capability, no permissions required

GCMODE

Get the mode bit of a capability, no permissions required

MODESW.CAP

Directly switch mode into Capability Pointer Mode

MODESW.INT

Directly switch mode into Integer Pointer Mode

C.ADDI16SP (RV32Y/RV64Y)

ADD immediate to stack pointer in Integer Pointer Mode, CADD

C.ADDI4SPN (RV32Y/RV64Y)

ADD immediate to stack pointer in Integer Pointer Mode, CADD

C.MV (RV32Y/RV64Y)

Integer register move in Integer Pointer Mode, capability register move

C.J

Jump to PC+offset, bounds check minimum size target instruction

C.JAL

Jump to PC+offset, bounds check minimum size target instruction, link to cd

JAL (RV32Y/RV64Y)

Jump to PC+offset, bounds check minimum size target instruction, link to cd

JALR (RV32Y/RV64Y)

Indirect jump and link, bounds check minimum size target instruction. set PCC=unseal(cs1),cd=seal(nextPCC)

C.JALR

Indirect jump and link, bounds check minimum size target instruction. set PCC=unseal(cs1),cd=seal(nextPCC)

C.JR

Indirect jump, bounds check minimum size target instruction. set PCC=unseal(cs1)

DRET (RV32Y/RV64Y)

Return from debug mode, sets ddc from dddc and pcc from dpcc

MRET(RV32Y/RV64Y)

Return from machine mode handler, sets pcc from mtvecc , needs ASR-permission

SRET (RV32Y/RV64Y)

Return from supervisor mode handler, sets pcc from stvecc, needs ASR-permission

CSRRW (RV32Y/RV64Y)

CSR write - can also read/write a full capability through an address alias

CSRRS (RV32Y/RV64Y)

CSR set - can also read/write a full capability through an address alias

CSRRC (RV32Y/RV64Y)

CSR clear - can also read/write a full capability through an address alias

CSRRWI (RV32Y/RV64Y)

CSR write - can also read/write a full capability through an address alias

CSRRSI (RV32Y/RV64Y)

CSR set - can also read/write a full capability through an address alias

CSRRCI (RV32Y/RV64Y)

CSR clear - can also read/write a full capability through an address alias

CBO.INVAL (RV32Y/RV64Y)

Cache block invalidate (implemented as clean)

CBO.CLEAN (RV32Y/RV64Y)

Cache block clean

CBO.FLUSH (RV32Y/RV64Y)

Cache block flush

CBO.ZERO (RV32Y/RV64Y)

Cache block zero

PREFETCH.R (RV32Y/RV64Y)

Prefetch instruction cache line, always valid

PREFETCH.W (RV32Y/RV64Y)

Prefetch read-only data cache line

PREFETCH.I (RV32Y/RV64Y)

Prefetch writeable data cache line

LR.C

Load reserved capability

SC.C

Store conditional capability

AMOSWAP.C

Atomic swap of cap

C.FLD

Load floating point double

C.FLDSP

Load floating point double, sp relative

C.FSD

Store floating point double

C.FSDSP

Store floating point double, sp relative

CM.PUSH (RV32Y)

Push integer stack frame

CM.POP (RV32Y)

Pop integer stack frame

CM.POPRET (RV32Y)

Pop integer stack frame and return

CM.POPRETZ (RV32Y)

Pop integer stack frame and return zero

CM.MVSA01 (RV32Y)

Move two integer registers

CM.MVA01S (RV32Y)

Move two integer registers

CM.JALT (RV32Y)

Table jump and link

CM.JT (RV32Y)

Table jump

ADD.UW (RV64Y)

add unsigned words, representability check

SH1ADD (RV32Y/RV64Y)

shift and add, representability check

SH1ADD.UW (RV64Y)

shift and add unsigned words, representability check

SH2ADD (RV32Y/RV64Y)

shift and add, representability check

SH2ADD.UW (RV64Y)

shift and add unsigned words, representability check

SH3ADD (RV32Y/RV64Y)

shift and add, representability check

SH3ADD.UW (RV64Y)

shift and add unsigned words, representability check

SH4ADD

shift and add, representability check

SH4ADD.UW

shift and add unsigned words, representability check

HLV.C

Hypervisor virtual machine load capability

HSV.C

Hypervisor virtual machine store capability

Table 63. Mnemonics with the same encoding but mapped to different instructions in Integer Pointer Mode and Capability Pointer Mode
Mnemonic Integer Pointer Mode mnemonic RV32 Integer Pointer Mode mnemonic RV64

C.LCSP

C.FLWSP

C.FLDSP

C.SCSP

C.FSWSP

C.FSDSP

C.LC

C.FLW

C.FLD

C.SC

C.FSW

C.FSD

Table 64. Instruction encodings which vary depending on the current XLEN
Mnemonic Function

C.LCSP

Load capability, SP relative

C.SCSP

Store capability, SP relative

C.LC

Load capability

C.SC

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.
Table 65. Conditions for detecting illegal CHERI instructions
Mnemonic illegal insn if (1) OR illegal insn if (2) OR illegal insn if (3)

C.J

MODE==D (optional)

C.JAL

MODE==D (optional)

JAL (RV32Y/RV64Y)

MODE==D (optional)

JALR (RV32Y/RV64Y)

MODE==D (optional)

C.JALR

MODE==D (optional)

C.JR

MODE==D (optional)

DRET (RV32Y/RV64Y)

MODE<D

MRET(RV32Y/RV64Y)

MODE<M

PCC.ASR==0

SRET (RV32Y/RV64Y)

MODE<S

PCC.ASR==0

mstatus.TSR==1 AND MODE==S

CSRRW (RV32Y/RV64Y)

CSR permission fault

CSRRS (RV32Y/RV64Y)

CSR permission fault

CSRRC (RV32Y/RV64Y)

CSR permission fault

CSRRWI (RV32Y/RV64Y)

CSR permission fault

CSRRSI (RV32Y/RV64Y)

CSR permission fault

CSRRCI (RV32Y/RV64Y)

CSR permission fault

CBO.INVAL (RV32Y/RV64Y)

MODE<M AND menvcfg.CBIE[0]==0

MODE<S AND senvcfg.CBIE[0]==0

CBO.CLEAN (RV32Y/RV64Y)

MODE<M AND menvcfg.CBIE[0]==0

MODE<S AND senvcfg.CBIE[0]==0

CBO.FLUSH (RV32Y/RV64Y)

MODE<M AND menvcfg.CBIE[0]==0

MODE<S AND senvcfg.CBIE[0]==0

CBO.ZERO (RV32Y/RV64Y)

MODE<M AND menvcfg.CBIE[0]==0

MODE<S AND senvcfg.CBIE[0]==0

C.FLW

Xstatus.fs==0

C.FLWSP

Xstatus.fs==0

C.FSW

Xstatus.fs==0

C.FSWSP

Xstatus.fs==0

C.FLD

Xstatus.fs==0

C.FLDSP

Xstatus.fs==0

C.FLD

Xstatus.fs==0

C.FLDSP

Xstatus.fs==0

C.FSD

Xstatus.fs==0

C.FSDSP

Xstatus.fs==0

C.FSD

Xstatus.fs==0

C.FSDSP

Xstatus.fs==0

HLV.C

V=1

MODE==U AND hstatus.HU=0

HSV.C

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 and mstatush 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).

Diagram
Figure 58. Machine-mode scratch register
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).

Diagram
Figure 59. Machine Cause (mcause) register.
Machine Trap-Vector Base-Address (mtvec) Register

See mtvec in Chapter Machine-Level ISA, Version 1.13 in (RISC-V, 2023).

Diagram
Figure 60. Machine-mode trap-vector base-address register
Machine Exception Program Counter (mepc)

See mepc in Chapter Machine-Level ISA, Version 1.13 in (RISC-V, 2023).

Diagram
Figure 61. Machine exception program counter register
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).

Diagram
Figure 62. Machine trap value register
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.

Diagram
Figure 63. Machine security configuration register (mseccfg)
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.

Diagram
Figure 64. Machine environment configuration register (menvcfg)
Supervisor Trap Vector Base Address (stvec) Register

See stvec in Chapter Supervisor-Level ISA, Version 1.13 in (RISC-V, 2023).

Diagram
Figure 65. Supervisor trap vector base address (stvec) register.
Supervisor Scratch (sscratch) Register

See sscratch in Chapter Supervisor-Level ISA, Version 1.13 in (RISC-V, 2023).

Diagram
Figure 66. Supervisor-mode scratch register
Supervisor Exception Program Counter (sepc) Register

See sepc in Chapter Supervisor-Level ISA, Version 1.13 in (RISC-V, 2023).

Diagram
Figure 67. Supervisor exception program counter register
Supervisor Trap Value (stval) Register

See stval in Chapter Supervisor-Level ISA, Version 1.13 in (RISC-V, 2023).

Diagram
Figure 68. Supervisor trap value register
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).

Diagram
Figure 69. Supervisor Cause (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.

Diagram
Figure 70. Supervisor environment configuration register (senvcfg)
Supervisor Status (sstatus) Register

See sstatus in Chapter Supervisor-Level ISA, Version 1.13 in (RISC-V, 2023).

Index

Bibliography

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