diff --git a/riscv/csrs.cc b/riscv/csrs.cc index 2bd8b0d92..31e05f22a 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -180,7 +180,7 @@ bool pmpaddr_csr_t::subset_match(reg_t addr, reg_t len) const noexcept { return !(is_tor ? tor_homogeneous : napot_homogeneous); } -bool pmpaddr_csr_t::access_ok(access_type type, reg_t mode) const noexcept { +bool pmpaddr_csr_t::access_ok(access_type type, reg_t mode, bool hlvx) const noexcept { const bool cfgx = cfg & PMP_X; const bool cfgw = cfg & PMP_W; const bool cfgr = cfg & PMP_R; @@ -191,7 +191,7 @@ bool pmpaddr_csr_t::access_ok(access_type type, reg_t mode) const noexcept { const bool typer = type == LOAD; const bool typex = type == FETCH; const bool typew = type == STORE; - const bool normal_rwx = (typer && cfgr) || (typew && cfgw) || (typex && cfgx); + const bool normal_rwx = (typer && cfgr && (!hlvx || cfgx)) || (typew && cfgw) || (typex && cfgx); const bool mseccfg_mml = state->mseccfg->get_mml(); if (mseccfg_mml) { diff --git a/riscv/csrs.h b/riscv/csrs.h index 0920544eb..c924a5211 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -102,7 +102,7 @@ class pmpaddr_csr_t: public csr_t { bool subset_match(reg_t addr, reg_t len) const noexcept; // Is the specified access allowed given the pmpcfg privileges? - bool access_ok(access_type type, reg_t mode) const noexcept; + bool access_ok(access_type type, reg_t mode, bool hlvx) const noexcept; // To check lock bit status from outside like mseccfg bool is_locked() const noexcept { diff --git a/riscv/mmu.cc b/riscv/mmu.cc index 8660b7151..d10e23aeb 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -63,7 +63,7 @@ reg_t mmu_t::translate(mem_access_info_t access_info, reg_t len) reg_t mode = (reg_t) access_info.effective_priv; reg_t paddr = walk(access_info) | (addr & (PGSIZE-1)); - if (!pmp_ok(paddr, len, access_info.flags.ss_access ? STORE : type, mode)) + if (!pmp_ok(paddr, len, access_info.flags.ss_access ? STORE : type, mode, access_info.flags.hlvx)) throw_access_exception(virt, addr, type); return paddr; } @@ -340,7 +340,7 @@ tlb_entry_t mmu_t::refill_tlb(reg_t vaddr, reg_t paddr, char* host_addr, access_ return entry; } -bool mmu_t::pmp_ok(reg_t addr, reg_t len, access_type type, reg_t mode) +bool mmu_t::pmp_ok(reg_t addr, reg_t len, access_type type, reg_t mode, bool hlvx) { if (!proc || proc->n_pmp == 0) return true; @@ -361,7 +361,7 @@ bool mmu_t::pmp_ok(reg_t addr, reg_t len, access_type type, reg_t mode) if (!all_match) return false; - return proc->state.pmpaddr[i]->access_ok(type, mode); + return proc->state.pmpaddr[i]->access_ok(type, mode, hlvx); } } diff --git a/riscv/mmu.h b/riscv/mmu.h index b218bf654..3e4ae9a74 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -449,7 +449,7 @@ class mmu_t { const size_t ptesize = sizeof(T); - if (!pmp_ok(pte_paddr, ptesize, LOAD, PRV_S)) + if (!pmp_ok(pte_paddr, ptesize, LOAD, PRV_S, false)) throw_access_exception(virt, addr, trap_type); void* host_pte_addr = sim->addr_to_mem(pte_paddr); @@ -466,7 +466,7 @@ class mmu_t { const size_t ptesize = sizeof(T); - if (!pmp_ok(pte_paddr, ptesize, STORE, PRV_S)) + if (!pmp_ok(pte_paddr, ptesize, STORE, PRV_S, false)) throw_access_exception(virt, addr, trap_type); void* host_pte_addr = sim->addr_to_mem(pte_paddr); @@ -499,7 +499,7 @@ class mmu_t } reg_t pmp_homogeneous(reg_t addr, reg_t len); - bool pmp_ok(reg_t addr, reg_t len, access_type type, reg_t mode); + bool pmp_ok(reg_t addr, reg_t len, access_type type, reg_t mode, bool hlvx); #ifdef RISCV_ENABLE_DUAL_ENDIAN bool target_big_endian;