From bf52a9b17e3d67450ae001d037cbe4ecf50603df Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Mon, 8 Mar 2021 13:31:01 -0500 Subject: [PATCH] target/riscv: Update the Hypervisor trap return/entry Backports f2d5850f71f3e41b240f328c2bc844a4e44e66c9 --- qemu/target/riscv/cpu_bits.h | 1 + qemu/target/riscv/cpu_helper.c | 15 ++++++--------- qemu/target/riscv/op_helper.c | 8 ++------ qemu/target/riscv/translate.c | 10 ---------- 4 files changed, 9 insertions(+), 25 deletions(-) diff --git a/qemu/target/riscv/cpu_bits.h b/qemu/target/riscv/cpu_bits.h index 3cb6de54..52a536b7 100644 --- a/qemu/target/riscv/cpu_bits.h +++ b/qemu/target/riscv/cpu_bits.h @@ -446,6 +446,7 @@ #define HSTATUS_VTSR 0x00400000 #define HSTATUS_HU 0x00000200 #define HSTATUS_GVA 0x00000040 +#define HSTATUS_SPVP 0x00000100 #define HSTATUS32_WPRI 0xFF8FF87E #define HSTATUS64_WPRI 0xFFFFFFFFFF8FF87EULL diff --git a/qemu/target/riscv/cpu_helper.c b/qemu/target/riscv/cpu_helper.c index 2496cd10..1c26f535 100644 --- a/qemu/target/riscv/cpu_helper.c +++ b/qemu/target/riscv/cpu_helper.c @@ -932,9 +932,7 @@ void riscv_cpu_do_interrupt(CPUState *cs) } else if (riscv_cpu_virt_enabled(env)) { /* Trap into HS mode, from virt */ riscv_cpu_swap_hypervisor_regs(env); - env->hstatus = set_field(env->hstatus, HSTATUS_SP2V, - get_field(env->hstatus, HSTATUS_SPV)); - env->hstatus = set_field(env->hstatus, HSTATUS_SP2P, + env->hstatus = set_field(env->hstatus, HSTATUS_SPVP, get_field(env->mstatus, SSTATUS_SPP)); env->hstatus = set_field(env->hstatus, HSTATUS_SPV, riscv_cpu_virt_enabled(env)); @@ -945,12 +943,11 @@ void riscv_cpu_do_interrupt(CPUState *cs) riscv_cpu_set_force_hs_excep(env, 0); } else { /* Trap into HS mode */ - env->hstatus = set_field(env->hstatus, HSTATUS_SP2V, - get_field(env->hstatus, HSTATUS_SPV)); - env->hstatus = set_field(env->hstatus, HSTATUS_SP2P, - get_field(env->mstatus, SSTATUS_SPP)); - env->hstatus = set_field(env->hstatus, HSTATUS_SPV, - riscv_cpu_virt_enabled(env)); + if (!riscv_cpu_two_stage_lookup(env)) { + env->hstatus = set_field(env->hstatus, HSTATUS_SPV, + riscv_cpu_virt_enabled(env)); + } + riscv_cpu_set_two_stage_lookup(env, false); htval = env->guest_phys_fault_addr; } } diff --git a/qemu/target/riscv/op_helper.c b/qemu/target/riscv/op_helper.c index c65223b9..77d8a32b 100644 --- a/qemu/target/riscv/op_helper.c +++ b/qemu/target/riscv/op_helper.c @@ -97,12 +97,8 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb) prev_priv = get_field(mstatus, MSTATUS_SPP); prev_virt = get_field(hstatus, HSTATUS_SPV); - hstatus = set_field(hstatus, HSTATUS_SPV, - get_field(hstatus, HSTATUS_SP2V)); - mstatus = set_field(mstatus, MSTATUS_SPP, - get_field(hstatus, HSTATUS_SP2P)); - hstatus = set_field(hstatus, HSTATUS_SP2V, 0); - hstatus = set_field(hstatus, HSTATUS_SP2P, 0); + hstatus = set_field(hstatus, HSTATUS_SPV, 0); + mstatus = set_field(mstatus, MSTATUS_SPP, 0); mstatus = set_field(mstatus, SSTATUS_SIE, get_field(mstatus, SSTATUS_SPIE)); mstatus = set_field(mstatus, SSTATUS_SPIE, 1); diff --git a/qemu/target/riscv/translate.c b/qemu/target/riscv/translate.c index 8f3b41d7..df254360 100644 --- a/qemu/target/riscv/translate.c +++ b/qemu/target/riscv/translate.c @@ -828,16 +828,6 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) #if !defined(CONFIG_USER_ONLY) if (riscv_has_ext(env, RVH)) { ctx->virt_enabled = riscv_cpu_virt_enabled(env); - if (env->priv_ver == PRV_M && - get_field(env->mstatus, MSTATUS_MPRV) && - MSTATUS_MPV_ISSET(env)) { - ctx->virt_enabled = true; - } else if (env->priv == PRV_S && - !riscv_cpu_virt_enabled(env) && - get_field(env->hstatus, HSTATUS_SPRV) && - get_field(env->hstatus, HSTATUS_SPV)) { - ctx->virt_enabled = true; - } } else { ctx->virt_enabled = false; }