From f5e1bbeb8617e97d39290c2fc8a6bd2ff54151b8 Mon Sep 17 00:00:00 2001 From: MuhammadHammad001 Date: Wed, 23 Apr 2025 16:04:13 +0500 Subject: [PATCH 1/8] Add yaml for mseccfg --- spec/std/isa/csr/mseccfg.yaml | 104 +++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 3 deletions(-) diff --git a/spec/std/isa/csr/mseccfg.yaml b/spec/std/isa/csr/mseccfg.yaml index 0329d08a12..759d78ee62 100644 --- a/spec/std/isa/csr/mseccfg.yaml +++ b/spec/std/isa/csr/mseccfg.yaml @@ -10,9 +10,107 @@ long_name: Machine Security Configuration address: 0x747 writable: true 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 e86c0f3aefd52804cec740e046a1811da87ff303 Mon Sep 17 00:00:00 2001 From: sudo-apt-Abdullah Date: Wed, 17 Sep 2025 13:30:11 +0000 Subject: [PATCH 2/8] Initial yaml for Smepmp extension and update definedby field for mseccfg and mseccfgh # Conflicts: # spec/std/isa/ext/Smepmp.yaml --- spec/std/isa/csr/mseccfg.yaml | 9 ++-- spec/std/isa/csr/mseccfgh.yaml | 7 ++- spec/std/isa/ext/Smepmp.yaml | 92 ++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 spec/std/isa/ext/Smepmp.yaml diff --git a/spec/std/isa/csr/mseccfg.yaml b/spec/std/isa/csr/mseccfg.yaml index 759d78ee62..430d9c9603 100644 --- a/spec/std/isa/csr/mseccfg.yaml +++ b/spec/std/isa/csr/mseccfg.yaml @@ -13,8 +13,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 @@ -113,4 +116,4 @@ fields: 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 + reset_value: UNDEFINED_LEGAL diff --git a/spec/std/isa/csr/mseccfgh.yaml b/spec/std/isa/csr/mseccfgh.yaml index 63daf6f407..3200468416 100644 --- a/spec/std/isa/csr/mseccfgh.yaml +++ b/spec/std/isa/csr/mseccfgh.yaml @@ -14,6 +14,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/spec/std/isa/ext/Smepmp.yaml b/spec/std/isa/ext/Smepmp.yaml new file mode 100644 index 0000000000..586e1f53b5 --- /dev/null +++ b/spec/std/isa/ext/Smepmp.yaml @@ -0,0 +1,92 @@ +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause-Clear + +# 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 From e79ff16b280616454ef0ac90fd3814a8a4dd9ce4 Mon Sep 17 00:00:00 2001 From: sudo-apt-Abdullah Date: Wed, 17 Sep 2025 13:35:46 +0000 Subject: [PATCH 3/8] Remove wrong param field # Conflicts: # spec/std/isa/ext/Smepmp.yaml --- spec/std/isa/ext/Smepmp.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/std/isa/ext/Smepmp.yaml b/spec/std/isa/ext/Smepmp.yaml index 586e1f53b5..1fb564f534 100644 --- a/spec/std/isa/ext/Smepmp.yaml +++ b/spec/std/isa/ext/Smepmp.yaml @@ -57,7 +57,6 @@ 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: | From 030779f75ade9038d7742e4e882e2692e21428e0 Mon Sep 17 00:00:00 2001 From: sudo-apt-Abdullah Date: Thu, 2 Oct 2025 14:07:34 +0000 Subject: [PATCH 4/8] feat: smepmp --- spec/std/isa/csr/mseccfg.yaml | 109 ++++++++++++++---- spec/std/isa/csr/mseccfgh.yaml | 10 +- spec/std/isa/ext/Smepmp.yaml | 205 ++++++++++++++++++++++++--------- 3 files changed, 241 insertions(+), 83 deletions(-) diff --git a/spec/std/isa/csr/mseccfg.yaml b/spec/std/isa/csr/mseccfg.yaml index 430d9c9603..5e869062ee 100644 --- a/spec/std/isa/csr/mseccfg.yaml +++ b/spec/std/isa/csr/mseccfg.yaml @@ -11,15 +11,12 @@ address: 0x747 writable: true 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. +description: Machine Security Configuration register is used for configuring various security mechanisms present on the hart. definedBy: - allOf: - - name: Sm - version: ">=1.12" - - name: Smepmp - version: ">= 1.0.0" + name: Smepmp + version: ~> 1.0.0 fields: - MML: + MMsL: location: 0 description: | Machine Mode Lockdown (mseccfg.MML) enforces strong isolation between Machine Mode and lower-privilege modes. This is a _sticky bit_ @@ -91,29 +88,101 @@ fields: type: RW definedBy: Smepmp reset_value: UNDEFINED_LEGAL - MMWP: - location: 1 + MML: + location: 0 + definedBy: Smepmp description: | - Machine Mode Whitelist Policy (mseccfg.MMWP). This is a _sticky bit_ meaning that once set, it can only be reset on PMP Reset. + Machine Mode Lockdown (mseccfg.MML) is a sticky bit, meaning that once set it cannot be unset until a PMP reset. When `mseccfg.MML` is set + the system's behavior changes in the following way: - 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*. + a. The meaning of `pmpcfg.L` changes: Instead of marking a rule as locked and enforced in all modes, it now marks a rule as M-mode-only + when set and S/U-mode-only when unset. The formerly reserved encoding of `pmpcfg.RW=01`, and the encoding `pmpcfg.LRWX=1111`, now encode + a Shared-Region. - 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. + An M-mode-only rule is enforced on Machine mode and denied in Supervisor or User mode. It also 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. - type: RW + An S/U-mode-only rule is enforced on Supervisor and User modes and denied on Machine mode. + + A Shared-Region rule is enforced on all modes, with restrictions depending on the `pmpcfg.L` and `pmpcfg.X` bits: + + - 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 writable. 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 by setting `mseccfg.RLB` e.g. during the boot process. + + 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(): | + if (MSECCFG_MML_TYPE == "read-only-0" || MSECCFG_MML_TYPE == "read-only-1") { + return CsrFieldType::RO; + } else if (MSECCFG_MML_TYPE == "sticky") { + return CsrFieldType::RW-R; // restricted: 0→1 allowed, 1→0 not allowed + } + sw_write(csr_value): return csr_value.MML | CSR[mseccfg].MML; + reset_value: UNDEFINED_LEGAL + MMWP: + location: 1 definedBy: Smepmp + description: | + Machine-Mode Allowlist Policy (mseccfg.MMWP) is a sticky bit, meaning that once set it cannot be unset until a PMP reset. When set it + changes the default PMP policy for M-mode when accessing memory regions that don't have a matching PMP rule, to denied instead of ignored. + type(): | + if (MSECCFG_MML_TYPE == "read-only-0" || MSECCFG_MML_TYPE == "read-only-1") { + return CsrFieldType::RO; + } else if (MSECCFG_MML_TYPE == "sticky") { + return CsrFieldType::RW-R; // restricted: 0→1 allowed, 1→0 not allowed + } + sw_write(csr_value): return csr_value.MMWP | CSR[mseccfg].MMWP; 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. + Rule Locking Bypass (mseccfg.RLB) bit has the following functionality: - When 1, locked PMP rules may be removed/modified and locked PMP enteries may be edited. + a. When `mseccfg.RLB` is 1 locked PMP rules may be removed/modified and locked PMP entries 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 + b. When `mseccfg.RLB` is 0 and `pmpcfg.L` is 1 in any rule or entry (including disabled entries), then + remains 0 and any further modifications to `mseccfg.RLB` are ignored until a PMP reset. + type(): | + return MUTABLE_MSECCFG_RLB ? CsrFieldType::RW : CsrFieldType:RO; definedBy: Smepmp reset_value: UNDEFINED_LEGAL diff --git a/spec/std/isa/csr/mseccfgh.yaml b/spec/std/isa/csr/mseccfgh.yaml index 3200468416..b60a3a628d 100644 --- a/spec/std/isa/csr/mseccfgh.yaml +++ b/spec/std/isa/csr/mseccfgh.yaml @@ -12,11 +12,9 @@ address: 0x757 writable: true priv_mode: M length: 32 -description: Machine Security Configuration +description: | + The `mseccfgh` is a 32-bit read/write register that aliases bits 63:32 of `mseccfg`. definedBy: - allOf: - - name: Sm - version: ">=1.12" - - name: Smepmp - version: ">= 1.0.0" + name: Smepmp + version: ~> 1.0.0 fields: {} diff --git a/spec/std/isa/ext/Smepmp.yaml b/spec/std/isa/ext/Smepmp.yaml index 1fb564f534..5233f889c3 100644 --- a/spec/std/isa/ext/Smepmp.yaml +++ b/spec/std/isa/ext/Smepmp.yaml @@ -7,7 +7,7 @@ $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 +long_name: PMP Enhancements for memory access and execution prevention in Machine mode versions: - version: "1.0.0" state: ratified @@ -24,68 +24,159 @@ versions: 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. + 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. + 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. + + However, there are no such mechanisms available on Machine mode in the current (v1.11) Privileged Spec. + It is not possible for a PMP rule to be enforced only on non-Machine modes and denied on Machine mode, + to only allow access to a memory region by less-privileged modes. It is only possible to have a locked + rule that will be enforced on all modes, or a rule that will be enforced on non-Machine modes and be + ignored by Machine mode. So for any physical memory region which is not protected with a Locked rule, + Machine mode has unlimited access, including the ability to execute it. + + Without being able to protect less-privileged modes from Machine mode, it is not possible to prevent + the mentioned attack vector. This becomes even more important for RISC-V than on other architectures, + since implementations are allowed where a hart only has Machine and User modes available, so the whole + OS will run on Machine mode instead of the non-existent Supervisor mode. In such implementations the + attack surface is greatly increased, and the same kind of attacks performed on Supervisor mode and + mitigated through SMAP/SMEP, can be performed on Machine mode without any available mitigations. Even + on implementations with Supervisor mode present attacks are still possible against the Firmware and/or + the Secure Monitor running on Machine mode. + + The proposal is given as: + + 1. Machine Security Configuration (mseccfg) is a new RW Machine mode CSR, used for + configuring various security mechanisms present on the hart, and only accessible to Machine + mode. It is 64 bits wide, and is at address 0x747 on RV64 and 0x747 (low 32bits), 0x757 (high + 32bits) on RV32. All mseccfg fields defined on this proposal are WARL, and the remaining bits are + reserved for future standard use and should always read zero. The reset value of mseccfg is + implementation-specific, otherwise if backwards compatibility is a requirement it should reset to + zero on hard reset. + + 2. On mseccfg we introduce a field on bit 2 called Rule Locking Bypass (mseccfg.RLB) with the + following functionality: + + a. When mseccfg.RLB is 1 locked PMP rules may be removed/modified and locked PMP entries may be edited. + + b. When mseccfg.RLB is 0 and pmpcfg.L is 1 in any rule or entry (including disabled entries), then + mseccfg.RLB remains 0 and any further modifications to mseccfg.RLB are ignored until a PMP reset. + + 3. On mseccfg we introduce a field in bit 1 called Machine-Mode Allowlist Policy (mseccfg.MMWP). + This is a sticky bit, meaning that once set it cannot be unset until a PMP reset. When set it + changes the default PMP policy for M-mode when accessing memory regions that don't have a + matching PMP rule, to denied instead of ignored. + + 4. On mseccfg we introduce a field in bit 0 called Machine Mode Lockdown (mseccfg.MML). This is + a sticky bit, meaning that once set it cannot be unset until a PMP reset. When mseccfg.MML is set + the system's behavior changes in the following way: + + a. The meaning of pmpcfg.L changes: Instead of marking a rule as locked and enforced in all + modes, it now marks a rule as M-mode-only when set and S/U-mode-only when unset. The + formerly reserved encoding of pmpcfg.RW=01 , and the encoding pmpcfg.LRWX=1111 , now encode a + Shared-Region. + + An M-mode-only rule is enforced on Machine mode and denied in Supervisor or User mode. It + also 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. + + An S/U-mode-only rule is enforced on Supervisor and User modes and denied on Machine mode. + + A Shared-Region rule is enforced on all modes, with restrictions depending on the pmpcfg.L and + pmpcfg.X bits: - The architecture mandates that the number of implemented PMP registers - must appear to be 0, 16, or 64. + - 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. - Therefore, pmp registers will behave as follows according to NUN_PMP_ENTRIES: + - 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 writable. 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. - [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 - !=== + - 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. - ** 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 + 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 by setting mseccfg.RLB e.g. during the boot process. - [NOTE] - `pmpcfgN` for an odd N never exists when XLEN == 64 + 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. - 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). + 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. + + Since all fields defined on mseccfg as part of this proposal are locked when set (MMWP/MML) or locked + when cleared (RLB), software can't poll them for determining the presence of Smepmp. It is expected + that BootROM will set mseccfg.MMWP and/or mseccfg.MML during early boot, before jumping to the + firmware, so that the firmware will be able to determine the presence of Smepmp by reading mseccfg + and checking the state of mseccfg.MMWP and mseccfg.MML. + +params: + MSECCFG_MML_TYPE: schema: - type: integer - minimum: 0 - maximum: 64 + enum: [read-only-0, read-only-1, sticky] + description: | + Determines the behavior of the mseccfg.MML bit: + + * "read-only-0": Bit is hardwired to 0 + * "read-only-1": Bit is hardwired to 1 + * "sticky": Bit resets to 0, can be set to 1 by software, but once set it cannot be cleared until reset. + MSECCFG_MMWP_TYPE: + schema: + enum: [read-only-0, read-only-1, sticky] + description: | + Determines the behavior of the mseccfg.MMWP bit: + + * "read-only-0": Bit is hardwired to 0 + * "read-only-1": Bit is hardwired to 1 + * "sticky": Bit resets to 0, can be set to 1 by software, but once set it cannot be cleared until reset. + MUTABLE_MSECCFG_RLB: + schema: + type: boolean + description: | + When set, mseccfg.RLB is writable. + When clear, mseccfg.RLB is read-only-0. From faa3aba0595d81a76f39a2455afb5d3d2cefd8a4 Mon Sep 17 00:00:00 2001 From: sudo-apt-Abdullah Date: Thu, 2 Oct 2025 14:10:10 +0000 Subject: [PATCH 5/8] fixed few mistakes in field --- spec/std/isa/csr/mseccfg.yaml | 72 ----------------------------------- 1 file changed, 72 deletions(-) diff --git a/spec/std/isa/csr/mseccfg.yaml b/spec/std/isa/csr/mseccfg.yaml index 5e869062ee..cd75ecfe25 100644 --- a/spec/std/isa/csr/mseccfg.yaml +++ b/spec/std/isa/csr/mseccfg.yaml @@ -16,78 +16,6 @@ definedBy: name: Smepmp version: ~> 1.0.0 fields: - MMsL: - 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 MML: location: 0 definedBy: Smepmp From 881c2b494814bce6281919f98fc03aab368a9900 Mon Sep 17 00:00:00 2001 From: sudo-apt-Abdullah Date: Mon, 6 Oct 2025 12:31:08 +0000 Subject: [PATCH 6/8] addressed the concerns so far. --- spec/std/isa/csr/mseccfg.yaml | 31 +++++++++++++++++++++++-------- spec/std/isa/ext/Smepmp.yaml | 2 ++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/spec/std/isa/csr/mseccfg.yaml b/spec/std/isa/csr/mseccfg.yaml index cd75ecfe25..4ea851a4fc 100644 --- a/spec/std/isa/csr/mseccfg.yaml +++ b/spec/std/isa/csr/mseccfg.yaml @@ -80,13 +80,20 @@ fields: *Locked rules cannot be removed or modified until a PMP reset, unless mseccfg.RLB is set. type(): | - if (MSECCFG_MML_TYPE == "read-only-0" || MSECCFG_MML_TYPE == "read-only-1") { + if ((MSECCFG_MML_TYPE == "read-only-0") || (MSECCFG_MML_TYPE == "read-only-1")) { return CsrFieldType::RO; } else if (MSECCFG_MML_TYPE == "sticky") { return CsrFieldType::RW-R; // restricted: 0→1 allowed, 1→0 not allowed } - sw_write(csr_value): return csr_value.MML | CSR[mseccfg].MML; - reset_value: UNDEFINED_LEGAL + sw_write(csr_value): | + return (MSECCFG_MML_TYPE == "read-only-1") ? 1 : (csr_value.MML | CSR[mseccfg].MML); + reset_value(): | + if ((MSECCFG_MML_TYPE == "read-only-0") || (MSECCFG_MML_TYPE == "sticky")) { + return 0; + } else if (MSECCFG_MML_TYPE == "read-only-1") { + return 1; + } + return UNDEFINED_LEGAL; MMWP: location: 1 definedBy: Smepmp @@ -94,13 +101,20 @@ fields: Machine-Mode Allowlist Policy (mseccfg.MMWP) is a sticky bit, meaning that once set it cannot be unset until a PMP reset. When set it changes the default PMP policy for M-mode when accessing memory regions that don't have a matching PMP rule, to denied instead of ignored. type(): | - if (MSECCFG_MML_TYPE == "read-only-0" || MSECCFG_MML_TYPE == "read-only-1") { + if ((MSECCFG_MMWP_TYPE == "read-only-0") || (MSECCFG_MMWP_TYPE == "read-only-1")) { return CsrFieldType::RO; - } else if (MSECCFG_MML_TYPE == "sticky") { + } else if (MSECCFG_MMWP_TYPE == "sticky") { return CsrFieldType::RW-R; // restricted: 0→1 allowed, 1→0 not allowed } - sw_write(csr_value): return csr_value.MMWP | CSR[mseccfg].MMWP; - reset_value: UNDEFINED_LEGAL + sw_write(csr_value): | + return (MSECCFG_MMWP_TYPE == "read-only-1") ? 1 : (csr_value.MMWP | CSR[mseccfg].MMWP); + reset_value(): | + if ((MSECCFG_MMWP_TYPE == "read-only-0") || (MSECCFG_MMWP_TYPE == "sticky")) { + return 0; + } else if (MSECCFG_MMWP_TYPE == "read-only-1") { + return 1; + } + return UNDEFINED_LEGAL; RLB: location: 2 description: | @@ -113,4 +127,5 @@ fields: type(): | return MUTABLE_MSECCFG_RLB ? CsrFieldType::RW : CsrFieldType:RO; definedBy: Smepmp - reset_value: UNDEFINED_LEGAL + reset_value(): | + return MUTABLE_MSECCFG_RLB ? 0 : UNDEFINED_LEGAL; diff --git a/spec/std/isa/ext/Smepmp.yaml b/spec/std/isa/ext/Smepmp.yaml index 5233f889c3..ec1280cf8a 100644 --- a/spec/std/isa/ext/Smepmp.yaml +++ b/spec/std/isa/ext/Smepmp.yaml @@ -158,6 +158,7 @@ description: | params: MSECCFG_MML_TYPE: schema: + type: string enum: [read-only-0, read-only-1, sticky] description: | Determines the behavior of the mseccfg.MML bit: @@ -167,6 +168,7 @@ params: * "sticky": Bit resets to 0, can be set to 1 by software, but once set it cannot be cleared until reset. MSECCFG_MMWP_TYPE: schema: + type: string enum: [read-only-0, read-only-1, sticky] description: | Determines the behavior of the mseccfg.MMWP bit: From 920efeb77ab0f825518ea4205ca7266e46f2b286 Mon Sep 17 00:00:00 2001 From: sudo-apt-Abdullah Date: Mon, 6 Oct 2025 13:59:35 +0000 Subject: [PATCH 7/8] fixed the syntax error --- spec/std/isa/csr/mseccfg.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/spec/std/isa/csr/mseccfg.yaml b/spec/std/isa/csr/mseccfg.yaml index 4ea851a4fc..a0a5eb54f2 100644 --- a/spec/std/isa/csr/mseccfg.yaml +++ b/spec/std/isa/csr/mseccfg.yaml @@ -83,7 +83,8 @@ fields: if ((MSECCFG_MML_TYPE == "read-only-0") || (MSECCFG_MML_TYPE == "read-only-1")) { return CsrFieldType::RO; } else if (MSECCFG_MML_TYPE == "sticky") { - return CsrFieldType::RW-R; // restricted: 0→1 allowed, 1→0 not allowed + # Restricted: 0→1 allowed, 1→0 not allowed + return CsrFieldType::RWR; } sw_write(csr_value): | return (MSECCFG_MML_TYPE == "read-only-1") ? 1 : (csr_value.MML | CSR[mseccfg].MML); @@ -104,7 +105,8 @@ fields: if ((MSECCFG_MMWP_TYPE == "read-only-0") || (MSECCFG_MMWP_TYPE == "read-only-1")) { return CsrFieldType::RO; } else if (MSECCFG_MMWP_TYPE == "sticky") { - return CsrFieldType::RW-R; // restricted: 0→1 allowed, 1→0 not allowed + # Restricted: 0→1 allowed, 1→0 not allowed + return CsrFieldType::RWR; } sw_write(csr_value): | return (MSECCFG_MMWP_TYPE == "read-only-1") ? 1 : (csr_value.MMWP | CSR[mseccfg].MMWP); @@ -125,7 +127,7 @@ fields: b. When `mseccfg.RLB` is 0 and `pmpcfg.L` is 1 in any rule or entry (including disabled entries), then remains 0 and any further modifications to `mseccfg.RLB` are ignored until a PMP reset. type(): | - return MUTABLE_MSECCFG_RLB ? CsrFieldType::RW : CsrFieldType:RO; + return MUTABLE_MSECCFG_RLB ? CsrFieldType::RW : CsrFieldType::RO; definedBy: Smepmp reset_value(): | return MUTABLE_MSECCFG_RLB ? 0 : UNDEFINED_LEGAL; From bd571d70f2d67d7e4188abd3367715497a4317ff Mon Sep 17 00:00:00 2001 From: sudo-apt-Abdullah Date: Tue, 7 Oct 2025 12:53:38 +0000 Subject: [PATCH 8/8] updated sw_write() --- spec/std/isa/csr/mseccfg.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/std/isa/csr/mseccfg.yaml b/spec/std/isa/csr/mseccfg.yaml index a0a5eb54f2..fca2dd729b 100644 --- a/spec/std/isa/csr/mseccfg.yaml +++ b/spec/std/isa/csr/mseccfg.yaml @@ -87,7 +87,7 @@ fields: return CsrFieldType::RWR; } sw_write(csr_value): | - return (MSECCFG_MML_TYPE == "read-only-1") ? 1 : (csr_value.MML | CSR[mseccfg].MML); + return csr_value.MML | CSR[mseccfg].MML; reset_value(): | if ((MSECCFG_MML_TYPE == "read-only-0") || (MSECCFG_MML_TYPE == "sticky")) { return 0; @@ -109,7 +109,7 @@ fields: return CsrFieldType::RWR; } sw_write(csr_value): | - return (MSECCFG_MMWP_TYPE == "read-only-1") ? 1 : (csr_value.MMWP | CSR[mseccfg].MMWP); + return csr_value.MMWP | CSR[mseccfg].MMWP; reset_value(): | if ((MSECCFG_MMWP_TYPE == "read-only-0") || (MSECCFG_MMWP_TYPE == "sticky")) { return 0;