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.

Zstid

Extension for supporting thread identifiers. This extension improves software compartmentalization on CHERI systems.

Zcheri0lvl/Zcheri1lvl

Extension for supporting capability flow control. This extension allows limiting storing of capabilities to specific regions and can be used, e.g., for safer data sharing between compartments. Zcheri0lvl imposes no restrictions on capability flow, Zcheri1lvl enables a 1-bit flow control level.

The following two extensions are useful independent of CHERI:

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

Zcheri0lvl

Stable

This extension is a candidate for freezing

Zcheri1lvl

Stabilizing

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

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

Zstid

Stabilizing

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

RV32Y/RV64Y is defined as the base extension which all CHERI RISC-V implementations must support. Zcherihybrid and Svucrg are optional extensions in addition to RV32Y/RV64Y.

We refer to software as purecap if it utilizes CHERI capabilities for all memory accesses — including loads, stores and instruction fetches — rather than integer addresses. Purecap software requires the CHERI RISC-V hart to support RV32Y/RV64Y. We refer to software as hybrid if it uses integer addresses or CHERI capabilities for memory accesses. Hybrid software requires the CHERI RISC-V hart to support RV32Y/RV64Y and Zcherihybrid.

See Appendix B for compatibility with other RISC-V extensions.

1.3. Risks and Known Uncertainty

  • All extensions could be divided up differently in the future, including after ratification

  • The RISC-V Architecture Review Committee (ARC) are likely to update all encodings

  • The ARC are likely to update all CSR addresses

  • Instruction mnemonics may be renamed

    • Any changes will affect assembly code, but assembler aliases can provide backwards compatibility

1.3.1. Partially Incompatible Extensions

There are RISC-V extensions in development that may duplicate some aspects of CHERI functionality or directly conflict with CHERI and should only be available in Integer Pointer Mode on a CHERI-enabled hart. These include:

  • RISC-V CFI specification

  • "J" Pointer Masking (see Chapter 11).

Chapters for the unprivileged specification

2. RV32Y and RV64Y Base Capability Instruction Sets, Version 1.0

This chapter will appear in the unpriv spec after the RV32I chapter.

This chapter describes the RV32Y and RV64Y base capability instruction sets, that extend the RV32I and RV64I integer instruction sets with CHERI.

CHERI enhances the base ISA to add hardware memory access control. It has an additional memory access mechanism that protects references to code and data (pointers), rather than the location of code and data (integer addresses). This mechanism is implemented by providing a new primitive, called a capability, that software components can use to implement strongly protected pointers within an address space. Capabilities are unforgeable and delegatable tokens of authority that grant software the ability to perform a specific set of operations. In CHERI, integer-based pointers are replaced by capabilities to provide memory access control.

2.1. CHERI protection model

The CHERI model is motivated by the principle of least privilege, which argues that greater security can be obtained by minimizing the privileges accessible to running software. A second guiding principle is the principle of intentional use, which argues that, where many privileges are available to a piece of software, the privilege to use should be explicitly named rather than implicitly selected. While CHERI does not prevent the expression of vulnerable software designs, it provides strong vulnerability mitigation: attackers have a more limited vocabulary for attacks, and should a vulnerability be successfully exploited, they gain fewer rights, and have reduced access to further attack surfaces.

Protection properties for capabilities include the ISA ensuring that capabilities are always derived via valid manipulations of other capabilities (provenance), that corrupted in-memory capabilities cannot be dereferenced (integrity), and that rights associated with capabilities shall only ever be equal or less permissive (monotonicity). Tampering or modifying capabilities in an attempt to elevate their rights will yield an invalid capability as the valid tag will be cleared. Attempting to dereference via an invalid capability will result in a hardware exception.

CHERI capabilities may be held in registers or in memories, and are loaded, stored, and dereferenced using CHERI-aware instructions that expect capability operands rather than integer addresses. On system initialization, initial capabilities are made available to software by the execution environment via general purpose registers. All other capabilities will be derived from these initial valid capabilities through valid capability transformations.

Developers can use CHERI to build fine-grained spatial and temporal memory protection into their system software and applications and significantly improve their security.

2.2. General purpose registers

RV32Y/RV64Y extends the general purpose registers to 2*XLEN-bit (hereafter referred to as CLEN), adding metadata to protect its integrity, limit how it is manipulated, and control its use. In addition to widening to CLEN, each register also gains an out-of-band (hidden / hardware managed) one-bit valid tag. The exact bitwise layout of capabilities as well as the precise encoding of each field for XLEN=32 and XLEN=64 is described in Appendix A, but always contain the fields listed in the following paragraphs.

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

2.2.2. Valid Tag

The valid tag is an additional hardware managed bit added to addressable memory and all c registers. It is stored separately and may be referred to as out of band or hidden. It indicates whether a c register or CLEN-aligned memory location contains a valid capability. If the valid tag is set, the capability is valid and can be dereferenced (contingent on checks such as permissions or bounds).

The capability is invalid if the valid tag is clear. Using an invalid capability to dereference memory or authorize any operation raises an exception. All capabilities derived from invalid capabilities are themselves invalid, i.e., their valid tags are 0.

All locations in registers or memory able to hold a capability are CLEN-bits wide including the valid tag bit. Those locations are referred as being CLEN-bit in this specification.

2.2.3. Bounds and Representability

Capabilities encode memory bounds, i.e. the lowest and highest byte in memory that it is permitted to access when dereferenced for data memory access, or for instruction execution.

Checking is on a byte-by-byte basis, so that it is possible for a memory access to be fully in-bounds, partially out-of-bounds or fully out-of-bounds.

All partially or fully out-of-bounds accesses cause an exception.

Every capability has two bounds - base and top. The base is returned by the GCBASE instruction. There is no equivalent instruction for the top, but there is for the length which is defined to be length = top - base, and is returned by GCLEN.

  • The base is XLEN-bits and is inclusive.

  • The top is XLEN+1 bits and is exclusive.

    • The extra bit is required to allow the bounds to include the top byte of memory.

Inclusive top, with XLEN-bits, was considered but rejected in favor of the exclusive top.

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

Checking every byte of every executed instruction and byte of every data memory access is fundamental to the memory safety which CHERI provides. In a typical load/store unit, the expansion of the bounds from cs1 and bounds checking is in parallel with the address calculation, the memory translation and/or the PMA/PMP checking.

A compressed format is used to encode the bounds with a scheme similar to floating-point using an exponent and a mantissa. Therefore small exponents can allow byte granularity on the bounds, but larger exponents give coarser granularity.

The ISA only allows the bounds of a capability to be reduced. Therefore instructions cannot output any capability with the valid tag set which include bounds (or permissions) which are greater than any input capability which also has its valid tag set. On system initialization the Infinite is available which has bounds which cover all of memory, and maximum permissions set. All smaller capabilities are derived from this.

Bounds can be reduced using the SCBNDS/SCBNDSI instructions, which require the final bounds to be accurately encoded, clearing the valid tag if that is not possible due to the granularity constraints. The requested bounds can be rounded up to the nearest encodable value above the requested bounds using SCBNDSR and CRAM can be used to determine the granularity which is possible to encode.

Bounds can only be reduced with SCBNDS/SCBNDSI/SCBNDSR. If SCBNDSR rounds up the requested bounds, they must still be no larger than the initial bounds.

The bounds are encoded relative to the address field, sharing some upper bits of the address. The number of shared bits depend on the exponent, see Section A.1.4.

Early versions of CHERI encoded the top and bottom bounds as full width addresses. This proved to be impractical for real systems, and so the CHERI-concentrate compressed system was developed to reduce the overhead.

Because the upper bits of the address are shared with the bounds, the address of a capability cannot be arbitrary modified without risking changing the meaning of the bounds. Therefore whenever a capability address is updated, the semantics of the SCADDR instruction are required to check that the decoding of the bounds hasn’t changed. If they have changed, then the valid tag (if set) is cleared, so that the capability can no longer be used for dereferencing memory.

Capabilities allow the address pointer to be outside of the bounds by a small amount.

Behavior was observed in software which allows pointers to legitimately move outside of arrays, and then only come back into the valid range on dereference.

The maximum range of address values that the pointer can take is defined by the representable region, which is checked on every update by SCADDR.

CHERI versions which use a different encoding scheme to the default may specify an alternative to the representable region check. Therefore the rest of the specification uses the phrase represented exactly

The bounds and representable region (or space) are illustrated in Figure 2. E, MW and R in the figure are all introduced in Section A.1.4.2 along with the bounds decoding.

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

In the presence of memory corruption, fault injection, or hardware bugs, bounds can theoretically become malformed. Instructions which decode bounds will typically clear the valid tag of the output if the input is found to be malformed.

CHERI requires that the capability is correctly formed if the valid tag is set. Including handling of malformed bounds, and invalid settings of reserved bits, in the architecture allows the behavior to be clearly specified for all 2(CLEN+1) input values.

2.2.4. Capability Type (CT)

This metadata field indicates the type of the capability. The type determines which operations the capability authorizes. The following capability types are defined in RV32Y/RV64Y:

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

0

Unsealed capability

1

Sentry capability

Unsealed capabilities

When CT=0, the capability authorizes access to a region of memory as defined by the permissions and bounds.

Sentry capabilities

Capabilities with CT=1 describe function entry points, known as sealed entry (sentry) capabilities. They cannot be dereferenced to access memory and are only allow very limited changes to the fields in the capability, which is restricted to reducing the CL field using ACPERM. Modifying any other fields with ACPERM, or any other instruction, clears the valid tag of the output capability. However, control-flow instruction can be used to jump to a sentry capability to begin executing the instructions it references.

Sentry capabilities can establish a form of control-flow integrity between mutually distrusting code. For example, the JALR (RV32Y/RV64Y) instruction with zero offset automatically unseals a sentry target capability and installs it in the program counter capability. The jump-and-link instructions also seal the return register, so the callee can return to the caller but cannot access the memory pointed at by the return register.
In addition to using them for secure entry points, sentry capabilities can also be useful to software as secure software tokens. They can be converted to an unsealed capability by rebuilding via a superset capability with the CBLD instruction.

2.2.5. Architectural Permissions (AP)

This metadata field encodes architecturally defined permissions of the capability. Permissions grant access subject to the valid tag being set, the capability being unsealed, and bounds checks passing. Any operation is also contingent on requirements imposed by other RISC-V architectural features, such as virtual memory, PMP and PMAs, even if the capability grants sufficient permissions. The permissions currently defined in RV32Y/RV64Y are listed below.

Permissions can only be removed using ACPERM, they cannot be added.

Read Permission (R)

Allow reading data from memory. Tags are always read as zero when reading non-capability data.

Write Permission (W)

Allow writing data to memory. Valid tags are always written as zero when writing non-capability data. Every CLEN aligned word in memory has a valid tag, if any byte is overwritten with non-capability data then the valid tag for all CLEN-bits is cleared.

Capability Permission (C)

Allow reading capability data from memory if the authorizing capability also grants R-permission. Allow writing capability data to memory if the authorizing capability also grants W-permission.

Execute Permission (X)

Allow instruction execution.

Load Mutable Permission (LM)

Allow preserving the W-permission of capabilities loaded from memory. If a capability grants R-permission and C-permission, but no LM-permission, then a capability loaded via this authorizing capability will have W-permission and LM-permission removed. The permission stripping behavior only applies to loaded capabilities that have their valid tag set and are not sealed; loaded capabilities that are sealed or invalid do not have their permissions changed. This ensures that capability loads/stores of non-capability data do not modify the stored value.

Clearing a capability’s LM-permission and W-permission allows sharing a read-only version of a data structure (e.g., a tree or linked list) without making a copy.
Access System Registers Permission (ASR)

Allow read and write access to privileged CSRs as well as some privileged instructions. In RV32Y/RV64Y, the only affected CSR is the unprivileged utidc CSR, which requires ASR-permission for writing (but not for reading).

This permission is important in privileged execution environments. Removing this permission allows constraining privileged software to a sandbox that cannot be subverted by changing privileged state.
Extensions may add additional non-privileged CSRs that require ASR-permission.
Store Level Permission (SL)

This is a variable width field that allows limiting the propagation of capabilities using the following logic: capabilities with a Capability Level (CL) less than the inverse of the authorizing capability’s SL-permission will be stored with the valid tag cleared. With LVLBITS=1 there is a single bit comparison, so it behaves as follows:

Elevate Level Permission (EL)

Any unsealed capability with its valid tag set to 1 that is loaded from memory has its EL-permission cleared and its Capability Level (CL) restricted to the authorizing capability’s Capability Level (CL) if the authorizing capability does not grant EL-permission. If sealed, then only CL is modified, EL-permission is unchanged. This permission is similar to the existing LM-permission, but instead of applying to the W-permission on the loaded capability it restricts the CL field.

2.2.6. Capability Level (CL)

The Capability Level (CL) is a variable width field that allows enforcing invariants on capability propagation. For example, the Capability Level can be used to ensure that a callee can only write a copy of the passed-in argument capability to specific locations in memory (e.g., the callee’s stack frame but not the heap). It can also be used to avoid sharing of compartment-local data (such as pointers to a stack object) between compartments.

This specification only defines the architectural mechanics of this feature, for further information on how this can be used by software please refer to (Watson et al., 2023).

The width of this field depends on whether the Zcheri0lvl or Zcheri1lvl extension is implemented:

Zcheri0lvl

In this case the field is hardwired to 1 and all checks based on the Capability Level can be omitted (since they always pass).

Zcheri1lvl

The Capability Level can hold two values: when set to 1 the capability is global (in general allowing it to be stored using any authorizing capability), and when set to 0 the capability is local, and can only be stored by authorizing capabilities with the SL-permission set. Furthermore, the EL-permission can be used to restrict loading of global capabilities — causing the hardware to automatically set the level of loaded capabilities to local instead.

As with permissions, the capability level can only be decreased but never increased (without deriving from a capability with a higher level). But unlike architectural permissions, CL can be reduced even if the capability is sealed.

A capability with CL=1 is referred to as global and with CL=0 as local.
Table 3. Zcheri1lvl summary table 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. Zcheri1lvl additional rules 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

Future extensions are permitted to add more levels.

2.2.7. Software-Defined Permissions (SDP)

The metadata also contains an encoding-dependent number of software-defined permission (SDP) bits. They can be inspected by the kernel or application programs to enforce restrictions on API calls (e.g. permit/deny system calls, memory allocation, etc.). They can be cleared by ACPERM but are not interpreted by the CPU otherwise.

While these bits are not used by the hardware as architectural permissions, modification follows the same rules: SDP bits can only be cleared and never set.

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

2.2.8. Special Capabilities

Infinite Capability

