Raise GSPR when a guest accesses IOCSR, debug, idle and cpucfg resources,
and decode HVC for guest PLV0.

Signed-off-by: SignKirigami <[email protected]>
Signed-off-by: Hengyu Yu <[email protected]>
---
 target/loongarch/disas.c                      |  1 +
 target/loongarch/insns.decode                 |  1 +
 target/loongarch/tcg/helper.h                 |  2 +-
 .../tcg/insn_trans/trans_extra.c.inc          |  5 +++
 .../tcg/insn_trans/trans_privileged.c.inc     | 32 +++++++++++++++++++
 target/loongarch/tcg/op_helper.c              |  3 ++
 6 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 6425dea17c..7d47fc0151 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -706,6 +706,7 @@ INSN(gtlbsrch,     empty)
 INSN(gtlbrd,       empty)
 INSN(gtlbwr,       empty)
 INSN(gtlbfill,     empty)
+INSN(hvcl,         i)
 INSN(cacop,        cop_r_i)
 INSN(lddir,        rr_i)
 INSN(ldpte,        j_i)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index cbcc30c31f..b40fabe9d7 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -505,6 +505,7 @@ gtlbsrch         0000 01100100 10000 01010 00000 00001    
@empty
 gtlbrd           0000 01100100 10000 01011 00000 00001    @empty
 gtlbwr           0000 01100100 10000 01100 00000 00001    @empty
 gtlbfill         0000 01100100 10000 01101 00000 00001    @empty
+hvcl             0000 0000 0010 1011 1 ...............    @i15
 
 iocsrrd_b        0000 01100100 10000 00000 ..... .....    @rr
 iocsrrd_h        0000 01100100 10000 00001 ..... .....    @rr
diff --git a/target/loongarch/tcg/helper.h b/target/loongarch/tcg/helper.h
index 84eaee208c..be1573af9d 100644
--- a/target/loongarch/tcg/helper.h
+++ b/target/loongarch/tcg/helper.h
@@ -10,7 +10,7 @@ DEF_HELPER_FLAGS_3(asrtgt_d, TCG_CALL_NO_WG, void, env, tl, 
tl)
 
 DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
 DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
-DEF_HELPER_FLAGS_2(cpucfg, TCG_CALL_NO_RWG_SE, tl, env, tl)
+DEF_HELPER_FLAGS_2(cpucfg, TCG_CALL_NO_WG_SE, tl, env, tl)
 
 /* Floating-point helper */
 DEF_HELPER_FLAGS_3(fadd_s, TCG_CALL_NO_WG, i64, env, i64, i64)
diff --git a/target/loongarch/tcg/insn_trans/trans_extra.c.inc 
b/target/loongarch/tcg/insn_trans/trans_extra.c.inc
index 655dce329e..275755a1f0 100644
--- a/target/loongarch/tcg/insn_trans/trans_extra.c.inc
+++ b/target/loongarch/tcg/insn_trans/trans_extra.c.inc
@@ -82,6 +82,11 @@ static bool trans_rdtime_d(DisasContext *ctx, arg_rdtime_d 
*a)
 
 static bool trans_cpucfg(DisasContext *ctx, arg_cpucfg *a)
 {
+    if (is_guest_mmu_idx(ctx->mem_idx)) {
+        generate_exception(ctx, EXCCODE_GSPR);
+        return true;
+    }
+
     TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
     TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
 
diff --git a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc 
b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
index ae481aa83f..bd50e91422 100644
--- a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
+++ b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
@@ -48,6 +48,7 @@ GEN_FALSE_TRANS(gtlbsrch)
 GEN_FALSE_TRANS(gtlbrd)
 GEN_FALSE_TRANS(gtlbwr)
 GEN_FALSE_TRANS(gtlbfill)
+GEN_FALSE_TRANS(hvcl)
 
 #else
 
@@ -301,6 +302,10 @@ static bool gen_iocsrrd(DisasContext *ctx, arg_rr *a,
     if (check_plv(ctx)) {
         return false;
     }
+    if (is_guest_mmu_idx(ctx->mem_idx)) {
+        generate_exception(ctx, EXCCODE_GSPR);
+        return true;
+    }
     func(dest, tcg_env, src1);
     return true;
 }
@@ -314,6 +319,10 @@ static bool gen_iocsrwr(DisasContext *ctx, arg_rr *a,
     if (check_plv(ctx)) {
         return false;
     }
+    if (is_guest_mmu_idx(ctx->mem_idx)) {
+        generate_exception(ctx, EXCCODE_GSPR);
+        return true;
+    }
     func(tcg_env, addr, val);
     return true;
 }
@@ -584,6 +593,10 @@ static bool trans_dbcl(DisasContext *ctx, arg_dbcl *a)
     if (check_plv(ctx)) {
         return false;
     }
+    if (is_guest_mmu_idx(ctx->mem_idx)) {
+        generate_exception(ctx, EXCCODE_GSPR);
+        return true;
+    }
     generate_exception(ctx, EXCCODE_DBP);
     return true;
 }
@@ -594,9 +607,28 @@ static bool trans_idle(DisasContext *ctx, arg_idle *a)
         return false;
     }
 
+    if (is_guest_mmu_idx(ctx->mem_idx)) {
+        generate_exception(ctx, EXCCODE_GSPR);
+        return true;
+    }
+
     tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
     gen_helper_idle(tcg_env);
     ctx->base.is_jmp = DISAS_NORETURN;
     return true;
 }
+
+static bool trans_hvcl(DisasContext *ctx, arg_hvcl *a)
+{
+    if (!avail_LVZ(ctx) || !is_guest_mmu_idx(ctx->mem_idx)) {
+        return false;
+    }
+
+    if (check_plv(ctx)) {
+        return false;
+    }
+
+    generate_exception(ctx, EXCCODE_HVC);
+    return true;
+}
 #endif
diff --git a/target/loongarch/tcg/op_helper.c b/target/loongarch/tcg/op_helper.c
index 3035dfa08d..e2fe4b212f 100644
--- a/target/loongarch/tcg/op_helper.c
+++ b/target/loongarch/tcg/op_helper.c
@@ -20,6 +20,9 @@
 /* Exceptions helpers */
 void helper_raise_exception(CPULoongArchState *env, uint32_t exception)
 {
+    if (exception == EXCCODE_GSPR || exception == EXCCODE_HVC) {
+        trigger_vm_exit(env);
+    }
     do_raise_exception(env, exception, GETPC());
 }
 
-- 
2.55.0


Reply via email to