From e90d73058869e251b8698c3c5bbd37e03a54603a Mon Sep 17 00:00:00 2001 From: MuhammadHammad001 Date: Wed, 23 Apr 2025 16:04:13 +0500 Subject: [PATCH 1/3] Add yaml for mseccfg --- arch/csr/mseccfg.yaml | 104 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 3 deletions(-) diff --git a/arch/csr/mseccfg.yaml b/arch/csr/mseccfg.yaml index bc76cd886..90f6dce7e 100644 --- a/arch/csr/mseccfg.yaml +++ b/arch/csr/mseccfg.yaml @@ -6,9 +6,107 @@ name: mseccfg long_name: Machine Security Configuration address: 0x747 priv_mode: M -length: 64 -description: Machine Security Configuration +length: MXLEN +description: Machine Security Configuration register is used for configuring various security mechanisms present on the hart and only accessible in Machine mode. definedBy: name: Sm version: ">= 1.12" -fields: {} +fields: + MML: + location: 0 + description: | + Machine Mode Lockdown (mseccfg.MML) enforces strong isolation between Machine Mode and lower-privilege modes. This is a _sticky bit_ + meaning that once set, it can only be reset on PMP Reset. + + When `mseccfg.MML` is 1 (set), it redefines: + + a). `pmpcfg.L` bit as: + + - When `pmpcfg.L` is set, PMP rules are *enforced* on M-Mode only and *denied* on S/U-modes. + + - When `pmpcfg.L` is unset, PMP rules are *enforced* on S/U-modes-only and *denied* on M-mode. + + Formerly Reserved Encodings `pmpcfg.RW=01` and the encoding `pmpcfg.LRWX=1111` as *Shared-Region*. + A _Shared region Rule_ is *enforced* on all modes, with restrictions depending on the `pmpcfg.L` and `pmpcfg.X` bits as: + + - A _Shared-Region rule_ where `pmpcfg.L` is not set can be used for sharing data between M-mode and + S/U-mode, so is not executable. M-mode has read/write access to that region, and S/U-mode has + read access if `pmpcfg.X` is not set, or read/write access if `pmpcfg.X` is set. + + - A Shared-Region rule where `pmpcfg.L` is set can be used for sharing code between M-mode and + S/U-mode, so is not writeable. Both M-mode and S/U-mode have execute access on the region, and + M-mode also has read access if `pmpcfg.X` is set. The rule remains locked so that any further + modifications to its associated configuration or address registers are ignored until a PMP reset, + unless `mseccfg.RLB` is set. + + - The encoding `pmpcfg.LRWX=1111` can be used for sharing data between M-mode and S/U mode, + where both modes only have read-only access to the region. The rule remains locked so that any + further modifications to its associated configuration or address registers are ignored until a PMP + reset, unless `mseccfg.RLB` is set. + + b). Adding a rule with executable privileges that either is M-mode-only or a locked Shared-Region is not + possible and such `pmpcfg` writes are ignored, leaving `pmpcfg` unchanged. This restriction can be + temporarily lifted e.g. during the boot process, by setting mseccfg.RLB. + + c). Executing code with Machine mode privileges is only possible from memory regions with a matching M- + mode-only rule or a locked Shared-Region rule with executable privileges. Executing code from a + region without a matching rule or with a matching S/U-mode-only rule is *denied*. + + d). If `mseccfg.MML` is not set, the combination of `pmpcfg.RW=01` remains reserved for future standard use. + + The truth table when the `mseccfg.MML` is set: + + [cols="4*^.^1,2*^.^3", separator="!", %autowidth, options="header"] + !==== + 4+^! Bits on _pmpcfg_ register 2+^! Result + ! L ! R ! W ! X ! M Mode ! S/U Mode + + ! 0 ! 0 ! 0 ! 0 2+^! Inaccessible region (Access Exception) + ! 0 ! 0 ! 0 ! 1 ! Access Exception ! Execute-only region + ! 0 ! 0 ! 1 ! 0 2+^! Shared data region: Read/write on M mode, Read-only on S/U mode + ! 0 ! 0 ! 1 ! 1 2+^! Shared data region: Read/write for both M and S/U mode + ! 0 ! 1 ! 0 ! 0 ! Access Exception ! Read-only region + ! 0 ! 1 ! 0 ! 1 ! Access Exception ! Read/Execute region + ! 0 ! 1 ! 1 ! 0 ! Access Exception ! Read/Write region + ! 0 ! 1 ! 1 ! 1 ! Access Exception ! Read/Write/Execute region + ! 1 ! 0 ! 0 ! 0 2+^! Locked inaccessible region* (Access Exception) + ! 1 ! 0 ! 0 ! 1 ! Locked Execute-only region* ! Access Exception + ! 1 ! 0 ! 1 ! 0 2+^! Locked Shared code region: Execute only on both M and S/U mode.* + ! 1 ! 0 ! 1 ! 1 2+^! Locked Shared code region: Execute only on S/U mode, read/execute on M mode.* + ! 1 ! 1 ! 0 ! 0 ! Locked Read-only region* ! Access Exception + ! 1 ! 1 ! 0 ! 1 ! Locked Read/Execute region* ! Access Exception + ! 1 ! 1 ! 1 ! 0 ! Locked Read/Write region* ! Access Exception + ! 1 ! 1 ! 1 ! 1 2+^! Locked Shared data region: Read only on both M and S/U mode.* + !==== + + *Locked rules cannot be removed or modified until a PMP reset, unless mseccfg.RLB is set. + + type: RW + definedBy: Smepmp + reset_value: UNDEFINED_LEGAL + MMWP: + location: 1 + description: | + Machine Mode Whitelist Policy (mseccfg.MMWP). This is a _sticky bit_ meaning that once set, it can only be reset on PMP Reset. + + When 1 (set), it changes the default PMP policy for M-mode when accessing memory regions that do not have a matching PMP rule, to + *denied* instead of *ignored*. + + When set to 0, `mseccfg.MMWP` enables the default PMP behavior in Machine mode, meaning that M-mode can access any memory region + even if it is not explicitly covered by a PMP rule. + + type: RW + definedBy: Smepmp + reset_value: UNDEFINED_LEGAL + RLB: + location: 2 + description: | + Rule Locking Bypass (mseccfg.RLB). This field can be set to 1 and once it is set back to 0, then it cannot be changed until the PMP Reset. + + When 1, locked PMP rules may be removed/modified and locked PMP enteries may be edited. + + When 0, with `pmpcfg.L=1` in any rule or entry (including disabled enteries), then mseccfg.RLB + remains 0 and any further modifications to mseccfg.RLB are ignored until a PMP reset. + type: RW + definedBy: Smepmp + reset_value: UNDEFINED_LEGAL \ No newline at end of file From 72709d17e7fb7c220247a7b0df20405bee81f0cd Mon Sep 17 00:00:00 2001 From: MuhammadHammad001 Date: Wed, 23 Apr 2025 16:56:35 +0500 Subject: [PATCH 2/3] Initial yaml for Smepmp extension and update definedby field for mseccfg and mseccfgh --- arch/csr/mseccfg.yaml | 7 +++- arch/csr/mseccfgh.yaml | 7 +++- arch/ext/Smepmp.yaml | 89 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 arch/ext/Smepmp.yaml diff --git a/arch/csr/mseccfg.yaml b/arch/csr/mseccfg.yaml index 90f6dce7e..c28687944 100644 --- a/arch/csr/mseccfg.yaml +++ b/arch/csr/mseccfg.yaml @@ -9,8 +9,11 @@ priv_mode: M length: MXLEN description: Machine Security Configuration register is used for configuring various security mechanisms present on the hart and only accessible in Machine mode. definedBy: - name: Sm - version: ">= 1.12" + allOf: + - name: Sm + version: ">=1.12" + - name: Smepmp + version: ">= 1.0.0" fields: MML: location: 0 diff --git a/arch/csr/mseccfgh.yaml b/arch/csr/mseccfgh.yaml index 3f2330a5c..da2881034 100644 --- a/arch/csr/mseccfgh.yaml +++ b/arch/csr/mseccfgh.yaml @@ -10,6 +10,9 @@ priv_mode: M length: 32 description: Machine Security Configuration definedBy: - name: Sm - version: ">= 1.12" + allOf: + - name: Sm + version: ">=1.12" + - name: Smepmp + version: ">= 1.0.0" fields: {} diff --git a/arch/ext/Smepmp.yaml b/arch/ext/Smepmp.yaml new file mode 100644 index 000000000..038b37813 --- /dev/null +++ b/arch/ext/Smepmp.yaml @@ -0,0 +1,89 @@ +# yaml-language-server: $schema=../../schemas/ext_schema.json + +$schema: "ext_schema.json#" +kind: extension +name: Smepmp +type: privileged +long_name: Personal Physical Memory Protection (PMP) Enhancements for memory access and execution prevention on Machine mode +versions: + - version: "1.0.0" + state: ratified + ratification_date: 2021-12 + contributors: + - name: Nick Kossifidis + - name: Joe Xie + - name: Bill Huffman + - name: Allen Baum + - name: Greg Favor + - name: Tariq Kurd + - name: Fumio Arakawa + - name: RISC-V TEE Task Group + +description: | + Being able to access the memory of a process running at a high privileged execution mode, such as the + Supervisor or Machine mode, from a lower privileged mode such as the User mode, introduces an obvious attack + vector since it allows for an attacker to perform privilege escalation, and tamper with the code and/or data of + that process. A less obvious attack vector exists when the reverse happens, in which case an attacker instead of + tampering with code and/or data that belong to a high-privileged process, can tamper with the memory of an + unprivileged / less-privileged process and trick the high-privileged process to use or execute it. + + To prevent this attack vector, two mechanisms known as Supervisor Memory Access Prevention (SMAP) and + Supervisor Memory Execution Prevention (SMEP) were introduced in recent systems. The first one prevents the + OS from accessing the memory of an unprivileged process unless a specific code path is followed, and the second + one prevents the OS from executing the memory of an unprivileged process at all times. RISC-V already includes + support for SMAP, through the sstatus.SUM bit, and for SMEP by always denying execution of virtual memory + pages marked with the U bit, with Supervisor mode (OS) privileges, as mandated on the Privilege Spec. + + [NOTE] + -- + + Terms: + + - *PMP Entry*: A pair of `pmpcfg[i]` / `pmpaddr[i]` registers. + + - *PMP Rule*: The contents of a pmpcfg register and its associated pmpaddr register(s), + that encode a valid protected physical memory region, where `pmpcfg[i].A != OFF`, and + if `pmpcfg[i].A == TOR`, `pmpaddr[i-1] < pmpaddr[i]`. + - *Ignored*: Any permissions set by a matching PMP rule are ignored, and all accesses to + the requested address range are allowed. + - *Enforced*: Only access types configured in the PMP rule matching the requested address + range are allowed; failures will cause an access-fault exception. + - *Denied*: Any permissions set by a matching PMP rule are ignored, and no accesses to the + requested address range are allowed.; failures will cause an access-fault exception. + - *Locked*: A PMP rule/entry where the `pmpcfg.L` bit is set. + - *PMP reset*: A reset process where all PMP settings of the hart, including locked + rules/settings, are re-initialized to a set of safe defaults, before releasing the hart (back) + to the firmware / OS / application. + -- +params: + NUM_PMP_ENTRIES1: + description: | + Number of implemented PMP entries. Can be any value between 0-64, inclusive. + + The architecture mandates that the number of implemented PMP registers + must appear to be 0, 16, or 64. + + Therefore, pmp registers will behave as follows according to NUN_PMP_ENTRIES: + + [separator="!"] + !=== + ! NUM_PMP_ENTRIES ! pmpaddr<0-15> / pmpcfg<0-3> ! pmpaddr<16-63> / pmpcfg<4-15> + ! 0 ! N ! N + ! 1-16 ! Y ! N + ! 17-64 ! Y ! Y + !=== + + ** N = Not implemented; access will cause `IllegalInstruction` + if TRAP_ON_UNIMPLEMENTED_CSR is true + ** Y = Implemented; access will not cause an exception (from M-mode), but register + may be read-only-zero if NUM_PMP_ENTRIES is less than the corresponding register + + [NOTE] + `pmpcfgN` for an odd N never exists when XLEN == 64 + + When NUM_PMP_ENTRIES is not exactly 0, 16, or 64, some extant pmp registers, + and associated pmpNcfg, will be read-only zero (but will never cause an exception). + schema: + type: integer + minimum: 0 + maximum: 64 \ No newline at end of file From 4ee10a86cea64c215c8748bd24d73b8d9a9c69b3 Mon Sep 17 00:00:00 2001 From: MuhammadHammad001 Date: Wed, 23 Apr 2025 16:58:25 +0500 Subject: [PATCH 3/3] Remove wrong param field --- arch/ext/Smepmp.yaml | 34 +--------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/arch/ext/Smepmp.yaml b/arch/ext/Smepmp.yaml index 038b37813..c46e16a5a 100644 --- a/arch/ext/Smepmp.yaml +++ b/arch/ext/Smepmp.yaml @@ -54,36 +54,4 @@ description: | - *PMP reset*: A reset process where all PMP settings of the hart, including locked rules/settings, are re-initialized to a set of safe defaults, before releasing the hart (back) to the firmware / OS / application. - -- -params: - NUM_PMP_ENTRIES1: - description: | - Number of implemented PMP entries. Can be any value between 0-64, inclusive. - - The architecture mandates that the number of implemented PMP registers - must appear to be 0, 16, or 64. - - Therefore, pmp registers will behave as follows according to NUN_PMP_ENTRIES: - - [separator="!"] - !=== - ! NUM_PMP_ENTRIES ! pmpaddr<0-15> / pmpcfg<0-3> ! pmpaddr<16-63> / pmpcfg<4-15> - ! 0 ! N ! N - ! 1-16 ! Y ! N - ! 17-64 ! Y ! Y - !=== - - ** N = Not implemented; access will cause `IllegalInstruction` - if TRAP_ON_UNIMPLEMENTED_CSR is true - ** Y = Implemented; access will not cause an exception (from M-mode), but register - may be read-only-zero if NUM_PMP_ENTRIES is less than the corresponding register - - [NOTE] - `pmpcfgN` for an odd N never exists when XLEN == 64 - - When NUM_PMP_ENTRIES is not exactly 0, 16, or 64, some extant pmp registers, - and associated pmpNcfg, will be read-only zero (but will never cause an exception). - schema: - type: integer - minimum: 0 - maximum: 64 \ No newline at end of file + -- \ No newline at end of file