The Infinite capability grants all permissions while its bounds also cover the whole address space. All capability checks pass when performed against an Infinite capability. The in-memory encoding of the Infinite capability is described in Section A.2.2.

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

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

2.3. Added State

A CHERI core adds state to allow capabilities to be used from within integer (X) registers, and to ensure they are not corrupted as they flow through the system. This means the following state is added by RV32Y/RV64Y:

Diagram
Figure 3. CHERI c registers extending existing x registers in RV32Y/RV64Y

2.3.1. Extended general purpose integer registers

The XLEN-wide integer registers (e.g., sp, a0) are all extended with another XLEN-bits of capability metadata plus a valid tag bit. When referring to the extended register, the x prefix is replaced with a c: i.e. the capability extended version of x0 becomes c0. The existing integer register names refer to the address part of the capability. For the ABI register names the c prefix is added, i.e., csp, ca0. The zero register is extended with zero metadata and a cleared valid tag: this is called the NULL capability.

Instruction encodings refer to c registers when they use cs1, cd, etc. instead of rs1, rd (which reads/writes the XLEN-bit subset of the register).

2.3.2. Extended CSRs

All registers that store addresses are extended to contain capabilities. In the base RV32Y/RV64Y ISA, only the program counter (pc) register is extended to become the Program Counter Capability (pcc).

All CSRs that hold pointers are extended to CLEN-bits, but since no CSRs are defined in the RV32I/RV64I base instruction set, any such change is described in the corresponding chapters.

2.3.3. The Program Counter Capability (pcc)

The pc is extended to be the Program Counter Capability. Extending the pc allows the range of branches, jumps and linear execution for currently executing code to be restricted. The pcc address field is the pc in the base RISC-V ISA so that the hardware automatically updates it as instructions are executed.

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

ARC suggest that this become a software check exception, which would need a CHERI specific value in Xtval2
  • The valid tag must be set

  • The capability must not be sealed

  • The capability must grant execute permission

  • All bytes of the instruction must be in bounds

On startup pcc bounds and permissions must be set such that the program can run successfully (e.g., by setting it to Infinite to ensure all instructions are in bounds).

Diagram
Figure 4. Program Counter Capability

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 clear the valid tag on the result capability if the operation is not permitted.

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

2.5. Instructions Which Update The Capability Pointer

Updating the value of the pointer (i.e., the address field) of a capability requires specific instructions instead of integer ADD/ADDI. They all include a check that the result can be represented exactly.

Table 5. 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 Which Manipulate Capability Data

For security, capabilities can only be modified in restricted ways. Special instructions are provided to copy capabilities or perform manipulations such as shrinking the bounds (SCBNDS), reducing the permissions (ACPERM) or authorizing a capability with another one which has a superset (or identical) bounds and permissions (CBLD).

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

Mask capability permissions

Mnemonics

acperm cd, cs1, rs2

Encoding
Diagram
Description

ACPERM performs the following operations:

  1. Convert the AP and SDP fields of capability cs1 into a bit field with the format shown in Figure 5.

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

    Some permission bits may be hardwired, in which case they are not included in this bitwise AND.
  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 case the requested permissions combination falls into this category, ACPERM will return useful minimal sets of permissions, which may be no permissions. Therefore, it is possible that requesting to clear a permission also clears others, but ACPERM will never add new permissions.
  4. Copy cs1 to cd, and update the AP and SDP fields with the newly calculated versions.

  5. Set cd.tag=0 if cs1 is sealed and any permission bits were affected by ACPERM.

    1. Do not invalidate the tag on sealed capability if only the capability levels (CL) changed.

The EL, SL and CL fields are only modifiable if the implementation supports Zcheri1lvl, for Zcheri0lvl they are hardwired to 1.
Diagram
Figure 5. 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 tagged capabilities which have malformed bounds, have reserved bits set or have a permission field which cannot be produced by ACPERM.

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

2.6.3. SCHI

Synopsis

Capability set metadata

Mnemonic

schi cd, cs1, rs2

Encoding
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 representable 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 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
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.4). This is not the case when the implementation supports the capability encoding described in Appendix A.
Operation
let cs1_val = C(cs1);
let inCap = clearTagIf(cs1_val, capIsSealed(cs1_val));
C(cd) = sealCap(inCap);
RETIRE_SUCCESS

2.6.8. CBLD

Synopsis

Capability build

Mnemonic

cbld cd, cs1, cs2

Encoding
Diagram
Description

Copy cs2 to cd.

Set cd.tag=1 if:

  1. cs1.tag is set, and

  2. cs1 's bounds are not malformed, and all reserved fields are zero, and

  3. cs1 's permissions could have been legally produced by ACPERM, and

  4. cs1 is not sealed, and

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

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

    With Zcheri0lvl this check always passes as the level is hardwired.
  7. cs2 's bounds are not malformed, and all reserved fields are zero, and

  8. cs2 's permissions could have been legally produced by ACPERM, and

  9. All reserved bits in cs2 's metadata are 0;

    Otherwise, set cd.tag=0

CBLD is typically used alongside SCHI to build capabilities from integer values.
When cs1 is c0 this will copy cs2 to cd and clear cd.tag. However this may change in future extensions, and so software should not assume cs1==0 to be a pseudo-instruction for tag clearing.
Operation
  let cs1_val = C(cs1);
  let cs2_val = C(cs2);

  let tag = cs1_val.tag &
            not(capIsSealed(cs1_val)) &
            capIsSubset(cs2_val, cs1_val); /* Subset checks for malformed bounds,
                                              perms, and reserved bits */

  C(cd) = { cs2_val with tag = tag };
  RETIRE_SUCCESS

2.7. Instructions Which Inspect Capability Data

2.7.1. Instructions Which Decode Capability Bounds

The bounds describing the range of addresses the capability gives access to are stored in a compressed format. These instructions query the bounds and related information.

Table 7. 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 Which Extract Capability Fields

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

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

GCTAG

Get tag field

GCPERM

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

GCTYPE

Get capability type

GCHI

Get 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 permissions from the format in Table 16.

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

If the AP field cannot be produced by ACPERM then all architectural permission bits in rd are set to 0.

Diagram
Figure 6. Capability permissions bit field
When Zcheri0lvl is implemented, the CL, SL, and EL fields always report 1. This ensures forwards-compatibility with Zcheri1lvl since loads/stores on a core without dynamic levels behave as if these permissions are always present.
Any future extension that defines new permission that are a refinement of existing permissions (e.g., finer-grained ASR-permission) must be allocated to the bits that are currently reported as 1 to ensure forward-compatibility. Completely new permissions (e.g., sealing) should use the bits that are reported as zero in the current specification.
The value of cs1.tag does not affect the result.
Operation
let capVal = C(cs1);
X(rd) = packPerms(getArchPermsLegalized(capVal), capVal.sd_perms).bits;
RETIRE_SUCCESS

2.7.7. GCTYPE

Synopsis

Capability get type

Mnemonic

gctype rd, cs1

Encoding
Diagram
Description

Decode the architectural capability type from cs1 and write the result to rd.

The value of cs1.tag does not affect the result.
While the architectural capability type maps directly to the value of the CT capability bit in RV32Y/RV64Y, future extensions may define an alternate mapping. Therefore, software should always use GCTYPE to obtain the capability type rather than directly reading the high bits of the capability using GCHI.
Operation
let capVal = C(cs1);
X(rd) = zero_extend(bool_to_bits(capVal.sealed));
RETIRE_SUCCESS

2.7.8. GCHI

Synopsis

Capability get metadata

Mnemonic

gchi rd, cs1

Encoding
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 Which Handle Capability Data

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

    With Zcheri0lvl this check always passes as the level is hardwired.
  4. neither cs1 or cs2 have bounds which are malformed, and

  5. neither cs1 or cs2 have any bits set in reserved fields, and

  6. neither cs1 or cs2 have permissions that could not have been legally produced by ACPERM

Otherwise set rd to 0.

The implementation of this instruction is similar to CBLD, although SCSS does not include the sealed bit in the check.
Operation
  let cs1_val = C(cs1);
  let cs2_val = C(cs2);

  X(rd) = zero_extend(bool_bits(
    (cs1_val.tag == cs2_val.tag) &
    capIsSubset(cs2_val, cs1_val) /* capIsSubset returns false if either input
                                     has malformed bounds, perms, or non-zero
                                     reserved bits */
  ));
  RETIRE_SUCCESS

2.8.3. CRAM

Synopsis

Get Capability Representable Alignment Mask (CRAM)

Mnemonic

cram rd, rs1

Encoding
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 Which Load and Store Capability Data

New loads and stores are introduced to handle capability data, LC and SC. They atomically access CLEN-bits of data and the associated valid tag.

All capability memory accesses check for C-permission in the authorizing capability in cs1.

If C-permission is granted then:

  • 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 a misaligned exception if this requirement is not met. They cannot be emulated.

ARC request that this become an access fault

All memory accesses, of any type, require permission from the authorizing capability in cs1.

  • All loads require R-permission, otherwise they raise an exception

  • All stores require W-permission, otherwise they raise an exception

Under some circumstances LC will modify metadata before returning the value. See LC for details.

Table 10. 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 trap (with a CHERI tag violation), as c0 is defined to always hold a NULL capability. As such, the encodings with a cs1=c0 are RESERVED for use by future extensions.
Description

Calculate the effective address of the memory access by adding the address of cs1 to the sign-extended 12-bit offset.

Authorize the memory access with the capability in cs1.

Load a naturally aligned CLEN-bit data value and the associated valid tag from memory.

Write the CLEN-bit data and the valid tag to cd and conditionally update them as specified below.

This instruction can propagate tagged capabilities which have malformed bounds, have reserved bits set or have a permission field which cannot be produced by ACPERM.

Any instance of this instruction with a cs1=c0 will trap (with a CHERI tag violation), 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.
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

If Zcheri1lvl is implemented, then also see Table 4.

Missing EL-permission also affects the level of sealed capabilities since notionally the Capability Level (CL) of a capability is not a permission but rather a data flow label attached to the loaded value.
While the implicit ACPERM introduces a dependency on the loaded data, implementations can avoid this by deferring the actual masking of permissions until the loaded capability is dereferenced or the metadata bits are inspected using GCPERM or GCHI. Additionally, metadata modifications are on naturally aligned data, and so on the read path from a data cache, the modification typically happens in parallel with data alignment multiplexers.

ARC feedback: this is change relative to 0.9.5 so that the choice is removed. Choosing the other option would need to be a future extension

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

Exceptions

ARC feedback: needs to be an access fault as it can’t be emulated

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

ARC suggestion: consider software check fault

CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):

Kind Reason

Tag violation

Authorizing capability valid tag set to 0, or has any reserved bits set

Seal violation

Authorizing capability is sealed

Permission violation

Authorizing capability does not grant R-permission, or the AP field could not have been produced by ACPERM

Bounds violation

At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds

Operation
  let offset : xlenbits = sign_extend(imm);
  let (auth_val, vaddr) = get_cheri_mode_cap_addr(rs1_cs1, offset);
  let aq : bool = false;
  let rl : bool = false;

  match check_and_handle_load_vaddr_for_triggers(vaddr, get_arch_pc()) {
    Some (ret) => return ret,
    None () => ()
  };
  if not(capTaggedAndReservedValid(auth_val)) then {
    handle_cheri_exception(CapCheckType_Data, CapEx_TagViolation);
    RETIRE_FAIL
  } else if capIsSealed(auth_val) then {
    handle_cheri_exception(CapCheckType_Data, CapEx_SealViolation);
    RETIRE_FAIL
  } else if not(canR(auth_val)) then {
    handle_cheri_exception(CapCheckType_Data, CapEx_PermissionViolation);
    RETIRE_FAIL
  } else if not(validAddrRange(vaddr, cap_size) | capBoundsInfinite(auth_val)) then {
    handle_cheri_exception(CapCheckType_Data, CapEx_InvalidAddressViolation);
    RETIRE_FAIL
  } else if not(inCapBounds(auth_val, vaddr, cap_size)) then {
    handle_cheri_exception(CapCheckType_Data, CapEx_LengthViolation);
    RETIRE_FAIL
  } else if not(is_aligned_addr(vaddr, cap_size)) then {
    handle_mem_exception(vaddr, E_Load_Addr_Align());
    RETIRE_FAIL
  } else match translateAddr(vaddr, Read(Cap)) {
    TR_Failure(E_Extension(_)) => { internal_error(__FILE__, __LINE__, "unexpected cheri exception for cap load") },
    TR_Failure(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
    TR_Address(addr, pbmt, ptw_info) => {
      let c = mem_read_cap(addr, pbmt, aq, aq & rl, false);
      match c {
        MemValue(v) => {
          let cr = clearTagIf(v, ptw_info.ptw_lc == PTW_LC_CLEAR | not(canC(auth_val)));
          C(cd) = legalizeLM(cr, auth_val);
          RETIRE_SUCCESS
        },
        MemException(e) => {handle_mem_exception(vaddr, e); RETIRE_FAIL }
      }
    }
  }

2.9.2. SC

Synopsis

Store capability

Mnemonic

sc cs2, offset(cs1)

Encoding
Diagram
Description

Calculate the effective address of the memory access by adding the address of cs1 to the sign-extended 12-bit offset.

Authorize the memory access with the capability in cs1.

Store a naturally aligned CLEN-bit data value in cs2 to memory and the associated valid tag in cs2.

This instruction can propagate tagged capabilities which have malformed bounds, have reserved bits set or have a permission field which cannot be produced by ACPERM.

Any instance of this instruction with a cs1=c0 will trap (with a CHERI tag violation), 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).

Exceptions

ARC feedback: needs to be an access fault as it can’t be emulated

Misaligned address fault exception when the effective address is not aligned to CLEN/8 if Zam is supported, otherwise store access fault exception.

ARC suggestion: consider software check fault

CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):

Kind Reason

Tag violation

Authorizing capability valid tag set to 0, or has any reserved bits set

Seal violation

Authorizing capability is sealed

Permission violation

Authorizing capability does not grant W-permission, or the AP field could not have been produced by ACPERM

Bounds violation

At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds

