* [PATCH v2 0/6] target/riscv: Implement Smsdid and Smmpt extension
@ 2025-09-18 6:19 LIU Zhiwei
2025-09-18 6:19 ` [PATCH v2 1/6] target/riscv: Add basic definitions and CSRs for SMMPT LIU Zhiwei
` (5 more replies)
0 siblings, 6 replies; 11+ messages in thread
From: LIU Zhiwei @ 2025-09-18 6:19 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, palmer, alistair.francis, dbarboza, liwei1518,
zhiwei_liu
This patch set introduces support for the RISC-V Smmpt (Supervisor
Memory-tracking and Protection Table) extension. Smmpt provides a
hardware mechanism for fine-grained memory protection, checked after
address translation, which is particularly useful for supervisor-level
sandboxing and security monitoring.
The rfc patch set:
https://mail.gnu.org/archive/html/qemu-riscv/2025-09/msg00216.html
rfc->v2:
1. When ext_smmpt is false or BARE mode, make other fields in mmpt
CSR zero.
2. Add patch 5 to fix smrnmi ISA string order.
3. Fix patch 6 smmpt and smsdid ISA string order.
4. Make smmpt and smsdid experiment extensions.
5. Add review tags.
LIU Zhiwei (6):
target/riscv: Add basic definitions and CSRs for SMMPT
target/riscv: Implement core SMMPT lookup logic
target/riscv: Integrate SMMPT checks into MMU and TLB fill
target/riscv: Implement SMMPT fence instructions
target/riscv: Fix smrnmi isa alphabetical order
target/riscv: Enable SMMPT extension
target/riscv/cpu.c | 6 +-
target/riscv/cpu.h | 9 +-
target/riscv/cpu_bits.h | 27 ++
target/riscv/cpu_cfg_fields.h.inc | 2 +
target/riscv/cpu_helper.c | 81 +++++-
target/riscv/csr.c | 95 ++++++
target/riscv/insn32.decode | 2 +
.../riscv/insn_trans/trans_privileged.c.inc | 30 ++
target/riscv/meson.build | 1 +
target/riscv/pmp.h | 3 +
target/riscv/riscv_smmpt.c | 274 ++++++++++++++++++
target/riscv/riscv_smmpt.h | 36 +++
12 files changed, 560 insertions(+), 6 deletions(-)
create mode 100644 target/riscv/riscv_smmpt.c
create mode 100644 target/riscv/riscv_smmpt.h
--
2.25.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 1/6] target/riscv: Add basic definitions and CSRs for SMMPT
2025-09-18 6:19 [PATCH v2 0/6] target/riscv: Implement Smsdid and Smmpt extension LIU Zhiwei
@ 2025-09-18 6:19 ` LIU Zhiwei
2025-10-12 17:32 ` Daniel Henrique Barboza
2025-09-18 6:19 ` [PATCH v2 2/6] target/riscv: Implement core SMMPT lookup logic LIU Zhiwei
` (4 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: LIU Zhiwei @ 2025-09-18 6:19 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, palmer, alistair.francis, dbarboza, liwei1518,
zhiwei_liu, Huang Tao, TANG Tiancheng
This patch lays the groundwork for the SMMPT (Supervisor Domains Access
Protection) extension by introducing its fundamental components.
It adds:
- New CPU configuration flags, `ext_smmpt` and `ext_smsdid`, to enable
the extension.
- Bit-field definitions for the `mmpt` CSR in `cpu_bits.h`.
- The `mmpt` and `msdcfg` CSR numbers and their read/write handlers in
`csr.c`.
- New fields in `CPUArchState` to store the state of these new CSRs.
- A new translation failure reason `TRANSLATE_MPT_FAIL`.
This provides the necessary infrastructure for the core MPT logic and
MMU integration that will follow.
Co-authored-by: Huang Tao <eric.huang@linux.alibaba.com>
Co-authored-by: TANG Tiancheng <lyndra@linux.alibaba.com>
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
---
target/riscv/cpu.h | 9 ++-
target/riscv/cpu_bits.h | 27 +++++++++
target/riscv/cpu_cfg_fields.h.inc | 2 +
target/riscv/csr.c | 95 +++++++++++++++++++++++++++++++
target/riscv/riscv_smmpt.h | 21 +++++++
5 files changed, 153 insertions(+), 1 deletion(-)
create mode 100644 target/riscv/riscv_smmpt.h
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 4a862da615..fa7b804cb3 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -130,7 +130,8 @@ enum {
TRANSLATE_SUCCESS,
TRANSLATE_FAIL,
TRANSLATE_PMP_FAIL,
- TRANSLATE_G_STAGE_FAIL
+ TRANSLATE_G_STAGE_FAIL,
+ TRANSLATE_MPT_FAIL
};
/* Extension context status */
@@ -180,6 +181,7 @@ extern RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[];
#if !defined(CONFIG_USER_ONLY)
#include "pmp.h"
#include "debug.h"
+#include "riscv_smmpt.h"
#endif
#define RV_VLEN_MAX 1024
@@ -486,6 +488,11 @@ struct CPUArchState {
uint64_t hstateen[SMSTATEEN_MAX_COUNT];
uint64_t sstateen[SMSTATEEN_MAX_COUNT];
uint64_t henvcfg;
+ /* Smsdid */
+ uint32_t mptmode;
+ uint32_t sdid;
+ uint64_t mptppn;
+ uint32_t msdcfg;
#endif
/* Fields from here on are preserved across CPU reset. */
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index b62dd82fe7..c6a34863d1 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -1164,4 +1164,31 @@ typedef enum CTRType {
#define MCONTEXT64 0x0000000000001FFFULL
#define MCONTEXT32_HCONTEXT 0x0000007F
#define MCONTEXT64_HCONTEXT 0x0000000000003FFFULL
+
+/* Smsdid */
+#define CSR_MMPT 0xbc0
+#define CSR_MSDCFG 0xbd1
+
+#define MMPT_MODE_MASK_32 0xC0000000
+#define MMPT_SDID_MASK_32 0x3F000000
+#define MMPT_PPN_MASK_32 0x003FFFFF
+
+#define MMPT_MODE_SHIFT_32 30
+#define MMPT_SDID_SHIFT_32 24
+
+#define MMPT_MODE_MASK_64 0xF000000000000000ULL
+#define MMPT_SDID_MASK_64 0x0FC0000000000000ULL
+#define MMPT_PPN_MASK_64 0x000FFFFFFFFFFFFFULL
+
+#define MPTE_L3_VALID 0x0000100000000000ULL
+#define MPTE_L3_RESERVED 0xFFFFE00000000000ULL
+
+#define MPTE_L2_RESERVED_64 0xFFFF800000000000ULL
+#define MPTE_L2_RESERVED_32 0xFE000000
+
+#define MPTE_L1_RESERVED_64 0xFFFFFFFF00000000ULL
+#define MPTE_L1_RESERVED_32 0xFFFF0000
+
+#define MMPT_MODE_SHIFT_64 60
+#define MMPT_SDID_SHIFT_64 54
#endif
diff --git a/target/riscv/cpu_cfg_fields.h.inc b/target/riscv/cpu_cfg_fields.h.inc
index e2d116f0df..8c8a4ac236 100644
--- a/target/riscv/cpu_cfg_fields.h.inc
+++ b/target/riscv/cpu_cfg_fields.h.inc
@@ -60,6 +60,8 @@ BOOL_FIELD(ext_svpbmt)
BOOL_FIELD(ext_svrsw60t59b)
BOOL_FIELD(ext_svvptc)
BOOL_FIELD(ext_svukte)
+BOOL_FIELD(ext_smmpt)
+BOOL_FIELD(ext_smsdid)
BOOL_FIELD(ext_zdinx)
BOOL_FIELD(ext_zaamo)
BOOL_FIELD(ext_zacas)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 8842e07a73..e7e85b4310 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -793,6 +793,15 @@ static RISCVException rnmi(CPURISCVState *env, int csrno)
return RISCV_EXCP_ILLEGAL_INST;
}
+
+static RISCVException smsdid(CPURISCVState *env, int csrno)
+{
+ if (riscv_cpu_cfg(env)->ext_smsdid) {
+ return RISCV_EXCP_NONE;
+ }
+
+ return RISCV_EXCP_ILLEGAL_INST;
+}
#endif
static RISCVException seed(CPURISCVState *env, int csrno)
@@ -5470,6 +5479,89 @@ static RISCVException write_mnstatus(CPURISCVState *env, int csrno,
return RISCV_EXCP_NONE;
}
+static RISCVException read_mmpt(CPURISCVState *env, int csrno,
+ target_ulong *val)
+{
+ if (riscv_cpu_xlen(env) == 32) {
+ uint32_t value = 0;
+ value |= env->mptmode << MMPT_MODE_SHIFT_32;
+ value |= (env->sdid << MMPT_SDID_SHIFT_32) & MMPT_SDID_MASK_32;
+ value |= env->mptppn & MMPT_PPN_MASK_32;
+ *val = value;
+ } else if (riscv_cpu_xlen(env) == 64) {
+ uint64_t value_64 = 0;
+ uint32_t mode_value = env->mptmode;
+ /* mpt_mode_t convert to mmpt.mode value */
+ if (mode_value) {
+ mode_value -= SMMPT43 - SMMPT34;
+ }
+ value_64 |= (uint64_t)mode_value << MMPT_MODE_SHIFT_64;
+ value_64 |= ((uint64_t)env->sdid << MMPT_SDID_SHIFT_64)
+ & MMPT_SDID_MASK_64;
+ value_64 |= (uint64_t)env->mptppn & MMPT_PPN_MASK_64;
+ *val = value_64;
+ } else {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_mmpt(CPURISCVState *env, int csrno,
+ target_ulong val, uintptr_t ra)
+{
+ uint32_t mode_value = 0;
+ if (!riscv_cpu_cfg(env)->ext_smmpt) {
+ goto set_remaining_fields_zero;
+ }
+
+ if (riscv_cpu_xlen(env) == 32) {
+ mode_value = (val & MMPT_MODE_MASK_32) >> MMPT_MODE_SHIFT_32;
+ /* If mode is bare, the remaining fields in mmpt must be zero */
+ if (mode_value == SMMPTBARE) {
+ goto set_remaining_fields_zero;
+ } else if (mode_value <= SMMPT34) {
+ /* Only write the legal value */
+ env->mptmode = mode_value;
+ }
+ env->sdid = (val & MMPT_SDID_MASK_32) >> MMPT_SDID_SHIFT_32;
+ env->mptppn = val & MMPT_PPN_MASK_32;
+ } else if (riscv_cpu_xlen(env) == 64) {
+ mode_value = (val & MMPT_MODE_MASK_64) >> MMPT_MODE_SHIFT_64;
+ if (mode_value == SMMPTBARE) {
+ goto set_remaining_fields_zero;
+ } else if (mode_value < SMMPTMAX) {
+ /* convert to mpt_mode_t */
+ mode_value += SMMPT43 - SMMPT34;
+ env->mptmode = mode_value;
+ }
+ env->sdid = (val & MMPT_SDID_MASK_64) >> MMPT_SDID_SHIFT_64;
+ env->mptppn = val & MMPT_PPN_MASK_64;
+ } else {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+ return RISCV_EXCP_NONE;
+
+set_remaining_fields_zero:
+ env->sdid = 0;
+ env->mptmode = SMMPTBARE;
+ env->mptppn = 0;
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_msdcfg(CPURISCVState *env, int csrno,
+ target_ulong *val)
+{
+ *val = env->msdcfg;
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_msdcfg(CPURISCVState *env, int csrno,
+ target_ulong val, uintptr_t ra)
+{
+ env->msdcfg = val;
+ return RISCV_EXCP_NONE;
+}
+
#endif
/* Crypto Extension */
@@ -6666,6 +6758,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
write_mhpmcounterh },
[CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf,
.min_priv_ver = PRIV_VERSION_1_12_0 },
+ /* Supervisor Domain Identifier and Protection Registers */
+ [CSR_MMPT] = { "mmpt", smsdid, read_mmpt, write_mmpt },
+ [CSR_MSDCFG] = { "msdcfg", smsdid, read_msdcfg, write_msdcfg },
#endif /* !CONFIG_USER_ONLY */
};
diff --git a/target/riscv/riscv_smmpt.h b/target/riscv/riscv_smmpt.h
new file mode 100644
index 0000000000..74dcccf4be
--- /dev/null
+++ b/target/riscv/riscv_smmpt.h
@@ -0,0 +1,21 @@
+/*
+ * QEMU RISC-V Smmpt (Memory Protection Table)
+ *
+ * Copyright (c) 2024 Alibaba Group. All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef RISCV_SMMPT_H
+#define RISCV_SMMPT_H
+
+typedef enum {
+ SMMPTBARE = 0,
+ SMMPT34 = 1,
+ SMMPT43 = 2,
+ SMMPT52 = 3,
+ SMMPT64 = 4,
+ SMMPTMAX
+} mpt_mode_t;
+
+#endif
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 2/6] target/riscv: Implement core SMMPT lookup logic
2025-09-18 6:19 [PATCH v2 0/6] target/riscv: Implement Smsdid and Smmpt extension LIU Zhiwei
2025-09-18 6:19 ` [PATCH v2 1/6] target/riscv: Add basic definitions and CSRs for SMMPT LIU Zhiwei
@ 2025-09-18 6:19 ` LIU Zhiwei
2025-10-12 17:32 ` Daniel Henrique Barboza
2025-09-18 6:19 ` [PATCH v2 3/6] target/riscv: Integrate SMMPT checks into MMU and TLB fill LIU Zhiwei
` (3 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: LIU Zhiwei @ 2025-09-18 6:19 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, palmer, alistair.francis, dbarboza, liwei1518,
zhiwei_liu, Huang Tao, TANG Tiancheng
This patch introduces the core implementation for the Memory Protection Table
(MPT) walk, which is the central mechanism of the SMMPT extension.
A new file, `riscv_smmpt.c`, is added to encapsulate the MPT logic. It
implements the `smmpt_lookup()` function, which performs a multi-level
page table-like walk starting from the physical address specified in the
`mptppn` CSR field. This walk determines the access permissions (read,
write, execute) for a given physical address.
The implementation supports various SMMPT modes (SMMPT34, SMMPT43, etc.) and
correctly handles leaf and non-leaf entries, including reserved bit
checks. Helper functions for parsing MPT entries and converting access
permissions are also included in the new `riscv_smmpt.h` header.
Co-authored-by: Huang Tao <eric.huang@linux.alibaba.com>
Co-authored-by: TANG Tiancheng <lyndra@linux.alibaba.com>
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
---
target/riscv/meson.build | 1 +
target/riscv/pmp.h | 3 +
target/riscv/riscv_smmpt.c | 274 +++++++++++++++++++++++++++++++++++++
target/riscv/riscv_smmpt.h | 15 ++
4 files changed, 293 insertions(+)
create mode 100644 target/riscv/riscv_smmpt.c
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index a4bd61e52a..e85b534a64 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -29,6 +29,7 @@ riscv_system_ss = ss.source_set()
riscv_system_ss.add(files(
'arch_dump.c',
'pmp.c',
+ 'riscv_smmpt.c',
'debug.c',
'monitor.c',
'machine.c',
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
index 271cf24169..d9c5e74345 100644
--- a/target/riscv/pmp.h
+++ b/target/riscv/pmp.h
@@ -85,6 +85,9 @@ void pmp_update_rule_nums(CPURISCVState *env);
uint32_t pmp_get_num_rules(CPURISCVState *env);
int pmp_priv_to_page_prot(pmp_priv_t pmp_priv);
void pmp_unlock_entries(CPURISCVState *env);
+int get_physical_address_pmp(CPURISCVState *env, int *prot, hwaddr addr,
+ int size, MMUAccessType access_type,
+ int mode);
#define MSECCFG_MML_ISSET(env) get_field(env->mseccfg, MSECCFG_MML)
#define MSECCFG_MMWP_ISSET(env) get_field(env->mseccfg, MSECCFG_MMWP)
diff --git a/target/riscv/riscv_smmpt.c b/target/riscv/riscv_smmpt.c
new file mode 100644
index 0000000000..b7b47c5ae1
--- /dev/null
+++ b/target/riscv/riscv_smmpt.c
@@ -0,0 +1,274 @@
+/*
+ * QEMU RISC-V Smmpt (Memory Protection Table)
+ *
+ * Copyright (c) 2024 Alibaba Group. All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "riscv_smmpt.h"
+#include "pmp.h"
+#include "system/memory.h"
+
+typedef uint64_t load_entry_fn(AddressSpace *, hwaddr,
+ MemTxAttrs, MemTxResult *);
+
+static uint64_t load_entry_32(AddressSpace *as, hwaddr addr,
+ MemTxAttrs attrs, MemTxResult *result)
+{
+ return address_space_ldl(as, addr, attrs, result);
+}
+
+static uint64_t load_entry_64(AddressSpace *as, hwaddr addr,
+ MemTxAttrs attrs, MemTxResult *result)
+{
+ return address_space_ldq(as, addr, attrs, result);
+}
+
+typedef union {
+ uint64_t raw;
+ struct {
+ uint32_t v:1;
+ uint32_t l:1;
+ uint32_t rsv1:5;
+ uint32_t perms:24;
+ uint32_t n:1;
+ } leaf32;
+ struct {
+ uint32_t v:1;
+ uint32_t l:1;
+ uint32_t rsv1:8;
+ uint32_t ppn:22;
+ } nonleaf32;
+ struct {
+ uint64_t v:1;
+ uint64_t l:1;
+ uint64_t rsv1:8;
+ uint64_t perms:48;
+ uint64_t rsv2:5;
+ uint64_t n:1;
+ } leaf64;
+ struct {
+ uint64_t v:1;
+ uint64_t l:1;
+ uint64_t rsv1:8;
+ uint64_t ppn:52;
+ uint64_t rsv2:1;
+ uint64_t n:1;
+ } nonleaf64;
+} mpte_union_t;
+
+static inline bool mpte_is_leaf(uint64_t mpte)
+{
+ return mpte & 0x2;
+}
+
+static inline bool mpte_is_valid(uint64_t mpte)
+{
+ return mpte & 0x1;
+}
+
+static uint64_t mpte_get_rsv(CPURISCVState *env, uint64_t mpte)
+{
+ RISCVMXL mxl = riscv_cpu_mxl(env);
+ bool leaf = mpte_is_leaf(mpte);
+ mpte_union_t *u = (mpte_union_t *)&mpte;
+
+ if (mxl == MXL_RV32) {
+ return leaf ? u->leaf32.rsv1 : u->nonleaf32.rsv1;
+ }
+ return leaf ? (u->leaf64.rsv1 << 5) | u->leaf64.rsv2
+ : (u->nonleaf64.rsv1 << 1) | u->nonleaf64.rsv2;
+}
+
+static uint64_t mpte_get_perms(CPURISCVState *env, uint64_t mpte)
+{
+ RISCVMXL mxl = riscv_cpu_mxl(env);
+ mpte_union_t *u = (mpte_union_t *)&mpte;
+
+ return (mxl == MXL_RV32) ? u->leaf32.perms : u->leaf64.perms;
+}
+
+static bool mpte_check_nlnapot(CPURISCVState *env, uint64_t mpte, bool *nlnapot)
+{
+ RISCVMXL mxl = riscv_cpu_mxl(env);
+ mpte_union_t *u = (mpte_union_t *)&mpte;
+ if (mxl == MXL_RV32) {
+ *nlnapot = false;
+ return true;
+ }
+ *nlnapot = u->nonleaf64.n;
+ return u->nonleaf64.n ? (u->nonleaf64.ppn & 0x1ff) == 0x100 : true;
+}
+
+static uint64_t mpte_get_ppn(CPURISCVState *env, uint64_t mpte, int pn,
+ bool nlnapot)
+{
+ RISCVMXL mxl = riscv_cpu_mxl(env);
+ mpte_union_t *u = (mpte_union_t *)&mpte;
+
+ if (nlnapot) {
+ return deposit64(u->nonleaf64.ppn, 0, 9, pn & 0x1ff);
+ }
+ return (mxl == MXL_RV32) ? u->nonleaf32.ppn : u->nonleaf64.ppn;
+}
+
+/* Caller should assert i before call this interface */
+static int mpt_get_pn(hwaddr addr, int i, mpt_mode_t mode)
+{
+ if (mode == SMMPT34) {
+ return i == 0
+ ? extract64(addr, 15, 10)
+ : extract64(addr, 25, 9);
+ } else {
+ int offset = 16 + i * 9;
+ if ((mode == SMMPT64) && (i == 4)) {
+ return extract64(addr, offset, 12);
+ } else {
+ return extract64(addr, offset, 9);
+ }
+ }
+}
+
+/* Caller should assert i before call this interface */
+static int mpt_get_pi(hwaddr addr, int i, mpt_mode_t mode)
+{
+ if (mode == SMMPT34) {
+ return i == 0
+ ? extract64(addr, 12, 3)
+ : extract64(addr, 22, 3);
+ } else {
+ int offset = 16 + i * 9;
+ return extract64(addr, offset - 4, 4);
+ }
+}
+
+static bool smmpt_lookup(CPURISCVState *env, hwaddr addr, mpt_mode_t mode,
+ mpt_access_t *allowed_access,
+ MMUAccessType access_type)
+{
+ MemTxResult res;
+ MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
+ CPUState *cs = env_cpu(env);
+ hwaddr mpte_addr, base = (hwaddr)env->mptppn << PGSHIFT;
+ load_entry_fn *load_entry;
+ uint32_t mptesize, levels, xwr;
+ int pn, pi, pmp_prot, pmp_ret;
+ uint64_t mpte, perms;
+
+ switch (mode) {
+ case SMMPT34:
+ load_entry = &load_entry_32; levels = 2; mptesize = 4; break;
+ case SMMPT43:
+ load_entry = &load_entry_64; levels = 3; mptesize = 8; break;
+ break;
+ case SMMPT52:
+ load_entry = &load_entry_64; levels = 4; mptesize = 8; break;
+ case SMMPT64:
+ load_entry = &load_entry_64; levels = 5; mptesize = 8; break;
+ case SMMPTBARE:
+ *allowed_access = ACCESS_ALLOW_RWX;
+ return true;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+ for (int i = levels - 1; i >= 0 ; i--) {
+ /* 1. Get pn[i] as the mpt index */
+ pn = mpt_get_pn(addr, i, mode);
+ /* 2. Get mpte address and get mpte */
+ mpte_addr = base + pn * mptesize;
+ pmp_ret = get_physical_address_pmp(env, &pmp_prot, mpte_addr,
+ mptesize, MMU_DATA_LOAD, PRV_M);
+ if (pmp_ret != TRANSLATE_SUCCESS) {
+ return false;
+ }
+ mpte = load_entry(cs->as, mpte_addr, attrs, &res);
+ /* 3. Check valid bit and reserve bits of mpte */
+ if (!mpte_is_valid(mpte) || mpte_get_rsv(env, mpte)) {
+ return false;
+ }
+
+ /* 4. Process non-leaf node */
+ if (!mpte_is_leaf(mpte)) {
+ bool nlnapot = false;
+ if (i == 0) {
+ return false;
+ }
+ if (!mpte_check_nlnapot(env, mpte, &nlnapot)) {
+ return false;
+ }
+ base = mpte_get_ppn(env, mpte, pn, nlnapot) << PGSHIFT;
+ continue;
+ }
+
+ /* 5. Process leaf node */
+ pi = mpt_get_pi(addr, i, mode);
+ perms = mpte_get_perms(env, mpte);
+ xwr = (perms >> (pi * 3)) & 0x7;
+ switch (xwr) {
+ case ACCESS_ALLOW_R:
+ *allowed_access = ACCESS_ALLOW_R;
+ return access_type == MMU_DATA_LOAD;
+ case ACCESS_ALLOW_X:
+ *allowed_access = ACCESS_ALLOW_X;
+ return access_type == MMU_INST_FETCH;
+ case ACCESS_ALLOW_RX:
+ *allowed_access = ACCESS_ALLOW_R;
+ return (access_type == MMU_DATA_LOAD ||
+ access_type == MMU_INST_FETCH);
+ case ACCESS_ALLOW_RW:
+ *allowed_access = ACCESS_ALLOW_RW;
+ return (access_type == MMU_DATA_LOAD ||
+ access_type == MMU_DATA_STORE);
+ case ACCESS_ALLOW_RWX:
+ *allowed_access = ACCESS_ALLOW_RWX;
+ return true;
+ default:
+ return false;
+ }
+ }
+ return false;
+}
+
+bool smmpt_check_access(CPURISCVState *env, hwaddr addr,
+ mpt_access_t *allowed_access, MMUAccessType access_type)
+{
+ bool mpt_has_access;
+ mpt_mode_t mode = env->mptmode;
+
+ mpt_has_access = smmpt_lookup(env, addr, mode,
+ allowed_access, access_type);
+ return mpt_has_access;
+}
+
+/*
+ * Convert MPT access to TLB page privilege.
+ */
+int smmpt_access_to_page_prot(mpt_access_t mpt_access)
+{
+ int prot;
+ switch (mpt_access) {
+ case ACCESS_ALLOW_R:
+ prot = PAGE_READ;
+ break;
+ case ACCESS_ALLOW_X:
+ prot = PAGE_EXEC;
+ break;
+ case ACCESS_ALLOW_RX:
+ prot = PAGE_READ | PAGE_EXEC;
+ break;
+ case ACCESS_ALLOW_RW:
+ prot = PAGE_READ | PAGE_WRITE;
+ break;
+ case ACCESS_ALLOW_RWX:
+ prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ break;
+ default:
+ prot = 0;
+ break;
+ }
+
+ return prot;
+}
diff --git a/target/riscv/riscv_smmpt.h b/target/riscv/riscv_smmpt.h
index 74dcccf4be..0d0597f8eb 100644
--- a/target/riscv/riscv_smmpt.h
+++ b/target/riscv/riscv_smmpt.h
@@ -9,6 +9,9 @@
#ifndef RISCV_SMMPT_H
#define RISCV_SMMPT_H
+#include "cpu.h"
+#include "exec/mmu-access-type.h"
+
typedef enum {
SMMPTBARE = 0,
SMMPT34 = 1,
@@ -18,4 +21,16 @@ typedef enum {
SMMPTMAX
} mpt_mode_t;
+typedef enum {
+ ACCESS_ALLOW_R = 0b001,
+ ACCESS_ALLOW_X = 0b100,
+ ACCESS_ALLOW_RX = 0b101 ,
+ ACCESS_ALLOW_RW = 0b011,
+ ACCESS_ALLOW_RWX = 0b111,
+} mpt_access_t;
+
+int smmpt_access_to_page_prot(mpt_access_t mpt_access);
+bool smmpt_check_access(CPURISCVState *env, hwaddr addr,
+ mpt_access_t *allowed_access,
+ MMUAccessType access_type);
#endif
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 3/6] target/riscv: Integrate SMMPT checks into MMU and TLB fill
2025-09-18 6:19 [PATCH v2 0/6] target/riscv: Implement Smsdid and Smmpt extension LIU Zhiwei
2025-09-18 6:19 ` [PATCH v2 1/6] target/riscv: Add basic definitions and CSRs for SMMPT LIU Zhiwei
2025-09-18 6:19 ` [PATCH v2 2/6] target/riscv: Implement core SMMPT lookup logic LIU Zhiwei
@ 2025-09-18 6:19 ` LIU Zhiwei
2025-09-18 6:19 ` [PATCH v2 4/6] target/riscv: Implement SMMPT fence instructions LIU Zhiwei
` (2 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: LIU Zhiwei @ 2025-09-18 6:19 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, palmer, alistair.francis, dbarboza, liwei1518,
zhiwei_liu, Huang Tao, TANG Tiancheng
With the core MPT lookup logic in place, this patch integrates the
permission checks into QEMU's main MMU processing functions.
A new helper, `get_physical_address_mpt`, is introduced to check the
permissions for a given physical address against the MPT. This helper
is then called at two critical points:
1. During page table walks (`get_physical_address`): The physical
address of the Page Table Entry (PTE) itself is checked to ensure
the supervisor has permission to read it.
2. After successful address translation (`riscv_cpu_tlb_fill`): The final
guest-physical address is checked against the MPT before the access
is allowed to proceed.
This ensures that SMMPT protection is enforced for both the translation
process and the final memory access, as required by the specification.
Co-authored-by: Huang Tao <eric.huang@linux.alibaba.com>
Co-authored-by: TANG Tiancheng <lyndra@linux.alibaba.com>
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
target/riscv/cpu_helper.c | 81 +++++++++++++++++++++++++++++++++++++--
1 file changed, 77 insertions(+), 4 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 3479a62cc7..f8ca74ef61 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -1089,9 +1089,8 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en)
* @access_type: The type of MMU access
* @mode: Indicates current privilege level.
*/
-static int get_physical_address_pmp(CPURISCVState *env, int *prot, hwaddr addr,
- int size, MMUAccessType access_type,
- int mode)
+int get_physical_address_pmp(CPURISCVState *env, int *prot, hwaddr addr,
+ int size, MMUAccessType access_type, int mode)
{
pmp_priv_t pmp_priv;
bool pmp_has_privs;
@@ -1162,6 +1161,60 @@ static bool check_svukte_addr(CPURISCVState *env, vaddr addr)
return !high_bit;
}
+/*
+ * get_physical_address_mpt - check mpt permission for this physical address
+ *
+ * Lookup the Memory Protection Table and check permission for this
+ * physical address. Returns 0 if the permission checking was successful
+ *
+ * @env: CPURISCVState
+ * @prot: The returned protection attributes
+ * @addr: The physical address to be checked permission
+ * @access_type: The type of MMU access
+ * @mode: Indicates current privilege level.
+ */
+static int get_physical_address_mpt(CPURISCVState *env, int *prot, hwaddr addr,
+ MMUAccessType access_type, int mode)
+{
+ mpt_access_t mpt_access;
+ bool mpt_has_access;
+
+ /*
+ * If the extension is not supported or the mmpt.mode is Bare,
+ * there is no protection, return success.
+ */
+ if (!riscv_cpu_cfg(env)->ext_smmpt || env->mptmode == 0) {
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ return TRANSLATE_SUCCESS;
+ }
+
+ /*
+ * MPT is checked for all accesses to physical memory, unless the
+ * effective privilege mode is M.
+ *
+ * Data accesses in M-mode when the MPRV bit in mstatus is set and
+ * the MPP field in mstatus contains S or U are subject to MPT checks.
+ *
+ * In riscv_env_mmu_index, The MPRV and MPP bits are already checked and
+ * encoded to mmu_idx, So we do not need to check it here.
+ */
+ if (mode == PRV_M) {
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ return TRANSLATE_SUCCESS;
+ }
+
+ mpt_has_access = smmpt_check_access(env, addr,
+ &mpt_access, access_type);
+ if (!mpt_has_access) {
+ *prot = 0;
+ return TRANSLATE_MPT_FAIL;
+ }
+
+ *prot = smmpt_access_to_page_prot(mpt_access);
+
+ return TRANSLATE_SUCCESS;
+}
+
/*
* get_physical_address - get the physical address for this virtual address
*
@@ -1356,6 +1409,13 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
pte_addr = base + idx * ptesize;
}
+ int mpt_prot;
+ int mpt_ret = get_physical_address_mpt(env, &mpt_prot, pte_addr,
+ MMU_DATA_LOAD, PRV_S);
+ if (mpt_ret != TRANSLATE_SUCCESS) {
+ return TRANSLATE_MPT_FAIL;
+ }
+
int pmp_prot;
int pmp_ret = get_physical_address_pmp(env, &pmp_prot, pte_addr,
sxlen_bytes,
@@ -1766,7 +1826,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
CPURISCVState *env = &cpu->env;
vaddr im_address;
hwaddr pa = 0;
- int prot, prot2, prot_pmp;
+ int prot, prot2, prot_pmp, mpt_prot;
bool pmp_violation = false;
bool first_stage_error = true;
bool two_stage_lookup = mmuidx_2stage(mmu_idx);
@@ -1820,6 +1880,13 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
prot &= prot2;
if (ret == TRANSLATE_SUCCESS) {
+ ret = get_physical_address_mpt(env, &mpt_prot, pa,
+ access_type, mode);
+ qemu_log_mask(CPU_LOG_MMU,
+ "%s MPT address=" HWADDR_FMT_plx " ret %d prot"
+ " %d\n",
+ __func__, pa, ret, mpt_prot);
+ prot &= mpt_prot;
ret = get_physical_address_pmp(env, &prot_pmp, pa,
size, access_type, mode);
tlb_size = pmp_get_tlb_size(env, pa);
@@ -1855,6 +1922,12 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
__func__, address, ret, pa, prot);
if (ret == TRANSLATE_SUCCESS) {
+ ret = get_physical_address_mpt(env, &mpt_prot, pa,
+ access_type, mode);
+ qemu_log_mask(CPU_LOG_MMU,
+ "%s MPT address=" HWADDR_FMT_plx " ret %d prot %d\n",
+ __func__, pa, ret, mpt_prot);
+ prot &= mpt_prot;
ret = get_physical_address_pmp(env, &prot_pmp, pa,
size, access_type, mode);
tlb_size = pmp_get_tlb_size(env, pa);
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 4/6] target/riscv: Implement SMMPT fence instructions
2025-09-18 6:19 [PATCH v2 0/6] target/riscv: Implement Smsdid and Smmpt extension LIU Zhiwei
` (2 preceding siblings ...)
2025-09-18 6:19 ` [PATCH v2 3/6] target/riscv: Integrate SMMPT checks into MMU and TLB fill LIU Zhiwei
@ 2025-09-18 6:19 ` LIU Zhiwei
2025-09-18 6:19 ` [PATCH v2 5/6] target/riscv: Fix smrnmi isa alphabetical order LIU Zhiwei
2025-09-18 6:19 ` [PATCH v2 6/6] target/riscv: Enable SMMPT extension LIU Zhiwei
5 siblings, 0 replies; 11+ messages in thread
From: LIU Zhiwei @ 2025-09-18 6:19 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, palmer, alistair.francis, dbarboza, liwei1518,
zhiwei_liu, Huang Tao, TANG Tiancheng
This patch completes the SMMPT implementation by adding support for the
new fence instructions: `mfence.spa` and `minval.spa`.
According to the specification, these instructions act as memory ordering
fences for MPT updates. In QEMU's TCG model, this is conservatively
implemented by flushing the entire TLB, which ensures that any subsequent
memory accesses will re-evaluate permissions and see the effects of any prior
MPT modifications.
The instructions are privileged and will cause an illegal instruction
exception if executed outside of M-mode.
Co-authored-by: Huang Tao <eric.huang@linux.alibaba.com>
Co-authored-by: TANG Tiancheng <lyndra@linux.alibaba.com>
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
target/riscv/insn32.decode | 2 ++
.../riscv/insn_trans/trans_privileged.c.inc | 30 +++++++++++++++++++
2 files changed, 32 insertions(+)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index cd23b1f3a9..cf58f1beee 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -120,6 +120,8 @@ sret 0001000 00010 00000 000 00000 1110011
mret 0011000 00010 00000 000 00000 1110011
wfi 0001000 00101 00000 000 00000 1110011
sfence_vma 0001001 ..... ..... 000 00000 1110011 @sfence_vma
+mfence_spa 1000011 ..... ..... 000 00000 1110011 @sfence_vma
+minval_spa 0000011 ..... ..... 000 00000 1110011 @sfence_vma
# *** NMI ***
mnret 0111000 00010 00000 000 00000 1110011
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
index 8a62b4cfcd..5ec6bf5991 100644
--- a/target/riscv/insn_trans/trans_privileged.c.inc
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
@@ -160,3 +160,33 @@ static bool trans_sfence_vma(DisasContext *ctx, arg_sfence_vma *a)
#endif
return false;
}
+
+#define REQUIRE_SMSDID(ctx) do { \
+ if (!ctx->cfg_ptr->ext_smsdid) { \
+ return false; \
+ } \
+} while (0)
+
+static bool do_mfence_spa(DisasContext *ctx)
+{
+#ifndef CONFIG_USER_ONLY
+ REQUIRE_SMSDID(ctx);
+ if (ctx->priv != PRV_M) {
+ return false;
+ }
+ decode_save_opc(ctx, 0);
+ gen_helper_tlb_flush_all(tcg_env);
+ return true;
+#endif
+ return false;
+}
+
+static bool trans_mfence_spa(DisasContext *ctx, arg_mfence_spa *a)
+{
+ return do_mfence_spa(ctx);
+}
+
+static bool trans_minval_spa(DisasContext *ctx, arg_minval_spa *a)
+{
+ return do_mfence_spa(ctx);
+}
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 5/6] target/riscv: Fix smrnmi isa alphabetical order
2025-09-18 6:19 [PATCH v2 0/6] target/riscv: Implement Smsdid and Smmpt extension LIU Zhiwei
` (3 preceding siblings ...)
2025-09-18 6:19 ` [PATCH v2 4/6] target/riscv: Implement SMMPT fence instructions LIU Zhiwei
@ 2025-09-18 6:19 ` LIU Zhiwei
2025-10-12 17:33 ` Daniel Henrique Barboza
2025-09-18 6:19 ` [PATCH v2 6/6] target/riscv: Enable SMMPT extension LIU Zhiwei
5 siblings, 1 reply; 11+ messages in thread
From: LIU Zhiwei @ 2025-09-18 6:19 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, palmer, alistair.francis, dbarboza, liwei1518,
zhiwei_liu
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Suggested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
target/riscv/cpu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d055ddf462..ad5597c9ac 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -203,9 +203,9 @@ const RISCVIsaExtData isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(smcsrind, PRIV_VERSION_1_13_0, ext_smcsrind),
ISA_EXT_DATA_ENTRY(smdbltrp, PRIV_VERSION_1_13_0, ext_smdbltrp),
ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
- ISA_EXT_DATA_ENTRY(smrnmi, PRIV_VERSION_1_12_0, ext_smrnmi),
ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_13_0, ext_smmpm),
ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_13_0, ext_smnpm),
+ ISA_EXT_DATA_ENTRY(smrnmi, PRIV_VERSION_1_12_0, ext_smrnmi),
ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
ISA_EXT_DATA_ENTRY(ssccfg, PRIV_VERSION_1_13_0, ext_ssccfg),
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 6/6] target/riscv: Enable SMMPT extension
2025-09-18 6:19 [PATCH v2 0/6] target/riscv: Implement Smsdid and Smmpt extension LIU Zhiwei
` (4 preceding siblings ...)
2025-09-18 6:19 ` [PATCH v2 5/6] target/riscv: Fix smrnmi isa alphabetical order LIU Zhiwei
@ 2025-09-18 6:19 ` LIU Zhiwei
2025-10-12 17:33 ` Daniel Henrique Barboza
5 siblings, 1 reply; 11+ messages in thread
From: LIU Zhiwei @ 2025-09-18 6:19 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, palmer, alistair.francis, dbarboza, liwei1518,
zhiwei_liu, Huang Tao, TANG Tiancheng
Co-authored-by: Huang Tao <eric.huang@linux.alibaba.com>
Co-authored-by: TANG Tiancheng <lyndra@linux.alibaba.com>
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
---
target/riscv/cpu.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ad5597c9ac..959024a0c5 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -204,8 +204,10 @@ const RISCVIsaExtData isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(smdbltrp, PRIV_VERSION_1_13_0, ext_smdbltrp),
ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_13_0, ext_smmpm),
+ ISA_EXT_DATA_ENTRY(smmpt, PRIV_VERSION_1_13_0, ext_smmpt),
ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_13_0, ext_smnpm),
ISA_EXT_DATA_ENTRY(smrnmi, PRIV_VERSION_1_12_0, ext_smrnmi),
+ ISA_EXT_DATA_ENTRY(smsdid, PRIV_VERSION_1_13_0, ext_smsdid),
ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
ISA_EXT_DATA_ENTRY(ssccfg, PRIV_VERSION_1_13_0, ext_ssccfg),
@@ -1371,6 +1373,8 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
/* These are experimental so mark with 'x-' */
const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
+ MULTI_EXT_CFG_BOOL("x-smmpt", ext_smmpt, false),
+ MULTI_EXT_CFG_BOOL("x-smsdid", ext_smsdid, false),
MULTI_EXT_CFG_BOOL("x-svukte", ext_svukte, false),
{ },
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/6] target/riscv: Add basic definitions and CSRs for SMMPT
2025-09-18 6:19 ` [PATCH v2 1/6] target/riscv: Add basic definitions and CSRs for SMMPT LIU Zhiwei
@ 2025-10-12 17:32 ` Daniel Henrique Barboza
0 siblings, 0 replies; 11+ messages in thread
From: Daniel Henrique Barboza @ 2025-10-12 17:32 UTC (permalink / raw)
To: LIU Zhiwei, qemu-devel
Cc: qemu-riscv, palmer, alistair.francis, liwei1518, Huang Tao,
TANG Tiancheng
On 9/18/25 3:19 AM, LIU Zhiwei wrote:
> This patch lays the groundwork for the SMMPT (Supervisor Domains Access
> Protection) extension by introducing its fundamental components.
>
> It adds:
> - New CPU configuration flags, `ext_smmpt` and `ext_smsdid`, to enable
> the extension.
> - Bit-field definitions for the `mmpt` CSR in `cpu_bits.h`.
> - The `mmpt` and `msdcfg` CSR numbers and their read/write handlers in
> `csr.c`.
> - New fields in `CPUArchState` to store the state of these new CSRs.
> - A new translation failure reason `TRANSLATE_MPT_FAIL`.
>
> This provides the necessary infrastructure for the core MPT logic and
> MMU integration that will follow.
>
> Co-authored-by: Huang Tao <eric.huang@linux.alibaba.com>
> Co-authored-by: TANG Tiancheng <lyndra@linux.alibaba.com>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> target/riscv/cpu.h | 9 ++-
> target/riscv/cpu_bits.h | 27 +++++++++
> target/riscv/cpu_cfg_fields.h.inc | 2 +
> target/riscv/csr.c | 95 +++++++++++++++++++++++++++++++
> target/riscv/riscv_smmpt.h | 21 +++++++
> 5 files changed, 153 insertions(+), 1 deletion(-)
> create mode 100644 target/riscv/riscv_smmpt.h
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 4a862da615..fa7b804cb3 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -130,7 +130,8 @@ enum {
> TRANSLATE_SUCCESS,
> TRANSLATE_FAIL,
> TRANSLATE_PMP_FAIL,
> - TRANSLATE_G_STAGE_FAIL
> + TRANSLATE_G_STAGE_FAIL,
> + TRANSLATE_MPT_FAIL
> };
>
> /* Extension context status */
> @@ -180,6 +181,7 @@ extern RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[];
> #if !defined(CONFIG_USER_ONLY)
> #include "pmp.h"
> #include "debug.h"
> +#include "riscv_smmpt.h"
> #endif
>
> #define RV_VLEN_MAX 1024
> @@ -486,6 +488,11 @@ struct CPUArchState {
> uint64_t hstateen[SMSTATEEN_MAX_COUNT];
> uint64_t sstateen[SMSTATEEN_MAX_COUNT];
> uint64_t henvcfg;
> + /* Smsdid */
> + uint32_t mptmode;
> + uint32_t sdid;
> + uint64_t mptppn;
> + uint32_t msdcfg;
> #endif
>
> /* Fields from here on are preserved across CPU reset. */
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index b62dd82fe7..c6a34863d1 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -1164,4 +1164,31 @@ typedef enum CTRType {
> #define MCONTEXT64 0x0000000000001FFFULL
> #define MCONTEXT32_HCONTEXT 0x0000007F
> #define MCONTEXT64_HCONTEXT 0x0000000000003FFFULL
> +
> +/* Smsdid */
> +#define CSR_MMPT 0xbc0
> +#define CSR_MSDCFG 0xbd1
> +
> +#define MMPT_MODE_MASK_32 0xC0000000
> +#define MMPT_SDID_MASK_32 0x3F000000
> +#define MMPT_PPN_MASK_32 0x003FFFFF
> +
> +#define MMPT_MODE_SHIFT_32 30
> +#define MMPT_SDID_SHIFT_32 24
> +
> +#define MMPT_MODE_MASK_64 0xF000000000000000ULL
> +#define MMPT_SDID_MASK_64 0x0FC0000000000000ULL
> +#define MMPT_PPN_MASK_64 0x000FFFFFFFFFFFFFULL
> +
> +#define MPTE_L3_VALID 0x0000100000000000ULL
> +#define MPTE_L3_RESERVED 0xFFFFE00000000000ULL
> +
> +#define MPTE_L2_RESERVED_64 0xFFFF800000000000ULL
> +#define MPTE_L2_RESERVED_32 0xFE000000
> +
> +#define MPTE_L1_RESERVED_64 0xFFFFFFFF00000000ULL
> +#define MPTE_L1_RESERVED_32 0xFFFF0000
> +
> +#define MMPT_MODE_SHIFT_64 60
> +#define MMPT_SDID_SHIFT_64 54
> #endif
> diff --git a/target/riscv/cpu_cfg_fields.h.inc b/target/riscv/cpu_cfg_fields.h.inc
> index e2d116f0df..8c8a4ac236 100644
> --- a/target/riscv/cpu_cfg_fields.h.inc
> +++ b/target/riscv/cpu_cfg_fields.h.inc
> @@ -60,6 +60,8 @@ BOOL_FIELD(ext_svpbmt)
> BOOL_FIELD(ext_svrsw60t59b)
> BOOL_FIELD(ext_svvptc)
> BOOL_FIELD(ext_svukte)
> +BOOL_FIELD(ext_smmpt)
> +BOOL_FIELD(ext_smsdid)
> BOOL_FIELD(ext_zdinx)
> BOOL_FIELD(ext_zaamo)
> BOOL_FIELD(ext_zacas)
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 8842e07a73..e7e85b4310 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -793,6 +793,15 @@ static RISCVException rnmi(CPURISCVState *env, int csrno)
>
> return RISCV_EXCP_ILLEGAL_INST;
> }
> +
> +static RISCVException smsdid(CPURISCVState *env, int csrno)
> +{
> + if (riscv_cpu_cfg(env)->ext_smsdid) {
> + return RISCV_EXCP_NONE;
> + }
> +
> + return RISCV_EXCP_ILLEGAL_INST;
> +}
> #endif
>
> static RISCVException seed(CPURISCVState *env, int csrno)
> @@ -5470,6 +5479,89 @@ static RISCVException write_mnstatus(CPURISCVState *env, int csrno,
> return RISCV_EXCP_NONE;
> }
>
> +static RISCVException read_mmpt(CPURISCVState *env, int csrno,
> + target_ulong *val)
> +{
> + if (riscv_cpu_xlen(env) == 32) {
> + uint32_t value = 0;
> + value |= env->mptmode << MMPT_MODE_SHIFT_32;
> + value |= (env->sdid << MMPT_SDID_SHIFT_32) & MMPT_SDID_MASK_32;
> + value |= env->mptppn & MMPT_PPN_MASK_32;
> + *val = value;
> + } else if (riscv_cpu_xlen(env) == 64) {
> + uint64_t value_64 = 0;
> + uint32_t mode_value = env->mptmode;
> + /* mpt_mode_t convert to mmpt.mode value */
> + if (mode_value) {
> + mode_value -= SMMPT43 - SMMPT34;
> + }
> + value_64 |= (uint64_t)mode_value << MMPT_MODE_SHIFT_64;
> + value_64 |= ((uint64_t)env->sdid << MMPT_SDID_SHIFT_64)
> + & MMPT_SDID_MASK_64;
> + value_64 |= (uint64_t)env->mptppn & MMPT_PPN_MASK_64;
> + *val = value_64;
> + } else {
> + return RISCV_EXCP_ILLEGAL_INST;
> + }
> + return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException write_mmpt(CPURISCVState *env, int csrno,
> + target_ulong val, uintptr_t ra)
> +{
> + uint32_t mode_value = 0;
> + if (!riscv_cpu_cfg(env)->ext_smmpt) {
> + goto set_remaining_fields_zero;
> + }
> +
> + if (riscv_cpu_xlen(env) == 32) {
> + mode_value = (val & MMPT_MODE_MASK_32) >> MMPT_MODE_SHIFT_32;
> + /* If mode is bare, the remaining fields in mmpt must be zero */
> + if (mode_value == SMMPTBARE) {
> + goto set_remaining_fields_zero;
> + } else if (mode_value <= SMMPT34) {
> + /* Only write the legal value */
> + env->mptmode = mode_value;
> + }
> + env->sdid = (val & MMPT_SDID_MASK_32) >> MMPT_SDID_SHIFT_32;
> + env->mptppn = val & MMPT_PPN_MASK_32;
> + } else if (riscv_cpu_xlen(env) == 64) {
> + mode_value = (val & MMPT_MODE_MASK_64) >> MMPT_MODE_SHIFT_64;
> + if (mode_value == SMMPTBARE) {
> + goto set_remaining_fields_zero;
> + } else if (mode_value < SMMPTMAX) {
> + /* convert to mpt_mode_t */
> + mode_value += SMMPT43 - SMMPT34;
> + env->mptmode = mode_value;
> + }
> + env->sdid = (val & MMPT_SDID_MASK_64) >> MMPT_SDID_SHIFT_64;
> + env->mptppn = val & MMPT_PPN_MASK_64;
> + } else {
> + return RISCV_EXCP_ILLEGAL_INST;
> + }
> + return RISCV_EXCP_NONE;
> +
> +set_remaining_fields_zero:
> + env->sdid = 0;
> + env->mptmode = SMMPTBARE;
> + env->mptppn = 0;
> + return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException read_msdcfg(CPURISCVState *env, int csrno,
> + target_ulong *val)
> +{
> + *val = env->msdcfg;
> + return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException write_msdcfg(CPURISCVState *env, int csrno,
> + target_ulong val, uintptr_t ra)
> +{
> + env->msdcfg = val;
> + return RISCV_EXCP_NONE;
> +}
> +
> #endif
>
> /* Crypto Extension */
> @@ -6666,6 +6758,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
> write_mhpmcounterh },
> [CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf,
> .min_priv_ver = PRIV_VERSION_1_12_0 },
> + /* Supervisor Domain Identifier and Protection Registers */
> + [CSR_MMPT] = { "mmpt", smsdid, read_mmpt, write_mmpt },
> + [CSR_MSDCFG] = { "msdcfg", smsdid, read_msdcfg, write_msdcfg },
>
> #endif /* !CONFIG_USER_ONLY */
> };
> diff --git a/target/riscv/riscv_smmpt.h b/target/riscv/riscv_smmpt.h
> new file mode 100644
> index 0000000000..74dcccf4be
> --- /dev/null
> +++ b/target/riscv/riscv_smmpt.h
> @@ -0,0 +1,21 @@
> +/*
> + * QEMU RISC-V Smmpt (Memory Protection Table)
> + *
> + * Copyright (c) 2024 Alibaba Group. All rights reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef RISCV_SMMPT_H
> +#define RISCV_SMMPT_H
> +
> +typedef enum {
> + SMMPTBARE = 0,
> + SMMPT34 = 1,
> + SMMPT43 = 2,
> + SMMPT52 = 3,
> + SMMPT64 = 4,
> + SMMPTMAX
> +} mpt_mode_t;
> +
> +#endif
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/6] target/riscv: Implement core SMMPT lookup logic
2025-09-18 6:19 ` [PATCH v2 2/6] target/riscv: Implement core SMMPT lookup logic LIU Zhiwei
@ 2025-10-12 17:32 ` Daniel Henrique Barboza
0 siblings, 0 replies; 11+ messages in thread
From: Daniel Henrique Barboza @ 2025-10-12 17:32 UTC (permalink / raw)
To: LIU Zhiwei, qemu-devel
Cc: qemu-riscv, palmer, alistair.francis, liwei1518, Huang Tao,
TANG Tiancheng
On 9/18/25 3:19 AM, LIU Zhiwei wrote:
> This patch introduces the core implementation for the Memory Protection Table
> (MPT) walk, which is the central mechanism of the SMMPT extension.
>
> A new file, `riscv_smmpt.c`, is added to encapsulate the MPT logic. It
> implements the `smmpt_lookup()` function, which performs a multi-level
> page table-like walk starting from the physical address specified in the
> `mptppn` CSR field. This walk determines the access permissions (read,
> write, execute) for a given physical address.
>
> The implementation supports various SMMPT modes (SMMPT34, SMMPT43, etc.) and
> correctly handles leaf and non-leaf entries, including reserved bit
> checks. Helper functions for parsing MPT entries and converting access
> permissions are also included in the new `riscv_smmpt.h` header.
>
> Co-authored-by: Huang Tao <eric.huang@linux.alibaba.com>
> Co-authored-by: TANG Tiancheng <lyndra@linux.alibaba.com>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> target/riscv/meson.build | 1 +
> target/riscv/pmp.h | 3 +
> target/riscv/riscv_smmpt.c | 274 +++++++++++++++++++++++++++++++++++++
> target/riscv/riscv_smmpt.h | 15 ++
> 4 files changed, 293 insertions(+)
> create mode 100644 target/riscv/riscv_smmpt.c
>
> diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> index a4bd61e52a..e85b534a64 100644
> --- a/target/riscv/meson.build
> +++ b/target/riscv/meson.build
> @@ -29,6 +29,7 @@ riscv_system_ss = ss.source_set()
> riscv_system_ss.add(files(
> 'arch_dump.c',
> 'pmp.c',
> + 'riscv_smmpt.c',
> 'debug.c',
> 'monitor.c',
> 'machine.c',
> diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
> index 271cf24169..d9c5e74345 100644
> --- a/target/riscv/pmp.h
> +++ b/target/riscv/pmp.h
> @@ -85,6 +85,9 @@ void pmp_update_rule_nums(CPURISCVState *env);
> uint32_t pmp_get_num_rules(CPURISCVState *env);
> int pmp_priv_to_page_prot(pmp_priv_t pmp_priv);
> void pmp_unlock_entries(CPURISCVState *env);
> +int get_physical_address_pmp(CPURISCVState *env, int *prot, hwaddr addr,
> + int size, MMUAccessType access_type,
> + int mode);
>
> #define MSECCFG_MML_ISSET(env) get_field(env->mseccfg, MSECCFG_MML)
> #define MSECCFG_MMWP_ISSET(env) get_field(env->mseccfg, MSECCFG_MMWP)
> diff --git a/target/riscv/riscv_smmpt.c b/target/riscv/riscv_smmpt.c
> new file mode 100644
> index 0000000000..b7b47c5ae1
> --- /dev/null
> +++ b/target/riscv/riscv_smmpt.c
> @@ -0,0 +1,274 @@
> +/*
> + * QEMU RISC-V Smmpt (Memory Protection Table)
> + *
> + * Copyright (c) 2024 Alibaba Group. All rights reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "riscv_smmpt.h"
> +#include "pmp.h"
> +#include "system/memory.h"
> +
> +typedef uint64_t load_entry_fn(AddressSpace *, hwaddr,
> + MemTxAttrs, MemTxResult *);
> +
> +static uint64_t load_entry_32(AddressSpace *as, hwaddr addr,
> + MemTxAttrs attrs, MemTxResult *result)
> +{
> + return address_space_ldl(as, addr, attrs, result);
> +}
> +
> +static uint64_t load_entry_64(AddressSpace *as, hwaddr addr,
> + MemTxAttrs attrs, MemTxResult *result)
> +{
> + return address_space_ldq(as, addr, attrs, result);
> +}
> +
> +typedef union {
> + uint64_t raw;
> + struct {
> + uint32_t v:1;
> + uint32_t l:1;
> + uint32_t rsv1:5;
> + uint32_t perms:24;
> + uint32_t n:1;
> + } leaf32;
> + struct {
> + uint32_t v:1;
> + uint32_t l:1;
> + uint32_t rsv1:8;
> + uint32_t ppn:22;
> + } nonleaf32;
> + struct {
> + uint64_t v:1;
> + uint64_t l:1;
> + uint64_t rsv1:8;
> + uint64_t perms:48;
> + uint64_t rsv2:5;
> + uint64_t n:1;
> + } leaf64;
> + struct {
> + uint64_t v:1;
> + uint64_t l:1;
> + uint64_t rsv1:8;
> + uint64_t ppn:52;
> + uint64_t rsv2:1;
> + uint64_t n:1;
> + } nonleaf64;
> +} mpte_union_t;
> +
> +static inline bool mpte_is_leaf(uint64_t mpte)
> +{
> + return mpte & 0x2;
> +}
> +
> +static inline bool mpte_is_valid(uint64_t mpte)
> +{
> + return mpte & 0x1;
> +}
> +
> +static uint64_t mpte_get_rsv(CPURISCVState *env, uint64_t mpte)
> +{
> + RISCVMXL mxl = riscv_cpu_mxl(env);
> + bool leaf = mpte_is_leaf(mpte);
> + mpte_union_t *u = (mpte_union_t *)&mpte;
> +
> + if (mxl == MXL_RV32) {
> + return leaf ? u->leaf32.rsv1 : u->nonleaf32.rsv1;
> + }
> + return leaf ? (u->leaf64.rsv1 << 5) | u->leaf64.rsv2
> + : (u->nonleaf64.rsv1 << 1) | u->nonleaf64.rsv2;
> +}
> +
> +static uint64_t mpte_get_perms(CPURISCVState *env, uint64_t mpte)
> +{
> + RISCVMXL mxl = riscv_cpu_mxl(env);
> + mpte_union_t *u = (mpte_union_t *)&mpte;
> +
> + return (mxl == MXL_RV32) ? u->leaf32.perms : u->leaf64.perms;
> +}
> +
> +static bool mpte_check_nlnapot(CPURISCVState *env, uint64_t mpte, bool *nlnapot)
> +{
> + RISCVMXL mxl = riscv_cpu_mxl(env);
> + mpte_union_t *u = (mpte_union_t *)&mpte;
> + if (mxl == MXL_RV32) {
> + *nlnapot = false;
> + return true;
> + }
> + *nlnapot = u->nonleaf64.n;
> + return u->nonleaf64.n ? (u->nonleaf64.ppn & 0x1ff) == 0x100 : true;
> +}
> +
> +static uint64_t mpte_get_ppn(CPURISCVState *env, uint64_t mpte, int pn,
> + bool nlnapot)
> +{
> + RISCVMXL mxl = riscv_cpu_mxl(env);
> + mpte_union_t *u = (mpte_union_t *)&mpte;
> +
> + if (nlnapot) {
> + return deposit64(u->nonleaf64.ppn, 0, 9, pn & 0x1ff);
> + }
> + return (mxl == MXL_RV32) ? u->nonleaf32.ppn : u->nonleaf64.ppn;
> +}
> +
> +/* Caller should assert i before call this interface */
> +static int mpt_get_pn(hwaddr addr, int i, mpt_mode_t mode)
> +{
> + if (mode == SMMPT34) {
> + return i == 0
> + ? extract64(addr, 15, 10)
> + : extract64(addr, 25, 9);
> + } else {
> + int offset = 16 + i * 9;
> + if ((mode == SMMPT64) && (i == 4)) {
> + return extract64(addr, offset, 12);
> + } else {
> + return extract64(addr, offset, 9);
> + }
> + }
> +}
> +
> +/* Caller should assert i before call this interface */
> +static int mpt_get_pi(hwaddr addr, int i, mpt_mode_t mode)
> +{
> + if (mode == SMMPT34) {
> + return i == 0
> + ? extract64(addr, 12, 3)
> + : extract64(addr, 22, 3);
> + } else {
> + int offset = 16 + i * 9;
> + return extract64(addr, offset - 4, 4);
> + }
> +}
> +
> +static bool smmpt_lookup(CPURISCVState *env, hwaddr addr, mpt_mode_t mode,
> + mpt_access_t *allowed_access,
> + MMUAccessType access_type)
> +{
> + MemTxResult res;
> + MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
> + CPUState *cs = env_cpu(env);
> + hwaddr mpte_addr, base = (hwaddr)env->mptppn << PGSHIFT;
> + load_entry_fn *load_entry;
> + uint32_t mptesize, levels, xwr;
> + int pn, pi, pmp_prot, pmp_ret;
> + uint64_t mpte, perms;
> +
> + switch (mode) {
> + case SMMPT34:
> + load_entry = &load_entry_32; levels = 2; mptesize = 4; break;
> + case SMMPT43:
> + load_entry = &load_entry_64; levels = 3; mptesize = 8; break;
> + break;
> + case SMMPT52:
> + load_entry = &load_entry_64; levels = 4; mptesize = 8; break;
> + case SMMPT64:
> + load_entry = &load_entry_64; levels = 5; mptesize = 8; break;
> + case SMMPTBARE:
> + *allowed_access = ACCESS_ALLOW_RWX;
> + return true;
> + default:
> + g_assert_not_reached();
> + break;
> + }
> + for (int i = levels - 1; i >= 0 ; i--) {
> + /* 1. Get pn[i] as the mpt index */
> + pn = mpt_get_pn(addr, i, mode);
> + /* 2. Get mpte address and get mpte */
> + mpte_addr = base + pn * mptesize;
> + pmp_ret = get_physical_address_pmp(env, &pmp_prot, mpte_addr,
> + mptesize, MMU_DATA_LOAD, PRV_M);
> + if (pmp_ret != TRANSLATE_SUCCESS) {
> + return false;
> + }
> + mpte = load_entry(cs->as, mpte_addr, attrs, &res);
> + /* 3. Check valid bit and reserve bits of mpte */
> + if (!mpte_is_valid(mpte) || mpte_get_rsv(env, mpte)) {
> + return false;
> + }
> +
> + /* 4. Process non-leaf node */
> + if (!mpte_is_leaf(mpte)) {
> + bool nlnapot = false;
> + if (i == 0) {
> + return false;
> + }
> + if (!mpte_check_nlnapot(env, mpte, &nlnapot)) {
> + return false;
> + }
> + base = mpte_get_ppn(env, mpte, pn, nlnapot) << PGSHIFT;
> + continue;
> + }
> +
> + /* 5. Process leaf node */
> + pi = mpt_get_pi(addr, i, mode);
> + perms = mpte_get_perms(env, mpte);
> + xwr = (perms >> (pi * 3)) & 0x7;
> + switch (xwr) {
> + case ACCESS_ALLOW_R:
> + *allowed_access = ACCESS_ALLOW_R;
> + return access_type == MMU_DATA_LOAD;
> + case ACCESS_ALLOW_X:
> + *allowed_access = ACCESS_ALLOW_X;
> + return access_type == MMU_INST_FETCH;
> + case ACCESS_ALLOW_RX:
> + *allowed_access = ACCESS_ALLOW_R;
> + return (access_type == MMU_DATA_LOAD ||
> + access_type == MMU_INST_FETCH);
> + case ACCESS_ALLOW_RW:
> + *allowed_access = ACCESS_ALLOW_RW;
> + return (access_type == MMU_DATA_LOAD ||
> + access_type == MMU_DATA_STORE);
> + case ACCESS_ALLOW_RWX:
> + *allowed_access = ACCESS_ALLOW_RWX;
> + return true;
> + default:
> + return false;
> + }
> + }
> + return false;
> +}
> +
> +bool smmpt_check_access(CPURISCVState *env, hwaddr addr,
> + mpt_access_t *allowed_access, MMUAccessType access_type)
> +{
> + bool mpt_has_access;
> + mpt_mode_t mode = env->mptmode;
> +
> + mpt_has_access = smmpt_lookup(env, addr, mode,
> + allowed_access, access_type);
> + return mpt_has_access;
> +}
> +
> +/*
> + * Convert MPT access to TLB page privilege.
> + */
> +int smmpt_access_to_page_prot(mpt_access_t mpt_access)
> +{
> + int prot;
> + switch (mpt_access) {
> + case ACCESS_ALLOW_R:
> + prot = PAGE_READ;
> + break;
> + case ACCESS_ALLOW_X:
> + prot = PAGE_EXEC;
> + break;
> + case ACCESS_ALLOW_RX:
> + prot = PAGE_READ | PAGE_EXEC;
> + break;
> + case ACCESS_ALLOW_RW:
> + prot = PAGE_READ | PAGE_WRITE;
> + break;
> + case ACCESS_ALLOW_RWX:
> + prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
> + break;
> + default:
> + prot = 0;
> + break;
> + }
> +
> + return prot;
> +}
> diff --git a/target/riscv/riscv_smmpt.h b/target/riscv/riscv_smmpt.h
> index 74dcccf4be..0d0597f8eb 100644
> --- a/target/riscv/riscv_smmpt.h
> +++ b/target/riscv/riscv_smmpt.h
> @@ -9,6 +9,9 @@
> #ifndef RISCV_SMMPT_H
> #define RISCV_SMMPT_H
>
> +#include "cpu.h"
> +#include "exec/mmu-access-type.h"
> +
> typedef enum {
> SMMPTBARE = 0,
> SMMPT34 = 1,
> @@ -18,4 +21,16 @@ typedef enum {
> SMMPTMAX
> } mpt_mode_t;
>
> +typedef enum {
> + ACCESS_ALLOW_R = 0b001,
> + ACCESS_ALLOW_X = 0b100,
> + ACCESS_ALLOW_RX = 0b101 ,
> + ACCESS_ALLOW_RW = 0b011,
> + ACCESS_ALLOW_RWX = 0b111,
> +} mpt_access_t;
> +
> +int smmpt_access_to_page_prot(mpt_access_t mpt_access);
> +bool smmpt_check_access(CPURISCVState *env, hwaddr addr,
> + mpt_access_t *allowed_access,
> + MMUAccessType access_type);
> #endif
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 5/6] target/riscv: Fix smrnmi isa alphabetical order
2025-09-18 6:19 ` [PATCH v2 5/6] target/riscv: Fix smrnmi isa alphabetical order LIU Zhiwei
@ 2025-10-12 17:33 ` Daniel Henrique Barboza
0 siblings, 0 replies; 11+ messages in thread
From: Daniel Henrique Barboza @ 2025-10-12 17:33 UTC (permalink / raw)
To: LIU Zhiwei, qemu-devel; +Cc: qemu-riscv, palmer, alistair.francis, liwei1518
On 9/18/25 3:19 AM, LIU Zhiwei wrote:
> Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
> Suggested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> target/riscv/cpu.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index d055ddf462..ad5597c9ac 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -203,9 +203,9 @@ const RISCVIsaExtData isa_edata_arr[] = {
> ISA_EXT_DATA_ENTRY(smcsrind, PRIV_VERSION_1_13_0, ext_smcsrind),
> ISA_EXT_DATA_ENTRY(smdbltrp, PRIV_VERSION_1_13_0, ext_smdbltrp),
> ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
> - ISA_EXT_DATA_ENTRY(smrnmi, PRIV_VERSION_1_12_0, ext_smrnmi),
> ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_13_0, ext_smmpm),
> ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_13_0, ext_smnpm),
> + ISA_EXT_DATA_ENTRY(smrnmi, PRIV_VERSION_1_12_0, ext_smrnmi),
> ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
> ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
> ISA_EXT_DATA_ENTRY(ssccfg, PRIV_VERSION_1_13_0, ext_ssccfg),
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 6/6] target/riscv: Enable SMMPT extension
2025-09-18 6:19 ` [PATCH v2 6/6] target/riscv: Enable SMMPT extension LIU Zhiwei
@ 2025-10-12 17:33 ` Daniel Henrique Barboza
0 siblings, 0 replies; 11+ messages in thread
From: Daniel Henrique Barboza @ 2025-10-12 17:33 UTC (permalink / raw)
To: LIU Zhiwei, qemu-devel
Cc: qemu-riscv, palmer, alistair.francis, liwei1518, Huang Tao,
TANG Tiancheng
On 9/18/25 3:19 AM, LIU Zhiwei wrote:
> Co-authored-by: Huang Tao <eric.huang@linux.alibaba.com>
> Co-authored-by: TANG Tiancheng <lyndra@linux.alibaba.com>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> target/riscv/cpu.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index ad5597c9ac..959024a0c5 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -204,8 +204,10 @@ const RISCVIsaExtData isa_edata_arr[] = {
> ISA_EXT_DATA_ENTRY(smdbltrp, PRIV_VERSION_1_13_0, ext_smdbltrp),
> ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
> ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_13_0, ext_smmpm),
> + ISA_EXT_DATA_ENTRY(smmpt, PRIV_VERSION_1_13_0, ext_smmpt),
> ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_13_0, ext_smnpm),
> ISA_EXT_DATA_ENTRY(smrnmi, PRIV_VERSION_1_12_0, ext_smrnmi),
> + ISA_EXT_DATA_ENTRY(smsdid, PRIV_VERSION_1_13_0, ext_smsdid),
> ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
> ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
> ISA_EXT_DATA_ENTRY(ssccfg, PRIV_VERSION_1_13_0, ext_ssccfg),
> @@ -1371,6 +1373,8 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
>
> /* These are experimental so mark with 'x-' */
> const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
> + MULTI_EXT_CFG_BOOL("x-smmpt", ext_smmpt, false),
> + MULTI_EXT_CFG_BOOL("x-smsdid", ext_smsdid, false),
> MULTI_EXT_CFG_BOOL("x-svukte", ext_svukte, false),
>
> { },
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2025-10-12 17:34 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-18 6:19 [PATCH v2 0/6] target/riscv: Implement Smsdid and Smmpt extension LIU Zhiwei
2025-09-18 6:19 ` [PATCH v2 1/6] target/riscv: Add basic definitions and CSRs for SMMPT LIU Zhiwei
2025-10-12 17:32 ` Daniel Henrique Barboza
2025-09-18 6:19 ` [PATCH v2 2/6] target/riscv: Implement core SMMPT lookup logic LIU Zhiwei
2025-10-12 17:32 ` Daniel Henrique Barboza
2025-09-18 6:19 ` [PATCH v2 3/6] target/riscv: Integrate SMMPT checks into MMU and TLB fill LIU Zhiwei
2025-09-18 6:19 ` [PATCH v2 4/6] target/riscv: Implement SMMPT fence instructions LIU Zhiwei
2025-09-18 6:19 ` [PATCH v2 5/6] target/riscv: Fix smrnmi isa alphabetical order LIU Zhiwei
2025-10-12 17:33 ` Daniel Henrique Barboza
2025-09-18 6:19 ` [PATCH v2 6/6] target/riscv: Enable SMMPT extension LIU Zhiwei
2025-10-12 17:33 ` Daniel Henrique Barboza
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).