From a5311a267d6ef6bef7df564228ca95ed61e38213 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Mon, 8 Mar 2021 13:26:29 -0500 Subject: [PATCH] target/riscv: Convert MSTATUS MTL to GVA Backports 9034e90ad9959b89da32978e3b6d71b7069050a5 --- qemu/target/riscv/cpu_bits.h | 5 +++-- qemu/target/riscv/cpu_helper.c | 24 ++++++++++++++++++++---- qemu/target/riscv/csr.c | 6 +++--- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/qemu/target/riscv/cpu_bits.h b/qemu/target/riscv/cpu_bits.h index 2b5caf02..3cb6de54 100644 --- a/qemu/target/riscv/cpu_bits.h +++ b/qemu/target/riscv/cpu_bits.h @@ -379,10 +379,10 @@ #define MSTATUS_TW 0x20000000 /* since: priv-1.10 */ #define MSTATUS_TSR 0x40000000 /* since: priv-1.10 */ #if defined(TARGET_RISCV64) -#define MSTATUS_MTL 0x4000000000ULL +#define MSTATUS_GVA 0x4000000000ULL #define MSTATUS_MPV 0x8000000000ULL #elif defined(TARGET_RISCV32) -#define MSTATUS_MTL 0x00000040 +#define MSTATUS_GVA 0x00000040 #define MSTATUS_MPV 0x00000080 #endif @@ -445,6 +445,7 @@ #define HSTATUS_VTVM 0x00100000 #define HSTATUS_VTSR 0x00400000 #define HSTATUS_HU 0x00000200 +#define HSTATUS_GVA 0x00000040 #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 5511ade8..47af43a8 100644 --- a/qemu/target/riscv/cpu_helper.c +++ b/qemu/target/riscv/cpu_helper.c @@ -904,6 +904,19 @@ void riscv_cpu_do_interrupt(CPUState *cs) if (riscv_has_ext(env, RVH)) { target_ulong hdeleg = async ? env->hideleg : env->hedeleg; + if ((riscv_cpu_virt_enabled(env) || + riscv_cpu_two_stage_lookup(env)) && tval) { + /* + * If we are writing a guest virtual address to stval, set + * this to 1. If we are trapping to VS we will set this to 0 + * later. + */ + env->hstatus = set_field(env->hstatus, HSTATUS_GVA, 1); + } else { + /* For other HS-mode traps, we set this to 0. */ + env->hstatus = set_field(env->hstatus, HSTATUS_GVA, 0); + } + if (riscv_cpu_virt_enabled(env) && ((hdeleg >> cause) & 1) && !force_hs_execp) { /* @@ -914,6 +927,7 @@ void riscv_cpu_do_interrupt(CPUState *cs) cause == IRQ_VS_EXT) cause = cause - 1; /* Trap to VS mode */ + env->hstatus = set_field(env->hstatus, HSTATUS_GVA, 0); } else if (riscv_cpu_virt_enabled(env)) { /* Trap into HS mode, from virt */ riscv_cpu_swap_hypervisor_regs(env); @@ -961,13 +975,15 @@ void riscv_cpu_do_interrupt(CPUState *cs) #ifdef TARGET_RISCV32 env->mstatush = set_field(env->mstatush, MSTATUS_MPV, riscv_cpu_virt_enabled(env)); - env->mstatush = set_field(env->mstatush, MSTATUS_MTL, - riscv_cpu_force_hs_excep_enabled(env)); + if (riscv_cpu_virt_enabled(env) && tval) { + env->mstatush = set_field(env->mstatush, MSTATUS_GVA, 1); + } #else env->mstatus = set_field(env->mstatus, MSTATUS_MPV, riscv_cpu_virt_enabled(env)); - env->mstatus = set_field(env->mstatus, MSTATUS_MTL, - riscv_cpu_force_hs_excep_enabled(env)); + if (riscv_cpu_virt_enabled(env) && tval) { + env->mstatus = set_field(env->mstatus, MSTATUS_GVA, 1); + } #endif mtval2 = env->guest_phys_fault_addr; diff --git a/qemu/target/riscv/csr.c b/qemu/target/riscv/csr.c index cf6f02ea..9757d06d 100644 --- a/qemu/target/riscv/csr.c +++ b/qemu/target/riscv/csr.c @@ -403,10 +403,10 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val) #if defined(TARGET_RISCV64) /* - * RV32: MPV and MTL are not in mstatus. The current plan is to + * RV32: MPV and GVA are not in mstatus. The current plan is to * add them to mstatush. For now, we just don't support it. */ - mask |= MSTATUS_MTL | MSTATUS_MPV; + mask |= MSTATUS_MPV | MSTATUS_GVA; #endif mstatus = (mstatus & ~mask) | (val & mask); @@ -432,7 +432,7 @@ static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val) tlb_flush(env_cpu(env)); } - val &= MSTATUS_MPV | MSTATUS_MTL; + val &= MSTATUS_MPV | MSTATUS_GVA; env->mstatush = val;