Operation
  let offset : xlenbits = sign_extend(imm);
  let (auth_val, vaddr) = get_cheri_mode_cap_addr(rs1_cs1, offset);
  let cs2_val = C(cs2);
  let aq : bool = false;
  let rl : bool = false;
  let cs2_val = clearTagIf(cs2_val, not(canC(auth_val)));

  match check_and_handle_store_vaddr_for_triggers(vaddr, get_arch_pc()) {
    Some (ret) => return ret,
    None () => ()
  };
  if not(capTaggedAndReservedValid(auth_val)) then {
    handle_cheri_exception(CapCheckType_Data, CapEx_TagViolation);
    RETIRE_FAIL
  } else if capIsSealed(auth_val) then {
    handle_cheri_exception(CapCheckType_Data, CapEx_SealViolation);
    RETIRE_FAIL
  } else if not(canW(auth_val)) then {
    handle_cheri_exception(CapCheckType_Data, CapEx_PermissionViolation);
    RETIRE_FAIL
  } else if not(validAddrRange(vaddr, cap_size) | capBoundsInfinite(auth_val)) then {
    handle_cheri_exception(CapCheckType_Data, CapEx_InvalidAddressViolation);
    RETIRE_FAIL
  } else if not(inCapBounds(auth_val, vaddr, cap_size)) then {
    handle_cheri_exception(CapCheckType_Data, CapEx_LengthViolation);
    RETIRE_FAIL
  } else if not(is_aligned_addr(vaddr, cap_size)) then {
    handle_mem_exception(vaddr, E_SAMO_Addr_Align());
    RETIRE_FAIL
  } else match translateAddr(vaddr, Write(if cs2_val.tag then Cap else Data)) {
    TR_Failure(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
    TR_Address(addr, pbmt, _) => {
      let eares : MemoryOpResult(unit) = mem_write_ea_cap(addr, aq & rl, rl, false);
      match (eares) {
        MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
        MemValue(_) => {
          let res : MemoryOpResult(bool) = mem_write_cap(addr, pbmt, cs2_val, aq & rl, rl, false);
          match (res) {
            MemValue(true)  => RETIRE_SUCCESS,
            MemValue(false) => internal_error(__FILE__, __LINE__, "store got false from mem_write_value"),
            MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }
          }
        }
      }
    }
  }

2.10. Changes to Existing RISC-V Base ISA Instructions

RV32Y/RV64Y extend existing instructions which are used for handling addresses so that they manipulate a whole capability. The affected operands change type from x to c to represent this, and/or the PC is replaced by the pcc

In the base ISA this affects AUIPC (RV32Y/RV64Y) and all jumps and branches as well as all loads and stores.

The rules for modifying the behavior of such instructions are:

  • The result written to the target register is always unchanged.

    • The lower XLEN-bits are always written with the value from RV32I/RV64I.

  • Whenever the PC is handled, it is always the pcc.

  • Any instruction that has a base address register (generally rs1) reads the full capability register (cs1) instead.

  • Any instruction writes back an address (e.g., AUIPC (RV32Y/RV64Y)), writes a full capability register instead.

  • Whenever the address field of any capability (including the pcc) is modified, it is always updated using SCADDR semantics.

    • This includes adding an offset to the pcc from jumps and branches for both the target address and the link register. In this case, e.g., new_pcc = SCADDR(old_pcc, offset)

  • All jumps and branches check that a minimum sized instruction is in bounds of the target pcc.

    • An exception is taken by the branch or jump on failure.

  • JALR (RV32Y/RV64Y) copies all of cs1 into the pcc. If cs1 is not suitable for execution then an exception is taken on the JALR (RV32Y/RV64Y) (see pcc for the definition of suitability).

  • Any memory access instruction that has a base address register (generally rs1) reads the full capability register (cs1) instead which is used to check whether the access is permitted, taking an exception if it is not.

  • Whenever the address field of any capability (including the pcc) is modified, it is always updated using SCADDR semantics.

    • This includes adding an offset to the pcc from jumps and branches for both the target address and the link register. In this case, e.g., new_pcc = SCADDR(old_pcc, offset)

  • All jumps and branches check that a minimum sized instruction is in bounds of the target pcc.

    • An exception is taken by the branch or jump on failure.

  • JALR (RV32Y/RV64Y) copies all of cs1 into the pcc. 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 11, and also apply to instructions added by other extensions (e.g. floating-point/vector loads/stores or the shift-and-add instruction from Zba).

These rules also apply to instructions added by other extensions (e.g., floating-point/vector loads/stores or the shift-and-add instruction from Zba).
Exceptions are taken on the branch or jump which cause an exception, not at the target, to reduce the attack surface and also to aid with debugging. Therefore it is not possible to execute from a memory location without having already checked that execution of that location is authorized.
Table 11. 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 need to push the AUIPC instruction into the same extension as the capability encoding

Operation
let off : xlenbits = sign_extend(imm @ 0x000);
let (representable, newCap) = setCapAddr(PCC, PC + off);
C(cd) = clearTagIf(newCap, not(representable));
RETIRE_SUCCESS

2.10.2. JAL (RV32Y/RV64Y)

Synopsis

Jump and link

Mnemonic

jal cd, offset

Encoding
Diagram
Description

JAL’s immediate encodes a signed offset in multiple of 2 bytes. The pcc is incremented by the sign-extended offset to form the jump target capability. The target capability is written to pcc. The pcc of the next instruction following the jump is sealed and written to cd.

Exceptions

CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):

Kind Reason

Bounds violation

Minimum length instruction is not within the pcc's bounds.

Operation
let off : xlenbits = sign_extend(imm);
let newPC = PC + off;
if not(validAddr(newPC) | capBoundsInfinite(PCC)) then {
  handle_cheri_exception(CapCheckType_JBr, CapEx_InvalidAddressViolation);
  RETIRE_FAIL
} else if not(inCapBounds(PCC, newPC, min_instruction_bytes())) then {
  handle_cheri_exception(CapCheckType_JBr, CapEx_LengthViolation);
  RETIRE_FAIL
} else if newPC[1] == bitone & not(extensionEnabled(Ext_Zca)) then {
  handle_mem_exception(newPC, E_Fetch_Addr_Align());
  RETIRE_FAIL
} else {
  let (success, linkCap) = setCapAddr(PCC, nextPC); /* Note that nextPC accounts for compressed instructions */
  assert(success, "Link cap should always be representable.");
  assert(not(capIsSealed(linkCap)), "Link cap should always be unsealed");
  C(cd) = sealCap(linkCap);
  set_next_pc(newPC);
  RETIRE_SUCCESS
}

2.10.3. JALR (RV32Y/RV64Y)

Synopsis

Jump and link register

Mnemonic

jalr cd, cs1, offset

Integer Pointer Mode Mnemonic

jalr rd, rs1, offset

Encoding
Diagram
This instruction is extended from the version in the base ISA.
Description

JALR allows unconditional, indirect jumps to a target capability in cs1. The target capability is unsealed if the offset is zero. The target address is obtained by adding the sign-extended 12-bit offset to cs1.address, then setting the least-significant bit of the result to zero. The pcc of the next instruction following the jump is sealed and written to cd.

Exceptions

CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):

Kind Reason

Tag violation

cs1 has tag set to 0, or has any reserved bits 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 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 the address field of pcc.

Exceptions

CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):

Kind Reason

Bounds violation

Minimum size instruction is not within the pcc's bounds.

2.10.5. Load and Store Instructions (RV32Y/RV64Y)

All load and store instructions behave as described in Load and Store Instructions with one fundamental difference:

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

All load and store instructions authorized by cs1 cause CHERI exceptions if any of these checks fails:

  • cs1 must not be c01

  • The valid tag (cs1.tag) must be set, and there must be no reserved bits set in cs1

  • cs1 must be unsealed

  • All bytes of accessed memory must be inside cs1’s bounds, and the bounds can’t be malformed.

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

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

1 All load/store encodings are reserved if cs1=c0 (since dereferencing NULL always faults). This principle is extended to all loads and stores authorized by cs1.

Load instructions, except for LC, always zero the valid tag and metadata of the result register.

Store instructions, except for SC, always write zero to the valid tag or tags associated with the memory locations that are written to.

Therefore, misaligned stores may clear up to two associated valid tag bits.

The changed interpretation of the base register also applies to all loads, stores and other memory operations defined in later chapters of this specification with a base operands of rs1 unless stated otherwise.

this applies to all existing loads and stores including integer, floating-point and vector.

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

3. "Zcherihybrid" Extension for CHERI Integer Pointer Mode

This chapter will appear in the unpriv spec somewhere after the Zicsr chapter (since it depends on Zicsr).

Zcherihybrid is an optional extension to the RV32Y/RV64Y base architectures. Zcherihybrid adds the ability to dynamically change the base ISA between using capability pointers for all memory references (RV32Y/RV64Y) and using integer pointers (RV32I/RV64I). The ability to choose between these two behaviors (referred to as CHERI Execution Modes) ensures CHERI can be fully compatible with the base RISC-V integers ISAs while saving instruction encoding space.

Additionally, Zcherihybrid adds a new unprivileged CSR: the default data capability, ddc, that is used to authorize all data memory accesses when treating pointers as integers.

Together with pcc, ddc allows confining code runs to a compartment (also called a sandbox), where all data memory and instruction memory accesses are bounded to fixed memory regions.

The remainder of this section describes these features in detail as well as their integration with the primary base integer variants of the base RISC-V ISA.

Implementations that support both RV32Y/RV64Y and Zcherihybrid have full binary compatibility with all existing ratified RISC-V base architectures and extensions.

3.1. CHERI Execution Mode

The two execution modes are:

Integer Pointer Mode

Executing with RV32I/RV64I base ISA.

All RV32Y/RV64Y instructions and CSRs are also available in Zcherihybrid.

All instructions from existing RISC-V extensions can be run in Integer Pointer Mode. This execution mode is fully binary compatible with non-CHERI-aware programs.
Capability Pointer Mode

Executing with the RV32Y/RV64Y base ISA.

Some instructions in the RV32I/RV64I base ISA (and in some other extensions) use capabilities instead of integers for memory references (see Section 2.10). In these cases, such as SH1ADD (RV32Y/RV64Y), the lower XLEN-bits of the result is the same in either mode and the upper XLEN-bits, and valid tag, are either handled as capabilities in Capability Pointer Mode, or are ignored in the source and written to zero in Integer Pointer Mode

The CHERI Execution Mode impacts the instruction set in the following way:

  • The authorizing capability used to execute memory access instructions depends on the mode. In Integer Pointer Mode, ddc is implicitly used. In Capability Pointer Mode, the authorizing capability is supplied as an explicit c operand to the instruction.

The CHERI Execution Mode is key in providing backwards compatibility with the base RV32I/RV64I ISA. RISC-V software is able to execute unchanged in implementations supporting both RV32Y/RV64Y and Zcherihybrid provided that the privileged environment sets up ddc and pcc appropriately.

The CHERI execution mode is always Capability Pointer Mode on implementations that support RV32Y/RV64Y, but not Zcherihybrid.
RV32Y/RV64Y implementations which support Zcherihybrid are typically referred to as CHERI Hybrid, whereas implementations which do not support Zcherihybrid are typically referred to as CHERI purecap.

3.1.1. CHERI Execution Mode Effect On Existing Encodings

All RV32I/RV64I instructions are available in both CHERI execution modes.

3.1.2. CHERI Execution Mode Encoding

The CHERI Execution Mode is determined by a bit in the metadata of the pcc called the M-bit. Zcherihybrid adds a new CHERI Execution Mode field (M) to the capability format. Although always present, it only takes effect in code capabilities, i.e., when the X-permission is set. The exact location of the M-bit in the capability format for XLEN=32 and XLEN=64 is described in Appendix A.

  • Mode (M)=0 indicates Capability Pointer Mode.

  • Mode (M)=1 indicates Integer Pointer Mode.

While the M-bit only has a effect when installed in pcc, it needs to be encoded in all capabilities. Since indirect jumps copy the full target capability into pcc, it allows indirect jumps to change between modes (see Section 3.1.3).

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

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

3.2. Added State

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

Table 13. 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 7. Unprivileged default data capability register
CHERI register and instruction access is not required for the implicit access required by checking memory accesses against ddc.
ddc is a data pointer, so it does not need to be able to hold all possible invalid addresses (see Invalid address conversion).

3.3. Zcherihybrid Memory Accesses

In Capability Pointer Mode all memory accesses behave as defined by RV32Y/RV64Y and are authorised by the base register (cs1), from which the bounds and permissions are taken. For example:

  • lw t0, 16(ca0)

In Integer Pointer Mode the lw has the same behavior and assembly syntax as the RV32I/RV64I:

  • lw t0, 16(a0)

All memory accesses must still be checked, but now they are authorized by the capability in ddc instead.

3.4. Zcherihybrid Branches and Jumps

The rules from Section 2.10 are applied, so that all branch and jump targets are checked against pcc.

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 14. 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 permissions can be 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 cannot be 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

RV32Y/RV64Y extends all RISC-V CSRs which hold addresses, to hold capabilities. Therefore, such registers are extended to CLEN-bits in RV32Y/RV64Y and a c suffix is added when referring to the entire CSR instead of the only the address field.

This assumes that the Zcmt CSR is extended to be a capability when the base architecture is RV32Y/RV64Y.

For example, the jvt CSR is extended to jvtc, the c suffix indicating that it’s a capability. It is referred to as jvt if only accessing the address or jvtc if accessing the whole capability.

  • In Capability Pointer Mode CSRRW (RV32Y/RV64Y) always read/writes the entire CLEN-bits of all CLEN-width CSRs, i.e., it accesses jvtc.

  • In Integer Pointer Mode CSRRW (RV32Y/RV64Y) only accesses XLEN-bits of extended CSRs (e.g., jvt, for compatibility) and all CLEN-bits of CSRs added by CHERI extensions (e.g., ddc).

    • CSRRW (RV32Y/RV64Y) in Integer Pointer Mode can only update the address field of jvt, but it can write a full value into ddc.

    • Capability Pointer Mode always accesses jvtc, never jvt.

  • when only writing XLEN-bits to an extended CSR (e.g., jvt), the CSR value is updated using SCADDR semantics.

need to resolve how to cross-reference the privileged spec to have a list of the new and extended CSRs

When any CLEN-width CSR is accessed with another CSR instruction:

The following rules apply:

  • The final address is calculated according to the standard RISC-V CSR rules (set bits, clear bits etc).

  • The final address is updated as specified in the privileged specification for an XLEN write.

    • Unless specified otherwise, the update uses SCADDR semantics

  • When accessing an extended CSR:

    • In Integer Pointer Mode, XLEN-bits are read from the capability address field and written to an output x register.

    • In Capability Pointer Mode, CLEN-bits are read from the CSR and written to an output c register.

  • When accessing a CSR added by a CHERI extension:

    • CLEN-bits are read from the CSR and written to an output c register.

3.7.1. CSRRWI (RV32Y/RV64Y)

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-wide CSRs (RV32Y/RV64Y)

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

Mnemonics for accessing XLEN-wide CSRs or extended CSRs in Integer Pointer Mode

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

Encoding
Diagram
Description

