Skip to content

Commit

Permalink
Added thread identifier (TID) (#187)
Browse files Browse the repository at this point in the history
This new extension, currently tentatively named Zstid, makes it possible
to reliably retrieve a thread identifier for U-mode (and to some extent 
also S-mode). The unprivileged tp register cannot be used for this
purpose since any untrusted could overwrite it. Being able to
efficiently identify the current thread ID is important for efficient
software compartmentalization.

Fixes #179
  • Loading branch information
francislaus authored Apr 15, 2024
1 parent 40c52c6 commit 8a8a3e8
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/attributes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ endif::[]
:cheri_pte_ext_name: Zcheri_pte
// Extension for CHERI capabilities in vector registers
:cheri_vectorcap_ext_name: Zcheri_vectorcap
// Extension for thread identification
:tid_ext_name: Zstid

// Extension for supporting lr/sc.[bh]
:lr_sc_bh_ext_name: Zabhlrsc
Expand Down
22 changes: 22 additions & 0 deletions src/img/stidcreg.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[bytefield]
----
(defattrs :plain [:plain {:font-family "M+ 1p Fallback" :font-size 21}])
(def row-height 40)
(def row-header-fn nil)
(def left-margin 100)
(def right-margin 100)
(def boxes-per-row 34)
(draw-column-headers {:height 20 :font-size 18 :labels (reverse ["0" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "MXLEN-1" "" ""])})

(draw-box "Tag" {:span 1})
(draw-box "" {:span 1 :borders {}})

(draw-box "stidc (Metadata)" {:span 32})

(draw-box "" {:span 2 :borders {}})

(draw-box "stidc (Address)" {:span 32})

(draw-box "" {:span 2 :borders {}})
(draw-box "MXLEN" {:span 32 :borders {}})
----
14 changes: 14 additions & 0 deletions src/img/stidreg.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[bytefield]
----
(defattrs :plain [:plain {:font-family "M+ 1p Fallback" :font-size 24}])
(def row-height 40)
(def row-header-fn nil)
(def left-margin 100)
(def right-margin 100)
(def boxes-per-row 32)
(draw-column-headers {:height 20 :font-size 18 :labels (reverse ["0" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "SXLEN-1"])})

(draw-box "stid" {:span 32})

(draw-box "SXLEN" {:span 32 :borders {}})
----
22 changes: 22 additions & 0 deletions src/img/utidcreg.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[bytefield]
----
(defattrs :plain [:plain {:font-family "M+ 1p Fallback" :font-size 21}])
(def row-height 40)
(def row-header-fn nil)
(def left-margin 100)
(def right-margin 100)
(def boxes-per-row 34)
(draw-column-headers {:height 20 :font-size 18 :labels (reverse ["0" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "MXLEN-1" "" ""])})

(draw-box "Tag" {:span 1})
(draw-box "" {:span 1 :borders {}})

(draw-box "utidc (Metadata)" {:span 32})

(draw-box "" {:span 2 :borders {}})

(draw-box "utidc (Address)" {:span 32})

(draw-box "" {:span 2 :borders {}})
(draw-box "MXLEN" {:span 32 :borders {}})
----
14 changes: 14 additions & 0 deletions src/img/utidreg.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[bytefield]
----
(defattrs :plain [:plain {:font-family "M+ 1p Fallback" :font-size 24}])
(def row-height 40)
(def row-header-fn nil)
(def left-margin 100)
(def right-margin 100)
(def boxes-per-row 32)
(draw-column-headers {:height 20 :font-size 18 :labels (reverse ["0" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "UXLEN-1"])})

(draw-box "utid" {:span 32})

(draw-box "UXLEN" {:span 32 :borders {}})
----
2 changes: 2 additions & 0 deletions src/introduction.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ virtual-memory
{cheri_vectorcap_ext_name}:: CHERI extension for the RISC-V Vector (V)
extension. It adds support for storing CHERI capabilities in
vector registers, intended for vectorised memory copying
{tid_ext_name}:: Extension for supporting thread identifiers. This extension
improves software compartmentalization on CHERI systems.

CAUTION: The extension names are provisional and subject to change.

Expand Down
2 changes: 2 additions & 0 deletions src/riscv-cheri.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ include::cheri-pte-ext.adoc[]

include::riscv-legacy-integration.adoc[]

include::tid-ext.adoc[]

include::instructions.adoc[]

include::tables.adoc[]
Expand Down
107 changes: 107 additions & 0 deletions src/tid-ext.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
== "Zstid Extension for Thread Identification

{tid_ext_name} is an optional extension to the RISC-V base ISA.
Implementations that support {cheri_base_ext_name} and {tid_ext_name}.
define a variant of the CHERI ISA that allows for more efficient
software compartmentalization of CHERI programs.

=== Control and Status Registers (CSRs)

{tid_ext_name} adds two new CSRs to implement a trusted thread
identifier (TID) used in compartmentalization. These CSRs are listed in
xref:tid-scsrnames-added[xrefstyle=short] and
xref:tid-ucsrnames-added[xrefstyle=short].

[[tid-scsrnames-added]]
.Added supervisor-mode CSRs in {tid_ext_name}
[%autowidth,float="center",align="center",cols="<,<,<,<,<",options="header"]
|===
|{tid_ext_name} CSR|Address|Prerequisites|Permissions|Description
|<<stid>>|0x580|S-mode|SRW, <<asr_perm>>|Supervisor Thread Identifier
|===

[[tid-ucsrnames-added]]
.Added user-mode CSRs in {tid_ext_name}
[%autowidth,float="center",align="center",cols="<,<,<,<,<",options="header"]
|===
|{tid_ext_name} CSR|Address|Prerequisites|Permissions|Description
|<<utid>>|0xC80|U-mode|URO|User Thread Identifier
|===

=== Supervisor-Level and Unprivileged CSRs

[#stid,reftext="stid"]
==== Supervisor Thread Identifier (stid)

The <<stid>> register is an SXLEN-bit read-write register. It is used to
identify the current thread. The reset value of this register is
UNSPECIFIED.

.Supervisor thread identifier register
include::img/stidreg.edn[]


[#utid,reftext="utid"]
==== User Thread Identifier (utid)

The <<utid>> register is an UXLEN-bit read-only register. It is a read-only
copy of the <<stid>> register. The reset value of this register is
UNSPECIFIED.

.User thread identifier register
include::img/utidreg.edn[]

When {cheri_base_ext_name} is implemented, the {tid_ext_name} CSRs are
extended as follows:

[#stidc,reftext="stidc"]
==== Supervisor Thread Identifier Capability (stidc)

The <<stidc>> register is an CLEN-bit read-write capability register.
It is the capability extension of the <<stid>> register.
It is used to identify the current thread. On reset the tag of <<stidc>>
will be set to 0 and the remainder of the data is UNSPECIFIED.

.Supervisor thread identifier capability register
include::img/stidcreg.edn[]


[#utidc,reftext="utidc"]
==== User Thread Identifier Capability (utidc)

The <<utidc>> register is an CLEN-wide read-only capability register.
It is the capability extension of the <<utid>> register. <<utidc>> is
a read-only copy of the <<stidc>> register. On reset the tag of <<utidc>>
will be set to 0 and the remainder of the data is UNSPECIFIED.

.User thread identifier capability register
include::img/utidcreg.edn[]

[#CHERI_COMP,reftext="CHERI Compartmentalization]
=== 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 threads and thus there needs to be a way of
identifying the current thread. While identifying the current 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 thread because
the tp register is a general purpose register and can be changed arbitrarily
by untrusted code. Therefore, this specification offers two additional CSRs
that facilitate a trusted source for the thread ID. The supervisor thread
identifier (<<stid>>) register is readable and writeable with <<asr_perm>>
from the supervisor mode allowing to change the thread ID on a context switch.
The user thread identifier (<<utid>>) exposes the current value of <<stid>> as a
read-only copy.

This extension extends <<stid>> to its capability variant <<stidc>> and
<<utid>> to its capability variant <<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 storage integers.

0 comments on commit 8a8a3e8

Please sign in to comment.