Skip to content

Commit fd604be

Browse files
authored
Merge pull request #2171 from riscv-software-src/fix-svukte
Fix Svukte implementation
2 parents 3d97c3e + 62d64ef commit fd604be

File tree

2 files changed

+23
-15
lines changed

2 files changed

+23
-15
lines changed

riscv/mmu.cc

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -630,28 +630,35 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty
630630
}
631631
}
632632

633-
bool mmu_t::check_svukte_qualified(reg_t addr, reg_t mode, bool forced_virt)
633+
bool mmu_t::svukte_qualified(mem_access_info_t access_info)
634634
{
635635
state_t* state = proc->get_state();
636636

637-
if (mode != PRV_U)
638-
return true;
637+
if (access_info.effective_priv != PRV_U)
638+
return false;
639639

640-
if (proc->extension_enabled('S') && get_field(state->senvcfg->read(), SENVCFG_UKTE)) {
641-
if (forced_virt && state->prv == PRV_U) {
642-
bool hstatus_hukte = proc->extension_enabled('H') && (get_field(state->hstatus->read(), HSTATUS_HUKTE) == 1);
643-
return !hstatus_hukte;
644-
}
640+
bool ukte = get_field(state->senvcfg->read(), SENVCFG_UKTE);
641+
if (access_info.flags.forced_virt && state->prv == PRV_U)
642+
ukte = get_field(state->hstatus->read(), HSTATUS_HUKTE);
645643

646-
assert(proc->get_xlen() == 64);
647-
if ((addr >> 63) & 1) {
648-
return (state->v || forced_virt) && ((state->vsatp->read() & SATP64_MODE) == 0);
649-
}
650-
}
644+
if (!ukte)
645+
return false;
646+
647+
reg_t mode_mask = proc->get_xlen() == 32 ? SATP32_MODE : SATP64_MODE;
648+
if (get_field(proc->get_state()->satp->readvirt(access_info.effective_virt), mode_mask) == 0)
649+
return false;
651650

652651
return true;
653652
}
654653

654+
bool mmu_t::svukte_fault(reg_t addr, mem_access_info_t access_info)
655+
{
656+
if (!svukte_qualified(access_info))
657+
return false;
658+
659+
return addr >> (proc->get_xlen() - 1);
660+
}
661+
655662
reg_t mmu_t::walk(mem_access_info_t access_info)
656663
{
657664
access_type type = access_info.type;
@@ -674,7 +681,7 @@ reg_t mmu_t::walk(mem_access_info_t access_info)
674681
if (vm.levels == 0)
675682
return s2xlate(addr, addr & ((reg_t(2) << (proc->xlen-1))-1), type, type, virt, hlvx, false) & ~page_mask; // zero-extend from xlen
676683

677-
if (proc->extension_enabled(EXT_SVUKTE) && !check_svukte_qualified(addr, mode, access_info.flags.forced_virt)) {
684+
if (svukte_fault(addr, access_info)) {
678685
throw_page_fault_exception(virt, addr, type);
679686
}
680687

riscv/mmu.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,8 @@ class mmu_t
453453
check_triggers(operation, address, virt, address, data);
454454
}
455455
void check_triggers(triggers::operation_t operation, reg_t address, bool virt, reg_t tval, std::optional<reg_t> data);
456-
bool check_svukte_qualified(reg_t addr, reg_t mode, bool forced_virt);
456+
bool svukte_qualified(mem_access_info_t access_info);
457+
bool svukte_fault(reg_t addr, mem_access_info_t access_info);
457458
reg_t translate(mem_access_info_t access_info, reg_t len);
458459

459460
reg_t pte_load(reg_t pte_paddr, reg_t addr, bool virt, access_type trap_type, size_t ptesize) {

0 commit comments

Comments
 (0)