These are standard RISC-V CSR instructions with extended functionality for accessing CLEN-wide CSRs (see Table 61), including extended CSRs with actions as shown in

For CLEN-wide CSRs, the full capability is read into cd in Capability Pointer Mode. In Integer Pointer Mode, the address field is instead read into rd.

Unlike CSRRW (RV32Y/RV64Y), these instructions only update the address field and the valid tag as defined in Table 58 when writing CLEN-wide CSRs regardless of the execution mode. The final address to write to the capability CSR is determined as defined by RISC-V for these instructions.

See Table 57 for a list of CLEN-wide CSRs and Table 58 for the action taken on writing an XLEN-wide value to each one.

If cd is c0 (or rd is x0), then CSRRWI shall not read the CSR and and shall not cause any of the side effects that might occur on a CSR read. If rs1 is x0 for CSRRS and CSRRC, or imm is 0 for CSRRSI and CSRRCI, then the instruction will not write to the CSR at all, and so shall not cause any of the side effects that might otherwise occur on a CSR write.

The assembler pseudoinstruction to read a capability CSR in Capability Pointer Mode, csrr cd, csr, is encoded as csrrs cd, csr, x0.

Access to XLEN-wide CSRs is as specified by RISC-V.

If the CSR accessed is a capability, and rs1 is x0 for CSRRS and CSRRC, or imm is 0 for CSRRSI and CSRRCI, then the CSR is not written so no representability check is needed in this case.
Permissions

Accessing privileged CSRs may require ASR-permission, including existing RISC-V CSRs, as described in (RISC-V, 2023).

Prerequisites for Capability Pointer Mode

RV32Y/RV64Y

Prerequisites for Integer Pointer Mode

Zcherihybrid

Operation
TBD

3.7.6. CSRRW (RV32Y/RV64Y)

Synopsis

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

Mnemonic for accessing CLEN-wide CSRs in Capability Pointer Mode

csrrw cd, csr, cs1

Mnemonic for accessing XLEN-wide CSRs or extended CSRs in Integer Pointer Mode

csrrw rd, csr, rs1

Encoding
Diagram
Description

These are standard RISC-V CSR instructions with extended functionality for accessing CLEN-wide CSRs (see Table 61).

See Table 57 for a list of CSRs extended to capabilities and Table 58 for the action taken on writing each one.

CLEN-wide CSRs and the action taken on accessing them is shown in Table 59.

CSRRW writes cs1 to extended CSRs in Capability Pointer Mode, and reads a full capability into cd.

CSRRW writes cs1 to CLEN-wide CSRs in both modes, and reads a full capability into cd.

CSRRW writes rs1 to extended CSRs in Integer Pointer Mode, and reads the address field into rd.

If cd is c0 (or rd is x0), then the instruction shall not read the CSR and shall not cause any of the side effects that might occur on a CSR read.

The assembler pseudoinstruction to write a capability CSR csrw csr, cs1, is encoded as csrrw c0, csr, cs1.

Access to XLEN-wide CSRs from other extensions is as specified by RISC-V.

When writing cs1, if the bounds are malformed, any reserved bits are set, or the permission could not have been produced by ACPERM then clear the valid tag before writing to the CSR.
Permissions

Accessing privileged CSRs may require ASR-permission, including existing RISC-V CSRs, as described in (RISC-V, 2023).

Prerequisites for Capability Pointer Mode

RV32Y/RV64Y

Prerequisites for Integer Pointer Mode

Zcherihybrid

Operation
TBD

4. "Zish4add" Extension for 16-byte pointer addition, Version 0.9

This chapter will appear in the unpriv spec (see github.com/riscv/riscv-isa-manual/pull/1923).

The B-extension adds SH[1|2|3]ADD instructions, and for RV64 all have an unsigned word *.UW version.

Zish4add adds two new analogous instructions to RV64: SH4ADD and SH4ADD.UW.

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.

6. Integrating RV32Y/RV64Y and Zcherihybrid with the Vector Extension

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

The RISC-V vector (V) extension is orthogonal to CHERI because the vector registers only hold integer or floating-point data. The vector registers are not extended to hold capabilities.

A future extension may allow tags to be stored in vector registers. Until that time, vector load and store instructions must not be used to implement generic memory copying in software, such as the memcpy() standard C library function, because the vector registers do not hold capabilities, so the valid tags of any copied capabilities will be set to 0 in the destination memory.

Vector loads and stores all follow the behavior as described in Loads and Stores.

The assembly syntax of all vector loads and stores are updated in Capability Pointer Mode, so that the address operand becomes a c operand instead of an x operand.

According to the vector extension (RISC-V, 2021) only active elements are accessed or updated in memory. Therefore only active elements are subject to CHERI exception checks. If a vector load or store has no active elements then no CHERI fault will be taken.

This is consistent with other exceptions such as page faults which are only taken on active elements.

In the case of fault-only-first loads, a CHERI bounds violation is only taken if any bytes of element 0 are out of bounds, or if the CHERI bounds are malformed and there are any active elements. If another active element causes a CHERI bounds violation then it is treated the same way as other exceptions, the trap is not taken and instead vl is reduced. All other CHERI fault types, such as tag violations, are only taken if element zero is active.

Indexed loads in Capability Pointer Mode check the bounds of every access against the authorizing capability in cs1. Therefore the approach of having a zero base register and treating every element as an absolute address may not work well in this mode.

Appendix A: Anatomy of Capabilities in RV32Y/RV64Y

This chapter will appear as an appendix in the unpriv specification.

RISC-V defines variants of the base integer instruction set characterized by the width of the integer registers and the corresponding size of the address space. There are two primary ISA variants, RV32I and RV64I, which provide 32-bit and 64-bit address spaces respectively. The term XLEN refers to the width of an integer register in bits (either 32 or 64). The value of XLEN may change dynamically at run-time depending on the values written to CSRs, so we define capability behavior in terms of MXLEN, which is the value of XLEN used in machine mode and the widest XLEN the implementation supports.

RV32Y/RV64Y assumes a version of the privileged architecture which defines MXLEN as constant and requires higher privilege modes to have at least the same XLEN as lower privilege modes; these changes are present in the current draft and expected to be part of privileged architecture 1.13.

RV32Y/RV64Y defines capabilities of size CLEN corresponding to 2 * MXLEN without including the valid tag bit. The value of CLEN is always calculated based on MXLEN regardless of the effective XLEN value.

We briefly note that the capability encoding described in this section could be replaced with an entirely different design without changing how CHERI integrates with the RISC-V ISA. In particular, this capability encoding specification was designed to run software initially ported to CHERIv9 while providing spatial safety, temporal safety and compartmentalization support alongside a good measure of compatibility with RISC-V software that is not aware of CHERI. Alternative capability encoding specifications must provide key primitives, such as permissions and bounds, from this specification while using a different encoding that, for example, changes the granularity of bounds or adds new features. For simplicity of expression, the text is written as if this was the only possible capability encoding for CHERI RISC-V.

A.1. Capability Encoding

The components of a capability, except the valid tag, are encoded as shown in Figure 8 for MXLEN=32 and Figure 9 for MXLEN=64. Each memory location or register able to hold a capability must also store the valid tag as out of band or hidden information that software cannot directly set or clear. The capability metadata is held in the most significant bits and the address is held in the least significant bits.

Diagram
Figure 8. Capability encoding for MXLEN=32
Diagram
Figure 9. Capability encoding for MXLEN=64

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

Reserved bits must be 0 in tagged capabilities.

The encoding of capabilities depends on the extensions supported by the current environment. The following extensions affect the capability encoding:

Zcherihybrid

When Zcherihybrid is supported, capabilities include a M-bit. If not supported this field becomes reserved and reads as zero.

Zcheri0lvl/Zcheri1lvl

Implementations of RV32Y/RV64Y may choose how many Capability Level (CL) bits (LVLBITS) to support. The CL field is variable width and depends on which of the mutually exclusive extensions Zcheri0lvl or Zcheri1lvl is supported.

  • When Zcheri0lvl is supported, then LVLBITS=0 and capability levels are not dynamically adjustable. Therefore, EL-permission, SL-permission and the Capability Level (CL) are hardwired to 1 and not encoded in the capability format. In this case, all capability checks related to levels always pass.

  • When Zcheri1lvl is supported, then LVLBITS=1 and capability levels are dynamically adjustable. All of EL-permission, SL-permission and the Capability Level (CL) are one bit wide and are encoded in the capability format memory.

Future extensions may increase the width of this field.

A.1.1. Architectural Permissions (AP) Encoding

The bit width of the permissions field depends on the value of MXLEN as shown in Table 15. A 5-bit vector encodes the permissions when MXLEN=32. For this case, the legal encodings of permissions are listed in Table 16. Certain combinations of permissions are impractical. For example, C-permission is superfluous when the capability does not grant either R-permission or W-permission. Therefore, it is only possible to encode a subset of all combinations.

Table 15. Permissions widths depending on MXLEN
MXLEN AP field width Comment

32

5

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

64

6/81

Separate bits for each architectural permission.

1 If Zcheri0lvl is supported this field is 6 bits wide, with Zcheri1lvl it uses 8 instead.

For MXLEN=32, the permissions encoding is split into four quadrants. The quadrant is taken from bits [4:3] of the permissions encoding. The meaning for bits [2:0] are shown in Table 16 for each quadrant.

Quadrants 2 and 3 are arranged to implicitly grant future permissions which may be added with the existing allocated encodings. Quadrant 0 does the opposite - the encodings are allocated not to implicitly add future permissions, and so granting future permissions will require new encodings. Quadrant 1 encodes permissions for executable capabilities and the M-bit.

Table 16. Encoding of architectural permissions for MXLEN=32 when Zcheri0lvl is implemented
Encoding[2:0] R W C LM X ASR Mode1 Notes

Quadrant 0: Non-capability data read/write

bit[2] - write, bit[1] - reserved (0), bit[0] - read

Reserved bits for future extensions are 0 so new permissions are not implicitly granted

0

N/A

No permissions

1

N/A

Data RO

2-3

reserved

4

N/A

Data WO

5

N/A

Data RW

6-7

reserved

Quadrant 1: Executable capabilities

bit[0] - M-bit (0-Capability Pointer Mode, 1-Integer Pointer Mode)

0-1

Mode1

Execute + ASR (see Infinite)

2-3

Mode1

Execute + Data & Cap RO

4-5

Mode1

Execute + Data & Cap RW

6-7

Mode1

Execute + Data RW

Quadrant 2: Restricted capability data read/write

R and C implicitly granted, LM dependent on W permission.

Reserved bits for future extensions must be 1 so they are implicitly granted

bit[2] is reserved to mean write for future encodings

0-2

reserved

3

N/A

Data & Cap RO (no LM)

4-7

reserved

Quadrant 3: Capability data read/write

bit[2] - write, R and C implicitly granted.

Reserved bits for future extensions must be 1 so they are implicitly granted

0-2

reserved

3

N/A

Data & Cap RO

4-6

reserved

7

N/A

Data & Cap RW

1 Mode (M-bit) can only be set on a tagged capability when Zcherihybrid is supported. Despite being encoded here it is not an architectural permission.

When MXLEN=32 there are many reserved permission encodings (see Table 16). It is not possible for a tagged capability to have one of these values since ACPERM will never create it. It is possible for untagged capabilities to have reserved values. GCPERM will interpret reserved values as if it were 0b00000 (no permissions). Future extensions may assign meanings to the reserved bit patterns, in which case GCPERM is allowed to report a non-zero value.
Mode is encoded with permissions for MXLEN=32, but is not a permission. It is orthogonal to permissions as it can vary arbitrarily using SCMODE.
Table 17. Encoding of architectural permissions for MXLEN=32 when Zcheri1lvl is implemented
Bits[4:3] R W C LM EL SL X ASR Mode1 Notes

Quadrant 0: Non-capability data read/write

bit[2] - write, bit[1] - reserved (0), bit[0] - read

Reserved bits for future extensions are 0 so new permissions are not implicitly granted

0

N/A

No permissions

1

N/A

Data RO

2-3

reserved

4

N/A

Data WO

5

N/A

Data RW

6-7

reserved

Quadrant 1: Executable capabilities

bit[0] - M-bit (0-Capability Pointer Mode, 1-Integer Pointer Mode)

Bits[4:3]

R

W

C

LM

EL

SL

X

ASR

Mode1

0-1

Mode1

Execute + ASR (see Infinite)

2-3

2

Mode1

Execute + Data & Cap RO

4-5

Mode1

Execute + Data & Cap RW

6-7

02

Mode1

Execute + Data RW

Quadrant 2: Restricted capability data read/write

bit[2] = write, bit[1:0] = store level. R and C implicitly granted, LM dependent on W permission.

Bits[4:3]

R

W

C

LM

EL

SL

X

ASR

Mode1

0-2

reserved

3

01

N/A

Data & Cap R0 (without LM-permission)

4

(3)

N/A

Reserved when LVLBITS=1 3

5

(2)

N/A

Reserved when LVLBITS=1 3

6

1

N/A

Data & Cap RW (with store local, no EL-permission)

7

0

N/A

Data & Cap RW (no store local, no EL-permission)

Quadrant 3: Capability data read/write

bit[2] = write, bit[1:0] = store level. R and C implicitly granted.

Reserved bits for future extensions must be 1 so they are implicitly granted

Bits[4:3]

R

W

C

LM

EL

SL

X

ASR

Mode1

0-2

reserved

3

02

N/A

Data & Cap R0

4

(3)

N/A

Reserved when LVLBITS=1 3

5

(2)

N/A

Reserved when LVLBITS=1 3

6

1

N/A

Data & Cap RW (with store local)

7

0

N/A

Data & Cap RW (no store local)

1 Mode (M-bit) can only be set on a tagged capability when Zcherihybrid is supported, otherwise such encodings are reserved. Despite being encoded here it is not an architectural permission.
2 SL isn’t applicable in these cases, but this value is reported by GCPERM to simplify the rules followed by ACPERM
3 These entries are reserved when LVLBITS=1 and in use when LVLBITS=2

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

Table 18. 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 with Zcheri1lvl / reserved with Zcheri0lvl

7

SL-permission with Zcheri1lvl / reserved with Zcheri0lvl

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

  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 16) or permission combinations which are not useful for MXLEN=64, such as ASR-permission set without X-permission. These cases are defined to return useful minimal sets of permissions.

When removing permissions with ACPERM the following rules are followed in order:

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

Depending on the supported extensions and permissions encoding some referenced bits may have a hardwired value. In this case the rules are applied starting with this hardwired value, and proceed as if it had been modified but any change is discarded after following the final rule. For example, RV64 without Zcherihybrid, the M-bit is a reserved bit, and so is not relevant to ACPERM. Similarly, if Zcheri0lvl is implemented then EL-permission is initialized to 1, and SL-permission is initialized to the maximum value, but the resulting EL-permission and SL-permission is discarded at the end.
Future extensions may allow more combinations of permissions, especially for MXLEN=64.

