[PATCH v8 05/11] target/riscv: Implement SMMPT fence instructions

LIU Zhiwei <[email protected]> Fri, 24 Jul 2026 04:03:19 +0800
Newsgroups org.nongnu.qemu-riscv,org.nongnu.qemu-devel
Message-ID <[email protected]>
This patch completes the SMMPT implementation by adding support for the
new fence instructions: `mfence.pa` and `minval.pa`.

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 <[email protected]>
Co-authored-by: TANG Tiancheng <[email protected]>
Signed-off-by: LIU Zhiwei <[email protected]>
---
 target/riscv/insn32.decode                    |  2 ++
 .../tcg/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 21272fdb50..f0917b7696 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_pa   0011001    ..... ..... 000 00000 1110011 @sfence_vma
+minval_pa   0011011    ..... ..... 000 00000 1110011 @sfence_vma
 
 # *** NMI ***
 mnret       0111000    00010 00000 000 00000 1110011
diff --git a/target/riscv/tcg/insn_trans/trans_privileged.c.inc b/target/riscv/tcg/insn_trans/trans_privileged.c.inc
index a8eaccef67..67f2e56034 100644
--- a/target/riscv/tcg/insn_trans/trans_privileged.c.inc
+++ b/target/riscv/tcg/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_pa(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_pa(DisasContext *ctx, arg_mfence_pa *a)
+{
+    return do_mfence_pa(ctx);
+}
+
+static bool trans_minval_pa(DisasContext *ctx, arg_minval_pa *a)
+{
+    return do_mfence_pa(ctx);
+}
-- 
2.43.0