aboutsummaryrefslogtreecommitdiff
path: root/riscv/mmu.cc
diff options
context:
space:
mode:
authorScott Johnson <scott.johnson@arilinc.com>2021-11-29 12:33:11 -0800
committerScott Johnson <scott.johnson@arilinc.com>2021-11-29 14:07:33 -0800
commit22e97db4c45231a8abd5d05273c77144e8ee026c (patch)
tree7d0ca76cb581b77fa4204b52d00a30575d5e841a /riscv/mmu.cc
parent3090cee163e4c38a2f33c28928fca623f549285c (diff)
downloadspike-22e97db4c45231a8abd5d05273c77144e8ee026c.zip
spike-22e97db4c45231a8abd5d05273c77144e8ee026c.tar.gz
spike-22e97db4c45231a8abd5d05273c77144e8ee026c.tar.bz2
Raise guest page fault if GPA is out of range
Based on this statement from priv spec 5.5.1 (regarding Sv39x4): "Address bits 63:41 must all be zeros, or else a guest-page-fault exception occurs."
Diffstat (limited to 'riscv/mmu.cc')
-rw-r--r--riscv/mmu.cc5
1 files changed, 5 insertions, 0 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 906694c..73a36f8 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -267,9 +267,13 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty
if (vm.levels == 0)
return gpa;
+ int maxgpabits = vm.levels * vm.idxbits + vm.widenbits + PGSHIFT;
+ reg_t maxgpa = (1ULL << maxgpabits) - 1;
+
bool mxr = proc->state.sstatus->readvirt(false) & MSTATUS_MXR;
reg_t base = vm.ptbase;
+ if ((gpa & ~maxgpa) == 0) {
for (int i = vm.levels - 1; i >= 0; i--) {
int ptshift = i * vm.idxbits;
int idxbits = (i == (vm.levels - 1)) ? vm.idxbits + vm.widenbits : vm.idxbits;
@@ -328,6 +332,7 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty
return page_base | (gpa & page_mask);
}
}
+ }
switch (trap_type) {
case FETCH: throw trap_instruction_guest_page_fault(gva, gpa >> 2, 0);