A.1.2. Software-Defined Permissions (SDP) Encoding

The width of the SDP field depends on the underlying base architecture. The value of the SDP bits of the GCPERM result maps 1:1 to the SDP field in the capability.

Table 20. 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 21.

Table 21. 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 22.

Table 22. 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 10 and Figure 11.

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

Figure 10 and Figure 11 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 23 and Table 24.

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

false

false

0

false

true

+1

true

false

-1

true

true

0

Table 24. 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)
The check is for malformed bounds, so it does not include reserved bits!

CHERI enforces the following invariants for all valid (i.e., tagged) capabilities:

  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.

A tagged capability that violates those invariants (i.e., a tagged but malformed capability or a tagged capability with any reserved bit set) can only possibly be caused by a logic or memory fault (e.g., bit flipping).

Capabilities with malformed bounds:

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

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

See specific instruction pages for full details of the effect of malformed capabilities.

A.2. Encoding of Special Capabilities

A.2.1. NULL Capability Encoding

The NULL capability is represented with 0 in all fields. This implies that it has no permissions and its exponent E is CAP_MAX_E (52 for MXLEN=64, 24 for MXLEN=32), so its bounds cover the entire address space such that the expanded base is 0 and top is 2MXLEN.

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

Tag

zero

Capability is not valid

SDP

zeros

Grants no permissions

AP

zeros

Grants no permissions

M

zero

No meaning since non-executable (MXLEN=64 only)

CL

zero1

Local

CT

zero

Unsealed

EF

zero

Internal exponent format

L8

zero

Top address reconstruction bit (MXLEN=32 only)

T

zeros

Top address bits

TE

zeros

Exponent bits

B

zeros

Base address bits

BE

zeros

Exponent bits

Address

zeros

Capability address

Reserved

zeros

All reserved fields

1 This field may be zero bits wide (i.e., omitted) if Zcheri0lvl is implemented.

A.2.2. Infinite Capability Encoding

The Infinite capability grants all permissions while its bounds also cover the whole address space. It includes X-permission and so includes the M-bit if Zcherihybrid is supported.

Future extension to the capability format may use a "multi-root" format where the infinite capability does not exist and instead have multiple roots with different permissions (e.g., one for code and one for data).
Table 26. 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 16)

Grants all permissions

AP (MXLEN=64)

0xFF (see Table 18)

Grants all permissions

CL

one2

Global

CT

zero

Unsealed

EF

zero

Internal exponent format

L8

zero

Top address reconstruction bit (MXLEN=32 only)

T

zeros

Top address bits

TE

zeros

Exponent bits

B

zeros

Base address bits

BE

zeros

Exponent bits

Address

zeros

Capability address

Reserved

zeros

All reserved fields

1If Zcherihybrid is supported, then the Infinite capability must represent Integer Pointer Mode for compatibility with standard RISC-V code. Therefore:

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

2 This field may be zero bits wide (i.e., omitted) if Zcheri0lvl is implemented.

A.3. Memory space

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

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

A.4. Representable Range Check

A.4.1. Concept

The new address, after updating the address of a capability, is within the representable range if decompressing the capability’s bounds with the original and new addresses yields the same base and top bounds.

In other words, given a capability with address a and the new address a' = a + x, the bounds b and t are decoded using a and the new bounds b' and t' are decoded using a'. The new address is within the capability’s representable range if b == b' && t == t'.

Changing a capability’s address to a value outside the representable range unconditionally clears the capability’s tag. Examples are:

  • Instructions such as CADD which include pointer arithmetic.

  • The SCADDR instruction which updates the capability address field.

A.4.2. Practical Information

An artifact of the bounds encoding is that if an address is changed such that t != t', then it is also the case that b != b'. The inverse is also true, if b != b' then t != t'. Therefore, for representable range checking, it is acceptable to either check t == t' or b == b'.

In the bounds encoding in this specification, the top and bottom capability bounds are formed of two or three sections:

  • Upper bits from the address

    • This is only if the other sections do not fill the available bits (E + MW < MXLEN)

  • Middle bits from T and B decoded from the metadata

  • Lower bits are set to zero

    • This is only if there is an internal exponent (EF=0)

Table 27. 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 27 to aid this description.

For the address to be valid for the current bounds encoding, the value in the Upper Section of Table 27 must not change as this will change the meaning of the bounds. This is because T, B and E will be unchanged for the source and destination capabilities. Therefore, the Middle and Lower sections of the bounds calculation are also unchanged for source and destination capabilities.

When E > CAP_MAX_E - 2, the calculation of the top bound is entirely derived from T and E which will be identical for both the source and destination capabilities, thus guaranteeing that t == t'. Likewise, with such values of E, the base bound is entirely derived from B and E and therefore b == b'.

The calculation of the MSB of the top bound maybe inverted as specified Section A.1.4.3. Assuming (E < (CAP_MAX_E - 1)), the truth-table for this inversion is as follows:

Table 28. 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 28 shows that output_t[MXLEN] does not depend on input_t[MXLEN] as:

  • output_t[MXLEN] = {input_t[MXLEN-1], b[MXLEN-1]} == 2’b01.

This leads to the conclusions:

  • If t[MXLEN-1] == t'[MXLEN-1] 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.

A.5. Extending Zcheri1lvl to more than two levels

When LVLBITS > 1, the behavior of ACPERM can no longer use masking to adjust the Capability Level (CL) or SL-permission, but instead must perform an integer minimum operation on those LVLBITS-wide fields. The CL field of the resulting capability is set to min(rs2[CL], cs1[CL]) (equivalent to rs2[CL] & cs1[CL] for LVLBITS=1). Similarly, SL-permission is set to min(rs2[SL], cs1[SL]) (equivalent to rs2[SL] & cs1[SL] for LVLBITS=1).

When storing capabilities, the SL-permission checks need to perform a LVLBITS-wide integer comparison instead of just testing a single bit. Considering for an example LVLBITS=2:

SL-permission Permitted for levels Resulting semantics

3

As low as ~0b11=0

Authorizes stores of capabilities with any level

2

As low as ~0b10=1

Strip tag for level 0 (most local), keep for 1,2,3

1

As low as ~0b01=2

Strip tag for level 0&1, keep for 2&3

0

As low as ~0b00=3

Strip tag for level 0,1,2, i.e., only the most global can be stored

While this extra negation is non-intuitive, it is required such that ACPERM can use a monotonically decreasing operation for both CL SL-permission.
The layout of the ACPERM input / GCPERM result is not yet defined, but existing bits will not be moved around so the SL/CL fields will be non-contiguous.

Chapters for the privileged specification

7. "Smcheri/Sscheri" Extensions, Version 1.0

This chapter will appear in the priv spec. Exact location TBD.

This chapter describes integration of RV32Y/RV64Y with the RISC-V privileged architecture.

7.1. Machine-Level CSRs added or extended by Smcheri

RV32Y/RV64Y extends some M-mode CSRs to hold capabilities or otherwise add new functions. ASR-permission in the pcc is typically required for access.

7.1.1. Machine Trap Vector Base Address Capability Register (mtvecc)

The mtvecc register extends mtvec to hold a code capability. Its reset value is the Infinite capability.

Diagram
Figure 12. 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 cleared. In particular, if any part of the range is in the invalid address space then clearing the valid tag is strongly recommended.

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

7.1.2. Machine Scratch Capability Register (mscratchc)

The 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 13. Machine-mode scratch capability register

7.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 14. 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 60, mepcc is a code capability, so it does not need to be able to hold all possible invalid addresses (see Invalid address conversion). Additionally, the capability in mepcc is unsealed when it is installed in pcc on execution of an MRET(RV32Y/RV64Y) instruction.

7.2. Machine-Level CSRs modified by Smcheri

7.2.1. Machine Status Registers (mstatus and mstatush)

The mstatus and mstatush registers operate as described in mstatus with two restrictions:

  • The SXL and UXL fields that control the value of XLEN for S-mode and U-mode must be read-only in implementations supporting RV32Y/RV64Y. Only 1 and 2 are supported values for SXL and UXL

  • The MBE, SBE, and UBE fields that control the memory system endianness for M-mode, S-mode, and U-mode must be read-only in implementations supporting RV32Y/RV64Y. SBE and UBE must be read only and equal to MBE, if S-mode or U-mode, respectively, is implemented, or read-only zero otherwise.

Changing XLEN or endianness would change the interpretation of all in-memory capabilities, so allowing these fields to change at runtime is prohibited.

These restrictions are relaxed if a further privileged CHERI extension, Smcherivarxlen, optionally makes SXL, UXL, MBE, SBE, and UBE writeable, to support CHERI on implementations that support dynamic XLEN or endianness changes.
CAUTION

ARC-QUESTION: Doesif Smcherivarxlen need to be a separate extension or just a "if xME,xXL bits are writable, then this behavior is followed" note in Smcheri

7.2.2. Machine Cause Register (mcause)

RV32Y/RV64Y adds a new exception code for CHERI exceptions that mcause must be able to represent. The new exception code and its priority are listed in Machine cause (mcause) register values after trap and Synchronous exception priority in decreasing priority order respectively. The behavior and usage of mcause otherwise remains as described in mcause.

The current specification uses the CHERI ISAv9 mcause value of 28, which is designated for custom extensions.
CAUTION

ARC-QUESTION: The exact code as well as the mechanism to report subcodes needs to be finalized: github.com/riscv/riscv-cheri/issues/536

If an instruction may raise multiple synchronous exceptions, the decreasing priority order of Table 29 indicates which exception is taken and reported in mcause. This table extends the existing priority order from Synchronous exception priority in decreasing priority order with new entries.

Once finalized this table should be merged with the main table.
Table 29. 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 32.

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

The full details of the CHERI exceptions with cause value 28 are in Table 34.

7.2.3. Machine Trap Delegation Register (medeleg)

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

7.2.4. Machine Trap Value Register (mtval)

The mtval register is an MXLEN-bit read-write register formatted as shown in Figure 15. When a data memory access causes a CHERI fault taken into M-mode, mtval is written with the MXLEN-bit effective address which caused the fault according to the existing rules for reporting load/store addresses. In this case the TYPE field of mtval2 shown in Table 30 is set to 1. For all other CHERI faults mtval is set to zero.

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 15. Machine trap value register

7.2.5. Machine Trap Value Register 2 (mtval2)

The mtval2 register is an MXLEN-bit read-write register, which is added as part of the Hypervisor extension (RISC-V, 2023). RV32Y/RV64Y also requires the implementation of this CSR.

When a CHERI fault, or CHERI PTE page fault, is taken into M-mode, mtval2 is written with additional CHERI-specific exception information with the format shown in Figure 16 to assist software in handling the trap.

mtval2 is written to zero for all other exceptions, except as listed otherwise by the Hypervisor extension in (RISC-V, 2023), or by other future extensions.

the use of mtval2/stval2/vstval2 may be irregular as the Hypervisor uses mtval2 and htval for guest page addresses on guest page fault, and CHERI has no use for htval.

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

mtval2 values for CHERI faults
Diagram
Figure 16. 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 16 are read-only-zero.

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

Table 30. 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 31. 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 32. 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.

7.3. Supervisor-Level CSRs added or extended by Sscheri

RV32Y/RV64Y extends some of the existing RISC-V CSRs to be able to hold capabilities or with other new functions. ASR-permission in the pcc is typically required for access.

7.3.1. Supervisor Trap Vector Base Address Capability Register (stvecc)

The stvecc register extends stvec that is able to hold a capability. Its reset value is the Infinite capability.

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

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

7.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 18. Supervisor scratch capability register

7.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 60, sepcc is a code capability, so it does not need to be able to hold all possible invalid addresses (see Invalid address conversion). Additionally, the capability in sepcc is unsealed when it is installed in pcc on execution of an SRET (RV32Y/RV64Y) instruction. The handling of sepcc is otherwise identical to mepcc, but in supervisor mode.

Diagram
Figure 19. Supervisor exception program counter capability register

7.3.4. Supervisor Trap Value Register 2 (stval2)

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

stval2 is updated following the same rules as mtval2 for CHERI exceptions and CHERI PTE page faults which are delegated to HS-mode or S-mode. It is written to zero for all other exceptions, except as listed otherwise by other future extensions.

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 20. Supervisor trap value register 2

7.4. Supervisor-Level CSRs modified by Sscheri

7.4.1. Supervisor Cause Register (scause)

RV32Y/RV64Y adds a new exception code for CHERI exceptions that scause must be able to represent. The new exception code is listed in .Supervisor cause (scause) register values after trap. The behavior and usage of scause otherwise remains as described in scause.

See Section 7.2.2 for the new exceptions priorities when RV32Y/RV64Y is implemented.

7.4.2. Supervisor Trap Value Register (stval)

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

7.5. CHERI Exception handling

ARC-QUESTION: Need feedback whether to add this info to xcause or xtval2: github.com/riscv/riscv-cheri/issues/536

CHERI faults require additional information to be reported. The CSRs updated depend on the mode the trap is taken into, as shown in Table 33.

The additional information is written for CHERI faults and CHERI PTE page faults, and is otherwise written to zero for all other exceptions, except as listed otherwise by other future extensions.

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

7.6. CHERI Exceptions and speculative execution

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

7.7. Physical Memory Attributes (PMA)

Typically, only parts of the entire memory space need to support CHERI valid tags. Therefore, it is desirable that harts supporting RV32Y/RV64Y extend PMAs with a CHERI taggable attribute indicating whether a memory region allows storing CHERI valid tags.

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

  • Cause an access fault exception

  • Implicitly set the stored tag to 0

8. "Smcherire" Extension, Version 1.0

ARC-QUESTION: The CBZE, CBIE etc. bits are specified by Zicbo*, can this be defined by Smcheri/Sscheri+Zcherihybrid instead of adding a new priv extension?

When using a system with Zcherihybrid, it may be desirable to disabling CHERI register and instruction access to some (or all) privilege levels such that they operate as a RV32I/RV64I system without any observable presence of CHERI features. Smcherire includes functions to disable explicit access to CHERI registers and instructions. The Smcherire extension makes the CRE bit of mseccfg, menvcfg, and senvcfg writable.

If RV32Y/RV64Y is supported and Zcherihybrid is not supported, then Smcherire must also not be supported. In this case all CRE bits are hardwired to 1 and access to CHERI registers is always permitted. This allows implementing a hart that always runs in Capability Pointer Mode.

