From: Ivan Klokov Date: Tue, 21 Nov 2023 07:17:56 +0000 (+0300) Subject: target/riscv/cpu_helper.c: Invalid exception on MMU translation stage X-Git-Tag: v8.1.4~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=87ff608c6fd258c7f323e3a17f948e4e8d412d36;p=thirdparty%2Fqemu.git 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 Reviewed-by: Alistair Francis Reviewed-by: Daniel Henrique Barboza Message-ID: <20231121071757.7178-2-ivan.klokov@syntacore.com> Signed-off-by: Alistair Francis (cherry picked from commit 82d53adfbb1aa0dbe7dac09b61ad86014efe81a7) Signed-off-by: Michael Tokarev --- diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 9f611d89bb9..3c482f9fd4e 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -1100,47 +1100,31 @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address, bool two_stage_indirect) { 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) { case MMU_INST_FETCH: if (env->virt_enabled && !first_stage) { cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT; } else { - cs->exception_index = page_fault_exceptions ? - RISCV_EXCP_INST_PAGE_FAULT : RISCV_EXCP_INST_ACCESS_FAULT; + cs->exception_index = pmp_violation ? + RISCV_EXCP_INST_ACCESS_FAULT : RISCV_EXCP_INST_PAGE_FAULT; } break; case MMU_DATA_LOAD: if (two_stage && !first_stage) { cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT; } else { - cs->exception_index = page_fault_exceptions ? - RISCV_EXCP_LOAD_PAGE_FAULT : RISCV_EXCP_LOAD_ACCESS_FAULT; + cs->exception_index = pmp_violation ? + RISCV_EXCP_LOAD_ACCESS_FAULT : RISCV_EXCP_LOAD_PAGE_FAULT; } break; case MMU_DATA_STORE: if (two_stage && !first_stage) { cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT; } else { - cs->exception_index = page_fault_exceptions ? - RISCV_EXCP_STORE_PAGE_FAULT : - RISCV_EXCP_STORE_AMO_ACCESS_FAULT; + cs->exception_index = pmp_violation ? + RISCV_EXCP_STORE_AMO_ACCESS_FAULT : + RISCV_EXCP_STORE_PAGE_FAULT; } break; default: