Version Information: Version 1.0
Other formats: This document is also available in the following formats:
1. Introduction
Capstone is a novel CPU instruction set architecture (ISA) that creates a single unified architectural abstraction for achieving multiple security goals, thus liberating software developers from the burden of working with the distinct fundamental primitives exposed by numerous security extensions that often do not interoperate easily.
1.1. Properties to Support
The ultimate goal of Capstone is to provide a unified architectural abstraction for multiple security goals. This goal requires Capstone to support the following properties.
- Exclusive access
Software should be guaranteed exclusive access to certain memory regions if needed. This is in spite of the existence of software traditionally entitled to higher privileges such as the OS kernel and the hypervisor.
- Revocable delegation
Software components should be able to delegate authority to other components in a revocable manner. For example, after an untrusted library function has been granted access to a memory region, the caller should be able to revoke this access.
- Dynamically extensible hierarchy
The hierarchy of authority should be dynamically extensible, rather than predefined by the architecture such as hypervisor-kernel-user found in traditional platforms. This makes it possible to use the same set of abstractions for memory isolation and memory sharing regardless of where a software component lies in the hierarchy.
- Safe context switching
A mechanism that protects the confidentiality and integrity of the execution context of software during control flow transfers across security domain boundaries, including asynchronous ones such as those for interrupt and exception handling, should be provided.
1.2. Major Design Elements
The Capstone architecture design is based on the idea of capabilities, which are unforgeable tokens that represent authority to perform memory accesses and control flow transfers, among other operations. Capstone extends the traditional capability model with new capability types including the following.
- Linear capabilities
Linear capabilities are guaranteed not to alias with other capabilities that both grant memory access and are in architecturally visible locations (i.e., their actual contents might affect the execution of the whole system). Operations on linear capabilities maintain this property. For example, instructions can only move, but not copy, linear capabilities between general-purpose registers. They can hence enable safe exclusive access to memory regions. Capabilities that do not have this property are called non-linear capabilities.
- Revocation capabilities
Revocation capabilities cannot be used to perform memory accesses or control flow transfers. Instead, they convey the authority to revoke other capabilities. Each revocation capability is derived from a linear capability and can later be used to revoke (i.e., invalidate) capabilities derived from it. This mechanism enables revocable and arbitrarily extensible chains of delegation of authority.
- Uninitialised capabilities
Uninitialised capabilities convey write-only authority to memory. They can be turned into linear capabilities after the memory region has been “initialised”, i.e., when the whole memory region has been overwritten with fresh data. Uninitialised capabilities enable safe initialisation of memory regions and prevent secret leakage without incurring extra performance overhead.
1.3. Capstone-RISC-V Academic Version ISA Overview
While Capstone does not assume any specific modern ISA, we choose to propose a Capstone variant to RISC-V due to its open nature and the availability of toolchains and simulators.
The Capstone-RISC-V Academic Version ISA is an RV64IZicsr variant that makes the following types of changes to the base architecture:
-
Each general-purpose register is extended to 129 bits to accommodate 128-bit capabilities.
-
Part of the machine state is extended and new instructions are added to support it.
-
New instructions for manipulating capabilities are added.
-
New instructions for memory accesses using capabilities are added.
-
New instructions for control flow transfers using capabilities are added.
-
Semantics of some existing instructions are adjusted to support capabilities.
-
Semantics of interrupts and exceptions are adjusted to support capabilities.
1.4. Assembly Mnemonics
Each Capstone-RISC-V Academic Version instruction is given a mnemonic prefixed with CS..
In contexts where it is clear we are discussing Capstone-RISC-V Academic Version instructions,
we will omit the CS. prefix for brevity.
In assembly code, the list of operands to an instruction is supplied following the
instruction mnemonic, with the operands separated by commas, in the order of
rd, rs1, rs2, imm for any operand the instruction expects.
1.5. Notations
When specifying the semantics of instructions, we use the following notations to represent the type of each operand:
- I
-
Integer register.
- C
-
Capability register.
- S
-
Sign-extended immediate.
- Z
-
Zero-extended immediate.
1.6. Bibliography
The initial motivation, design, evaluation, and analysis of Capstone have been discussed in the following paper:
-
Capstone: A Capability-based Foundation for Trustless Secure Memory Access by Jason Zhijingcheng Yu, Conrad Watt, Aditya Badole, Trevor E. Carlson, Prateek Saxena. In Proceedings of the 32nd USENIX Security Symposium. Anaheim, CA, USA. August 2023.
2. Programming Model
The Capstone-RISC-V Academic Version ISA has extended part of the machine state, including both some registers and the memory, to enable the storage and handling of capabilities.
2.1. Capabilities
2.1.1. Width
The width of a capability is 128 bits. We represent this as
CLEN = 128 and CLENBYTES = 16. Note that this does not
affect the width of a raw address, which is XLEN = 64 bits,
or equivalently, XLENBYTES = 8 bytes, same as
in RV64IZicsr.
2.1.2. Fields
Each capability has the following architecturally-visible fields:
| Name | Range | Description |
|---|---|---|
|
|
Whether the capability is valid: |
|
|
The type of the capability:
|
|
|
Not applicable when |
|
|
The base memory address of the memory region associated with the capability |
|
|
Not applicable when |
|
|
Not applicable when |
|
|
Only applicable when |
|
|
Only applicable when |
The range of the perms field has a partial order <=p defined as follows:
<=p = {
(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7),
(1, 1), (1, 3), (1, 5), (1, 7),
(2, 2), (2, 3), (2, 6), (2, 7),
(3, 3), (3, 7),
(4, 4), (4, 5), (4, 6), (4, 7),
(5, 5), (5, 7),
(6, 6), (6, 7),
(7, 7)
}
We say a capability c aliases with a capability d if and only if the intersection
between [c.base, c.end) and [d.base, d.end) is non-empty.
For two revocation capabilities c and d (i.e., c.type = d.type = 2),
we say c <t d if and only if
-
caliases withd -
The creation of
cwas earlier than the creation ofd
In addition to the above fields, an implementation also needs to maintain
sufficient metadata to test the <t relation.
It will be clear that for any pair of aliasing revocation capabilities,
the order of their creations is well-defined.
Note: the implementation of valid field
Note: addition/compression to capability fields
For different types of capabilities, a specific subset of the fields is used. The table below summarises the fields used for each type of capabilities.
| Type | type |
valid |
cursor |
base |
end |
perms |
async |
reg |
|---|---|---|---|---|---|---|---|---|
Linear |
|
Yes |
Yes |
Yes |
Yes |
Yes |
- |
- |
Non-linear |
|
Yes |
Yes |
Yes |
Yes |
Yes |
- |
- |
Revocation |
|
Yes |
Yes |
Yes |
Yes |
Yes |
- |
- |
Uninitialised |
|
Yes |
Yes |
Yes |
Yes |
Yes |
- |
- |
Sealed |
|
Yes |
- |
Yes |
- |
- |
Yes |
- |
Sealed-return |
|
Yes |
Yes |
Yes |
- |
- |
Yes |
Yes |
When the async field of a sealed-return capability is 0 (synchronous),
some memory accesses are granted by this capability.
The following table shows the memory accesses granted in such scenarios,
where size is the size of the memory access in bytes.
| Capability type | async |
Read | Write | Execute |
|---|---|---|---|---|
Sealed-return |
|
|
|
No |
In other scenarios and for other capability types without the perms field, no read/write/execute
memory accesses are granted by the capability.
The following figure shows the overview of different types of capabilities in the Capstone-RISC-V Academic Version ISA, and the operations that change the type of a capability.
2.2. Extension to General-Purpose Registers
The Capstone-RISC-V Academic Version ISA extends each of the 32 general-purpose
registers, so it contains either a capability or a raw XLEN-bit
integer.
The type of data contained in a register is maintained and confusion
of the type is not allowed, except for x0/c0 as discussed below.
In assembly code, the type of data expected in a register operand
is indicated by the alias used for the register, as summarised
in the following table.
| Index | XLEN-bit integer |
Capability |
|---|---|---|
0 |
|
|
1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
|
|
21 |
|
|
22 |
|
|
23 |
|
|
24 |
|
|
25 |
|
|
26 |
|
|
27 |
|
|
28 |
|
|
29 |
|
|
30 |
|
|
31 |
|
|
x0/c0 is a read-only register that can be used both as an
integer and as a capability, depending on the context. When used
as an integer, it has the value 0.
When used as a capability, it has the value
{ valid = 0, type = 0, cursor = 0, base = 0, end = 0, perms = 0 }.
Any attempt to write to x0/c0 will be silently ignored (no
exceptions are raised).
In this document,
for i = 0, 1, …, 31, we use x[i] to refer to the general-purpose
register with index i.
2.3. Extension to Other Registers
2.3.1. Program Counter
The program counter (pc) is changed to contain a capability only.
During the instruction fetch stage, an exception is raised when any of the following conditions is met:
If no exception is raised:
-
The instruction pointed to by
pc.cursoris fetched and executed. -
Set
pc.cursortopc.cursor + 4at the end of the instruction.
2.4. Added Registers
The Capstone-RISC-V Academic Version ISA adds the following registers.
| Mnemonic | CCSR encoding | CSR encoding | Description |
|---|---|---|---|
|
|
- |
The sealed capability or PC entry for the exception handler |
|
|
- |
The sealed capability for the interrupt handler |
|
|
- |
The initial capability covering the entire address space of the memory |
|
|
- |
The exception program counter register |
|
- |
|
The interrupt status register |
|
- |
|
The exception data (trap value) register |
|
- |
|
The exception cause register |
Some of the registers only allow capability values and have special semantics related to the system-wide machine state. They are referred to as capability control and status registers (CCSRs). Under their respective constraints, CCSRs can be manipulated using control and status instructions.
The manipulation constraints for each CCSR are indicated below.
| Mnemonic | Read | Write |
|---|---|---|
|
No constraint |
No constraint |
|
- |
The original content must not be a capability |
|
Oone-time only |
- |
|
No constraint |
No constraint |
Some of the registers are added as control and status registers (CSRs). These registers are manipulated by the same instructions that manipulate CSRs as in RV64IZicsr. When the manipulation constraints of these additional CSRs are not satisfied, the behaviour of these instructions follows the RV64IZicsr convention for other CSRs.
The manipulation constraints for each additional CSR are indicated below.
| Mnemonic | Read | Write |
|---|---|---|
|
No constraint |
No constraint |
|
No constraint |
No constraint |
|
No constraint |
No constraint |
Note: ceh and cih
Note: cinit
2.5. Extension to Memory
The memory is addressed using an XLEN-bit integer at byte-level
granularity.
In addition to raw integers, each CLEN-bit aligned address can
also store a capability.
The type of data contained in a memory location is maintained and
confusion of the type is not allowed.
The physical memory can only be accessed through capabilities.
| Address Space | Access Method |
|---|---|
|
Capabilities |
2.6. Instruction Set
The Capstone-RISC-V Academic Version instruction set is based on the RV64IZicsr instruction set.
The (uncompressed) instructions are fixed 32-bit wide, and laid out in memory
in little-endian order. In the encoding space of the RV64IZicsr instruction set,
Capstone-RISC-V Academic Version instructions occupies the “custom-2” subset, i.e., the opcode
of all Capstone-RISC-V Academic Version instructions is 0b1011011.
Capstone-RISC-V Academic Version instruction encodings follow three basic formats: R-type, I-type and S-type, as described below (more details are also provided in the RISC-V ISA Manual).
R-type instructions receive up to three register operands, and I-type/S-type instructions receive up to two register operands and a 12-bit-wide immediate operand.
The Capstone-RISC-V Academic Version ISA also uses a register operand of R-type as an immediate operand in some instructions, which is called register-immediate (RI) type for convenience in this document.
The so-called RI-type instructions are actually derivatives of R-type instructions. They receive up to two register operands and a 5-bit-wide immediate operand.
2.7. System Reset
Upon reset, the system state must conform to the following specifications.
3. Capability Manipulation Instructions
Capstone provides instructions for creating, modifying, and destroying capabilities. Note that due to the guarantee of provenance of capabilities, those instructions are the only way to manipulate capabilities. In particular, it is not possible to manipulate capabilities by manipulating the content of a memory location or register using other instructions.
3.1. Cursor, Bounds, and Permissions Manipulation
3.1.1. Capability Movement
Capabilities can be moved between registers with the MOVC instruction.
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
If
rs1 = rd, the instruction is a no-op. -
Otherwise
-
Write
x[rs1]tox[rd] -
If
x[rs1]is not a non-linear capability (i.e.,type != 1), writecnulltox[rs1].
-
3.1.2. Cursor Increment
The CINCOFFSET and CINCOFFSETIMM instructions increment the cursor of a
capability by a given amount (offset).
CINCOFFSET
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
Set
valtox[rs2]. -
MOVC rd, rs1. -
Set
x[rd].cursortox[rd].cursor + val.
CINCOFFSETIMM
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
MOVC rd, rs1. -
Set
x[rd].cursortox[rd].cursor + imm.
3.1.3. Cursor Setter
The cursor field of a capability can also be directly set with the SCC instruction.
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
Set
valtox[rs2]. -
MOVC rd, rs1. -
Set
x[rd].cursortoval.
3.1.4. Field Query
The LCC instruction is used to read a field from a capability.
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
If
imm > 7, writezerotox[rd] -
Otherwise, write
fieldtox[rd]according to the LCC multiplexing table.
imm |
field |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3.1.5. Bounds Shrinking
The bounds (base and end fields) of a capability can be shrunk with the SHRINK instruction.
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
Set
x[rd].basetox[rs1]andx[rd].endtox[rs2]. -
If
x[rd].cursor < x[rs1], setx[rd].cursortox[rs1]. -
If
x[rd].cursor > x[rs2], setx[rd].cursortox[rs2].
3.1.6. Bounds Splitting
The SPLIT instruction can split a capability into two by splitting the bounds.
It attempts to split the capability x[rs1] into two capabilities,
one with bounds [x[rs1].base, x[rs2]) and the other with bounds [x[rs2], x[rs1].end).
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
If
rs1 = rd, the instruction is a no-op. -
Set
valtox[rs2]. -
Write
x[rs1]tox[rd]. -
Set
x[rs1].endtoval,x[rs1].cursortox[rs1].base. -
Set
x[rd].basetoval,x[rd].cursortoval.
3.1.7. Permission Tightening
The TIGHTEN instruction tightens the permissions (perms field) of a capability.
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
MOVC rd, rs1. -
If
imm > 7, setx[rs1].permsto0. Otherwise, setx[rs1].permstoimm.
3.2. Type Manipulation
Some instructions can affect the type field of a capability directly.
In general, the type field cannot be set arbitrarily.
Instead, it is changed as the side effect of certain semantically significant operations.
3.2.1. Delinearisation
The DELIN instruction delinearises a linear capability.
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
Set
x[rd].typeto1(non-linear).
3.2.2. Initialisation
The INIT instruction transforms an uninitialised capability into a linear capability after its associated memory region has been fully initialised (written with new data).
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
Set
valtox[rs2]. -
MOVC rd, rs1. -
Set
x[rd].typeto0(linear), andx[rd].cursortox[rd].base + val.
3.2.3. Sealing
The SEAL instruction seals a linear capability.
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
MOVC rd, rs1. -
Set
x[rd].typeto2(sealed), andx[rd].asyncto0(synchronous).
3.3. Dropping
The DROP instruction invalidates a capability.
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
If
x[rs1].validis0(invalid), the instruction is a no-op. -
Otherwise, set
x[rs1].validto0(invalid).
3.4. Revocation
3.4.1. Revocation Capability Creation
The MREV instruction creates a revocation capability.
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
Write
x[rs1]tox[rd]. -
Set
x[rd].typeto2(revocation).
3.4.2. Revocation Operation
The REVOKE instruction revokes a capability.
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
For each capability
cin the system (in either a register or memory location),c.validis set to0(invalid) if any of the following conditions are met: -
x[rs1].typeis set to0(linear) if at least one of the following conditions are met:-
For every invalidated capability
c, the type ofcis non-linear (i.e.,c.typeis1). -
2 <=p x[rs1].permsdoes not hold.
-
-
Otherwise, set
x[rs1].typeto3(uninitialised), andx[rs1].cursortox[rs1].base.
4. Memory Access Instructions
Capstone provides instructions to load and store capabilities from/to memory regions.
4.1. Load Capabilities
The LDC instruction loads a capability from the memory.
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
Set
captox[rs1]. -
Load the capability at the memory location
cap.cursor + imm, cap.cursor + imm + CLENBYTES)intox[rd]. -
If
x[rd].typeis not1(non-linear), writecnullto the memory location[cap.cursor + imm, cap.cursor + imm + CLENBYTES).
4.2. Store Capabilities
The STC instruction stores a capability to the memory.
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
Store
x[rs2]to the memory location[x[rs1].cursor + imm, x[rs1].cursor + imm + CLENBYTES). -
If
x[rs1].typeis3(uninitialised), setx[rs1].cursortox[rs1].cursor + CLENBYTES. -
If
x[rs2].typeis not1(non-linear), writecnulltox[rs2].
5. Control Flow Instructions
5.1. Jump to Capabilities
The CJALR and CBNZ instructions allow jumping to a capability, i.e., setting the program counter to a given capability, in a unconditional or conditional manner.
5.1.1. CJALR
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
Set
captox[rs1]. -
Set
pc.cursortopc.cursor + 4, writepctox[rd]. -
Set
cap.cursortocap.cursor + imm, writecaptopc. -
If
rs1 != rdandx[rs1].type != 1, writecnulltox[rs1].
5.1.2. CBNZ
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
If
x[rs1]is0, the instruction is a no-op. -
Otherwise
-
Write
x[rd]topc. -
Set
pc.cursortopc.cursor + imm. -
If
x[rd].type != 1, writecnulltox[rd].
-
5.2. Domain Crossing
Domains in the Capstone-RISC-V Academic Version ISA are individual software compartments that are protected by a safe context switching mechanism, i.e., domain crossing. The mechanism is provided by the CALL and RETURN instructions.
5.2.1. CALL
The CALL instruction is used to call a sealed capability, i.e., to switch to another domain.
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
MOVC cra, rs1. -
Swap the program counter (
pc) with the content at the memory location[cra.base, cra.base + CLENBYTES). -
Swap
cehwith the content at the memory location[cra.base + CLENBYTES, cra.base + 2 * CLENBYTES). -
Swap
cspwith the content at the memory location[cra.base + 2 * CLENBYTES, cra.base + 3 * CLENBYTES). -
Set
cra.typeto5(sealed-return),cra.cursortocra.base,cra.regtord, andcra.asyncto0(synchronous).
5.2.2. RETURN
An exception is raised when any of the following conditions is met:
If no exception is raised:
If rs1 = 0:
-
Set
pc.cursortox[rs2]. -
Write
pctoceh, andepctopc. -
If
epc.type != 1, writecnulltoepc.
Otherwise:
When x[rs1].async = 0 (synchronous):
-
Write
x[rs1]tocapandcnulltox[rs1]. -
Set
pc.cursortox[rs2], and swap the program counter (pc) with the content at the memory location[cap.base, cap.base + CLENBYTES). -
Swap
cehwith the content at the memory location[cap.base + CLENBYTES, cap.base + 2 * CLENBYTES). -
Swap
cspwith the content at the memory location[cap.base + 2 * CLENBYTES, cap.base + 3 * CLENBYTES). -
Write
captox[cap.reg]and setx[cap.reg].typeto4(sealed).
When x[rs1].async = 1 (upon exception):
-
Set
pc.cursortox[rs2], and swap the program counter (pc) with the content at the memory location[x[rs1].base, x[rs1].base + CLENBYTES). -
Store
cehto the memory location[x[rs1].base + CLENBYTES, x[rs1].base + 2 * CLENBYTES). -
Set
x[rs1].typeto4(sealed),x[rs1].asyncto0(synchronous). -
Write the resulting
x[rs1]toceh, andcnulltox[rs1]. -
For
i = 1, 2, …, 31, swapx[i]with the content at the memory location[ceh.base + (i + 1) * CLENBYTES, ceh.base + (i + 2) * CLENBYTES).
When x[rs1].async = 2 (upon interrupt):
-
Set
pc.cursortox[rs2], and swap the program counter (pc) with the content at the memory location[x[rs1].base, x[rs1].base + CLENBYTES). -
Swap
cehwith the content at the memory location[x[rs1].base + CLENBYTES, x[rs1].base + 2 * CLENBYTES). -
Set
x[rs1].typeto4(sealed),x[rs1].asyncto0(synchronous). -
Write the resulting
x[rs1]tocih, andcnulltox[rs1]. -
For
i = 1, 2, …, 31, swapx[i]with the content at the memory location[cih.base + (i + 1) * CLENBYTES, cih.base + (i + 2) * CLENBYTES).
6. Control and Status Instructions
The CCSRRW instruction is used to read and write specified capability control and status registers (CCSRs).
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
If the read constraint is satisfied
-
The content of the CCSR specified by
immis written tox[rd]. -
If
x[rd].typeis not1(non-linear), writecnullto the CCSR specified byimm.
-
-
Otherwise, write
cnulltox[rd]. -
If the write constraint is satisfied
-
Write
x[rs1]to the CCSR specified byimm. -
If
x[rs1].typeis not1(non-linear), writecnulltox[rs1].
-
-
Otherwise, preserve the current content of the CCSR specified by
imm.
7. Adjustments to Existing Instructions
For most of the existing instructions in RV64IZicsr, their behaviour is unmodified.
The cursor field (if type != 4) or base field (if type = 4) of the capability is used
if a register containing a capability is used as an operand.
The following instructions in RV64IZicsr are adjusted in Capstone:
7.1. Memory Access Instructions
In RV64IZicsr, memory access instructions include load instructions
(i.e., lb, lh, ld, lw, lbu, lhu, lwu), and store instructions (i.e., sb, sh, sw, sd).
These instructions take an integer as a raw address, and load or store a value from/to this address.
In Capstone, these instructions are extended to take a capability as an address.
7.1.1. Load Instructions
In the Capstone-RISC-V Academic Version ISA, RV64IZicsr load instructions are modified to load integers of different sizes using capabilities.
Note: size of load instructions
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
Load the content at the memory location
[x[rs1].cursor + imm, x[rs1].cursor + imm + size)as a signed integer tox[rd].
If no exception is raised:
-
Load the content at the memory location
[x[rs1].cursor + imm, x[rs1].cursor + imm + size)as an unsigned integer tox[rd].
7.1.2. Store Instructions
Note: size of store instructions
An exception is raised when any of the following conditions is met:
If no exception is raised:
-
Store
x[rs2]to the memory location[x[rs1].cursor + imm, x[rs1].cursor + imm + size)as an integer. -
The content in the
CLENBYTES-byte aligned memory location[cbase, cend), which aliases with the memory location[x[rs1].cursor + imm, x[rs1].cursor + imm + size), is set to integer type, wherecbase = (x[rs1].cursor + imm) & ~(CLENBYTES - 1)andcend = cbase + CLENBYTES. -
If
x[rs1].typeis3(uninitialised), setx[rs1].cursortox[rs1].cursor + size.
Note: undefined behaviour
7.2. Control Flow Instructions
In RV64IZicsr, conditional branch instructions (i.e., beq, bne, blt, bge, bltu, and bgeu),
and unconditional jump instructions (i.e., jal and jalr) are used to control the flow of execution.
In Capstone, these instructions are adjusted to support the situation where the program counter is a capability.
7.2.1. Branch Instructions
The following adjustments are made to these instructions:
7.2.2. Jump Instructions
The following adjustments are made to these instructions:
7.3. Illegal Instructions
Some instructions in RV64IZicsr now raise illegal instruction (2) exceptions
when executed in the Capstone-RISC-V Academic Version ISA, under all or some circumstances.
These instructions are:
8. Interrupts and Exceptions
8.1. Exception and Exit Codes
Note: where are the exception codes relevant?
The exception code is what the exception handler domain receives as an argument when an exception occurs. It is an integer value that indicates what the type of the exception is.
We define the exception code for each type of exception below. It aligns with the exception codes defined in RV64IZicsr, where applicable, for ease of implementation and interoperability.
| Exception | Exception code |
|---|---|
Instruction address misaligned |
0 |
Instruction access fault |
1 |
Illegal instruction |
2 |
Breakpoint |
3 |
Load address misaligned |
4 |
Load access fault |
5 |
Store/AMO address misaligned |
6 |
Store/AMO access fault |
7 |
Unexpected operand type |
24 |
Invalid capability |
25 |
Unexpected capability type |
26 |
Insufficient capability permissions |
27 |
Capability out of bound |
28 |
Illegal operand value |
29 |
Insufficient system resources |
30 |
Unhandleable exception |
63 |
For interrupts, the same encodings as in RV64IZicsr are used.
Note: Implementation specified exception
8.2. Exception Data
In the Capstone-RISC-V Academic Version ISA, the exception-related data is stored in the tval CSR,
similar to RV64IZicsr. The exception handler
can use the value to decide how to handle the exception.
However, such data is available only for in-domain exception handling, where the
exception handling process does not involve a domain switch.
Note: tval is only available in in-domain exception handling
For exceptions defined in RV64IZicsr, the same data as in it is written to tval.
For the added exceptions, the following data is written to tval:
| Exception | Data |
|---|---|
|
The instruction itself (or the lowest XLEN bits if it is wider than XLEN) |
|
The instruction itself (or the lowest XLEN bits if it is wider than XLEN) |
|
The instruction itself (or the lowest XLEN bits if it is wider than XLEN) |
|
The instruction itself (or the lowest XLEN bits if it is wider than XLEN) |
|
The instruction itself (or the lowest XLEN bits if it is wider than XLEN) |
|
The instruction itself (or the lowest XLEN bits if it is wider than XLEN) |
|
N/A |
8.3. Overview of Interrupt and Exception Handling
For the Capstone-RISC-V Academic Version ISA, the handling of interrupts and exceptions is relatively
straightforward. Regardless of whether the event is an interrupt or an
exception (and what the type of the interrupt or exception is), the processor
core will always transfer the control flow to the corresponding handler domain
(specified in the ceh register for exceptions and
the cih register for interrupts).
The current context is saved and sealed in a sealed-return capability which is then supplied to the exception/interrupt handler domain as an argument.
When exception/interrupt handling is complete, the exception/interrupt handler domain can use the RETURN instruction to resume the execution of the excepted domain. This process resembles that of a CALL-RETURN pair, except that it is asynchronous, rather than synchronous, to the execution of the original domain.
8.4. Interrupt Status
The cis CSR encodes the control and status associated with interrupts.
The diagram below shows its layout.
cis CSR layoutEach pair of xIP and xIE fields describes the status of
the interrupt type x.
The interrupt type x is pending if the xIP field is set to
1, and enabled if the xIE field is set to 1.
Currently, three types of interrupts
are supported: external interrupts (E), timer interrupts (T),
and software interrupts (S).
The definitions for those interrupt types match those in RV64IZicsr.
All the fields are read-write, but only when cih contains a capability.
Note: why not require a valid sealed capability?
8.5. Interrupt Delivery
The interrupt delivery process starts with a certain event
typically asynchronous to the execution of the hardware thread.
The sources of such events include the external interrupt controller,
the timer, and other CPU cores, which correspond to the external,
timer, and software interrupt types (i.e., x = E, T, and S).
When such an event occurs, the xIP field in the cis register
is set to 1 to indicate that the interrupt is pending.
At any point during the execution of a hardware thread,
if any pair of xIP and xIE fields are both 1 and at the same
time the cih register contains
a capability, the interrupt is delivered to the interrupt handler
domain.
Note: global interrupt enable/disable
8.6. Handling of Interrupts
The interrupt is ignored if any of the following conditions is met:
Otherwise:
-
Swap
pcwith the content at the memory location[cih.base, cih.base + CLENBYTES). -
Swap
cehwith the content at the memory location[cih.base + CLENBYTES, cih.base + 2 * CLENBYTES). -
For
i = 1, 2, …, 31, swapx[i]with the content at memory location[cih.base + (i + 1) * CLENBYTES, cih.base + (i + 2) * CLENBYTES). -
Set
cih.typeto5(sealed-return),cih.cursortocih.base,cih.regto0, andcih.asyncto2(upon interrupt). -
Write
cihto the registercra, andcnullto the registercih. -
Write the exception code to the register
a0.
8.7. Handling of Exceptions
Note: the stack of exception handler domains
Follow the interrupt handling procedure with exception code unhandleable exception (63) if any of the following conditions is met:
Otherwise:
If the content in ceh is a valid sealed capability:
-
Swap
pcwith the content at the memory location[ceh.base, ceh.base + CLENBYTES). -
For
i = 1, 2, …, 31, swapx[i]with the content at the memory location[ceh.base + (i + 1) * CLENBYTES, ceh.base + (i + 2) * CLENBYTES). -
Set
ceh.typeto5(sealed-return),ceh.cursortoceh.base,ceh.regto0, andceh.asyncto1(upon exception). -
Write
cehto the registercra, andcnullto the registerceh. -
Swap
cehwith the content at the memory location[cra.base + CLENBYTES, cra.base + 2 * CLENBYTES). -
Write the exception code to the register
a0.
If the content is ceh is a valid executable non-linear capability or linear capability:
-
Write
pctoepc. -
Write
cehtopc. Ifceh.type != 1, writecnulltoceh. -
Write the exception code to
cause. -
Write extra exception data to
tval.
Otherwise, the CPU core enters the state of panic.
Note: sealing mechanism of in-domain exception handling
8.7.1. Panic
When a CPU core is unable to handle an exception, it enters a state called panic.
The aim of the constraints above is to uphold the invariants of the capability model and in turn the security guarantees of the system.
9. Memory Consistency Model
Appendix A: Instruction Listing
A.1. Capstone Instructions
| Mnemonic | Format | Func3 | Func7 | rs1 | rs2 | rd | imm [4:0] | imm[11:0] |
|---|---|---|---|---|---|---|---|---|
R |
|
|
C |
- |
- |
- |
- |
|
R |
|
|
I |
I |
C |
- |
- |
|
RI |
|
|
C |
- |
C |
Z |
- |
|
R |
|
|
- |
- |
C |
- |
- |
|
RI |
|
|
C |
- |
I |
Z |
- |
|
R |
|
|
I |
- |
C |
- |
- |
|
R |
|
|
C |
I |
C |
- |
- |
|
R |
|
|
C |
- |
C |
- |
- |
|
R |
|
|
C |
- |
C |
- |
- |
|
R |
|
|
C |
I |
C |
- |
- |
|
R |
|
|
C |
- |
C |
- |
- |
|
R |
|
|
C |
- |
- |
- |
- |
|
R |
|
|
C |
I |
C |
- |
- |
|
I |
|
- |
C |
- |
C |
- |
S |
| Mnemonic | Format | emode |
Func3 | Func7 | rs1 | rs2 | rd | imm[11:0] |
|---|---|---|---|---|---|---|---|---|
I |
- |
|
- |
C |
- |
C |
S |
|
S |
- |
|
- |
C |
C |
- |
S |
| Mnemonic | Format | Func3 | Func7 | rs1 | rs2 | rd | imm[11:0] |
|---|---|---|---|---|---|---|---|
R |
|
|
C |
- |
C |
- |
|
R |
|
|
C |
I |
- |
- |
|
I |
|
- |
C |
- |
C |
S |
|
I |
|
- |
I |
- |
C |
S |
| Mnemonic | Format | Func3 | Func7 | rs1 | rs2 | rd | imm[11:0] |
|---|---|---|---|---|---|---|---|
I |
|
- |
C |
- |
C |
Z |
A.2. Adjusted RV64IZicsr Memory Access Instructions
| Mnemonic | Format | Func3 | Func7 | rs1 | rs2 | rd | imm[11:0] |
|---|---|---|---|---|---|---|---|
I |
|
- |
C |
- |
I |
S |
|
I |
|
- |
C |
- |
I |
S |
|
I |
|
- |
C |
- |
I |
S |
|
I |
|
- |
C |
- |
I |
S |
|
I |
|
- |
C |
- |
I |
S |
|
I |
|
- |
C |
- |
I |
S |
|
I |
|
- |
C |
- |
I |
S |
| Mnemonic | Format | Func3 | Func7 | rs1 | rs2 | rd | imm[11:0] |
|---|---|---|---|---|---|---|---|
S |
|
- |
C |
I |
- |
S |
|
S |
|
- |
C |
I |
- |
S |
|
S |
|
- |
C |
I |
- |
S |
|
S |
|
- |
C |
I |
- |
S |