CHERI register access is disabled if

  • XLEN in the current mode is less than MXLEN, or

  • the endianness in the current mode is not the reset value of mstatus.MBE, or

  • the effective CRE for the current privilege is 0.

The effective CRE for the current privilege is:

The effective CRE is always 1 in debug mode.
On reset CHERI register access is disabled (mseccfg.CRE resets to zero).

The following occurs when executing code in a privilege mode that has CHERI register access disabled:

  • Instructions that access c registers (implicitly or explicitly) cause illegal instruction exceptions

    The only instruction added by RV32Y/RV64Y that does not access capability state is CRAM, all others are disabled.
  • Executing CSR instructions accessing any CSR added by any CHERI extension (Zcherihybrid, Smcheri, Sscheri, Shcheri) causes an illegal instruction exception

  • Executing CSR instructions accessing any CSR extended to CLEN only allows XLEN access.

  • All allowed instructions execute as if the CHERI execution mode is Integer Pointer Mode.

Disabling CHERI register access has no effect on implicit accesses or security checks. The last capability installed in pcc and ddc before disabling CHERI register access will be used to authorize instruction execution and data memory accesses.

Disabling CHERI register access prevents low-privileged Integer Pointer Mode software from interfering with the correct operation of higher-privileged Integer Pointer Mode software that do not perform ddc switches on trap entry and return.

Disabling CHERI register access allows harts supporting CHERI to be fully compatible with standard RISC-V, so CHERI instructions, such as CRAM, that do not change the state of CHERI CSRs raise exceptions when CRE=0. This is the default behavior on reset.

Table 35 summarizes the behavior of a hart in connection with the CRE and the CHERI Execution Mode while in a privilege other than debug mode.

Table 35. 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 65 for a list of remapped instructions.
3 The hart is fully compatible with standard RISC-V when CRE=0 provided that pcc, mtvecc, mepcc, stvecc, sepcc, vstvecc, vsepcc and ddc have not been changed from the default reset state (i.e., hold the Infinite capability).

9. "Smcherivarxlen" Extension, Version 1.0

Smcherivarxlen eliminates some restrictions for SXL and UXL imposed in Smcheri to allow implementations supporting multiple base ISAs. This extension allows the SXL, UXL, MBE, SBE, and UBE fields of mstatus/sstatus to be writable (which is prohibited by Smcheri otherwise).

ARC-QUESTION: Should this extension be folded into the Smcherire extension?
Changing XLEN

Setting the SXL or UXL field to a value that is not MXLEN disables most CHERI features and instructions, as described in Chapter 8, while in that privilege mode.

If CHERI register access must be disabled in a mode for security reasons, software should set CRE to 0 regardless of the SXL and UXL fields.

Whenever XLEN in any mode is set to a value less than MXLEN, standard RISC-V rules from (RISC-V, 2023) are followed. This means that all operations must ignore source operand register bits above the configured XLEN, and must sign-extend results to fill all MXLEN-bits in the destination register. Similarly, pc bits above XLEN are ignored, and when the pc is written, it is sign-extended to fill MXLEN. The integer writing rule from CHERI is followed, so that every register write also zeroes the metadata and tag of the destination register.

However, CHERI operations and security checks will continue using the entire hardware register (i.e., CLEN-bits) to correctly decode capability bounds.

Changing endianness

Setting the MBE, SBE, or UBE field to a value that is not the reset value of MBE disables most CHERI features and instructions, as described in Chapter 8, while in that privilege mode.

10. "Svcheri" Extension, Version 1.0

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

Svcheri requires that the pcc grants the ASR-permission to change the page-table root satp and other virtual-memory parameters as described in Section 7.3.

10.1. Capability Write (CW) Bit

Svcheri defines the Capability Write (CW) bit in Page Table Entries (PTEs) for Sv39, Sv48, and Sv57 virtual memory systems on RV64 harts. The CW bit controls whether capabilities with their valid tag set can be written to a virtual page.

Sv32 does not have any spare PTE bits, and so this bit does not exist for RV32.
Any hart that supports RV32Y/RV64Y and at least one of the Sv39, Sv48, and Sv57 virtual memory translation schemes must also implement Svcheri.

10.1.1. Limiting Capability Propagation

ARC-QUESTION: Is this too much rationale? Should it be trimmed down and just describe the mechanism?

Page table enforcement can allow the operating system to limit the flow of capabilities between processes. It is highly desirable that a process should only possess capabilities that have been issued for that address space by the operating system. Unix processes may share memory for efficient communication, but capability pointers must not be shared across these channels into a foreign address space. An operating system might defend against this by only issuing a capability to the shared region that does not grant the load/store capability permission. However, there are circumstances where portions of general-purpose, mmapped* memory become shared, and the operating system must prevent future capability communication through those pages. This is not possible without restructuring software, as the capability for the original allocation, which spans both shared memory and private memory, would need to be deleted and replaced with a list of distinct capabilities with appropriate permissions for each range. Such a change would not be transparent to the program. Such sharing through virtual memory is on the page granularity, so preventing capability writes with a PTE permission is a natural solution.

* allocated using mmap

10.2. CHERI PTE page faults

CHERI adds the concept of CHERI PTE page faults. These reuse the load page fault and store/AMO page fault exception causes, and write additional information to mtval2/stval2/vstval2.

Page faults are considered to be CHERI PTE page faults if the Xtval2 register is written with a non-zero value.

It is possible for both a normal page fault and a CHERI PTE page fault to both trigger at once, as represented in the Xtval2 value, as shown in Table 32.
Where two stage translation is enabled, the CHERI PTE page fault is only raised when the second stage translation has completed, and so is prioritized below guest page faults.

All RV64 harts with virtual memory can raise CHERI store/AMO PTE page faults. Only harts which implement Svcheri can raise CHERI load PTE page faults.

10.2.1. Extending the Page Table Entry Format

The page table entry format remains unchanged for Sv32. However, a new bit, Capability Write (CW), is added to leaf PTEs in Sv39, Sv48 and Sv57 as shown in Figure 21, Figure 22 and Figure 23 respectively. For non-leaf PTEs this bit remains reserved and must be cleared by software for forward compatibility, or else a page-fault exception is raised. Additionally, if the hypervisor extension is enabled this bit remains reserved for leaf and non-leaf PTEs used in guest address translation.

ARC-QUESTION: The current bit 60 has been allocated by Svrsw60t59b, should we use bit 58?
Diagram
Figure 21. Sv39 page table entry
Diagram
Figure 22. Sv48 page table entry
Diagram
Figure 23. 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 36. 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.

10.3. Invalid Address Handling

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

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

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

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

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

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

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

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

10.3.1. Updating CSRs

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

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

  • executing instructions, such as CSRRW (RV32Y/RV64Y)

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

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

  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.

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

10.3.3. Memory Accesses

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

  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.

10.3.4. Debug Mode

When executing code due to an abstract command, the hart stays in debug mode and the rules outlined in Section 4.1 of (RISC-V, 2022) apply.

10.3.5. Core Debug Registers

RV32Y/RV64Y renames and extends debug CSRs that are designated to hold addresses to be able to hold capabilities. The renamed debug CSRs are listed in Table 49.

The pcc must grant ASR-permission to access debug CSRs. This permission is automatically provided when the hart enters debug mode as described in the dpcc section. The pcc metadata can only be changed if the implementation supports executing control transfer instructions from the program buffer — this is an optional feature according to (RISC-V, 2022).

10.3.6. Debug Program Counter (dpc)

The dpc register is as defined in (RISC-V, 2022). It is a DXLEN-bit register used as the PC saved when entering debug mode. dpc is extended into dpcc.

Diagram
Figure 24. Debug program counter

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

10.3.8. Debug Scratch Register 0 (dscratch0)

The dscratch0 register is as defined in (RISC-V, 2022). It is an optional DXLEN-bit scratch register that can be used by implementations which need it. dscratch0 is extended into dscratch0c.

Diagram
Figure 26. Debug scratch 0 register

10.3.9. Debug Scratch Register 0 Capability (dscratch0c)

The dscratch0c register extends dscratch0 to hold a capability.

The valid tag of the CSR must be reset to zero. The reset values of the metadata and address fields are UNSPECIFIED.

Diagram
Figure 27. Debug scratch 0 capability register

10.3.10. Debug Scratch Register 1 (dscratch1)

The dscratch1 register is as defined in (RISC-V, 2022). It is an optional DXLEN-bit scratch register that can be used by implementations which need it. dscratch1 is extended into dscratch1c.

Diagram
Figure 28. Debug scratch 1 register

10.3.11. Debug Scratch Register 1 Capability (dscratch1c)

The dscratch1c register extends dscratch1 to hold a capability.

The valid tag of the CSR must be reset to zero. The reset values of the metadata and address fields are UNSPECIFIED.

Diagram
Figure 29. Debug scratch 1 capability register

10.3.12. Debug Infinite Capability Register (dinfc)

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

The reset value is the Infinite capability.

If Zcherihybrid is implemented:

  • The M-bit is reset to Integer Pointer Mode (1).

  • The debugger can set the M-bit to Capability Pointer Mode (0) by executing MODESW.CAP from the program buffer.

    • Executing MODESW.CAP causes subsequent instructions execution from the program buffer, starting from the next instruction, to be executed in Capability Pointer Mode. It also sets the CHERI execution mode to Capability Pointer Mode on future entry into debug mode.

    • Therefore to enable use of a CHERI debugger, a single MODESW.CAP only needs to be executed once from the program buffer after resetting the core.

    • The debugger can also execute MODESW.INT to change the mode back to Integer Pointer Mode, which also affects the execution of the next instruction in the program buffer, updates the M-bit of dinfc and controls which CHERI execution mode to enter on the next entry into debug mode.

The M-bit of dinfc is only updated by executing MODESW.CAP or MODESW.INT from the program buffer.

A future version of this specification may add writeable fields to allow creation of other capabilities, if, for example, a future extension requires multiple formats for the Infinite capability.
Diagram
Figure 30. Debug infinite capability register

10.4. Integrating Zcherihybrid with Sdext

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

Zcherihybrid allows MODESW.CAP and MODESW.INT to execute in debug mode.

When entering debug mode, whether the core enters Integer Pointer Mode or Capability Pointer Mode is controlled by the M-bit in dinfc.

The current mode can be read from dinfc.

The following sequence executed from the program buffer will write 0 for Capability Pointer Mode and 1 for Integer Pointer Mode to x1:

csrr   c1, dinfc
gcmode x1, c1

10.4.1. Debug Default Data Capability CSR (dddc)

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

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

10.5. Integrating RV32Y/RV64Y with Sdtrig

This chapter will appear in the priv spec. Exact location TBD.

The Sdtrig extension is generally orthogonal to RV32Y/RV64Y. However, the priority of synchronous exceptions and where triggers fit is adjusted as shown in Table 37.

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

11. Integrating RV32Y/RV64Y and Zcherihybrid with Pointer Masking

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

The pointer masking extensions Smmpm, Smnpm, SSnpm, Sspm and Supm are compatible with both RV32Y/RV64Y and Zcherihybrid. Whenever pointer masking is enabled, all bounds decoding and bounds checks are affected.

The suggestion in this section is based on the pointer masking approach from Morello but with changes to sign extension and to address the dynamic nature of bit masking. Further evaluation on RISCV, especially for Capability Pointer Mode, is still required.

When bounds are encoded or decoded, a masked but not sign extended address is used. Changing how many bits are masked can therefore change the interpretation of the bounds of a capability, both for the purpose of implicit accesses via bounds checks and any instructions that report the bounds of a capability. Apart from treating high address bits as 0, there are no other changes to bounds decode, which are still based on MXLEN, not the new effectively addressable space. That is, the maximum length of a capability does not change, and it is not invalid to have a capability that covers a longer range than could be actually be addressed with pointer masking enabled (such as one that covers the entire MXLEN address space). For the representable range check, both the original and new address are masked. Bounds setting instructions also mask the address in the same way.

Because dynamically changing the number of masked bits changes the interpretation of a capability, software must take the same care when sharing capabilities between address spaces with differing pointer masking as it generally must when sharing capabilities between address spaces with different page mappings.

Any address that is checked against a capability (whether via loads/stores in Integer Pointer Mode or Capability Pointer Mode), is also first subject to the same masking as bounds decode (masking without extension). After any CHERI operations, the final access address is still subject to as much sign extension as the masking extensions mandate.

Chapters that still need review

Any chapter after this point still needs to be updated for the new document structure!

12. "Svucrg" Extension, Version 1.0

This chapter will appear in the priv spec. Exact location TBD.
This chapter needs additional updates before it is ready for ARC review
Sv32 (for RV32) does not have any spare PTE bits, and so no features from this chapter can be implemented.

The Svucrg extension adds the ability to perform capability revocation of user mode pages (see Section 12.1) by adding the PTE.CRG bit, and sstatus.UCRG as described below.

Svucrg depends on Svcheri also being supported.
Svucrg is strongly recommended but not mandatory as a future version of this specification may specify an improved method.
There is no explicit mechanism for enabling or disabling Svucrg.
If software ignores the new PTE bits then there is no change in functionality unless capabilities are accessed.
A future version of this specification may include kernel revocation which may require an sstatus.SCRG bit.

The remainder of this chapter jointly specifies the behavior of PTE.CW, PTE.CRG and sstatus.UCRG.

The description below assumes that Svucrg has been implemented. If that is not the case then PTE.CRG and sstatus.UCRG should be taken as read-only-zero for purpose of the description in the remainder of this chapter only. PTE.CRG and sstatus.UCRG remain reserved in this case.

The minimum level of PTE support is to set CW to 1 in all PTEs intended for storing capabilities (i.e., private anonymous mappings) and leave sstatus.UCRG and CRG in all PTEs set to 0, which will allow capabilities with their tags set to be loaded and stored successfully.

Hardware initiated memory accesses from the page-table walker are not checked by a capability.

12.1. Capability Revocation

Page table enforcement can accelerate concurrent capability revocation for temporal safety. Without page table capability protection, a concurrent capability revocation sweep must begin by visiting all PTEs to mark them unreadable, henceforth trapping on any read to a new page to sweep it clean before proceeding. With a page-granularity generational capability read permission, we can eliminate the initial permission change of all PTEs. In addition, a page-granularity capability write control can eliminate many pages from the sweep that are known to not contain capabilities.

12.2. Extending the Page Table Entry Format

The page table entry format remains unchanged for Sv32. However, one new bit, Capability Read Generation (CRG), is added to leaf PTEs in Sv39, Sv48 and Sv57 as shown in Figure 32, Figure 33 and Figure 34 respectively. For non-leaf PTEs these bits remain reserved and must be cleared by software for forward compatibility, or else a page-fault exception is raised. Additionally, if the hypervisor extension is enabled these bits remain reserved for leaf and non-leaf PTEs used in guest address translation.

