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.

Backports commit 635b0b0ea39a13d1a3df932452e5728aebbb3f6e from qemu
This commit is contained in:
Hesham Almatary 2019-08-08 16:50:55 -04:00 committed by Lioncash
parent f597727171
commit e8edd4d109
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -319,12 +319,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 ?
@ -406,6 +407,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",
@ -420,6 +422,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) {
@ -429,7 +432,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