target/riscv: Remove the HS_TWO_STAGE flag

The HS_TWO_STAGE flag is no longer required as the MMU index contains
the information if we are performing a two stage access.

Backports 1c1c060aa866986ef8b7eb334abbb8c104a46e5c
This commit is contained in:
Alistair Francis 2021-03-08 15:03:13 -05:00 committed by Lioncash
parent e5a9b8fc17
commit bd81c057ed
7 changed files with 25 additions and 53 deletions

View file

@ -7324,7 +7324,6 @@ riscv_symbols = (
'riscv_cpu_set_force_hs_excep',
'riscv_cpu_set_mode',
'riscv_cpu_set_rdtime_fn',
'riscv_cpu_set_two_stage_lookup',
'riscv_cpu_set_virt_enabled',
'riscv_cpu_swap_hypervisor_regs',
'riscv_cpu_tlb_fill',

View file

@ -4760,7 +4760,6 @@
#define riscv_cpu_set_force_hs_excep riscv_cpu_set_force_hs_excep_riscv32
#define riscv_cpu_set_mode riscv_cpu_set_mode_riscv32
#define riscv_cpu_set_rdtime_fn riscv_cpu_set_rdtime_fn_riscv32
#define riscv_cpu_set_two_stage_lookup riscv_cpu_set_two_stage_lookup_riscv32
#define riscv_cpu_set_virt_enabled riscv_cpu_set_virt_enabled_riscv32
#define riscv_cpu_swap_hypervisor_regs riscv_cpu_swap_hypervisor_regs_riscv32
#define riscv_cpu_tlb_fill riscv_cpu_tlb_fill_riscv32

View file

@ -4760,7 +4760,6 @@
#define riscv_cpu_set_force_hs_excep riscv_cpu_set_force_hs_excep_riscv64
#define riscv_cpu_set_mode riscv_cpu_set_mode_riscv64
#define riscv_cpu_set_rdtime_fn riscv_cpu_set_rdtime_fn_riscv64
#define riscv_cpu_set_two_stage_lookup riscv_cpu_set_two_stage_lookup_riscv64
#define riscv_cpu_set_virt_enabled riscv_cpu_set_virt_enabled_riscv64
#define riscv_cpu_swap_hypervisor_regs riscv_cpu_swap_hypervisor_regs_riscv64
#define riscv_cpu_tlb_fill riscv_cpu_tlb_fill_riscv64

View file

@ -328,8 +328,7 @@ bool riscv_cpu_virt_enabled(CPURISCVState *env);
void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
bool riscv_cpu_force_hs_excep_enabled(CPURISCVState *env);
void riscv_cpu_set_force_hs_excep(CPURISCVState *env, bool enable);
bool riscv_cpu_two_stage_lookup(CPURISCVState *env);
void riscv_cpu_set_two_stage_lookup(CPURISCVState *env, bool enable);
bool riscv_cpu_two_stage_lookup(int mmu_idx);
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,

View file

@ -469,7 +469,6 @@
* page table fault.
*/
#define FORCE_HS_EXCEP 2
#define HS_TWO_STAGE 4
/* RV32 satp CSR field masks */
#define SATP32_MODE 0x80000000

View file

@ -207,22 +207,9 @@ void riscv_cpu_set_force_hs_excep(CPURISCVState *env, bool enable)
env->virt = set_field(env->virt, FORCE_HS_EXCEP, enable);
}
bool riscv_cpu_two_stage_lookup(CPURISCVState *env)
bool riscv_cpu_two_stage_lookup(int mmu_idx)
{
if (!riscv_has_ext(env, RVH)) {
return false;
}
return get_field(env->virt, HS_TWO_STAGE);
}
void riscv_cpu_set_two_stage_lookup(CPURISCVState *env, bool enable)
{
if (!riscv_has_ext(env, RVH)) {
return;
}
env->virt = set_field(env->virt, HS_TWO_STAGE, enable);
return mmu_idx & TB_FLAGS_PRIV_HYP_ACCESS_MASK;
}
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts)
@ -327,7 +314,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
* was called. Background registers will be used if the guest has
* forced a two stage translation to be on (in HS or M mode).
*/
if (riscv_cpu_two_stage_lookup(env) && access_type != MMU_INST_FETCH) {
if (!riscv_cpu_virt_enabled(env) && riscv_cpu_two_stage_lookup(mmu_idx)) {
use_background = true;
}
@ -566,7 +553,7 @@ restart:
static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
MMUAccessType access_type, bool pmp_violation,
bool first_stage)
bool first_stage, bool two_stage)
{
CPUState *cs = env_cpu(env);
int page_fault_exceptions;
@ -589,8 +576,7 @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
}
break;
case MMU_DATA_LOAD:
if ((riscv_cpu_virt_enabled(env) || riscv_cpu_two_stage_lookup(env)) &&
!first_stage) {
if (two_stage && !first_stage) {
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
} else {
cs->exception_index = page_fault_exceptions ?
@ -598,8 +584,7 @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
}
break;
case MMU_DATA_STORE:
if ((riscv_cpu_virt_enabled(env) || riscv_cpu_two_stage_lookup(env)) &&
!first_stage) {
if (two_stage && !first_stage) {
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
} else {
cs->exception_index = page_fault_exceptions ?
@ -687,6 +672,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
int prot, prot2;
bool pmp_violation = false;
bool first_stage_error = true;
bool two_stage_lookup = false;
int ret = TRANSLATE_FAIL;
int mode = mmu_idx;
target_ulong tlb_size = 0;
@ -706,11 +692,12 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
access_type != MMU_INST_FETCH &&
get_field(env->mstatus, MSTATUS_MPRV) &&
get_field(env->mstatus, MSTATUS_MPV)) {
riscv_cpu_set_two_stage_lookup(env, true);
two_stage_lookup = true;
}
if (riscv_cpu_virt_enabled(env) ||
(riscv_cpu_two_stage_lookup(env) && access_type != MMU_INST_FETCH)) {
((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
access_type != MMU_INST_FETCH)) {
/* Two stage lookup */
ret = get_physical_address(env, &pa, &prot, address,
&env->guest_phys_fault_addr, access_type,
@ -773,14 +760,6 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
__func__, address, ret, pa, prot);
}
/* We did the two stage lookup based on MPRV, unset the lookup */
if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
access_type != MMU_INST_FETCH &&
get_field(env->mstatus, MSTATUS_MPRV) &&
get_field(env->mstatus, MSTATUS_MPV)) {
riscv_cpu_set_two_stage_lookup(env, false);
}
if (riscv_feature(env, RISCV_FEATURE_PMP) &&
(ret == TRANSLATE_SUCCESS) &&
!pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
@ -802,7 +781,10 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
} else if (probe) {
return false;
} else {
raise_mmu_exception(env, address, access_type, pmp_violation, first_stage_error);
raise_mmu_exception(env, address, access_type, pmp_violation,
first_stage_error,
riscv_cpu_virt_enabled(env) ||
riscv_cpu_two_stage_lookup(mmu_idx));
riscv_raise_exception(env, cs->exception_index, retaddr);
}
@ -902,9 +884,16 @@ void riscv_cpu_do_interrupt(CPUState *cs)
/* handle the trap in S-mode */
if (riscv_has_ext(env, RVH)) {
target_ulong hdeleg = async ? env->hideleg : env->hedeleg;
bool two_stage_lookup = false;
if ((riscv_cpu_virt_enabled(env) ||
riscv_cpu_two_stage_lookup(env)) && write_tval) {
if (env->priv == PRV_M ||
(env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
(env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
get_field(env->hstatus, HSTATUS_HU))) {
two_stage_lookup = true;
}
if ((riscv_cpu_virt_enabled(env) || two_stage_lookup) && write_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
@ -942,11 +931,10 @@ void riscv_cpu_do_interrupt(CPUState *cs)
riscv_cpu_set_force_hs_excep(env, 0);
} else {
/* Trap into HS mode */
if (!riscv_cpu_two_stage_lookup(env)) {
if (!two_stage_lookup) {
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;
}
}

View file

@ -237,8 +237,6 @@ target_ulong helper_hyp_load(CPURISCVState *env, target_ulong address,
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_mmuidx_ra(env, address, mmu_idx, GETPC());
@ -265,8 +263,6 @@ target_ulong helper_hyp_load(CPURISCVState *env, target_ulong address,
g_assert_not_reached();
}
riscv_cpu_set_two_stage_lookup(env, false);
return pte;
}
@ -286,7 +282,6 @@ void helper_hyp_store(CPURISCVState *env, target_ulong address,
(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:
@ -308,8 +303,6 @@ void helper_hyp_store(CPURISCVState *env, target_ulong address,
g_assert_not_reached();
}
riscv_cpu_set_two_stage_lookup(env, false);
return;
}
@ -330,8 +323,6 @@ target_ulong helper_hyp_x_load(CPURISCVState *env, target_ulong address,
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_mmuidx_ra(env, address, mmu_idx, GETPC());
@ -343,8 +334,6 @@ target_ulong helper_hyp_x_load(CPURISCVState *env, target_ulong address,
g_assert_not_reached();
}
riscv_cpu_set_two_stage_lookup(env, false);
return pte;
}