On 2026/10/9 上午11:05, SignKirigami wrote:
Add MMU_GUEST_IDX and MMU_GUEST_DA_IDX. Provide is_guest_mmu idx() and
mmu_idx_to_plv to calculate plv with new mmu_idx.

Signed-off-by: SignKirigami <[email protected]>
Signed-off-by: Hengyu Yu <[email protected]>
---
  target/loongarch/cpu.h                         | 18 ++++++++++++++++++
  .../tcg/insn_trans/trans_privileged.c.inc      |  2 +-
  target/loongarch/tcg/tcg_cpu.c                 |  7 +++++++
  target/loongarch/tcg/translate.c               |  3 +++
  4 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 183210efd8..9eea1badaf 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -513,6 +513,24 @@ struct LoongArchCPUClass {
  #define MMU_KERNEL_IDX   MMU_PLV_KERNEL
  #define MMU_USER_IDX     MMU_PLV_USER
  #define MMU_DA_IDX       4
+#define MMU_GUEST_IDX    5
+#define MMU_GUEST_DA_IDX 9
how about replace constant 9 with (MMU_DA_IDX + MMU_GUEST_DA_IDX).

+
+static inline bool is_guest_mmu_idx(int mmu_idx)
+{
+    return mmu_idx >= MMU_GUEST_IDX;
+}
+
+static inline int mmu_idx_to_plv(int mmu_idx)
+{
+    if (mmu_idx == MMU_DA_IDX || mmu_idx == MMU_GUEST_DA_IDX) {
+        return 0;
+    }
+    if (is_guest_mmu_idx(mmu_idx)) {
+        return mmu_idx - MMU_GUEST_IDX;
+    }
+    return mmu_idx;
+}
static inline CPUSysState *env_sys(CPULoongArchState *env)
  {
diff --git a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc 
b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
index 6728ce5ec9..7ee3bb8e27 100644
--- a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
+++ b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
@@ -249,7 +249,7 @@ TRANS64(iocsrwr_d, IOCSR, gen_iocsrwr, gen_helper_iocsrwr_d)
static void check_mmu_idx(DisasContext *ctx)
  {
-    if (ctx->mem_idx != MMU_DA_IDX) {
+    if (ctx->mem_idx != MMU_DA_IDX && ctx->mem_idx != MMU_GUEST_DA_IDX) {
          tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
          ctx->base.is_jmp = DISAS_EXIT;
      }
diff --git a/target/loongarch/tcg/tcg_cpu.c b/target/loongarch/tcg/tcg_cpu.c
index 14fa5f5809..b60d9e7cf8 100644
--- a/target/loongarch/tcg/tcg_cpu.c
+++ b/target/loongarch/tcg/tcg_cpu.c
@@ -309,6 +309,13 @@ static int loongarch_cpu_mmu_index(CPUState *cs, bool 
ifetch)
      CPULoongArchState *env = cpu_env(cs);
      CPUSysState *sys = env_sys(env);
+ if (env_vm_level(env) == VM_LEVEL1) {
+        if (FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PG)) {
+            return MMU_GUEST_IDX + FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV);
+        }
+        return MMU_GUEST_DA_IDX;
+    }
+
      if (FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PG)) {
          return FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV);
      }
diff --git a/target/loongarch/tcg/translate.c b/target/loongarch/tcg/translate.c
index 124dce6269..4ab06b48da 100644
--- a/target/loongarch/tcg/translate.c
+++ b/target/loongarch/tcg/translate.c
@@ -129,6 +129,9 @@ static void 
loongarch_tr_init_disas_context(DisasContextBase *dcbase,
      } else {
          ctx->mem_idx = MMU_DA_IDX;
      }
+    if (ctx->base.tb->flags & HW_FLAGS_GUEST_MODE) {
+        ctx->mem_idx += MMU_GUEST_IDX;
+    }
/* Bound the number of insns to execute to those left on the page. */
      bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;



Reply via email to