Browse Source

Merge pull request #1926 from riscv-software-src/fix-1925

Check for NAPOT PTE validity before raising SS-related faults
pull/1930/head
Andrew Waterman 1 year ago
committed by GitHub
parent
commit
b8eab3090b
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 14
      riscv/mmu.cc

14
riscv/mmu.cc

@ -431,6 +431,7 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty
reg_t ppn = (pte & ~reg_t(PTE_ATTR)) >> PTE_PPN_SHIFT;
bool pbmte = proc->get_state()->menvcfg->read() & MENVCFG_PBMTE;
bool hade = proc->get_state()->menvcfg->read() & MENVCFG_ADUE;
int napot_bits = ((pte & PTE_N) ? (ctz(ppn) + 1) : 0);
if (pte & PTE_RSVD) {
break;
@ -446,6 +447,8 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty
base = ppn << PGSHIFT;
} else if (!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) {
break;
} else if (((pte & PTE_N) && (ppn == 0 || i != 0)) || (napot_bits != 0 && napot_bits != 4)) {
break;
} else if (!(pte & PTE_U)) {
break;
} else if (type == FETCH || hlvx ? !(pte & PTE_X) :
@ -457,10 +460,6 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty
} else {
reg_t ad = PTE_A | ((type == STORE) * PTE_D);
int napot_bits = ((pte & PTE_N) ? (ctz(ppn) + 1) : 0);
if (((pte & PTE_N) && (ppn == 0 || i != 0)) || (napot_bits != 0 && napot_bits != 4))
break;
if ((pte & ad) != ad) {
if (hade) {
// set accessed and possibly dirty bits
@ -536,6 +535,7 @@ reg_t mmu_t::walk(mem_access_info_t access_info)
bool hade = virt ? (proc->get_state()->henvcfg->read() & HENVCFG_ADUE) : (proc->get_state()->menvcfg->read() & MENVCFG_ADUE);
bool sse = virt ? (proc->get_state()->henvcfg->read() & HENVCFG_SSE) : (proc->get_state()->menvcfg->read() & MENVCFG_SSE);
bool ss_page = !(pte & PTE_R) && (pte & PTE_W) && !(pte & PTE_X);
int napot_bits = ((pte & PTE_N) ? (ctz(ppn) + 1) : 0);
if (pte & PTE_RSVD) {
break;
@ -557,6 +557,8 @@ reg_t mmu_t::walk(mem_access_info_t access_info)
// not shadow stack access xwr=110 or xwr=010 page cause page fault
// shadow stack access with PTE_X moved to following check
break;
} else if (((pte & PTE_N) && (ppn == 0 || i != 0)) || (napot_bits != 0 && napot_bits != 4)) {
break;
} else if ((ppn & ((reg_t(1) << ptshift) - 1)) != 0) {
break;
} else if (ss_page && ((type == STORE && !ss_access) || access_info.flags.clean_inval)) {
@ -575,10 +577,6 @@ reg_t mmu_t::walk(mem_access_info_t access_info)
} else {
reg_t ad = PTE_A | ((type == STORE) * PTE_D);
int napot_bits = ((pte & PTE_N) ? (ctz(ppn) + 1) : 0);
if (((pte & PTE_N) && (ppn == 0 || i != 0)) || (napot_bits != 0 && napot_bits != 4))
break;
if ((pte & ad) != ad) {
if (hade) {
// Check for write permission to the first-stage PT in second-stage

Loading…
Cancel
Save