RISC-V: Raise access fault exceptions on PMP violations
Section 3.6 in RISC-V v1.10 privilege specification states that PMP violations report "access exceptions." The current PMP implementation has a bug which wrongly reports "page exceptions" on PMP violations. This patch fixes this bug by reporting the correct PMP access exceptions trap values. Signed-off-by: Hesham Almatary <Hesham.Almatary@cl.cam.ac.uk> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
This commit is contained in:
parent
e0f8fa72de
commit
635b0b0ea3
@ -337,12 +337,13 @@ restart:
|
||||
}
|
||||
|
||||
static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
|
||||
MMUAccessType access_type)
|
||||
MMUAccessType access_type, bool pmp_violation)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
int page_fault_exceptions =
|
||||
(env->priv_ver >= PRIV_VERSION_1_10_0) &&
|
||||
get_field(env->satp, SATP_MODE) != VM_1_10_MBARE;
|
||||
get_field(env->satp, SATP_MODE) != VM_1_10_MBARE &&
|
||||
!pmp_violation;
|
||||
switch (access_type) {
|
||||
case MMU_INST_FETCH:
|
||||
cs->exception_index = page_fault_exceptions ?
|
||||
@ -424,6 +425,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||
CPURISCVState *env = &cpu->env;
|
||||
hwaddr pa = 0;
|
||||
int prot;
|
||||
bool pmp_violation = false;
|
||||
int ret = TRANSLATE_FAIL;
|
||||
|
||||
qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
|
||||
@ -438,6 +440,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||
if (riscv_feature(env, RISCV_FEATURE_PMP) &&
|
||||
(ret == TRANSLATE_SUCCESS) &&
|
||||
!pmp_hart_has_privs(env, pa, TARGET_PAGE_SIZE, 1 << access_type)) {
|
||||
pmp_violation = true;
|
||||
ret = TRANSLATE_FAIL;
|
||||
}
|
||||
if (ret == TRANSLATE_SUCCESS) {
|
||||
@ -447,7 +450,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||
} else if (probe) {
|
||||
return false;
|
||||
} else {
|
||||
raise_mmu_exception(env, address, access_type);
|
||||
raise_mmu_exception(env, address, access_type, pmp_violation);
|
||||
riscv_raise_exception(env, cs->exception_index, retaddr);
|
||||
}
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user