target/riscv: Set the virtualised MMU mode when doing hyp accesses

When performing the hypervisor load/store operations set the MMU mode to
indicate that we are virtualised.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: e411c61a1452cad16853f13cac2fb86dc91ebee8.1604464950.git.alistair.francis@wdc.com
This commit is contained in:
Alistair Francis 2020-11-03 20:43:26 -08:00
parent c445593d30
commit 3e5979046f

View file

@ -235,30 +235,31 @@ target_ulong helper_hyp_load(CPURISCVState *env, target_ulong address,
(env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
get_field(env->hstatus, HSTATUS_HU))) {
target_ulong pte;
int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
riscv_cpu_set_two_stage_lookup(env, true);
switch (memop) {
case MO_SB:
pte = cpu_ldsb_data_ra(env, address, GETPC());
pte = cpu_ldsb_mmuidx_ra(env, address, mmu_idx, GETPC());
break;
case MO_UB:
pte = cpu_ldub_data_ra(env, address, GETPC());
pte = cpu_ldub_mmuidx_ra(env, address, mmu_idx, GETPC());
break;
case MO_TESW:
pte = cpu_ldsw_data_ra(env, address, GETPC());
pte = cpu_ldsw_mmuidx_ra(env, address, mmu_idx, GETPC());
break;
case MO_TEUW:
pte = cpu_lduw_data_ra(env, address, GETPC());
pte = cpu_lduw_mmuidx_ra(env, address, mmu_idx, GETPC());
break;
case MO_TESL:
pte = cpu_ldl_data_ra(env, address, GETPC());
pte = cpu_ldl_mmuidx_ra(env, address, mmu_idx, GETPC());
break;
case MO_TEUL:
pte = cpu_ldl_data_ra(env, address, GETPC());
pte = cpu_ldl_mmuidx_ra(env, address, mmu_idx, GETPC());
break;
case MO_TEQ:
pte = cpu_ldq_data_ra(env, address, GETPC());
pte = cpu_ldq_mmuidx_ra(env, address, mmu_idx, GETPC());
break;
default:
g_assert_not_reached();
@ -284,23 +285,25 @@ void helper_hyp_store(CPURISCVState *env, target_ulong address,
(env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
(env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
get_field(env->hstatus, HSTATUS_HU))) {
int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
riscv_cpu_set_two_stage_lookup(env, true);
switch (memop) {
case MO_SB:
case MO_UB:
cpu_stb_data_ra(env, address, val, GETPC());
cpu_stb_mmuidx_ra(env, address, val, mmu_idx, GETPC());
break;
case MO_TESW:
case MO_TEUW:
cpu_stw_data_ra(env, address, val, GETPC());
cpu_stw_mmuidx_ra(env, address, val, mmu_idx, GETPC());
break;
case MO_TESL:
case MO_TEUL:
cpu_stl_data_ra(env, address, val, GETPC());
cpu_stl_mmuidx_ra(env, address, val, mmu_idx, GETPC());
break;
case MO_TEQ:
cpu_stq_data_ra(env, address, val, GETPC());
cpu_stq_mmuidx_ra(env, address, val, mmu_idx, GETPC());
break;
default:
g_assert_not_reached();
@ -326,15 +329,16 @@ target_ulong helper_hyp_x_load(CPURISCVState *env, target_ulong address,
(env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
get_field(env->hstatus, HSTATUS_HU))) {
target_ulong pte;
int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
riscv_cpu_set_two_stage_lookup(env, true);
switch (memop) {
case MO_TEUW:
pte = cpu_lduw_data_ra(env, address, GETPC());
pte = cpu_lduw_mmuidx_ra(env, address, mmu_idx, GETPC());
break;
case MO_TEUL:
pte = cpu_ldl_data_ra(env, address, GETPC());
pte = cpu_ldl_mmuidx_ra(env, address, mmu_idx, GETPC());
break;
default:
g_assert_not_reached();