Diagram
Figure 32. Sv39 page table entry
Diagram
Figure 33. Sv48 page table entry
Diagram
Figure 34. 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 12.3):

    • The same behavior as when CRG is clear, allowing software interpretation of this state.

    • When a capability store or AMO instruction is executed and the valid tag bit of the capability being written is set, the implementation sets the CW bit and assigns the CRG bit equal to sstatus.UCRG.

      The PTE update must be atomic with respect to other accesses to the PTE, and must atomically check that the PTE is valid and grants sufficient permissions. Updates to the CW bit and CRG bit must be exact (i.e., not speculative), and observed in program order by the local hart. Furthermore, the PTE update must appear in the global memory order no later than the explicit memory access, or any subsequent explicit memory access to that virtual page by the local hart. The ordering on loads and stores provided by FENCE instructions and the acquire/release bits on atomic instructions also orders the PTE updates associated with those loads and stores as observed by remote harts.

      The PTE update is not required to be atomic with respect to the explicit memory access that caused the update, and the sequence is interruptible. However, the hart must not perform explicit memory access before the PTE update is globally visible.

When CW is set, the CRG bit indicates the current generation of the virtual memory page with regards to the ongoing capability revocation cycle. Two schemes are permitted:

  • A CHERI load PTE page fault exception is raised when a capability load or AMO instruction is executed with C-permission granted and the virtual page’s CRG bit does not equal sstatus.UCRG and PTE.U is set.

  • A CHERI load PTE page fault exception is raised when a capability load or AMO instruction is executed with C-permission granted and the virtual page’s CRG bit does not equal sstatus.UCRG and PTE.U is set and the capability read from memory has its tag set.

Table 38. 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 39. 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.

12.3. Enabling Software or Hardware PTE updates

The decision about whether to take exceptions on capability stores with the valid tag set to a page with PTE.CW=0 and PTE.CRG=1 is determined by whether the Svade and Svadu extensions are enabled. These cause PTE Accessed and Dirty updates to be done in software, via the exception handler, or by a hardware mechanism respectively.

  • If only Svade is implemented, or enabled through henvcfg.ADUE or menvcfg.ADUE, then take a CHERI store/AMO PTE page fault.

  • If only Svadu is implemented, or enabled through henvcfg.ADUE or menvcfg.ADUE, then do the hardware update of setting PTE.CW=1 and setting PTE.CRG=sstatus.UCRG as described in Section 12.2.

12.4. Extending the Supervisor (sstatus) and Virtual Supervisor (vsstatus) Status Registers

The sstatus and vsstatus CSRs are extended to include the new Capability Read Generation (CRG) bit as shown.

When V=1 vsstatus.UCRG is in effect.

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

Diagram
Figure 35. Machine-mode status (mstatus) register when MXLEN=64
Diagram
Figure 36. Supervisor-mode status (sstatus) register when SXLEN=64
Diagram
Figure 37. Virtual Supervisor-mode status (vsstatus) register when VSXLEN=64

13. "Shcheri", Integrating RV32Y/RV64Y and Zcherihybrid with the Hypervisor Extension

This chapter will appear in the priv spec. Exact location TBD.

The RISC-V hypervisor (H) extension virtualizes the supervisor-level architecture to support the efficient hosting of guest operating systems atop a type-1 or type-2 hypervisor (RISC-V, 2023). The hypervisor extension is generally orthogonal to CHERI; the main requirements, when integrating with RV32Y/RV64Y and Zcherihybrid, is that address CSRs added for hypervisors are extended to CLEN size. The remainder of this chapter describes these changes in detail.

13.1. Hypervisor Status Register (hstatus)

The hstatus register operates as described in (RISC-V, 2023) except for the VSXL field that controls the value of XLEN for VS-mode (known as VSXLEN).

The encoding of the VSXL field is the same as the MXL field of misa. Only 1 and 2 are supported values for VSXL. When the implementation supports RV32Y/RV64Y (but not Zcherihybrid), then hstatus's VSXL must be read-only as described in mstatus for mstatus.SXL. When the implementation supports both RV32Y/RV64Y and Zcherihybrid, then VSXL behaves as described in Section 7.2.1 for mstatus.SXL.

The VSBE field determines controls the endianness of explicit memory accesses from VS-mode and implicit memory accesses to VS-level memory management data structures. VSBE=0 indicates little endian and VSBE=1 is big endian. VSBE must be read-only and equal to MBE when the implementation only supports RV32Y/RV64Y. VSBE is optionally writeable when Zcherihybrid is also supported.

13.2. Hypervisor Environment Configuration Register (henvcfg)

The henvcfg register operates as described in the RISC-V Privileged Specification. A new enable bit is added to henvcfg when the implementation supports Zcherihybrid as shown in Figure 38.

Diagram
Figure 38. 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 8.

The reset value is 0.

13.3. Hypervisor Exception Delegation Register (hedeleg)

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

13.4. Virtual Supervisor Status Register (vsstatus)

The vsstatus register operates as described in (RISC-V, 2023) except for the UXL field that controls the value of XLEN for VU-mode.

The encoding of the UXL field is the same as the MXL field of misa. Only 1 and 2 are supported values for UXL. When the implementation supports RV32Y/RV64Y (but not Zcherihybrid), then vsstatus.UXL must be read-only as described in mstatus for mstatus.UXL. When the implementation supports both RV32Y/RV64Y and Zcherihybrid, then UXL behaves as described in Section 7.2.1 for mstatus.UXL.

13.5. Virtual Supervisor Trap Vector Base Address Register (vstvec)

The vstvec register is as defined in (RISC-V, 2023). It is the VSXLEN-bit read/write register that is the VS mode’s version of the supervisor register stvec.

Diagram
Figure 39. Virtual supervisor trap vector base address register

13.6. Virtual Supervisor Trap Vector Base Address Capability Register (vstvecc)

The vstvecc register extends vstvec to hold a capability. Its reset value is the Infinite capability.

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

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

13.7. Virtual Supervisor Scratch Register (vsscratch)

The vsscratch register is as defined in (RISC-V, 2023). It is a VSXLEN read/write register that is VS-mode’s version of supervisor register sscratch. vsscratch is extended into vsscratchc.

Diagram
Figure 41. Virtual supervisor scratch register

13.8. Virtual Supervisor Scratch Register (vsscratchc)

The vsscratchc register extends vsscratch to hold a capability.

The valid tag of the CSR must be reset to zero. The reset values of the metadata and address fields are UNSPECIFIED.

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

Diagram
Figure 42. Virtual supervisor scratch capability register

13.9. Virtual Supervisor Exception Program Counter (vsepc)

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

Diagram
Figure 43. Virtual supervisor exception program counter

13.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 60, vsepcc is a code capability, so it does not need to be able to hold all possible invalid addresses (see Invalid address conversion). Additionally, the capability in vsepcc is unsealed when it is installed in pcc on execute of an SRET (RV32Y/RV64Y) instruction. The handling of vsepcc is otherwise identical to mepcc, but in virtual supervisor mode.

Diagram
Figure 44. Virtual supervisor exception program counter capability

13.11. Virtual Supervisor Cause Register (vscause)

The vscause register is as defined in (RISC-V, 2023). It must additionally support the new exception code for CHERI exceptions that scause supports.

13.12. Virtual Supervisor Trap Value Register (vstval)

The vstval register is a VSXLEN-bit read-write register.

vstval is updated following the same rules as mtval for CHERI exceptions and CHERI PTE page faults which are delegated to VS-mode.

Diagram
Figure 45. Virtual supervisor trap value register

13.13. Virtual Supervisor Trap Value Register 2 (vstval2)

The vstval2 register is a VSXLEN-bit read-write register, which is added as part of RV32Y/RV64Y when the hypervisor extension is supported. Its CSR address is 0x24b.

vstval2 is updated following the same rules as mtval2 for CHERI exceptions and CHERI PTE page faults which are delegated to VS-mode. It is written to zero for all other exceptions, except as listed otherwise by other future extensions.

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

13.14. Hypervisor Load and Store Instructions For Capability Data

Hypervisor virtual-machine load ([HLV.C]) and store ([HSV.C]) instructions read or write CLEN-bits from memory as though V=1. These instructions change behavior depending on the CHERI execution mode although the instruction’s encoding remains unchanged.

When in Capability Pointer Mode, the hypervisor load and store capability instructions behave as described in Section 2.10. In Integer Pointer Mode, the instructions behave as rely on an x register operand providing the effective address for the memory access and the capability authorizing the memory access is ddc.

14. "Zstid" Extension for Software Thread Identification

This chapter needs to be split.

Zstid is an optional extension to the RISC-V base ISA. Implementations that support RV32Y/RV64Y and Zstid define a variant of the CHERI ISA that allows for more efficient software compartmentalization of CHERI programs.

14.1. Control and Status Registers (CSRs)

Zstid adds new CSRs to implement a trusted software thread identifier (TID) used in compartmentalization. These CSRs are listed in Table 40, Table 41, Table 42 and Table 43.

Table 40. Added machine-mode CSRs in Zstid
Zstid CSR Address Prerequisites Read-Permission Write-Permission Description

mtid

0x780

M-mode

M

M, ASR-permission

Machine Thread Identifier

Table 41. Added supervisor-mode CSRs in Zstid
Zstid CSR Address Prerequisites Read-Permission Write-Permission Description

stid

0x580

S-mode

S

S, ASR-permission

Supervisor Thread Identifier

Table 42. Added virtual supervisor-mode CSRs in Zstid
Zstid CSR Address Prerequisites Read-Permission Write-Permission Description

vstid

0xA80

VS-mode

S

H, ASR-permission

Virtual Supervisor Thread Identifier

Table 43. Added user-mode CSRs in Zstid
Zstid CSR Address Prerequisites Read-Permission Write-Permission Description

utid

0x480

U-mode

U

U, ASR-permission

User Thread Identifier

14.2. Machine-Level, Supervisor-Level and Unprivileged CSRs

14.2.1. Machine Thread Identifier (mtid)

The mtid register is an MXLEN-bit read-write register. It is used to identify the current software thread in machine mode. The reset value of this register is UNSPECIFIED.

Diagram
Figure 47. Supervisor thread identifier register

14.2.2. Supervisor Thread Identifier (stid)

The stid register is an SXLEN-bit read-write register. It is used to identify the current software thread in supervisor mode. The reset value of this register is UNSPECIFIED.

Diagram
Figure 48. Supervisor thread identifier register

14.2.3. Virtual Supervisor Thread Identifier (vstid)

The vstid register is a VSLEN-bit read-write register. It is VS-mode’s version of supervisor register stid used to identify the current software thread in virtual supervisor mode. As other Virtual Supervisor registers when V=1, vstid substitutes for stid, so that instructions that normally read or modify stid actually access vstid instead. When V=0, vstid does not directly affect the behavior of the machine.

The reset value of this register is UNSPECIFIED.

Diagram
Figure 49. Virtual supervisor thread identifier register

14.2.4. User Thread Identifier (utid)

The utid register is an UXLEN-bit read-write register. It is used to identify the current software thread in user mode. The reset value of this register is UNSPECIFIED.

Diagram
Figure 50. User thread identifier register

When RV32Y/RV64Y is implemented, the Zstid CSRs are extended as follows:

14.2.5. Machine Thread Identifier Capability (mtidc)

The mtidc register extends mtid to hold a capability. It is used to identify the current software thread in machine mode. On reset the valid tag of mtidc will be set to 0 and the remainder of the data is UNSPECIFIED.

Diagram
Figure 51. Machine thread identifier capability register

14.2.6. Supervisor Thread Identifier Capability (stidc)

The stidc register extends stid to hold a capability. It is used to identify the current software thread in supervisor mode. On reset the valid tag of stidc will be set to 0 and the remainder of the data is UNSPECIFIED.

Diagram
Figure 52. Supervisor thread identifier capability register

14.2.7. Virtual Supervisor Thread Identifier Capability (vstidc)

The vstidc register extends vstid to hold a capability. It is used to identify the current software thread in virtual supervisor mode. As other Virtual Supervisor registers when V=1, vstidc substitutes for stidc, so that instructions that normally read or modify stidc actually access vstidc instead. When V=0, vstidc does not directly affect the behavior of the machine. On reset the valid tag of vstidc will be set to 0 and the remainder of the data is UNSPECIFIED.

Diagram
Figure 53. Virtual supervisor thread identifier capability register

14.2.8. User Thread Identifier Capability (utidc)

The utidc register extends utid to hold a capability. It is used to identify the current software thread in user mode. On reset the valid tag of utidc will be set to 0 and the remainder of the data is UNSPECIFIED.

Diagram
Figure 54. User thread identifier capability register

14.3. "Smstateen/Ssstateen" Integration

The TID bit controls access to the CSRs in Table 41, Table 42 and Table 43 provided by the Zstid extension.

Diagram
Figure 55. Machine State Enable 0 Register (mstateen0)
Diagram
Figure 56. Hypervisor State Enable 0 Register (hstateen0)
Diagram
Figure 57. Supervisor State Enable 0 Register (sstateen0)

14.4. CHERI Compartmentalization

This section describes how this specification enables support for compartmentalization for CHERI systems. Compartmentalization seeks to separate the privileges between different protection units, e.g., two or more libraries. Code can be separated by sentries, which allow for giving out code capabilities to untrusted code where the untrusted code can only call the code capability, but not modify it. Sentries can be called from different software threads and thus there needs to be a way of identifying the current software thread. While identifying the current software thread can be done by privileged code, e.g., the kernel, the implied performance overhead of this is not bearable for CHERI systems with many compartments.

The RISC-V ABI includes a thread pointer (tp) register, which is not usable for the purpose of reliably identifying the current software thread because the tp register is a general purpose register and can be changed arbitrarily by untrusted code. Therefore, this specification offers additional CSRs that facilitate a trusted source for the thread ID. All registers are readable from their respective privilege levels and writeable with ASR-permission.

This extension extends mtid, stid, vstid and utid to their respective capability variants mtidc, stidc, vstidc and utidc. This presents software with the freedom to still use these registers with capabilities or leave the metadata untouched and only use the registers to store integers.

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 integer data of the indicated size (byte, halfword, word, double-word) from memory. The effective address of the load is obtained by adding the sign-extended 12-bit offset to the address of cs1. The authorizing capability for the operation is cs1. A copy of the loaded value is written to rd.

Any instance of this instruction with a cs1=c0 will trap (with a CHERI tag violation), as c0 is defined to always hold a NULL capability. As such, the encodings with a cs1=c0 are RESERVED for use by future extensions.
Integer Pointer Mode Description

