mirror of
https://github.com/qemu/qemu.git
synced 2024-12-05 01:33:41 +08:00
target/riscv/cpu_helper.c: Invalid exception on MMU translation stage
According to RISCV privileged spec sect. 5.3.2 Virtual Address Translation Process
access-fault exceptions may raise only after PMA/PMP check. Current implementation
generates an access-fault for mbare mode even if there were no PMA/PMP errors.
This patch removes the erroneous MMU mode check and generates an access-fault
exception based on the pmp_violation flag only.
Fixes: 1448689c7b
("target/riscv: Allow specifying MMU stage")
Signed-off-by: Ivan Klokov <ivan.klokov@syntacore.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20231121071757.7178-2-ivan.klokov@syntacore.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
a7472560ca
commit
82d53adfbb
@ -1143,47 +1143,31 @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
|
|||||||
bool two_stage_indirect)
|
bool two_stage_indirect)
|
||||||
{
|
{
|
||||||
CPUState *cs = env_cpu(env);
|
CPUState *cs = env_cpu(env);
|
||||||
int page_fault_exceptions, vm;
|
|
||||||
uint64_t stap_mode;
|
|
||||||
|
|
||||||
if (riscv_cpu_mxl(env) == MXL_RV32) {
|
|
||||||
stap_mode = SATP32_MODE;
|
|
||||||
} else {
|
|
||||||
stap_mode = SATP64_MODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (first_stage) {
|
|
||||||
vm = get_field(env->satp, stap_mode);
|
|
||||||
} else {
|
|
||||||
vm = get_field(env->hgatp, stap_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
page_fault_exceptions = vm != VM_1_10_MBARE && !pmp_violation;
|
|
||||||
|
|
||||||
switch (access_type) {
|
switch (access_type) {
|
||||||
case MMU_INST_FETCH:
|
case MMU_INST_FETCH:
|
||||||
if (env->virt_enabled && !first_stage) {
|
if (env->virt_enabled && !first_stage) {
|
||||||
cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT;
|
cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT;
|
||||||
} else {
|
} else {
|
||||||
cs->exception_index = page_fault_exceptions ?
|
cs->exception_index = pmp_violation ?
|
||||||
RISCV_EXCP_INST_PAGE_FAULT : RISCV_EXCP_INST_ACCESS_FAULT;
|
RISCV_EXCP_INST_ACCESS_FAULT : RISCV_EXCP_INST_PAGE_FAULT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MMU_DATA_LOAD:
|
case MMU_DATA_LOAD:
|
||||||
if (two_stage && !first_stage) {
|
if (two_stage && !first_stage) {
|
||||||
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
|
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
|
||||||
} else {
|
} else {
|
||||||
cs->exception_index = page_fault_exceptions ?
|
cs->exception_index = pmp_violation ?
|
||||||
RISCV_EXCP_LOAD_PAGE_FAULT : RISCV_EXCP_LOAD_ACCESS_FAULT;
|
RISCV_EXCP_LOAD_ACCESS_FAULT : RISCV_EXCP_LOAD_PAGE_FAULT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MMU_DATA_STORE:
|
case MMU_DATA_STORE:
|
||||||
if (two_stage && !first_stage) {
|
if (two_stage && !first_stage) {
|
||||||
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
|
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
|
||||||
} else {
|
} else {
|
||||||
cs->exception_index = page_fault_exceptions ?
|
cs->exception_index = pmp_violation ?
|
||||||
RISCV_EXCP_STORE_PAGE_FAULT :
|
RISCV_EXCP_STORE_AMO_ACCESS_FAULT :
|
||||||
RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
|
RISCV_EXCP_STORE_PAGE_FAULT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user