diff --git a/Makefile b/Makefile index 0558e240..d0ab9433 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ GEN_SCRIPT = $(SCRIPTS_DIR)/generate_tables.py # Version and date DATE ?= $(shell date +%Y-%m-%d) -VERSION ?= v0.8.3 +VERSION ?= v0.9.0 REVMARK ?= Draft # URLs for downloaded CSV files diff --git a/src/attributes.adoc b/src/attributes.adoc index 9566259d..ed71f4cf 100644 --- a/src/attributes.adoc +++ b/src/attributes.adoc @@ -46,6 +46,8 @@ endif::[] :cheri_default_ext_name: Zcherihybrid // Extension for CHERI PTE bits :cheri_pte_ext_name: Zcheripte +// Extension for capability levels (flow control) +:cheri_levels_ext_name: Zcherilevels // Extension for thread identification :tid_ext_name: Zstid @@ -77,7 +79,10 @@ endif::[] :cap_rv32_mw_width: 10 :cap_rv64_mw_width: 14 :cap_rv32_perms_width: 5 +//including Zcherilevels, 6 without :cap_rv64_perms_width: 6 +//CL is not a permission, so 8 not 9 +:cap_rv64_perms_levels_width: 8 :cap_rv32_addr_width: 32 :cap_rv64_addr_width: 64 :cap_rv32_exp_width: 5 diff --git a/src/cap-description.adoc b/src/cap-description.adoc index e7121388..dd700c45 100644 --- a/src/cap-description.adoc +++ b/src/cap-description.adoc @@ -60,6 +60,8 @@ Reserved bits are available for future extensions to {cheri_base_ext_name}. NOTE: Reserved bits must be 0 in tagged capabilities. +NOTE: The CL field is only present if {cheri_levels_ext_name} is implemented, otherwise it is reserved. + === Components of a Capability Capabilities contain the software accessible fields described in this section. @@ -102,6 +104,7 @@ The byte-address of a memory location is encoded as MXLEN integer value. ifdef::cheri_v9_annotations[] WARNING: *CHERI v9 Note:* The permissions are encoded differently in this specification. +Additionally, this specification incorporates permissions that were present in Morello and/or CHERIoT but not CHERI v9. endif::[] This field encodes architecturally defined permissions of the capability. @@ -166,6 +169,8 @@ Therefore, it is only possible to encode a subset of all combinations. ^| 64 | {cap_rv64_perms_width} | Separate bits for each architectural permission. |============================================================================== +NOTE: if {cheri_levels_ext_name} is supported then there are {cap_rv64_perms_levels_width} architectural permission bits. + 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 <> for each quadrant. @@ -222,8 +227,8 @@ reserved values as if it were 0b00000 (no permissions). Future extensions may as meanings to the reserved bit patterns, in which case <> is allowed to report a non-zero value. -A {cap_rv64_perms_width}-bit vector encodes the permissions when MXLEN=64. In -this case, there is a bit per permission as shown in +A {cap_rv64_perms_width}-bit vector encodes the permissions when MXLEN=64 ({cap_rv64_perms_levels_width}-bit if {cheri_levels_ext_name} is supported). +In this case, there is a bit per permission as shown in xref:cap_perms_encoding64[xrefstyle=short]. A permission is granted if its corresponding bit is set, otherwise the capability does not grant that permission. @@ -240,8 +245,10 @@ permission. | 3 | <> | 4 | <> | 5 | <> -//| 6 | <> +| 6 | <>^1^ +| 7 | <>^1^ |============================================================================== +^1^ This permission is only supported if the implementation supports <>. The <> is only assigned meaning when the implementation supports {cheri_default_ext_name} _and_ <> is set. @@ -617,8 +624,9 @@ or 'root' capability. | SDP | ones | Grants all permissions | AP (MXLEN=32) | 0x8/0x9^1^ (see xref:cap_perms_encoding32[xrefstyle=short]) | Grants all permissions -| AP (MXLEN=64) | 0x3F (see xref:cap_perms_encoding64[xrefstyle=short]) +| AP (MXLEN=64) | 0xFF (see xref:cap_perms_encoding64[xrefstyle=short]) | Grants all permissions +| CL | one^2^| _Global_ | CT | zero | Unsealed | EF | zero | Internal exponent format | L~8~ | zero | Top address reconstruction bit (MXLEN=32 only) @@ -636,6 +644,8 @@ or 'root' capability. * For MXLEN=32, the <> is set to {INT_MODE_VALUE} in the AP field, giving the value 0x9 * For MXLEN=64, the <> is set to {INT_MODE_VALUE} in a separate M field which is _not shown_ in the table above. +^2^ This field only exists if {cheri_levels_ext_name} is implemented. + [#section_cap_representable_check, reftext="Representable Range"] === Representable Range Check diff --git a/src/csv/CHERI_ISA.csv b/src/csv/CHERI_ISA.csv index c1df7dc6..eef8d0de 100644 --- a/src/csv/CHERI_ISA.csv +++ b/src/csv/CHERI_ISA.csv @@ -52,8 +52,8 @@ "GCTYPE","✔","✔","","","","✔","✔","Both","","","","","","","","","","","","","","","","","OP","1-src 1-dst","","","Get capability type","","","","","","","","" "SCMODE","✔","✔","","","","✔","","Both","","","","","","","","","","","","","","","","","OP","1-src 1-dst","","","Set the mode bit of a capability, no permissions required","","","","","","","","" "GCMODE","✔","✔","","","","✔","","Both","","","","","","","","","","","","","","","","","OP","1-src 1-dst","","","Get the mode bit of a capability, no permissions required","","","","","","","","" -"MODESW","✔","✔","","","","✔","","Both","","","","","","","","","","","","","","","","","OP","no operands","","","Directly switch mode ({cheri_int_mode_name}/ {cheri_cap_mode_name})","mode==D (optional)","","","","","","","" -"C.MODESW","✔","✔","","","","✔","","Both","","","","","","","","","","","","","","","","","C1","no operands","","","Directly switch mode ({cheri_int_mode_name}/ {cheri_cap_mode_name})","mode==D (optional)","","","","","","","" +"MODESW.CAP","✔","✔","","","","✔","","Both","","","","","","","","","","","","","","","","","OP","no operands","","","Directly switch mode into {cheri_cap_mode_name}","","","","","","","","" +"MODESW.INT","✔","✔","","","","✔","","Both","","","","","","","","","","","","","","","","","OP","no operands","","","Directly switch mode into {cheri_int_mode_name}","","","","","","","","" "C.ADDI16SP","✔","✔","","","","✔","✔","Both","","","","✔","","","","","","","","","","","","","C0","","","","ADD immediate to stack pointer, CADD in Capability Mode","","","","","","","","" "C.ADDI4SPN","✔","✔","","","","✔","✔","Both","","","","✔","","","","","","","","","","","","","C0","","","","ADD immediate to stack pointer, CADDI in Capability Mode","","","","","","","","" "C.MV","✔","✔","","","","✔","✔","Both","","","","✔","","","","","","","","","","","","","C2","","","","Register Move, cap reg move in Capability Mode","","","","","","","","" diff --git a/src/debug-integration.adoc b/src/debug-integration.adoc index 03c1de4d..6a2f653a 100644 --- a/src/debug-integration.adoc +++ b/src/debug-integration.adoc @@ -108,8 +108,8 @@ include::img/dpccreg.edn[] Upon entry to debug mode, cite:[riscv-debug-spec], 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 <>, which refers to -all jumps, conditional branches and <>. The exception is <> -which _is_ supported if {cheri_default_ext_name} is implemented, see <> +all jumps, conditional branches and <>. The exceptions are <> and <> +which _are_ supported if {cheri_default_ext_name} is implemented, see <> for details. As a result, the value of <> is UNSPECIFIED in debug mode according @@ -180,13 +180,12 @@ The reset value is the <> capability. If {cheri_default_ext_name} is implemented: * The <> is reset to {cheri_int_mode_name} ({INT_MODE_VALUE}). -* The debugger can set the <> to {cheri_cap_mode_name} ({CAP_MODE_VALUE}) by executing <> from the program buffer -** if <> is not supported in debug mode then the same can be done by reading the CSR, using <> and then writing the CSR. -** This only needs doing once after resetting the core. -* The <> is used on debug mode entry to determine which CHERI execution mode to enter. +* The debugger can set the <> to {cheri_cap_mode_name} ({CAP_MODE_VALUE}) by executing <> from the program buffer. +** Executing <> causes subsequent instruction execution from the program buffer, starting from the next instruction, to be executed in {cheri_cap_mode_name}. It also sets the CHERI execution mode to {cheri_cap_mode_name} on future entry into debug mode. +** Therefore to enable use of a CHERI debugger, a single <> only needs to be executed once from the program buffer after resetting the core. +** The debugger can also execute <> to change the mode back to {cheri_int_mode_name}, which also affects the execution of the next instruction in the program buffer, updates the <> of <> and controls which CHERI execution mode to enter on the next entry into debug mode. -The <> is the only writeable field in <>. -Therefore if {cheri_default_ext_name} is not implemented then it is read-write with no writeable fields. +The <> of <> is _only_ updated by executing <> or <> from the program buffer. NOTE: 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 diff --git a/src/img/acperm_bit_field.edn b/src/img/acperm_bit_field.edn index fce5cd87..1412c887 100644 --- a/src/img/acperm_bit_field.edn +++ b/src/img/acperm_bit_field.edn @@ -6,7 +6,7 @@ (def left-margin 100) (def right-margin 100) (def boxes-per-row 32) -(draw-column-headers {:height 20 :font-size 18 :labels (reverse ["0" "1" "2" "" "4" "5" "6" "" "" "SDPLEN+5" "" "" "" "" "" "15" "16" "17" "18" "19" "" "" "" "" "" "" "" "" "" "" "" "XLEN-1"])}) +(draw-column-headers {:height 20 :font-size 18 :labels (reverse ["0" "1" "2" "3" "4" "5" "6" "" "" "SDPLEN+5" "" "" "" "" "" "15" "16" "17" "18" "19" "" "" "" "" "" "" "" "" "" "" "" "XLEN-1"])}) (draw-box "Reserved" {:span 13}) (draw-box "R" {:span 1}) @@ -15,7 +15,9 @@ (draw-box "Reserved" {:span 6}) (draw-box "SDP" {:span 4}) (draw-box "C" {:span 1}) -(draw-box "Reserved" {:span 3}) +(draw-box "CL" {:span 1}) +(draw-box "SL" {:span 1}) +(draw-box "EL" {:span 1}) (draw-box "LM" {:span 1}) (draw-box "W" {:span 1}) @@ -23,10 +25,12 @@ (draw-box "1" {:span 1 :borders {}}) (draw-box "1" {:span 1 :borders {}}) (draw-box "1" {:span 1 :borders {}}) -(draw-box "8" {:span 6 :borders {}}) +(draw-box "10-SDPLEN" {:span 6 :borders {}}) (draw-box "SDPLEN" {:span 4 :borders {}}) (draw-box "1" {:span 1 :borders {}}) -(draw-box "3" {:span 3 :borders {}}) +(draw-box "1" {:span 1 :borders {}}) +(draw-box "1" {:span 1 :borders {}}) +(draw-box "1" {:span 1 :borders {}}) (draw-box "1" {:span 1 :borders {}}) (draw-box "1" {:span 1 :borders {}}) ---- diff --git a/src/img/cap-encoding-xlen32.edn b/src/img/cap-encoding-xlen32.edn index cf5e0622..b6fed7a7 100644 --- a/src/img/cap-encoding-xlen32.edn +++ b/src/img/cap-encoding-xlen32.edn @@ -6,11 +6,12 @@ (def left-margin 100) (def right-margin 100) (def boxes-per-row 32) -(draw-column-headers {:height 50 :font-size 22 :labels (reverse ["0" "1" "2" "" "" "" "" "" "" "9" "10" "11" "12" "" "" "" "" "17" "18" "19" "20" "21" "" "" "24" "25" "" "" "" "29" "30" "31"])}) +(draw-column-headers {:height 50 :font-size 22 :labels (reverse ["0" "1" "2" "" "" "" "" "" "" "9" "10" "11" "12" "" "" "" "" "17" "18" "19" "20" "21" "" "23" "24" "25" "" "" "" "29" "30" "31"])}) (draw-box "SDP" {:span 2}) (draw-box "AP, M" {:span 5}) -(draw-box "Reserved" {:span 4}) +(draw-box "CL" {:span 1}) +(draw-box "Reserved" {:span 3}) (draw-box "CT" {:span 1}) (draw-box "EF" {:span 1}) (draw-box "L8" {:span 1}) diff --git a/src/img/cap-encoding-xlen64.edn b/src/img/cap-encoding-xlen64.edn index 9d6dc3ba..cb2a7d09 100644 --- a/src/img/cap-encoding-xlen64.edn +++ b/src/img/cap-encoding-xlen64.edn @@ -6,13 +6,14 @@ (def left-margin 100) (def right-margin 100) (def boxes-per-row 32) -(draw-column-headers {:height 50 :font-size 22 :labels (reverse ["0" "2" "3" "" "" "" "13" "14" "16" "17" "" "" "25" "26" "27" "28" "" "" "" "" "45" "46" "" "" "51" "52" "53" "56" "57" "" "" "63"])}) +(draw-column-headers {:height 50 :font-size 22 :labels (reverse ["0" "2" "3" "" "" "" "13" "14" "16" "17" "" "" "25" "26" "27" "28" "" "42" "43" "44" "" "" "" "" "51" "52" "53" "56" "57" "" "" "63"])}) (draw-box "Reserved" {:span 4}) (draw-box "SDP" {:span 2}) (draw-box "M" {:span 1}) -(draw-box "AP" {:span 4}) -(draw-box "Reserved" {:span 6}) +(draw-box "AP" {:span 6}) +(draw-box "CL" {:span 1}) +(draw-box "Reserved" {:span 3}) (draw-box "CT" {:span 1}) (draw-box "EF" {:span 1}) (draw-box "T[11:3]" {:span 4}) diff --git a/src/img/htval2reg.edn b/src/img/htval2reg.edn index 08866916..f7ec9e17 100644 --- a/src/img/htval2reg.edn +++ b/src/img/htval2reg.edn @@ -8,9 +8,9 @@ (def boxes-per-row 32) (draw-column-headers {:height 20 :font-size 18 :labels (reverse ["0" "" "" "3" "4" "" "" "" "" "" "" "" "" "" "" "15" "16" "" "" "19" "20" "" "" "" "" "" "" "" "" "" "" "HSXLEN-1"])}) -(draw-box "Reserved" {:span 12}) +(draw-box "WPRI" {:span 12}) (draw-box "TYPE" {:span 4}) -(draw-box "Reserved" {:span 12}) +(draw-box "WPRI" {:span 12}) (draw-box "CAUSE" {:span 4}) (draw-box "HSXLEN-20" {:span 12 :borders {}}) diff --git a/src/img/large_cheri_purecap_system.drawio.png b/src/img/large_cheri_purecap_system.drawio.png new file mode 100644 index 00000000..ed5cf33d Binary files /dev/null and b/src/img/large_cheri_purecap_system.drawio.png differ diff --git a/src/img/large_cheri_system.drawio.png b/src/img/large_cheri_system.drawio.png new file mode 100644 index 00000000..572304ba Binary files /dev/null and b/src/img/large_cheri_system.drawio.png differ diff --git a/src/img/mtval2reg.edn b/src/img/mtval2reg.edn index 575ad9b5..6588291f 100644 --- a/src/img/mtval2reg.edn +++ b/src/img/mtval2reg.edn @@ -8,9 +8,9 @@ (def boxes-per-row 32) (draw-column-headers {:height 20 :font-size 18 :labels (reverse ["0" "" "" "3" "4" "" "" "" "" "" "" "" "" "" "" "15" "16" "" "" "19" "20" "" "" "" "" "" "" "" "" "" "" "MXLEN-1"])}) -(draw-box "Reserved" {:span 12}) +(draw-box "WPRI" {:span 12}) (draw-box "TYPE" {:span 4}) -(draw-box "Reserved" {:span 12}) +(draw-box "WPRI" {:span 12}) (draw-box "CAUSE" {:span 4}) (draw-box "MXLEN-20" {:span 12 :borders {}}) diff --git a/src/img/small_cheri_system.drawio.png b/src/img/small_cheri_system.drawio.png new file mode 100644 index 00000000..7b7e8862 Binary files /dev/null and b/src/img/small_cheri_system.drawio.png differ diff --git a/src/img/stval2reg.edn b/src/img/stval2reg.edn index bdcad87c..dfe2cbd1 100644 --- a/src/img/stval2reg.edn +++ b/src/img/stval2reg.edn @@ -8,9 +8,9 @@ (def boxes-per-row 32) (draw-column-headers {:height 20 :font-size 18 :labels (reverse ["0" "" "" "3" "4" "" "" "" "" "" "" "" "" "" "" "15" "16" "" "" "19" "20" "" "" "" "" "" "" "" "" "" "" "SXLEN-1"])}) -(draw-box "Reserved" {:span 12}) +(draw-box "WPRI" {:span 12}) (draw-box "TYPE" {:span 4}) -(draw-box "Reserved" {:span 12}) +(draw-box "WPRI" {:span 12}) (draw-box "CAUSE" {:span 4}) (draw-box "SXLEN-20" {:span 12 :borders {}}) diff --git a/src/img/vstval2reg.edn b/src/img/vstval2reg.edn index 7c20561f..e2661456 100644 --- a/src/img/vstval2reg.edn +++ b/src/img/vstval2reg.edn @@ -8,9 +8,9 @@ (def boxes-per-row 32) (draw-column-headers {:height 20 :font-size 18 :labels (reverse ["0" "" "" "3" "4" "" "" "" "" "" "" "" "" "" "" "15" "16" "" "" "19" "20" "" "" "" "" "" "" "" "" "" "" "VSXLEN-1"])}) -(draw-box "Reserved" {:span 12}) +(draw-box "WPRI" {:span 12}) (draw-box "TYPE" {:span 4}) -(draw-box "Reserved" {:span 12}) +(draw-box "WPRI" {:span 12}) (draw-box "CAUSE" {:span 4}) (draw-box "VSXLEN-20" {:span 12 :borders {}}) diff --git a/src/insns/acperm_32bit.adoc b/src/insns/acperm_32bit.adoc index 04d94ac7..346cbd4c 100644 --- a/src/insns/acperm_32bit.adoc +++ b/src/insns/acperm_32bit.adoc @@ -50,6 +50,10 @@ The common rules are: .. Clear <> unless <> is set . <> cannot be set without <> being set .. Clear <> unless <> is set. +. <> cannot be set without <> being set +.. Zero <> unless <> is set. +. <> cannot be set without <> being set +.. Zero <> unless <> is set. NOTE: The combination of <> clear and <> set is reserved for future extensions. @@ -64,6 +68,10 @@ The MXLEN=32 additional rules are: [#acperm_bit_field] include::../img/acperm_bit_field.edn[] +NOTE: The <>, <> and <> fields are only defined if the implementation supports <>. + +NOTE: Even though being included here <> is not considered an architectural permission. + Exceptions:: include::require_cre.adoc[] diff --git a/src/insns/atomic_exceptions.adoc b/src/insns/atomic_exceptions.adoc index 6ef9f35e..6969e952 100644 --- a/src/insns/atomic_exceptions.adoc +++ b/src/insns/atomic_exceptions.adoc @@ -6,7 +6,9 @@ Requires <> and <> in the authorising capability. + If <> is not granted then store the memory tag as zero, and load `cd.tag` as zero. + -If the authorizing capability does not grant <>, and the tag of `cd` is 1 and `cd` is not sealed, then an implicit <> clearing <> and <> is performed to obtain the final permissions on `cd` (see <>). +If the authorizing capability does not grant <>, and the tag of `cd` is 1 and `cd` is not sealed, then an implicit <> clearing <> and <> is performed to obtain the intermediate permissions on `cd` (see <>). ++ +If the authorizing capability does not grant <>, and the tag of `cd` is 1, then an implicit <> clearing <> and restricting <> to the level of the authorizing capability is performed to obtain the final permissions on `cd` (see <>). + endif::[] ifndef::cap_atomic[] diff --git a/src/insns/auipc_32bit.adoc b/src/insns/auipc_32bit.adoc index dbdbeb42..bc3be14e 100644 --- a/src/insns/auipc_32bit.adoc +++ b/src/insns/auipc_32bit.adoc @@ -6,6 +6,8 @@ Synopsis:: Add upper immediate to *pc*/<> +NOTE: CHERI extensions which use an alternative capability format may choose to redefine the handling of the immediate operand for this instruction in {cheri_cap_mode_name}. + {cheri_cap_mode_name} Mnemonic:: `auipc cd, imm` diff --git a/src/insns/hypv-virt-loadx.adoc b/src/insns/hypv-virt-loadx.adoc index aaea5fc3..88640f66 100644 --- a/src/insns/hypv-virt-loadx.adoc +++ b/src/insns/hypv-virt-loadx.adoc @@ -5,8 +5,6 @@ See <>. -<<< - [#HLVX_WU,reftext="HLVX.WU"] ==== HLVX.WU @@ -14,12 +12,12 @@ Synopsis:: Hypervisor virtual machine load from executable memory {cheri_cap_mode_name} Mnemonics:: -`hlv.hu rd, cs1` + -`hlv.wu rd, cs1` +`hlvx.hu rd, cs1` + +`hlvx.wu rd, cs1` {cheri_int_mode_name} Mnemonics:: -`hlv.hu rd, rs1` + -`hlv.wu rd, rs1` +`hlvx.hu rd, rs1` + +`hlvx.wu rd, rs1` Encoding:: include::wavedrom/hypv-virt-loadx.adoc[] diff --git a/src/insns/hypv-virt-store-cap.adoc b/src/insns/hypv-virt-store-cap.adoc index ad892b68..77373445 100644 --- a/src/insns/hypv-virt-store-cap.adoc +++ b/src/insns/hypv-virt-store-cap.adoc @@ -19,9 +19,7 @@ include::wavedrom/hypv-virt-store-cap.adoc[] Store a CLEN+1 bit value in `cs2` to memory as though V=1; i.e., with the address translation and protection, and endianness, that apply to memory accesses in either VS-mode or VU-mode. The effective address is the address of -`cs1`. The authorising capability for the operation is `cs1`. The capability -written to memory has the tag set to 0 if the tag of `cs2` is 0 or `cs1` does -not grant <>. +`cs1`. The authorising capability for the operation is `cs1`. + include::load_store_c0.adoc[] @@ -29,9 +27,9 @@ include::load_store_c0.adoc[] Store a CLEN+1 bit value in `cs2` to memory as though V=1; i.e., with the address translation and protection, and endianness, that apply to memory accesses in either VS-mode or VU-mode. The effective address is the `rs1`. The -authorising capability for the operation is <>. The capability written to -memory has the tag set to 0 if the tag of `cs2` is 0 or <> does not grant -<>. +authorising capability for the operation is <>. + +include::store_tag_perms.adoc[] include::malformed_no_check.adoc[] diff --git a/src/insns/load_tag_perms.adoc b/src/insns/load_tag_perms.adoc index e89839b0..3ab397c2 100644 --- a/src/insns/load_tag_perms.adoc +++ b/src/insns/load_tag_perms.adoc @@ -2,9 +2,14 @@ Resulting value of `cd`:: The tag value written to `cd` is 0 if the tag of the memory location loaded is 0 or the authorizing capability (<> or `cs1`) does not grant <>. + -If the authorizing capability does not grant <>, and the tag of `cd` is 1 and `cd` is not sealed, then an implicit <> clearing <> and <> is performed to obtain the final permissions on `cd`. +If the authorizing capability does not grant <>, and the tag of `cd` is 1 and `cd` is not sealed, then an implicit <> clearing <> and <> is performed to obtain the intermediate permissions on `cd`. ++ +If the authorizing capability does not grant <>, and the tag of `cd` is 1, then an implicit <> clearing <> and restricting <> to the level of the authorizing capability is performed to obtain the final permissions on `cd`. NOTE: Missing <> does not affect untagged values since this could result in surprising bit patterns when copying non-capability data. Similarly, sealed capabilities are not modified as they are not directly dereferenceable. +NOTE: Missing <> also affects the level of sealed capabilities since notionally the <> of a capability is not a permission but rather a data flow label attached to the loaded value. +However, untagged values are not affected by <>. + NOTE: While the implicit <> introduces a dependency on the loaded data, microarchitectures can avoid this by deferring the actual masking of permissions until the loaded capability is dereferenced or the metadata bits are inspected using <> or <>. diff --git a/src/insns/modesw_16bit.adoc b/src/insns/modesw_16bit.adoc deleted file mode 100644 index f99cb27c..00000000 --- a/src/insns/modesw_16bit.adoc +++ /dev/null @@ -1,32 +0,0 @@ -<<< -//[#insns-modeswitch-16bit,reftext="Mode switching (C.MODESW), 16-bit encodings"] - -[#C_MODESW,reftext="C.MODESW"] -==== C.MODESW - -ifdef::cheri_v9_annotations[] -NOTE: *CHERI v9 Note:* This instruction is *new*. -endif::[] - -Synopsis:: -{cheri_cap_mode_name}/{cheri_int_mode_name} switching (C.MODESW), 16-bit encoding - -Mnemonic:: -`c.modesw` - -Expansion:: -`modesw` - -Encoding:: -include::wavedrom/modesw_16bit.adoc[] - -include::modesw_common.adoc[] - -Exceptions:: -include::require_cre.adoc[] - -Prerequisites:: -{c_cheri_default_ext_names} - -Operation (after expansion to 32-bit encodings):: - See <> diff --git a/src/insns/modesw_32bit.adoc b/src/insns/modesw_32bit.adoc index 416b25b8..7b3f015f 100644 --- a/src/insns/modesw_32bit.adoc +++ b/src/insns/modesw_32bit.adoc @@ -1,20 +1,31 @@ <<< -[#MODESW,reftext="MODESW"] -==== MODESW +[#MODESW_INT,reftext="MODESW.INT"] +==== MODESW.INT +See <>. -include::new_encoding_note.adoc[] +[#MODESW_CAP,reftext="MODESW.CAP"] +==== MODESW.CAP Synopsis:: -{cheri_cap_mode_name}/{cheri_int_mode_name} switching (MODESW), 32-bit encoding +Switch execution mode to {cheri_cap_mode_name} (MODESW.CAP), or {cheri_int_mode_name} (MODESW.INT), 32-bit encodings Mnemonic:: -`modesw` +`modesw.cap` + +`modesw.int` Encoding:: include::wavedrom/modesw_32bit.adoc[] -include::modesw_common.adoc[] +Description:: +Set the hart's current CHERI execution mode in <>. ++ +* MODESW.CAP: If the current mode in <> is {cheri_int_mode_name} ({INT_MODE_VALUE}), then the <> in <> is set to {cheri_cap_mode_name} ({CAP_MODE_VALUE}). Otherwise no effect. +* MODESW.INT: If the current mode in <> is {cheri_cap_mode_name} ({CAP_MODE_VALUE}), then the <> in <> is set to {cheri_int_mode_name} ({INT_MODE_VALUE}). Otherwise no effect. + +NOTE: Executing <> or <> from the program buffer in debug mode updates the <> of <>. + The <> of <> sets the CHERI execution mode for the execution of the next instruction from the program buffer, and is used to control which CHERI execution mode to enter next time debug mode is entered. + The CHERI execution mode is *only* controlled by the <> of <> in debug mode. Exceptions:: include::require_cre.adoc[] diff --git a/src/insns/modesw_common.adoc b/src/insns/modesw_common.adoc deleted file mode 100644 index 1844efcf..00000000 --- a/src/insns/modesw_common.adoc +++ /dev/null @@ -1,17 +0,0 @@ - -Description:: -Toggle the hart's current CHERI execution mode in <>. -+ -* If the current mode in <> is {cheri_int_mode_name} ({INT_MODE_VALUE}), then the <> in <> is set to {cheri_cap_mode_name} ({CAP_MODE_VALUE}). -* If the current mode is {cheri_cap_mode_name} ({CAP_MODE_VALUE}), then the <> in <> is set to {cheri_int_mode_name} ({INT_MODE_VALUE}). - -NOTE: The effective CHERI execution mode is give by the value of some CSRs and -the <>'s <>, so executing <> does not necessarily change -the machine's current mode. The current, effective CHERI execution mode can be -observed as described in xref:m_bit_observe[xrefstyle=short]. - -NOTE: Implementations may optionally support executing <> from the -program buffer while in debug mode. If supported them the <> in -<> is toggled and used to control which mode to enter next time debug -mode is entered. The CHERI execution mode is only controlled by the <> -of <> in debug mode. diff --git a/src/insns/scbnds_32bit.adoc b/src/insns/scbnds_32bit.adoc index fd8074c3..5b6455b9 100644 --- a/src/insns/scbnds_32bit.adoc +++ b/src/insns/scbnds_32bit.adoc @@ -42,6 +42,8 @@ tag is 0 or `cs1` is sealed. + `immediate = ZeroExtend(s ? uimm<<4 : uimm)` +NOTE: The <> encoding with `s=1` and `uimm ≤ 1` is RESERVED since these immediates can also be encoded with `s=0`. + include::malformed_clear_tag.adoc[] Exceptions:: diff --git a/src/insns/store_32bit_cap.adoc b/src/insns/store_32bit_cap.adoc index a41aeb3a..4b7a4267 100644 --- a/src/insns/store_32bit_cap.adoc +++ b/src/insns/store_32bit_cap.adoc @@ -20,18 +20,16 @@ include::wavedrom/storecap.adoc[] {cheri_cap_mode_name} Description:: Store the CLEN+1 bit value in `cs2` to memory. The capability in `cs1` authorizes the operation. The effective address of the memory access is -obtained by adding the address of `cs1` to the sign-extended 12-bit offset. The -capability written to memory has the tag set to 0 if the tag of `cs2` is 0 or -`cs1` does not grant <>. +obtained by adding the address of `cs1` to the sign-extended 12-bit offset. + include::load_store_c0.adoc[] {cheri_int_mode_name} Description:: Store the CLEN+1 bit value in `cs2` to memory. The capability authorising the operation is <>. The effective address of the memory -access is obtained by adding `rs1` to the sign-extended 12-bit offset. The -capability written to memory has the tag set to 0 if `cs2` 's tag is 0 or -<> does not grant <>. +access is obtained by adding `rs1` to the sign-extended 12-bit offset. + +include::store_tag_perms.adoc[] include::malformed_no_check.adoc[] diff --git a/src/insns/store_tag_perms.adoc b/src/insns/store_tag_perms.adoc new file mode 100644 index 00000000..acd0683c --- /dev/null +++ b/src/insns/store_tag_perms.adoc @@ -0,0 +1,5 @@ +Tag of the written capability value:: + +The capability written to memory has the tag set to 0 if the tag of `cs2` is 0 or if the authorizing capability (<> or `cs1`) does not grant <>. ++ +The stored tag is also set to zero if the authorizing capability does not have <> set but the stored data has a <> of 0. diff --git a/src/insns/wavedrom/c-clc-clcsp.adoc b/src/insns/wavedrom/c-clc-clcsp.adoc index aac8d437..dc1149ab 100644 --- a/src/insns/wavedrom/c-clc-clcsp.adoc +++ b/src/insns/wavedrom/c-clc-clcsp.adoc @@ -16,7 +16,7 @@ .... {reg: [ {bits: 2, name: 'op', type: 8, attr: ['2','C2=10']}, - {bits: 5, name: 'fs2', type: 4, attr: ['5','src',]}, + {bits: 5, name: 'rs2', type: 4, attr: ['5','src',]}, {bits: 6, name: 'imm', type: 3, attr: ['6','offset[5:3|8:6]']}, {bits: 3, name: 'funct3', type: 8, attr: ['3','cap rv64: C.LCSP=001']}, ], config: {bits: 16}} diff --git a/src/insns/wavedrom/c-jal-format-ls.adoc b/src/insns/wavedrom/c-jal-format-ls.adoc index 671b7c3a..4defe592 100644 --- a/src/insns/wavedrom/c-jal-format-ls.adoc +++ b/src/insns/wavedrom/c-jal-format-ls.adoc @@ -3,6 +3,6 @@ {reg: [ {bits: 2, name: 'op', type: 8, attr: ['2','C1=01']}, {bits: 11, name: 'imm', type: 2, attr: ['11','offset[11|4|9:8|10|6|7|3:1|5]']}, - {bits: 3, name: 'funct3', type: 8, attr: ['3','leg: C.JAL=001']}, + {bits: 3, name: 'funct3', type: 8, attr: ['3','int: C.JAL=001']}, ], config: {bits: 16}} .... diff --git a/src/insns/wavedrom/c-sp-load-css-dp-sprel.adoc b/src/insns/wavedrom/c-sp-load-css-dp-sprel.adoc index 278529f4..5726f5e6 100644 --- a/src/insns/wavedrom/c-sp-load-css-dp-sprel.adoc +++ b/src/insns/wavedrom/c-sp-load-css-dp-sprel.adoc @@ -3,8 +3,8 @@ .... {reg: [ {bits: 2, name: 'op', type: 8, attr: ['2','C2=10']}, - {bits: 5, name: 'fs2', type: 4, attr: ['5','src']}, + {bits: 5, name: 'rs2', type: 4, attr: ['5','src']}, {bits: 6, name: 'imm', type: 3, attr: ['6','offset[5:3|8:6]']}, - {bits: 3, name: 'funct3', type: 8, attr: ['3', 'leg: C.FLDSP=001', 'cap rv32: C.FLDSP=001']}, + {bits: 3, name: 'funct3', type: 8, attr: ['3', 'int: C.FLDSP=001', 'cap rv32: C.FLDSP=001']}, ], config: {bits: 16}} .... diff --git a/src/insns/wavedrom/c-sp-load-css-dp.adoc b/src/insns/wavedrom/c-sp-load-css-dp.adoc index ce4e2a14..e3e33f5d 100644 --- a/src/insns/wavedrom/c-sp-load-css-dp.adoc +++ b/src/insns/wavedrom/c-sp-load-css-dp.adoc @@ -3,10 +3,10 @@ .... {reg: [ {bits: 2, name: 'op', attr: ['2', 'C0=00'], type: 8}, - {bits: 3, name: 'frd`', attr: ['3', 'dest'], type: 3}, + {bits: 3, name: 'rd`', attr: ['3', 'dest'], type: 3}, {bits: 2, name: 'imm', attr: ['2', 'offset[7:6]'], type: 2}, {bits: 3, name: 'rs1`/cs1`', attr: ['3', 'base'], type: 2}, {bits: 3, name: 'imm', attr: ['3', 'offset[5:3]'], type: 3}, - {bits: 3, name: 'funct3', attr: ['3', 'leg C.FLD=001', 'cap rv32: C.FLD=001'], type: 8}, + {bits: 3, name: 'funct3', attr: ['3', 'int C.FLD=001', 'cap rv32: C.FLD=001'], type: 8}, ], config: {bits: 16}} .... diff --git a/src/insns/wavedrom/c-sp-load-css-fp-sprel.adoc b/src/insns/wavedrom/c-sp-load-css-fp-sprel.adoc index 4e7f0683..1654b2f6 100644 --- a/src/insns/wavedrom/c-sp-load-css-fp-sprel.adoc +++ b/src/insns/wavedrom/c-sp-load-css-fp-sprel.adoc @@ -4,8 +4,8 @@ {reg: [ {bits: 2, name: 'op', type: 8, attr: ['2','C2=10']}, {bits: 5, name: 'uimm', type: 3, attr: ['5','offset[4:2|7:6]']}, - {bits: 5, name: 'frd', type: 4, attr: ['5','src']}, + {bits: 5, name: 'rd', type: 4, attr: ['5','src']}, {bits: 1, name: 'uimm[5]',type: 3, attr: ['1','offset[5]']}, - {bits: 3, name: 'funct3', type: 8, attr: ['3', 'leg rv32: C.FLWSP=011']}, + {bits: 3, name: 'funct3', type: 8, attr: ['3', 'int rv32: C.FLWSP=011']}, ], config: {bits: 16}} .... diff --git a/src/insns/wavedrom/c-sp-load-css-fp.adoc b/src/insns/wavedrom/c-sp-load-css-fp.adoc index f93dd077..9ad0723e 100644 --- a/src/insns/wavedrom/c-sp-load-css-fp.adoc +++ b/src/insns/wavedrom/c-sp-load-css-fp.adoc @@ -7,6 +7,6 @@ {bits: 2, name: 'imm', type: 2, attr: ['2', 'offset[2|6]']}, {bits: 3, name: 'rs1\'', type: 3, attr: ['3', 'base']}, {bits: 3, name: 'imm', types:3, attr: ['3', 'offset[5:3]']}, - {bits: 3, name: 'funct3', type: 8, attr: ['3', 'leg rv32: C.FLW=011']}, + {bits: 3, name: 'funct3', type: 8, attr: ['3', 'int rv32: C.FLW=011']}, ], config: {bits: 16}} .... diff --git a/src/insns/wavedrom/c-sp-load-store-fp.adoc b/src/insns/wavedrom/c-sp-load-store-fp.adoc index 9e3a2849..d52c2012 100644 --- a/src/insns/wavedrom/c-sp-load-store-fp.adoc +++ b/src/insns/wavedrom/c-sp-load-store-fp.adoc @@ -8,6 +8,6 @@ {bits: 5, name: 'imm', type: 5, attr: ['5', 'offset[4:2|7:6]']}, {bits: 5, name: 'rd', type: 5, attr: ['5','dest']}, {bits: 1, name: 'imm', type: 1, attr: ['1','[5]']}, - {bits: 3, name: 'funct3', type: 3, attr: ['3', 'leg rv32: C.FLWSP=011']}, + {bits: 3, name: 'funct3', type: 3, attr: ['3', 'int rv32: C.FLWSP=011']}, ], config: {bits: 16}} .... diff --git a/src/insns/wavedrom/c-sp-store-css-fp-dp-sprel.adoc b/src/insns/wavedrom/c-sp-store-css-fp-dp-sprel.adoc index 93eb390e..97cd8a50 100644 --- a/src/insns/wavedrom/c-sp-store-css-fp-dp-sprel.adoc +++ b/src/insns/wavedrom/c-sp-store-css-fp-dp-sprel.adoc @@ -4,8 +4,8 @@ .... {reg: [ {bits: 2, name: 'op', type: 8, attr: ['2','C2=10']}, - {bits: 5, name: 'fs2', type: 4, attr: ['5','src']}, + {bits: 5, name: 'rs2', type: 4, attr: ['5','src']}, {bits: 6, name: 'imm', type: 3, attr: ['6','offset[5:3|8:6]']}, - {bits: 3, name: 'funct3', type: 8, attr: ['3', 'leg C.FSDSP=101', 'cap rv32: C.FSDSP=101']}, + {bits: 3, name: 'funct3', type: 8, attr: ['3', 'int C.FSDSP=101', 'cap rv32: C.FSDSP=101']}, ], config: {bits: 16}} .... diff --git a/src/insns/wavedrom/c-sp-store-css-fp-dp.adoc b/src/insns/wavedrom/c-sp-store-css-fp-dp.adoc index 349b0dcc..a85c1f15 100644 --- a/src/insns/wavedrom/c-sp-store-css-fp-dp.adoc +++ b/src/insns/wavedrom/c-sp-store-css-fp-dp.adoc @@ -4,8 +4,8 @@ .... {reg: [ {bits: 2, name: 'op', type: 8, attr: ['2','C0=00']}, - {bits: 5, name: 'fs2', type: 4, attr: ['5','src']}, + {bits: 5, name: 'rs2', type: 4, attr: ['5','src']}, {bits: 6, name: 'imm', type: 3, attr: ['6','offset[5:3|8:6]']}, - {bits: 3, name: 'funct3', type: 8, attr: ['3', 'leg C.FSD=101', 'cap rv32: C.FSD=101']}, + {bits: 3, name: 'funct3', type: 8, attr: ['3', 'int C.FSD=101', 'cap rv32: C.FSD=101']}, ], config: {bits: 16}} .... diff --git a/src/insns/wavedrom/c-sp-store-css-fp-sprel.adoc b/src/insns/wavedrom/c-sp-store-css-fp-sprel.adoc index e5a5adb5..2dafccc4 100644 --- a/src/insns/wavedrom/c-sp-store-css-fp-sprel.adoc +++ b/src/insns/wavedrom/c-sp-store-css-fp-sprel.adoc @@ -4,8 +4,8 @@ .... {reg: [ {bits: 2, name: 'op', type: 8, attr: ['2','C2=10']}, - {bits: 5, name: 'fs2', type: 4, attr: ['5','src']}, + {bits: 5, name: 'rs2', type: 4, attr: ['5','src']}, {bits: 6, name: 'imm', type: 3, attr: ['6','offset[5:2|7:6]']}, - {bits: 3, name: 'funct3', type: 8, attr: ['3', 'leg rv32: C.FSWSP=111']}, + {bits: 3, name: 'funct3', type: 8, attr: ['3', 'int rv32: C.FSWSP=111']}, ], config: {bits: 16}} .... diff --git a/src/insns/wavedrom/c-sp-store-css-fp.adoc b/src/insns/wavedrom/c-sp-store-css-fp.adoc index b3c3962e..bb91e151 100644 --- a/src/insns/wavedrom/c-sp-store-css-fp.adoc +++ b/src/insns/wavedrom/c-sp-store-css-fp.adoc @@ -7,6 +7,6 @@ {bits: 2, name: 'uimm', type: 2, attr: ['2', 'offset[2|6]']}, {bits: 3, name: 'rs1\'', type: 3, attr: ['3', 'base']}, {bits: 3, name: 'uimm', types:3, attr: ['3', 'offset[5:3]']}, - {bits: 3, name: 'funct3', type: 8, attr: ['3', 'leg rv32: C.FSW=111']}, + {bits: 3, name: 'funct3', type: 8, attr: ['3', 'int rv32: C.FSW=111']}, ], config: {bits: 16}} .... diff --git a/src/insns/wavedrom/fpload.adoc b/src/insns/wavedrom/fpload.adoc index 1b0dcff4..8237a98c 100644 --- a/src/insns/wavedrom/fpload.adoc +++ b/src/insns/wavedrom/fpload.adoc @@ -3,7 +3,7 @@ .... {reg: [ {bits: 7, name: 'opcode', attr: ['7','LOAD-FP=0000111'], type: 8}, - {bits: 5, name: 'frd', attr: ['5','dest'], type: 2}, + {bits: 5, name: 'rd', attr: ['5','dest'], type: 2}, {bits: 3, name: 'width', attr: ['3','FLD=011','FLW=010', 'FLH=001'], type: 8}, {bits: 5, name: 'rs1/cs1!=0',attr: ['5','base'], type: 4}, {bits: 12, name: 'imm[11:0]', attr: ['12','offset[11:0]'], type: 3}, diff --git a/src/insns/wavedrom/fpstore.adoc b/src/insns/wavedrom/fpstore.adoc index 66895f4c..c76fe885 100644 --- a/src/insns/wavedrom/fpstore.adoc +++ b/src/insns/wavedrom/fpstore.adoc @@ -6,7 +6,7 @@ {bits: 5, name: 'imm[4:0]', attr: ['5','offset[4:0]'], type: 3}, {bits: 3, name: 'width', attr: ['3','FSD=011','FSW=010', 'FSH=001'], type: 8}, {bits: 5, name: 'rs1/cs1!=0',attr: ['5','base'], type: 4}, - {bits: 5, name: 'fs2', attr: ['5','src'], type: 4}, + {bits: 5, name: 'rs2', attr: ['5','src'], type: 4}, {bits: 7, name: 'imm[11:5]', attr: ['7','offset[11:5]'], type: 3}, ]} .... diff --git a/src/insns/wavedrom/loadcap.adoc b/src/insns/wavedrom/loadcap.adoc index 3c145935..32a5c33b 100644 --- a/src/insns/wavedrom/loadcap.adoc +++ b/src/insns/wavedrom/loadcap.adoc @@ -3,7 +3,7 @@ [wavedrom, ,svg] .... {reg: [ - {bits: 7, name: 'opcode', attr: ['7', 'MISCMEM=0001111','LOAD=0000011',], type: 8}, + {bits: 7, name: 'opcode', attr: ['7', 'MISCMEM=0001111'], type: 8}, {bits: 5, name: 'cd', attr: ['5', 'dest'], type: 2}, {bits: 3, name: 'funct3', attr: ['3', 'LC=100'], type: 8}, {bits: 5, name: 'rs1/cs1!=0',attr: ['5', 'base'], type: 4}, diff --git a/src/insns/wavedrom/modesw_16bit.adoc b/src/insns/wavedrom/modesw_16bit.adoc deleted file mode 100644 index 842e7e31..00000000 --- a/src/insns/wavedrom/modesw_16bit.adoc +++ /dev/null @@ -1,13 +0,0 @@ -//ct-unconditional-2 - -[wavedrom, ,svg] -.... -{reg:[ - { bits: 2, name: 0x1, attr: ['2', 'C1=1'] }, - { bits: 3, name: 0x7, attr: ['3', 'C.MODESW'] }, - { bits: 2, name: 0x3, attr: ['2', 'FUNCT2'] }, - { bits: 3, name: 0x0, attr: ['3', 'FUNCT3'] }, - { bits: 3, name: 0x7, attr: ['3', 'FUNCT3'] }, - { bits: 3, name: 0x4, attr: ['3', 'FUNCT3'] }, -],config:{bits:16}} -.... diff --git a/src/insns/wavedrom/modesw_32bit.adoc b/src/insns/wavedrom/modesw_32bit.adoc index fb091a06..41ca8cde 100644 --- a/src/insns/wavedrom/modesw_32bit.adoc +++ b/src/insns/wavedrom/modesw_32bit.adoc @@ -7,6 +7,6 @@ {bits: 3, name: 'funct3', attr: ['3', 'MSW=001'], type: 8}, {bits: 5, name: 'funct5', attr: ['5', 'MSW=00000'], type: 4}, {bits: 5, name: 'funct5', attr: ['5', 'MSW=00000'], type: 3}, - {bits: 7, name: 'funct7', attr: ['7', 'MSW=0001001'], type: 3}, + {bits: 7, name: 'funct7', attr: ['7', 'MSW.CAP=0001001', 'MSW.INT=0001010'], type: 3}, ]} .... diff --git a/src/insns/wavedrom/scbnds_32bit.adoc b/src/insns/wavedrom/scbnds_32bit.adoc index bd774a86..b9e8e7f4 100644 --- a/src/insns/wavedrom/scbnds_32bit.adoc +++ b/src/insns/wavedrom/scbnds_32bit.adoc @@ -18,7 +18,7 @@ {bits: 5, name: 'cd', attr: ['5', 'dest'], type: 2}, {bits: 3, name: 'funct3', attr: ['3', 'SCBNDSI=101'], type: 8}, {bits: 5, name: 'cs1', attr: ['5', 'src'], type: 4}, - {bits: 5, name: 'uimm', attr: ['5', 'uimm'], type: 3}, + {bits: 5, name: 'uimm', attr: ['5', 'uimm', '(> 1 if s=1)'], type: 3}, {bits: 1, name: 's', attr: ['1', 'scaled'], type: 3}, {bits: 6, name: 'funct6', attr: ['6', 'SCBNDSI','=000001'], type: 3}, ]} diff --git a/src/insns/zcmt_cmjalt.adoc b/src/insns/zcmt_cmjalt.adoc index 39d2f469..40bd00db 100644 --- a/src/insns/zcmt_cmjalt.adoc +++ b/src/insns/zcmt_cmjalt.adoc @@ -25,7 +25,7 @@ Encoding:: [NOTE] - For this encoding to decode as <<>, _index>=32_, otherwise it decodes as <>. + For this encoding to decode as <>, _index≥32_, otherwise it decodes as <>. {cheri_cap_mode_name} Description:: 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 <> bounds (not against <>) and requiring <>. Link to `cra`. diff --git a/src/instructions.adoc b/src/instructions.adoc index ecfb350f..0814ecfd 100644 --- a/src/instructions.adoc +++ b/src/instructions.adoc @@ -212,8 +212,6 @@ include::insns/addi16sp_16bit.adoc[] include::insns/addi4spn_16bit.adoc[] -include::insns/modesw_16bit.adoc[] - include::insns/jalr_16bit.adoc[] include::insns/jr_16bit.adoc[] diff --git a/src/introduction.adoc b/src/introduction.adoc index 9c13a044..53192c3b 100644 --- a/src/introduction.adoc +++ b/src/introduction.adoc @@ -91,6 +91,8 @@ RISC-V. {lr_sc_bh_ext_name}:: Addition of <>, <>, <>, <> for more accurate atomic locking as the memory ranges are restricted by using bounds, therefore precise locking is needed. {cheri_pte_ext_name}:: CHERI extension for RISC-V harts supporting page-based virtual-memory. +{cheri_levels_ext_name}:: 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. {tid_ext_name}:: Extension for supporting thread identifiers. This extension improves software compartmentalization on CHERI systems. @@ -107,6 +109,7 @@ CAUTION: The extension names are provisional and subject to change. |{lr_sc_bh_ext_name} | Stable | This extension is a candidate for freezing |{cheri_pte_ext_name} | Prototype | This extension is a prototype, software is being developed to use it to increase the maturity level |{tid_ext_name} | Prototype | This extension is a prototype, software is being developed to use it to increase the maturity level +|{cheri_levels_ext_name} | Prototype | This extension is a prototype, software is being developed to use it to increase the maturity level |============================================================================== {cheri_base_ext_name} is defined as the base extension which all CHERI RISC-V diff --git a/src/level-ext.adoc b/src/level-ext.adoc new file mode 100644 index 00000000..365dfed3 --- /dev/null +++ b/src/level-ext.adoc @@ -0,0 +1,156 @@ +[#section_ext_cheri_levels] +== "{cheri_levels_ext_name}" Extension for Capability Levels + +{cheri_levels_ext_name} is an extension to {cheri_base_ext_name} that adds support for associating a level with capabilities and limiting the flow of capabilities to specific memory region subsets. +This extension allows assigning a level to capabilities, which in conjunction with two new permissions allows enforcing invariants on capability propagation. +For example, this 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. + +NOTE: This specification only defines the architectural mechanics of this feature, for further information on how this can be used by software please refer to cite:[cheri-v9-spec]. + +The number of supported capability levels is implementation-defined, but this specification currently only requires supporting two levels (_local_ and _global_). + + +=== Capability format changes +{cheri_levels_ext_name} adds a new `LVLBITS`-bit field to the <>, the _<>_. +It also adds two new permission fields, <> and <>. + +- For `MXLEN=64` <>, the AP field is widened by `LVLBITS+1` bits (i.e. 2 bits for `LVLBITS=1`) + +NOTE: The <> diagram shows the layout for `LVLBITS=1` + +- For `MXLEN=32` the capability's <> field is able to encode these permissions without increasing in size (provided that LVLBITS≤2). + +NOTE: {cheri_levels_ext_name} requires that LVLBITS≥1 although LVLBITS>1 is considered an experimental enhancement of this extension. +See <> for the mechanics when LVLBITS>1. + +[#section_cap_level,reftext="capability level"] +==== Capability Level (CL) + +The Capability Level (CL) is a new field added to the capability encoding, as shown in xref:section_cap_encoding[xrefstyle=short]. + +With `LVLBITS=1`, 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 <> set. +Furthermore, the <> can be used to restrict loading of _global_ capabilities -- causing the hardware to automatically set the level of loaded capabilities to _local_ instead. + +NOTE: The current specification only defines two levels, equivalent to _local_ and _global_ capabilities from CHERI v9, Morello and CHERIoT. + +As with permissions, the capability level can only be decreased but never increased (without deriving from a capability with a higher level). +Therefore, the capability level is adjusted using the <> instruction (see <>) and are queried using <>. + +==== New capability permissions +{cheri_levels_ext_name} introduces two new capability permissions: +[#sl_perm,reftext="SL-permission"] +Store Level Permission (SL):: This is a `LVLBITS` wide field that allows limiting the propagation of capabilities using the following logic: capabilities with a <> less than the inverse of the authorizing capability's <> will be stored with the tag cleared. +With `LVLBITS=1` there is a single bit comparison, so it behaves as follows: +- If this field (as well as <> and <>) is set to 1 then capabilities may be stored via this capability regardless of their associated <>. +- If this field is zero, then any capability with a <> of zero (i.e. _local_), will be stored with the tag cleared. + +NOTE: For `LVLBITS=1` this permission is equivalent to _StoreLocal_ in CHERI v9, Morello and CHERIoT. + +[#el_perm,reftext="EL-permission"] +Elevate Level Permission (EL):: Any capability with its tag set to 1 that is loaded from memory has its <> cleared and its <> restricted to the authorizing capability's <> if the authorizing capability does not grant <>. +This permission is similar to the existing <>, but instead of applying to the <> on the loaded capability it restricts the <> field. + + + +ifdef::cheri_v9_annotations[] +NOTE: *CHERI v9 Note:* This permission does not exist in CHERI v9, but is similar to CHERIoT's _LoadGlobal_ permission, except that any _global_ capability implicitly grants _LoadGlobal_. +endif::[] + +.Encoding of architectural permissions for MXLEN=32 when {cheri_levels_ext_name} is implemented +[#cap_perms_encoding_levels32,width="100%",options=header,cols="^2,^1,^1,^1,^1,^1,^1,^1,^1,^2,4",align="center"] +|============================================================================== +|Bits[4:3]| R | W | C | LM | EL | SL | X | ASR | Mode^1^ | Notes +11+| *Quadrant 0: Non-capability data read/write* +11+| bit[2] - write, bit[1] - reserved (0), bit[0] - read +11+| _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 10+| reserved +| 4 | | ✔ | | | | | | | N/A | Data WO +| 5 | ✔ | ✔ | | | | | | | N/A | Data RW +| 6-7 10+| reserved +11+| *Quadrant 1: Executable capabilities* +11+| bit[0] - <> ({CAP_MODE_VALUE}-{cheri_cap_mode_name}, {INT_MODE_VALUE}-{cheri_int_mode_name}) +|Bits[4:3]| R | W | C | LM | EL | SL | X | ASR | Mode^1^ | +| 0-1 | ✔ | ✔ | ✔ | ✔ | ✔ | ∞ | ✔ | ✔ | Mode^1^ | Execute + ASR (see <>) +| 2-3 | ✔ | | ✔ | ✔ | ✔ | ∞ | | | Mode^1^ | Execute + Data & Cap RO +| 4-5 | ✔ | ✔ | ✔ | ✔ | ✔ | ∞ | ✔ | | Mode^1^ | Execute + Data & Cap RW +| 6-7 | ✔ | ✔ | | | | N/A | | | Mode^1^ | Execute + Data RW +11+| *Quadrant 2: Restricted capability data read/write* +11+| 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 | Mode^1^ | +| 0-2 10+| reserved +| 3 | ✔ | | ✔ | | | N/A | | | N/A | Data & Cap R0 (without <>) +| 4 | ✔ | ✔ | ✔ | ✔ | | _(3)_ | | | N/A | Reserved for `LVLBITS=2` +| 5 | ✔ | ✔ | ✔ | ✔ | | _(2)_ | | | N/A | Reserved for `LVLBITS=2` +| 6 | ✔ | ✔ | ✔ | ✔ | | 1 | | | N/A | Data & Cap RW (with store _local_, no <>) +| 7 | ✔ | ✔ | ✔ | ✔ | | 0 | | | N/A | Data & Cap RW (no store _local_, no <>) +11+| *Quadrant 3: Capability data read/write* +11+| bit[2] = write, bit[1:0] = store level. R and C implicitly granted. +11+| _Reserved bits for future extensions must be 1 so they are implicitly granted_ +|Bits[4:3]| R | W | C | LM | EL | SL | X | ASR | Mode^1^ | +| 0-2 10+| reserved +| 3 | ✔ | | ✔ | ✔ | ✔ | N/A | | | N/A | Data & Cap R0 +| 4 | ✔ | ✔ | ✔ | ✔ | ✔ | _(3)_ | | | N/A | Reserved for `LVLBITS=2` +| 5 | ✔ | ✔ | ✔ | ✔ | ✔ | _(2)_ | | | N/A | Reserved for `LVLBITS=2` +| 6 | ✔ | ✔ | ✔ | ✔ | ✔ | 1 | | | N/A | Data & Cap RW (with store _local_) +| 7 | ✔ | ✔ | ✔ | ✔ | ✔ | 0 | | | N/A | Data & Cap RW (no store _local_) +|============================================================================== + +[#section_cap_level_change] +=== Changing capability levels and permissions +While capability levels (<>) are conceptually a label on the capability rather than a permission granted by the capability, they are adjusted using the <> instruction. +This avoids the need for a dedicated instruction and allows reducing the level and removing <> in a single instruction. + +<<< + +[#section_cap_level_summary] +=== Capability level summary table + +.{cheri_levels_ext_name} `LVLBITS=1` summary table for stored capabilities +[#cap_level_store_summary,width="100%",options=header,halign=center,cols="1,1,1,1,5"] +|============================================================================== + 3+|Auth cap field | Data cap field | + h|*W* h|*C* h|*SL* h|*CL* h| Notes +.3+.^|1 .3+.^| 1 | 1 | X | Store data capability unmodified + .2+.^| 0 | 1 | Store data capability unmodified (CL ≥ ~SL) + | 0 | Store data capability with tag cleared (CL < ~SL) +|============================================================================== + +NOTE: if W=0 or C=0 then SL is irrelevant + +.{cheri_levels_ext_name} `LVLBITS=1` summary table for loaded capabilities +[#cap_level_load_summary,width="100%",options=header,align=center,cols="1,1,1,1,1,6"] +|============================================================================== + 4+|Auth cap field | Data cap field | + h|*R* h|*C* h|*EL* h|*CL* h| Tag h|Action +.4+.^|1 .4+.^| 1 | 1 | X | X |Load data capability unmodified + .3+.^| 0 | 1 | X |Load data capability unmodified + .2+.^| 0 | 1 |Load data capability with CL=0,EL=0 + | 0 |Load data capability unmodified +|============================================================================== + +NOTE: if R=0 or C=0 then EL and CL are irrelevant + +[#section_ext_cheri_multiple_levels] +=== Extending {cheri_levels_ext_name} to more than two levels +When `LVLBITS>1`, the behaviour of <> can no longer use masking to adjust the <> or <>, but instead must perform an integer minimum operation on those `LVLBITS`-wide fields. +The <> field of the resulting capability is set to `min(rs2[CL], cs1[CL])` (equivalent to `rs2[CL] & cs1[CL]` for `LVLBITS=1`). +Similarly, <> is set to `min(rs2[SL], cs1[SL])` (equivalent to `rs2[SL] & cs1[SL]` for `LVLBITS=1`). + +When storing capabilities, the <> checks need to perform a `LVLBITS`-wide integer comparison instead of just testing a single bit. +Considering for an example `LVLBITS=2`: + +[options=header,grid=rows,cols="2,3,6"] +|=== +|<> | 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 +|=== + +NOTE: While this extra negation is non-intuitive, it is required such that <> can use a monotonically decreasing operation for both <> <>. + +NOTE: The layout of the <> input / <> result is not yet defined, but existing bits will not be moved around so the <>/<> fields will be non-contiguous. diff --git a/src/riscv-cheri.adoc b/src/riscv-cheri.adoc index 34e0f32a..b6fe70f9 100644 --- a/src/riscv-cheri.adoc +++ b/src/riscv-cheri.adoc @@ -36,6 +36,8 @@ include::contributors.adoc[] // Document body /////////////////////////////////////////////////////////////////////////////// +include::summary.adoc[] + include::introduction.adoc[] include::cap-description.adoc[] @@ -48,6 +50,8 @@ include::trigger-integration.adoc[] include::cheri-pte-ext.adoc[] +include::level-ext.adoc[] + include::riscv-hybrid-integration.adoc[] include::hypervisor-integration.adoc[] @@ -60,6 +64,8 @@ include::tid-ext.adoc[] include::instructions.adoc[] +include::system.adoc[] + include::tables.adoc[] /////////////////////////////////////////////////////////////////////////////// diff --git a/src/riscv-cheri.bib b/src/riscv-cheri.bib index a3a44968..0a9939d9 100644 --- a/src/riscv-cheri.bib +++ b/src/riscv-cheri.bib @@ -30,10 +30,36 @@ @TechReport{cheri-v9-spec institution = {University of Cambridge, Computer Laboratory}, doi = {10.48456/tr-987}, issn = {1476-2986}, - issn = {1476-2986}, number = {UCAM-CL-TR-987} } +@misc{tagged-memory, + author = { + Alexandre Joannou, + Jonathan Woodruff, + Robert Kovacsics, + Simon W. Moore, + Alex Bradbury, + Hongyan Xia, + Robert N. M. Watson, + David Chisnall, + Michael Roe, + Brooks Davis, + Edward Napierala, + John Baldwin, + Khilan Gudka, + Peter G. Neumann, + Alfredo Mazzinghi, + Alex Richardson, + Stacey Son, + A. Theodore Markettos}, + + title = {Efficient Tagged Memory}, + year = 2017, + month = nov, + url = {https://www.cl.cam.ac.uk/research/security/ctsrd/pdfs/201711-iccd2017-efficient-tags.pdf}, +} + @misc{riscv-priv-spec, author = {RISC-V}, title = {RISC-V Privileged Specification}, @@ -73,3 +99,11 @@ @misc{riscv-v-spec note = {Version 1.0}, url = {https://github.com/riscv/riscv-v-spec/releases/download/v1.0/riscv-v-spec-1.0.pdf} } + +@misc{msrc-cheri-eval, + author = {Joly, Nicolas and ElSherei, Saif and Amar, Saar}, + title = {Security analysis of CHERI ISA}, + url={https://github.com/microsoft/MSRC-Security-Research/blob/master/papers/2020/Security%20analysis%20of%20CHERI%20ISA.pdf}, + year= {2020}, + month={10} +} diff --git a/src/riscv-hybrid-integration.adoc b/src/riscv-hybrid-integration.adoc index 7e4d8a54..73e8129c 100644 --- a/src/riscv-hybrid-integration.adoc +++ b/src/riscv-hybrid-integration.adoc @@ -151,11 +151,12 @@ unprivileged *x* register. ==== Mode Change Instructions -A new CHERI execution mode switch (<>) instruction allows software -to toggle the hart's current CHERI execution mode. If the current mode in the -<> is {cheri_int_mode_name}, then the mode after executing <> is {cheri_cap_mode_name} -and vice-versa. This instruction effectively writes the CHERI execution mode -bit M of the capability currently installed in the <>. +New CHERI execution mode switch instructions, <> and +<>, allow software +to change the hart's current <> in <>. If the current mode in the +<> is {cheri_int_mode_name}, then the mode after executing <> is {cheri_cap_mode_name} +and similarly for <> when in {cheri_cap_mode_name}. This instruction effectively writes the CHERI execution mode +<> of the capability currently installed in the <>. === Existing RISC-V Instructions @@ -277,18 +278,16 @@ All CSR instructions cause CHERI exceptions if the <> does not grant A new debug default data capability (<>) CSR is added at the CSR number shown in xref:default-csrnames-added[xrefstyle=short]. -{cheri_default_ext_name} optionally allows <> to execute in debug mode. +{cheri_default_ext_name} allows <> and <> to execute in debug mode. When entering debug mode, whether the core enters {cheri_int_mode_name} or {cheri_cap_mode_name} is controlled by the <> in <>. -Implementations may optionally support switching CHERI execution mode by -executing <> from the program buffer. The current mode can be read from <>. ifdef::cheri_v9_annotations[] -NOTE: *CHERI v9 Note:* The mode change instruction <> is new -and the requirement to optionally support it in debug mode is also new. +NOTE: *CHERI v9 Note:* The mode change instructions <> and <> are new +and the requirement to support them in debug mode is also new. endif::[] [#dddc,reftext="dddc"] @@ -358,10 +357,21 @@ checks. The last capability installed in <> and <> before disabling CHERI register access will be used to authorise instruction execution and data memory accesses. -NOTE: Disabling CHERI register access prevents low-privileged {cheri_int_mode_name} software +[NOTE] +==== +Disabling CHERI register access prevents low-privileged {cheri_int_mode_name} software from interfering with the correct operation of higher-privileged {cheri_int_mode_name} software that do not perform <> switches on trap entry and return. +Disable CHERI register access also allows harts supporting CHERI to be fully +compatible with standard RISC-V, so CHERI instructions, such as <>, that +do not change the state of CHERI CSRs raise exceptions when CRE=0. +==== + +NOTE: xref:cheri_behavior_cre_mode[xrefstyle=short] summarizes the behavior of +a hart in connection with the <> and the +<>. + === Added CLEN-wide CSRs {cheri_default_ext_name} adds the CLEN-wide CSRs shown in diff --git a/src/riscv-integration.adoc b/src/riscv-integration.adoc index b4dca872..2672b3ce 100644 --- a/src/riscv-integration.adoc +++ b/src/riscv-integration.adoc @@ -15,6 +15,14 @@ NOTE: The changes described in this specification also ensure that NOTE: RV128 is not currently supported by any CHERI extension. +NOTE: In line with the base RISC-V ISA, the unprivileged component +with its corresponding {cheri_base_ext_name} changes +as described in this chapter can be used with +an entirely different privileged-level design. The changes for the privileged +component described in this chapter are designed to support existing +popular operating systems, and assume the standard +privileged architecture specified in the RISC-V ISA. + === Memory A hart supporting {cheri_base_ext_name} has a single byte-addressable address @@ -778,10 +786,13 @@ xref:mtval2-format[xrefstyle=short] to assist software in handling the trap. If <> is read-only zero for CHERI exceptions then <> is also read-only zero for CHERI exceptions. -.Machine trap value register 2 +.Machine trap value register 2 format for CHERI faults [#mtval2-format] include::img/mtval2reg.edn[] +NOTE: <> 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 <> 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 xref:mtval2-cheri-type[xrefstyle=short] and @@ -1107,6 +1118,7 @@ CHERI adds architectural guarantees that can prove to be microarchitecturally us 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. +[#section_pma] === Physical Memory Attributes (PMA) Typically, the entire memory space need not support tagged data. Therefore, it diff --git a/src/summary.adoc b/src/summary.adoc new file mode 100644 index 00000000..5e44155f --- /dev/null +++ b/src/summary.adoc @@ -0,0 +1,84 @@ +== Quick Start + +This document describes the RISC-V extensions for supporting CHERI capabilities in hardware. +Capabilities can be used to provide memory safety, mitigating up to 70% of memory safety issues cite:[msrc-cheri-eval], as well as to provide efficient compartmentalisation. +The extensions are split into the core features required for a working capability system ({cheri_base_ext_name}), and features required to support a mix-and-match of binaries compiled for CHERI and unchanged binaries ({cheri_default_ext_name}). +Some other smaller extensions are described that provide additional functionality relevant to CHERI. + +=== Capability Properties + +Capabilities are 2*XLEN (which we call CLEN) bit structures, containing all the information required to identify and authorise access to a region of memory. +This includes: + + * An XLEN bit address, describing where the capability currently points. + + * Bounds: a _base_ and a _top_ address, describing the range of addresses the capability can be used to access. + + * Permissions (read, write, execute, read capability, ...) describing the kinds of accesses the capability can be used for. + + * Sealing information: a capability can be _sealed_, restricting it to only be used or modified in particular ways. + +A one-bit integrity tag is stored alongside a capability: this is maintained by hardware and cannot be directly modified by software. +It indicates whether the capability is valid. +An initial <> capability with access to all of memory with all permissions is provided in system registers on reset: all valid capabilities are derived from it. +This is the only way to obtain a valid capability: no software, even machine mode, can _forge_ a capability. + +=== Added State + +A CHERI core adds state to allow capabilities to be used from within registers, and to ensure they are not corrupted as they flow through the system. +This means the following state is added: + +* Metadata within architectural registers: XLEN-wide integer registers (e.g. `sp`, `a0`) are all extended with another XLEN bits of capability metadata, including bounds and permissions. + The resulting CLEN bits in full form a capability, and we refer to the same register prefixed with a `c`, i.e. `csp`, `ca0`. + The integer part of the register is interpreted as the address field of the capability. + The zero register is extended with zero metadata and a cleared tag: this is called the <> capability. + As well as general purpose registers, system registers that store addresses are extended to contain capabilities. + For example, <> is extended to a capability version <> (the machine trap vector capability) to allow the code bounds to be changed on an exception. + +* Tags in registers, caches, and memory: + +** Every register has a one-bit tag, indicating whether the capability in the register is valid to be dereferenced. + This tag is cleared if the register is written as an integer. + +** The tags are also tracked through the memory subsystem: every aligned CLEN-bits wide region has a non-addressable one-bit tag, which the hardware manages atomically with the data. + The tag is cleared if the memory region is ever written other than using a capability store from a tagged capability register. + Any caches must preserve this abstraction. + +=== Checking Memory + +Every memory access performed by a CHERI core must be authorised by a capability. +It is explicitly defined for every instruction where to find the capability to check against. +In _purecap_ code, where all pointers are individual capabilities, the capability and address are used together, so e.g. `lw t0, 16(csp)` loads a word from memory, getting the address and bounds from the `csp` register. +For code that has not yet been fully adapted to CHERI (_hybrid_ code), the processor can run in a pointer mode (not to be confused with a privilege mode) where the authorising capability is instead taken from a special CSR: the default data capability (<>). + +Instruction fetch is also authorised by a capability: the program counter capability (<>) which extends PC. +This allows code fetch to be bounded, preventing a wide range of attacks that subvert control flow with integer data. +Where {cheri_default_ext_name} is supported, the <> also contains the <> indicating whether the processor is running in integer or capability pointer mode. +Changing the bounds used for instruction fetch or the pointer mode can be as easy as performing a capability-based jump (<> in capability pointer mode). +<> and <> instructions are also added to allow cheap mode switching. + +Exception codes are added for CHERI-specific exceptions on fetch, jumps, and memory access. +No other exception paths are added: in particular, capability manipulations do not trap, but may clear the tag on the result capability if the operation is not permitted. + +=== Added Instructions + +The added instructions can be split into the following categories: + +* Capability manipulations (e.g. <>, <>): for security, capabilities can only be modified in restricted ways. + Special instructions are provided to perform these allowed operations, for example _shrinking_ the bounds or _reducing_ the permissions. + Any attempt to manipulate capabilities without using the instructions clears the tag, rendering them unusable for accessing memory. + +* Capability inspection (e.g. <>, <>): capability fields (for example the _bounds_ describing what addresses the capability gives access to) are stored compressed in registers and memory. + These instructions give convenient access to allow software to query them. + +* Memory access instructions (e.g. <>, <>): capabilities must be read from and written to memory atomically along with their tag. + Instructions are added to perform these wider accesses, allowing capability flow between the memory and the register file. + +=== Existing Instructions + +Existing RISC-V instructions are largely unmodified: in {cheri_int_mode_name}, there is binary compatibility. +Instructions that access memory, as well as branches and jumps, are automatically checked against <> and <>, raising an exception if the checks fail. +However, <> and <> are reset to <> capabilities, meaning the checks will always pass on systems that have not written to CHERI system registers. + +In {cheri_cap_mode_name}, these instructions are instead modified to check against the full capability from the address register (e.g. `lw t0, 16(csp)`). +In some cases, they are also changed to return a full capability value, e.g. <> will return the full <> including the metadata. diff --git a/src/system.adoc b/src/system.adoc new file mode 100644 index 00000000..e56d7019 --- /dev/null +++ b/src/system.adoc @@ -0,0 +1,81 @@ +[appendix] +== CHERI System Implications + +CHERI processors need memory systems which support the capability validity 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: + +. Tag-aware busses, where the bus protocol is extended to carry the tag along with the data. This is typically done using user defined bits in the protocol. +.. These busses will read tags from memory (if tags are present in the target memory) and return them to the requestor. +.. These busses will write the tag to memory as an extension of the data write. +. Non-tag aware busses, i.e. current non-CHERI aware busses. +.. Reads of tagged memory will not read the tag. +.. Writes to tagged memory will clear the 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 tag and data are always accessed atomically. For every naturally aligned CLEN-wide memory location, it must never be possible to: + +. Update any data bytes without also writing the tag +.. This implies clearing the tag if a non-CHERI aware bus master overwrites a capability in memory +. Read a tagged value with mismatched (stale or newer) data +. Set the tag without also writing the data. + +NOTE: Clearing tags in memory does not necessarily require updating the associated data. + +=== Small CHERI system example + +[#small_cheri_system] +.Example small CHERI system with local capability tag storage +image::small_cheri_system.drawio.png[width=80%,align=center] + +This example shows a minimum sized system where only the local memory is extended to support capability tags. +The 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. + +=== Large CHERI system example + +[#large_cheri_system] +.Example large CHERI system with tag cache +image::large_cheri_system.drawio.png[width=80%,align=center] + +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 129-bit words and so a typical system will have a tag cache IP. + +A region of DRAM is reserved for CHERI tag storage. + +The tag cache sits on the boundary of the 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 tag. + +The key property of the 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 tag cache, therefore no bus initiators should be able to write to the DRAM without the transactions passing through the tag cache. + +Therefore the GPUs and peripherals cannot write to the tag storage in the DRAM, or the 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 tagged memory data storage region of the DRAM, if required. + +NOTE: It would be possible to allow a DMA to access the 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 tags, and so the root-of-trust will need to authenticate and encrypt the transfer, with anti-rollback protection. + +For further information on the tag cache see cite:[tagged-memory]. + +<<< + +=== Large CHERI pure-capability system example + +[#large_cheri_purecap_system] +.Example large CHERI system with only tag-aware bus masters +image::large_cheri_purecap_system.drawio.png[width=80%,align=center] + +In this example every DRAM access passes through the tag cache, and so _all_ bus masters are tag-aware and can access the tagged memory if permitted by the network-on-chip. + +The system topology is simpler than in xref:large_cheri_system[xrefstyle=short]. + +There is likely to be a performance difference between the two systems. +The main motivation for xref:large_cheri_system[xrefstyle=short] is to avoid the GPU DRAM traffic needing to look-up every tag in the tag cache, potentially adding overhead to every transaction. diff --git a/src/tables.adoc b/src/tables.adoc index 4b2984d2..98715634 100644 --- a/src/tables.adoc +++ b/src/tables.adoc @@ -171,7 +171,7 @@ include::generated/legacy_mnemonic_insns_table_body.adoc[] include::generated/xlen_dependent_encoding_insns_table_body.adoc[] |============================================================================== -NOTE: <> and <> only exist in {cheri_cap_mode_name} if +NOTE: <>, <> and <> only exist in {cheri_cap_mode_name} if {cheri_int_mode_name} is _also_ present. A hart does not support the <> if it does not implement the {cheri_default_ext_name} extension. @@ -181,3 +181,75 @@ if it does not implement the {cheri_default_ext_name} extension. |============================================================================== include::generated/illegal_insns_table_body.adoc[] |============================================================================== + +<<< + +xref:cheri_behavior_cre_mode[xrefstyle=short] summarizes the behavior of a hart +supporting both {cheri_base_ext_name} and {cheri_default_ext_name} in +connection with the <> and the +<> while in a privilege +other than debug mode. + +.Hart's behavior depending on the effective <> and <> +[#cheri_behavior_cre_mode,width=100%,options=header,align=center,%autowidth,cols="8,8,15,12,12,15,15,15"] +|============================================================================== +// Header +| <> +| <>.<> +| Authorizing capability^1^ +| <>^2^ +| <>^3^ +| CHERI instructions^4^ +| <>^5^ +| Note + +// Body +| 0 +| X^6^ +| <> or <> +| ✘ +| XLEN +| ✘ +| No +| **_Fully RISC-V compatible_**^7^ + +| 1 +| 0 +| <> or <> +| CLEN +| XLEN +| ✔ +| No +| **{cheri_int_mode_name}** + +| 1 +| 1 +| Instruction's capability operand +| CLEN +| CLEN +| ✔ +| Yes +| **{cheri_cap_mode_name}** +|============================================================================== + +^1^ Authorizing capability for memory access instructions. + +^2^ Whether accesses to <> are permitted +or raise illegal instruction exceptions. If permitted, then the bit width of +the CSR read/write with <> is indicated. + +^3^ The bit width of accesses to <> +using <>. + +^4^ Whether CHERI instructions are permitted or raise illegal instruction +exceptions. + +^5^ See xref:legacy_mnemonics[xrefstyle=short] for a list of remapped +instructions. + +^6^ <>.<> is irrelevant when <>=0. + +^7^ The hart is fully compatible with standard RISC-V when +<>=0 provided that <>, <>, <>, +<>, <>, <>, <> and <> hold the +<> capability. diff --git a/src/tid-ext.adoc b/src/tid-ext.adoc index 9712e916..26ed39a6 100644 --- a/src/tid-ext.adoc +++ b/src/tid-ext.adoc @@ -7,7 +7,7 @@ software compartmentalization of CHERI programs. === Control and Status Registers (CSRs) -{tid_ext_name} adds two new CSRs to implement a trusted thread +{tid_ext_name} adds new CSRs to implement a trusted thread identifier (TID) used in compartmentalization. These CSRs are listed in xref:tid-mcsrnames-added[xrefstyle=short], xref:tid-scsrnames-added[xrefstyle=short],