Skip to content

Commit

Permalink
reorder capability chapter
Browse files Browse the repository at this point in the history
Show the encoding first so it is easier to find.

Signed-off-by: Axel Heider <[email protected]>
  • Loading branch information
Axel Heider committed Jan 24, 2024
1 parent 6364a67 commit 8d9f89b
Showing 1 changed file with 105 additions and 96 deletions.
201 changes: 105 additions & 96 deletions src/cap-description.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,64 @@ define XLENMAX to be widest XLEN that the implementation supports.
XLENMAX without including the tag bit. The value of CLEN is always calculated
based on XLENMAX regardless of the effective XLEN value.

[#section_cap_encoding]
=== Capability Encoding

ifdef::cheri_v9_annotations[]
NOTE: *CHERI v9 Note:* The encoding changes eliminate the concept of the
in-memory format, and also increase precision for RV32. When EF=0, T and B
are now shifted right rather than left within the address. Also, the bounds
decoding for XLENMAX=32 uses a trick (see bit T8) to save one bit when encoding
the exponent.
endif::[]

The components of a capability except the tag are encoded as shown in
xref:cap_encoding_xlen32[xrefstyle=short] for XLENMAX=32 and
xref:cap_encoding_xlen64[xrefstyle=short] for XLENMAX=64. Each memory location
or register able to hold a capability must also store the tag as out of band
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.

.Capability encoding for XLENMAX=32
[#cap_encoding_xlen32]
include::img/cap-encoding-xlen32.edn[]

.Capability encoding for XLENMAX=64
[#cap_encoding_xlen64]
include::img/cap-encoding-xlen64.edn[]

Reserved bits are available for future extensions to {cheri_base_ext_name}.

NOTE: Reserved bits must be 0 in valid capabilities.

=== Components of a Capability

Capabilities contain the software accessible fields described in this section.

[#section_tag]
==== Tag

An additional hardware managed bit added to addressable memory and registers.
It is stored separately and may be referred to as "out of band". It indicates
whether a register or CLEN-aligned memory location contains a valid capability.
If the tag is set, the capability is valid and can be dereferenced (contingent
on checks such as permissions or bounds).
The tag is an additional hardware managed bit added to addressable memory and
registers. It is stored separately and may be referred to as "out of band". It
indicates whether a register or CLEN-aligned memory location contains a valid
capability. If the 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 tag is clear. Using an invalid capability to
dereference memory or authorize any operation gives rise to exceptions. All
capabilities derived from invalid capabilities are themselves invalid i.e.
their tags are 0.


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

[#section_cap_perms]
==== Architectural Permissions (AP)

===== Description

ifdef::cheri_v9_annotations[]
WARNING: *CHERI v9 Note:* The permissions are encoded differently in this
specification.
Expand Down Expand Up @@ -75,7 +107,7 @@ Execute Permission (X):: Allow instruction execution.
[#asr_perm,reftext="ASR-permission"]
Access System Registers Permission (ASR):: Allow access to privileged CSRs.

===== Permission Encoding
===== Encoding

The bit width of the permissions field depends on the value of XLENMAX as shown
in xref:perms_bit_width[xrefstyle=short]. A {cap_rv32_perms_width}-bit vector
Expand Down Expand Up @@ -192,7 +224,9 @@ also seals the return address capability (if any) since it is the entry point
to the caller function.

[#section_cap_bounds]
==== Bounds
==== Bounds (EF, T, TE, B, BE)

===== Concept

ifdef::cheri_v9_annotations[]
NOTE: *CHERI v9 Note:* The bounds mantissa width is different in XLENMAX=32.
Expand Down Expand Up @@ -262,52 +296,8 @@ xref:exp_bit_width[xrefstyle=short].
NOTE: The address and bounds must be representable in valid capabilities i.e.
when the tag is set (see xref:section_cap_malformed[xrefstyle=short]).

==== Address

XLENMAX integer value that encodes the byte-address of a memory location.

.Address widths depending on XLENMAX
[#address_bit_width,options=header,align="center",width="55%"]
|==============================================================================
^| XLENMAX ^| Address width
^| 32 ^| {cap_rv32_addr_width}
^| 64 ^| {cap_rv64_addr_width}
|==============================================================================

==== Reserved Bits

Reserved bits available for future extensions to {cheri_base_ext_name}.

NOTE: Reserved bits must be 0 in valid capabilities.

[#section_cap_encoding]
=== Capability Encoding

ifdef::cheri_v9_annotations[]
NOTE: *CHERI v9 Note:* The encoding changes eliminate the concept of the
in-memory format, and also increase precision for RV32. When EF=0, T and B
are now shifted right rather than left within the address. Also, the bounds
decoding for XLENMAX=32 uses a trick (see bit T8) to save one bit when encoding
the exponent.
endif::[]

The components of a capability are encoded as shown in
xref:cap_encoding_xlen32[xrefstyle=short] and
xref:cap_encoding_xlen64[xrefstyle=short] when XLENMAX=32 and XLENMAX=64
respectively.

.Capability encoding when XLENMAX=32
[#cap_encoding_xlen32]
include::img/cap-encoding-xlen32.edn[]

.Capability encoding when XLENMAX=64
[#cap_encoding_xlen64]
include::img/cap-encoding-xlen64.edn[]

Each memory location or register able to hold a capability must also store the
tag as out of band 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.
[#section_cap_bounds_decoding]
===== Decoding

The metadata is encoded in a compressed format cite:[woodruff2019cheri]. It
uses a floating point representation to encode the bounds relative to the
Expand Down Expand Up @@ -427,23 +417,49 @@ if ( (E < (CAP_MAX_E - 1)) & (t[XLENMAX: XLENMAX - 1] - b[XLENMAX - 1] > 1) )
That is, invert the most significant bit of _t_ if the decoded length of the
capability is larger than E.

[#section_null_inf_cap]
=== NULL and Infinite Capabilities
[#section_cap_malformed]
===== Malformed Bounds

ifdef::cheri_v9_annotations[]
NOTE: *CHERI v9 Note:* Encoding <<null-cap>> as zeros removes the need for
the difference between in-memory and architectural format.
endif::[]
A capability is _malformed_ if its encoding does not describe a valid
capability because its bounds cannot be correctly decoded. The following check
indicates whether a capability is malformed.

```
malformedMSB = (E == CAP_MAX_E && B[MW - 1:MW - 2] != 0)
|| (E == CAP_MAX_E - 1 && B[MW - 1] != 0)
malformedLSB = (E < 0)
malformed = !EF && (malformedMSB || malformedLSB)
```

The <<null-cap>> capability is represented with 0 in all fields. This implies
that <<null-cap>> has no permissions and its exponent E is CAP_MAX_E e.g. 52
when XLENMAX=64, so its bounds cover the entire address space such that the
expanded base is 0 and top is 2^XLENMAX^. In contrast, the <<infinite-cap>>
capability grants all permissions while its bounds also cover the whole address
space.
NOTE: The check is for malformed _bounds_, so it does not include reserved
bits!

NOTE: The <<infinite-cap>> capability is also known as 'default', 'almighty',
or 'root' capability.
Capabilities with malformed bounds are always invalid anywhere in the system
i.e. their tags are always 0.

==== Address

XLENMAX integer value that encodes the byte-address of a memory location.

.Address widths depending on XLENMAX
[#address_bit_width,options=header,align="center",width="55%"]
|==============================================================================
^| XLENMAX ^| Address width
^| 32 ^| {cap_rv32_addr_width}
^| 64 ^| {cap_rv64_addr_width}
|==============================================================================


[#section_special_caps]
=== Special Capabilities

[#section_null_cap]
==== NULL Capability

The <<null-cap>> 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 XLENMAX=64,
24 for XLENMAX=32), so its bounds cover the entire address space such that the
expanded base is 0 and top is 2^XLENMAX^.

.Field values of the NULL capability
[#null-cap,reftext="NULL",options=header,align=center,width="55%",cols="1,1,3"]
Expand All @@ -462,6 +478,20 @@ or 'root' capability.
| Reserved| zeros | All reserved fields
|==============================================================================

ifdef::cheri_v9_annotations[]
NOTE: *CHERI v9 Note:* Encoding <<null-cap>> as zeros removes the need for
the difference between in-memory and architectural format.
endif::[]

[#section_infinite_cap]
==== Infinite Capability

The <<infinite-cap>> capability grants all permissions while its bounds also
cover the whole address space.

NOTE: The <<infinite-cap>> capability is also known as 'default', 'almighty',
or 'root' capability.

.Field values of the Infinite capability
[#infinite-cap,reftext="Infinite"]
[options=header,width="100%",align=center,width="55%",cols="1,1,3"]
Expand All @@ -484,14 +514,13 @@ or 'root' capability.
=== Representable Limit Check

Pointer arithmetic on capabilities must be checked to ensure that the new
address is within the capability's representable region described in
xref:section_cap_encoding[xrefstyle=short]. The new address, after pointer
arithmetic, is within the representable region if decompressing the
capability's bounds with the original and new addresses yields the same base
and top addresses. 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 region if `b == b' && t == t'`.
address is within the capability's representable region described by the bounds.
The new address, after pointer arithmetic, is within the representable region if
decompressing the capability's bounds with the original and new addresses yields
the same base and top addresses. 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 region if `b == b' && t == t'`.

Changing a capability's address to a value outside the representable region
unconditionally clears the capability's tag.
Expand All @@ -502,23 +531,3 @@ then the bounds will need to be recalculated. Instructions like <<CINCOFFSET>>
and <<CSETADDR>> update the address field but do not recalculate the bounds.
Therefore, if the leading 1 moves relative to when the bounds were calculated
then the tag is cleared on the result as the encoding has been invalidated.

[#section_cap_malformed]
=== Malformed Capability Bounds

A capability is _malformed_ if its encoding does not describe a valid
capability because its bounds cannot be correctly decoded. The following check
indicates whether a capability is malformed.

```
malformedMSB = (E == CAP_MAX_E && B[MW - 1:MW - 2] != 0)
|| (E == CAP_MAX_E - 1 && B[MW - 1] != 0)
malformedLSB = (E < 0)
malformed = !EF && (malformedMSB || malformedLSB)
```

NOTE: The check is for malformed _bounds_, so it does not include reserved
bits!

Capabilities with malformed bounds are always invalid anywhere in the system
i.e. their tags are always 0.

0 comments on commit 8d9f89b

Please sign in to comment.