Skip to content

Commit 8f38b09

Browse files
committed
Fix Svukte implementation
- Change polarity of svukte_qualified to match ISA spec - Avoid address dependence of svukte_qualified, per ISA spec - Move address check to separate routine
1 parent 3d97c3e commit 8f38b09

File tree

2 files changed

+23
-14
lines changed

2 files changed

+23
-14
lines changed

riscv/mmu.cc

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -630,28 +630,36 @@ 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(reg_t mode, bool forced_virt)
634634
{
635635
state_t* state = proc->get_state();
636636

637637
if (mode != PRV_U)
638-
return true;
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 (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+
assert(proc->get_xlen() == 64);
648+
649+
if ((proc->get_state()->satp->readvirt(state->v) & SATP64_MODE) == 0)
650+
return false;
651651

652652
return true;
653653
}
654654

655+
bool mmu_t::svukte_fault(reg_t addr, reg_t mode, bool forced_virt)
656+
{
657+
if (!svukte_qualified(mode, forced_virt))
658+
return false;
659+
660+
return addr >> (proc->get_xlen() - 1);
661+
}
662+
655663
reg_t mmu_t::walk(mem_access_info_t access_info)
656664
{
657665
access_type type = access_info.type;
@@ -674,7 +682,7 @@ reg_t mmu_t::walk(mem_access_info_t access_info)
674682
if (vm.levels == 0)
675683
return s2xlate(addr, addr & ((reg_t(2) << (proc->xlen-1))-1), type, type, virt, hlvx, false) & ~page_mask; // zero-extend from xlen
676684

677-
if (proc->extension_enabled(EXT_SVUKTE) && !check_svukte_qualified(addr, mode, access_info.flags.forced_virt)) {
685+
if (proc->extension_enabled(EXT_SVUKTE) && svukte_fault(addr, mode, access_info.flags.forced_virt)) {
678686
throw_page_fault_exception(virt, addr, type);
679687
}
680688

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(reg_t mode, bool forced_virt);
457+
bool svukte_fault(reg_t addr, reg_t mode, bool forced_virt);
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)