Add EXCCODE_GSPR and EXCCODE_HVC macros. Execute real vm exit at end of loongarch_cpu_do_interrupt().
Signed-off-by: SignKirigami <[email protected]> Signed-off-by: Hengyu Yu <[email protected]> --- target/loongarch/cpu.h | 2 ++ target/loongarch/tcg/tcg_cpu.c | 28 ++++++++++++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 891eea47bd..3e3ae2bfa7 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -95,6 +95,8 @@ FIELD(FCSR0, CAUSE, 24, 5) #define EXCCODE_WPEM EXCODE(19, 1) #define EXCCODE_BTD EXCODE(20, 0) #define EXCCODE_BTE EXCODE(21, 0) +#define EXCCODE_GSPR EXCODE(22, 0) +#define EXCCODE_HVC EXCODE(23, 0) #define EXCCODE_DBP EXCODE(26, 0) /* Reserved subcode used for debug */ /* cpucfg[0] bits */ diff --git a/target/loongarch/tcg/tcg_cpu.c b/target/loongarch/tcg/tcg_cpu.c index 101fe6fc7a..6f1ba12edb 100644 --- a/target/loongarch/tcg/tcg_cpu.c +++ b/target/loongarch/tcg/tcg_cpu.c @@ -44,6 +44,8 @@ static const struct TypeExcp excp_names[] = { {EXCCODE_BCE, "Bound Check Exception"}, {EXCCODE_SXD, "128 bit vector instructions Disable exception"}, {EXCCODE_ASXD, "256 bit vector instructions Disable exception"}, + {EXCCODE_GSPR, "Guest Sensitive and Privileged Resources"}, + {EXCCODE_HVC, "Hypervisor call"}, {EXCP_HLT, "EXCP_HLT"}, }; @@ -78,9 +80,11 @@ void G_NORETURN do_raise_exception(CPULoongArchState *env, static void loongarch_cpu_do_interrupt(CPUState *cs) { CPULoongArchState *env = cpu_env(cs); - CPUSysState *sys = env_sys(env); bool update_badinstr = 1; int cause = -1; + bool real_guest = !env->vm_exit && env_vm_level(env); + CPUSysState *sys = get_sys(env, real_guest); + CPUSysState *host = get_sys(env, VM_LEVEL0); bool tlbfill = FIELD_EX64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR); uint32_t vec_size = FIELD_EX64(sys->CSR_ECFG, CSR_ECFG, VS); uint64_t last_pc = env->pc; @@ -96,17 +100,17 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) switch (cs->exception_index) { case EXCCODE_DBP: - sys->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, DCL, 1); - sys->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, ECODE, 0xC); + host->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, DCL, 1); + host->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, ECODE, 0xC); goto set_DERA; set_DERA: - sys->CSR_DERA = env->pc; - sys->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, DST, 1); - set_pc(env, sys->CSR_EENTRY + 0x480); + host->CSR_DERA = env->pc; + host->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, DST, 1); + set_pc(env, host->CSR_EENTRY + 0x480); break; case EXCCODE_INT: - if (FIELD_EX64(sys->CSR_DBG, CSR_DBG, DST)) { - sys->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, DEI, 1); + if (FIELD_EX64(host->CSR_DBG, CSR_DBG, DST)) { + host->CSR_DBG = FIELD_DP64(host->CSR_DBG, CSR_DBG, DEI, 1); goto set_DERA; } QEMU_FALLTHROUGH; @@ -117,6 +121,8 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) update_badinstr = 0; break; case EXCCODE_BCE: + case EXCCODE_GSPR: + case EXCCODE_HVC: sys->CSR_BADV = env->pc; QEMU_FALLTHROUGH; case EXCCODE_SYS: @@ -218,6 +224,12 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) qemu_plugin_vcpu_exception_cb(cs, last_pc); } cs->exception_index = -1; + if (env->vm_exit) { + host->CSR_GSTAT = FIELD_DP64(host->CSR_GSTAT, CSR_GSTAT, VM, 0); + set_sys(env, VM_LEVEL0); + cpu_reset_interrupt(cs, CPU_INTERRUPT_GUEST); + } + env->vm_exit = false; } static void loongarch_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, -- 2.55.0
