Forbid S-mode execution from user memory
authorAndrew Waterman <andrew@sifive.com>
Wed, 7 Jun 2017 21:17:58 +0000 (14:17 -0700)
committerAndrew Waterman <aswaterman@gmail.com>
Wed, 7 Jun 2017 22:04:34 +0000 (15:04 -0700)
https://github.com/riscv/riscv-isa-manual/commit/285c81746fe664060b62ae0584865dbfa9f42e1a

riscv/mmu.cc

index 76a6ab1d4f685cf142a83d03a87f68847529e266..54b5b1d3d3692e60a30e58854679aa2b3a5c87ad 100644 (file)
@@ -163,7 +163,7 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode)
   if (vm.levels == 0)
     return addr & ((reg_t(2) << (proc->xlen-1))-1); // zero-extend from xlen
 
-  bool supervisor = mode == PRV_S;
+  bool s_mode = mode == PRV_S;
   bool sum = get_field(proc->state.mstatus, MSTATUS_SUM);
   bool mxr = get_field(proc->state.mstatus, MSTATUS_MXR);
 
@@ -189,7 +189,7 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode)
 
     if (PTE_TABLE(pte)) { // next level of page table
       base = ppn << PGSHIFT;
-    } else if ((pte & PTE_U) ? supervisor && !sum : !supervisor) {
+    } else if ((pte & PTE_U) ? s_mode && (type == FETCH || !sum) : !s_mode) {
       break;
     } else if (!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) {
       break;