Browse Source

Merge pull request #2171 from riscv-software-src/fix-svukte

Fix Svukte implementation
pull/2175/head
Andrew Waterman 5 months ago
committed by GitHub
parent
commit
fd604be778
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 35
      riscv/mmu.cc
  2. 3
      riscv/mmu.h

35
riscv/mmu.cc

@ -630,28 +630,35 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty
}
}
bool mmu_t::check_svukte_qualified(reg_t addr, reg_t mode, bool forced_virt)
bool mmu_t::svukte_qualified(mem_access_info_t access_info)
{
state_t* state = proc->get_state();
if (mode != PRV_U)
return true;
if (access_info.effective_priv != PRV_U)
return false;
if (proc->extension_enabled('S') && get_field(state->senvcfg->read(), SENVCFG_UKTE)) {
if (forced_virt && state->prv == PRV_U) {
bool hstatus_hukte = proc->extension_enabled('H') && (get_field(state->hstatus->read(), HSTATUS_HUKTE) == 1);
return !hstatus_hukte;
}
bool ukte = get_field(state->senvcfg->read(), SENVCFG_UKTE);
if (access_info.flags.forced_virt && state->prv == PRV_U)
ukte = get_field(state->hstatus->read(), HSTATUS_HUKTE);
assert(proc->get_xlen() == 64);
if ((addr >> 63) & 1) {
return (state->v || forced_virt) && ((state->vsatp->read() & SATP64_MODE) == 0);
}
}
if (!ukte)
return false;
reg_t mode_mask = proc->get_xlen() == 32 ? SATP32_MODE : SATP64_MODE;
if (get_field(proc->get_state()->satp->readvirt(access_info.effective_virt), mode_mask) == 0)
return false;
return true;
}
bool mmu_t::svukte_fault(reg_t addr, mem_access_info_t access_info)
{
if (!svukte_qualified(access_info))
return false;
return addr >> (proc->get_xlen() - 1);
}
reg_t mmu_t::walk(mem_access_info_t access_info)
{
access_type type = access_info.type;
@ -674,7 +681,7 @@ reg_t mmu_t::walk(mem_access_info_t access_info)
if (vm.levels == 0)
return s2xlate(addr, addr & ((reg_t(2) << (proc->xlen-1))-1), type, type, virt, hlvx, false) & ~page_mask; // zero-extend from xlen
if (proc->extension_enabled(EXT_SVUKTE) && !check_svukte_qualified(addr, mode, access_info.flags.forced_virt)) {
if (svukte_fault(addr, access_info)) {
throw_page_fault_exception(virt, addr, type);
}

3
riscv/mmu.h

@ -453,7 +453,8 @@ private:
check_triggers(operation, address, virt, address, data);
}
void check_triggers(triggers::operation_t operation, reg_t address, bool virt, reg_t tval, std::optional<reg_t> data);
bool check_svukte_qualified(reg_t addr, reg_t mode, bool forced_virt);
bool svukte_qualified(mem_access_info_t access_info);
bool svukte_fault(reg_t addr, mem_access_info_t access_info);
reg_t translate(mem_access_info_t access_info, reg_t len);
reg_t pte_load(reg_t pte_paddr, reg_t addr, bool virt, access_type trap_type, size_t ptesize) {

Loading…
Cancel
Save