diff options
author | Weiwei Li <liweiwei@iscas.ac.cn> | 2023-06-03 21:42:34 +0800 |
---|---|---|
committer | Alistair Francis <alistair.francis@wdc.com> | 2023-07-10 22:29:14 +1000 |
commit | 869d76f2073f6ed28e26bb264d4c2c8841f06496 (patch) | |
tree | 4b3209aeedf091518033e57e210958d673a9b33c /target/riscv | |
parent | 318df7238b9f842af96aad01ec183012c8fecab9 (diff) |
target/riscv: Make MPV only work when MPP != PRV_M
Upon MRET or explicit memory access with MPRV=1, MPV should be ignored
when MPP=PRV_M.
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20230603134236.15719-2-liweiwei@iscas.ac.cn>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target/riscv')
-rw-r--r-- | target/riscv/cpu_helper.c | 3 | ||||
-rw-r--r-- | target/riscv/op_helper.c | 3 |
2 files changed, 4 insertions, 2 deletions
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index a944f25694..8e3c73da52 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -47,7 +47,8 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch) if (mode == PRV_M && get_field(status, MSTATUS_MPRV)) { mode = get_field(env->mstatus, MSTATUS_MPP); - virt = get_field(env->mstatus, MSTATUS_MPV); + virt = get_field(env->mstatus, MSTATUS_MPV) && + (mode != PRV_M); if (virt) { status = env->vsstatus; } diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index f563dc3981..9cdb9cdd06 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -335,7 +335,8 @@ target_ulong helper_mret(CPURISCVState *env) riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, GETPC()); } - target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV); + target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV) && + (prev_priv != PRV_M); mstatus = set_field(mstatus, MSTATUS_MIE, get_field(mstatus, MSTATUS_MPIE)); mstatus = set_field(mstatus, MSTATUS_MPIE, 1); |