Load integer data of the indicated size (byte, halfword, word, double-word) from memory. The effective address of the load is obtained by adding the sign-extended 12-bit offset to rs1. The authorizing capability for the operation is ddc. A copy of the loaded value is written 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 integer data of the indicated size (byte, halfword, word, double-word) to memory. The effective address of the store is obtained by adding the sign-extended 12-bit offset to the address of cs1. The authorizing capability for the operation 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 trap (with a CHERI tag violation), as c0 is defined to always hold a NULL capability. As such, the encodings with a cs1=c0 are RESERVED for use by future extensions.
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 trap (with a CHERI tag violation), as c0 is defined to always hold a NULL capability. As such, the encodings with a cs1=c0 are RESERVED for use by future extensions.
Integer Pointer Mode Description

Standard atomic instructions, authorized by the capability in ddc.

Permissions

Requires R-permission and W-permission in the authorizing capability.

Requires all bytes of the access to be in capability bounds.

Exceptions

All misaligned atomics cause a store/AMO address misaligned exception to allow software emulation (if the Zam extension is supported, see (RISC-V, 2023)), otherwise they take a store/AMO access fault exception.

CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):

Kind Reason

Tag violation

Authorizing capability valid tag set to 0, or has any reserved bits set

Seal violation

Authorizing capability is sealed

Permission violation

Authorizing capability does not grant R-permission or W-permission, or the AP field could not have been produced by ACPERM

Invalid address violation

The effective address is invalid according to Invalid address conversion

Bounds violation

At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds

If virtual memory is enabled on an RV64 hart, then the state of PTE.CW, and, if Svucrg is implemented, PTE.CRG from the current virtual memory page may cause a CHERI PTE store/AMO page fault exception in addition to a normal RISC-V page fault when operating in user mode. See Table 32 for the exception reporting in this case.

Prerequisites for Capability Pointer Mode AMO<OP>.W, AMO<OP>.D

RV32Y/RV64Y, and A

Prerequisites for Integer Pointer Mode AMO<OP>.W, AMO<OP>.D

Zcherihybrid, and A

Capability Pointer Mode Operation
TBD
Integer Pointer Mode Operation

TODO

B.3.3. AMOSWAP.C

Synopsis

Atomic Operation (AMOSWAP.C), 32-bit encoding

Mnemonic

amoswap.c cd, cs2, 0(cs1)

Encoding
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 trap (with a CHERI tag violation), as c0 is defined to always hold a NULL capability. As such, the encodings with a cs1=c0 are RESERVED for use by future extensions.

If Zcherihybrid is implemented and the CHERI execution mode is Integer Pointer Mode then the base address is rs1 and the authorizing capability is ddc.

Prerequisites

RV32Y/RV64Y, and A or Zaamo

Operation

TODO

B.3.4. LR.D

See LR.B.

B.3.5. LR.W

See LR.B.

B.3.6. LR.H

See LR.B.

B.3.7. LR.B

Synopsis

Load Reserved (LR.D, LR.W, LR.H, LR.B), 32-bit encodings

Capability Pointer Mode Mnemonics (RV64)

lr.[d|w|h|b] rd, 0(cs1)

Capability Pointer Mode Mnemonics (RV32)

lr.[w|h|b] rd, 0(cs1)

Integer Pointer Mode Mnemonics (RV64)

lr.[d|w|h|b] rd, 0(rs1)

Integer Pointer Mode Mnemonics (RV32)

lr.[w|h|b] rd, 0(rs1)

Encoding
Diagram
Capability Pointer Mode Description

Load reserved instructions, authorized by the capability in cs1.

Any instance of this instruction with a cs1=c0 will trap (with a CHERI tag violation), 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 the address of cs1 to the sign-extended 12-bit offset.

Authorize the memory access with the capability in cs1.

Load a naturally aligned CLEN-bit data value and the associated valid tag from memory.

Set the reservation as for LR.W/D.

Write the CLEN-bit data and the valid tag to cd and conditionally update them as specified below.

Any instance of this instruction with a cs1=c0 will trap (with a CHERI tag violation), 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 tagged capabilities which have malformed bounds, have reserved bits set or have a permission field which cannot be produced by ACPERM.

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

If Zcheri1lvl is implemented, then also see Table 4.

Missing EL-permission also affects the level of sealed capabilities since notionally the Capability Level (CL) of a capability is not a permission but rather a data flow label attached to the loaded value.
While the implicit ACPERM introduces a dependency on the loaded data, implementations can avoid this by deferring the actual masking of permissions until the loaded capability is dereferenced or the metadata bits are inspected using GCPERM or GCHI. Additionally, metadata modifications are on naturally aligned data, and so on the read path from a data cache, the modification typically happens in parallel with data alignment multiplexers.

ARC feedback: this is change relative to 0.9.5 so that the choice is removed. Choosing the other option would need to be a future extension

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

Exceptions

All misaligned load reservations cause a load address misaligned exception to allow software emulation (if the Zam extension is supported, see (RISC-V, 2023)), otherwise they take a load access fault exception.

ARC suggestion: consider software check fault

CHERI fault exception when one of the checks below fail (see CHERI Exception handling in the privileged specification for further details):

Kind Reason

Tag violation

Authorizing capability valid tag set to 0, or has any reserved bits set

Seal violation

Authorizing capability is sealed

Permission violation

Authorizing capability does not grant R-permission, or the AP field could not have been produced by ACPERM

Bounds violation

At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds

Prerequisites

RV32Y/RV64Y, and A or Zalrsc

Operation
TBD

B.3.9. SC.D

See SC.B.

B.3.10. SC.W

See SC.B.

B.3.11. SC.H

See SC.B.

B.3.12. SC.B

Synopsis

Store Conditional (SC.D, SC.W, SC.H, SC.B), 32-bit encodings

Capability Pointer Mode Mnemonics (RV64)

sc.[d|w|h|b] rd, rs2, 0(cs1)

Capability Pointer Mode Mnemonics (RV32)

sc.[w|h|b] rd, rs2, 0(cs1)

Integer Pointer Mode Mnemonics (RV64)

sc.[d|w|h|b] rd, rs2, 0(rs1)

Integer Pointer Mode Mnemonics (RV32)

sc.[w|h|b] rd, rs2, 0(rs1)

Encoding
Diagram
Capability Pointer Mode Description

Store conditional instructions, authorized by the capability in cs1.

Any instance of this instruction with a cs1=c0 will trap (with a CHERI tag violation), 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 the address of cs1 to the sign-extended 12-bit offset.

Authorize the memory access with the capability in cs1.

Conditionally store, following the same rules as SC.W, a naturally aligned CLEN-bit data value in cs2 to memory and the associated valid tag in cs2.

Set rd to 1 for success or 0 for failure.

Any instance of this instruction with a cs1=c0 will trap (with a CHERI tag violation), 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 tagged capabilities which have malformed bounds, have reserved bits set or have a permission field which cannot be produced by ACPERM.

Exceptions

ARC feedback: needs to be an access fault as it can’t be emulated

Misaligned address fault exception when the effective address is not aligned to CLEN/8 if Zam is supported, otherwise store access fault exception.

ARC suggestion: consider software check fault

CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):

Kind Reason

Tag violation

Authorizing capability valid tag set to 0, or has any reserved bits set

Seal violation

Authorizing capability is sealed

Permission violation

Authorizing capability does not grant W-permission, or the AP field could not have been produced by ACPERM

Bounds violation

At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds

Prerequisites

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 trap (with a CHERI tag violation), as c0 is defined to always hold a NULL capability. As such, the encodings with a cs1=c0 are RESERVED for use by future extensions.
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 trap (with a CHERI tag violation), as c0 is defined to always hold a NULL capability. As such, the encodings with a cs1=c0 are RESERVED for use by future extensions.
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 44. 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 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.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 46. 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 47. 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 tagged capabilities which have malformed bounds, have reserved bits set or have a permission field which cannot be produced by ACPERM.

Prerequisites

C or Zca, RV32Y/RV64Y

Operation (after expansion to 32-bit encoding)

See CMV

B.5.5. C.ADDI16SP (RV32Y/RV64Y)

Synopsis

Stack pointer increment in blocks of 16 (C.ADDI16SP), 16-bit encodings

Mnemonic

c.addi16sp nzimm

Expansion

caddi csp, csp, nzimm

The suggested assembly syntax distinguishes from integer c.addi16sp by operand type.
Encoding
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 tagged capabilities which have malformed bounds, have reserved bits set or have a permission field which cannot be produced by ACPERM.

Exceptions

ARC feedback: needs to be an access fault as it can’t be emulated

Misaligned address fault exception when the effective address is not aligned to CLEN/8 if Zam is supported, otherwise store access fault exception.

ARC suggestion: consider software check fault

CHERI data fault exceptions occur when the authorizing capability fails one of the checks listed below (see CHERI Exception handling in the privileged specification for further details):

Kind Reason

Tag violation

Authorizing capability valid tag set to 0, or has any reserved bits set

Seal violation

Authorizing capability is sealed

Permission violation

Authorizing capability does not grant W-permission, or the AP field could not have been produced by ACPERM

Bounds violation

At least one byte accessed is outside the authorizing capability bounds, or the capability has malformed bounds

Prerequisites

C or Zca, RV32Y/RV64Y

Operation (after expansion to 32-bit encodings)

See SC

B.6. "Zicbom", "Zicbop", "Zicboz" Standard Extensions for Base Cache Management Operations

Cache-related instructions and how CHERI affects them.

B.6.1. CBO.CLEAN (RV32Y/RV64Y)

Synopsis

Perform a clean operation on a cache block

Mnemonic

cbo.clean 0(cs1)

Encoding
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 reserved bits are set

  • The permissions could not have been produced by ACPERM

  • The bounds are malformed

Prerequisites

Zicbop, RV32Y/RV64Y

Operation
TODO

B.6.6. PREFETCH.R (RV32Y/RV64Y)

Synopsis

Provide a HINT to hardware that a cache block is likely to be accessed by a data read in the near future

Mnemonic

prefetch.r offset(cs1)

Encoding
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 reserved bits are set

  • The permissions could not have been produced by ACPERM

  • The bounds are malformed

Prerequisites

Zicbop, RV32Y/RV64Y

Operation
TODO

B.6.7. PREFETCH.W (RV32Y/RV64Y)

Synopsis

Provide a HINT to hardware that a cache block is likely to be accessed by a data write in the near future

Mnemonic

prefetch.w offset(cs1)

Encoding
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 reserved bits are set

  • The permissions could not have been produced by ACPERM

  • The bounds are malformed

Prerequisites

Zicbop, RV32Y/RV64Y

Operation
TODO

B.7. "Zba" Extension for Bit Manipulation Instructions

Bit manipulation instruction reference.

B.7.1. ADD.UW (RV64Y)

Synopsis

Add unsigned word for address generation

Mnemonic

add.uw cd, rs1, cs2

Encoding
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 ({cheri_base32ext_name}), CM.POPRET (RV32Y), CM.POPRETZ (RV32Y)) instructions are redefined in Capability Pointer Mode to save/restore capability data.

The double move instructions (CM.MVSA01 (RV32Y), CM.MVA01S (RV32Y)) are redefined in Capability Pointer Mode to move capability data between registers. The saved register mapping is as shown in Table 48.

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

Atomically move two saved capability registers cs0-cs7 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 48.
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 58. 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

Appendix C: Control and Status Registers (CSRs) overview

Smcheri and Sscheri extend the CSRs listed in Table 49, Table 50, Table 51, Table 52 and Table 53 from the base RISC-V ISA and its extensions. The CSRs are renamed to reflect the fact that they are extended to CLEN-bits wide, as the x registers are renamed to c registers. Even though the CSR is extended, the CSR index remains identical.

If Zcherihybrid is supported then the CHERI Execution Mode determines whether CLEN or XLEN-bits are returned (see CSRRW (RV32Y/RV64Y)).
Table 49. 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 50. 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

mtidc

0x780

mtid

Zstid

Read: M, Write: M, ASR-permission

Machine thread ID

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

stidc

0x580

stid

Zstid

Read: S, Write: S, ASR-permission

Supervisor thread ID

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

utidc

0x480

utid

Zstid

Read: U, Write: U, ASR-permission

User thread ID

Appendix D: CHERI System Implications

Unclear if this chapter will appear in the priv spec. May just be in the standalone spec.

CHERI processors need memory systems which support the capability valid tags in memory.

There are, or will soon be, a wide range of CHERI systems in existence from tiny IoT devices up to server chips.

There are two types of bus connections used in SoCs which contain CHERI CPUs:

  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 clear the valid tag of any CLEN-aligned CLEN-wide memory location where any byte matches the memory write.

The fundamental rule for any CHERI system is that the valid tag and data are always accessed atomically. For every naturally aligned CLEN-wide memory location, it must never be possible to:

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

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

  2. Read a tagged 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 59. 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 60. 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 61. 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 60.

There is likely to be a performance difference between the two systems. The main motivation for Figure 60 is to avoid the GPU DRAM traffic needing to look-up every tag in the valid tag cache, potentially adding overhead to every transaction.

Appendix E: Extension summary

E.1. Zabhlrsc

Zabhlrsc is a separate extension independent of CHERI, but is required for CHERI software.

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

Table 54. 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 55.

Table 55. 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 ({cheri_base32ext_name})

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

utidc

utid

Zstid

stidc

stid

Zstid

vstidc

vstid

Zstid

mtidc

mtid

Zstid

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

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

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

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 60. 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 60. These are WARL CSRs that do not need to store full 64-bit addresses on RV64, and so need not be capable of holding all possible invalid addresses. Prior to writing an invalid address to these CSRs, the address must be converted to another invalid address that the CSR is capable of holding. CSRs that store fewer address bits are also subject to the invalid address check in Invalid address conversion on writing.

Table 61 shows all CLEN-wide CSRs.

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

Zstid

0x480

Read: U, Write: U, ASR-permission

tag=0, otherwise undefined

User thread ID

stidc

Zstid

0x580

Read: S, Write: S, ASR-permission

tag=0, otherwise undefined

Supervisor thread ID

vstidc

Zstid

0xA80

Read: VS, Write: VS, ASR-permission

tag=0, otherwise undefined

Virtual supervisor thread ID

mtidc

Zstid

0x780

Read: M, Write: M, ASR-permission

tag=0, otherwise undefined

Machine thread ID

Appendix G: Instructions and CHERI Execution Mode

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

Table 62. 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 63. 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 64. 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 ({cheri_base32ext_name})

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 65. 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 66. 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 67. 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 62. 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 63. 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 64. 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 65. 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 66. 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 67. 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 68. 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 69. 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 70. 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 71. 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 72. 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 73. 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 74. 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