diff options
author | SuHsien Ho <su-hsien.ho@mediatek.com> | 2023-10-04 15:00:49 +0800 |
---|---|---|
committer | SuHsien Ho <su-hsien.ho@mediatek.com> | 2024-04-18 13:05:28 +0800 |
commit | 9ba5bd3171e97560bc28fe555ff7b8404272a3bb (patch) | |
tree | c0ac867c7df2ce90c83071e93c0ea5f0c6745d70 /riscv/mmu.cc | |
parent | 3192ee4d31f481e84281a24d55bb6130e3743668 (diff) | |
download | riscv-isa-sim-9ba5bd3171e97560bc28fe555ff7b8404272a3bb.zip riscv-isa-sim-9ba5bd3171e97560bc28fe555ff7b8404272a3bb.tar.gz riscv-isa-sim-9ba5bd3171e97560bc28fe555ff7b8404272a3bb.tar.bz2 |
Add Zicfiss extension from CFI extension, v0.4.0
1. Add EXT_ZICFISS for enable Zicfiss with zicfiss extension name.
2. Add new software exception with tval 3 for shadow stack.
3. Implement sspush_x1/sspush_x5/sspopchk_x1/sspopchk_x5/ssrdp/ssamoswap_w/ssamoswap_d.
4. Implement c_sspush_x1/c_sspopchk_x5 in c_lui.h which has same encoding.
5. Add new special access type ss_access in xlate_flags_t for checking special read/write permission in SS(Shadow Stack) page.
6. Add new ss_load/ss_store/ssamoswap to enable ss_access flag.
7. Check special pte(xwr=010) of SS page.
Diffstat (limited to 'riscv/mmu.cc')
-rw-r--r-- | riscv/mmu.cc | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc index 1a0c830..8660b71 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -63,7 +63,7 @@ reg_t mmu_t::translate(mem_access_info_t access_info, reg_t len) reg_t mode = (reg_t) access_info.effective_priv; reg_t paddr = walk(access_info) | (addr & (PGSIZE-1)); - if (!pmp_ok(paddr, len, type, mode)) + if (!pmp_ok(paddr, len, access_info.flags.ss_access ? STORE : type, mode)) throw_access_exception(virt, addr, type); return paddr; } @@ -491,6 +491,15 @@ reg_t mmu_t::walk(mem_access_info_t access_info) reg_t page_mask = (reg_t(1) << PGSHIFT) - 1; reg_t satp = proc->get_state()->satp->readvirt(virt); vm_info vm = decode_vm_info(proc->get_const_xlen(), false, mode, satp); + + bool ss_access = access_info.flags.ss_access; + + if (ss_access) { + if (vm.levels == 0) + trap_store_access_fault(virt, addr, 0, 0); + type = STORE; + } + if (vm.levels == 0) return s2xlate(addr, addr & ((reg_t(2) << (proc->xlen-1))-1), type, type, virt, hlvx, false) & ~page_mask; // zero-extend from xlen @@ -516,6 +525,7 @@ reg_t mmu_t::walk(mem_access_info_t access_info) reg_t ppn = (pte & ~reg_t(PTE_ATTR)) >> PTE_PPN_SHIFT; bool pbmte = virt ? (proc->get_state()->henvcfg->read() & HENVCFG_PBMTE) : (proc->get_state()->menvcfg->read() & MENVCFG_PBMTE); 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); if (pte & PTE_RSVD) { break; @@ -531,11 +541,24 @@ reg_t mmu_t::walk(mem_access_info_t access_info) base = ppn << PGSHIFT; } else if ((pte & PTE_U) ? s_mode && (type == FETCH || !sum) : !s_mode) { break; - } else if (!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) { + } else if (!(pte & PTE_V) || + (!(pte & PTE_R) && (pte & PTE_W) && ((!sse && !(pte & PTE_X)) || (pte & PTE_X)))) { + // invalid + // 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_R) && (pte & PTE_W) && !(pte & PTE_X)) && (type == STORE && !ss_access)) { + // not shadow stack store and xwr = 010 cause access-fault + throw trap_store_access_fault(virt, addr, 0, 0); + } else if ((!(pte & PTE_R) && (pte & PTE_W) && !(pte & PTE_X)) && type == FETCH) { + // fetch from shadow stack pages cause instruction access-fault + throw trap_instruction_access_fault(virt, addr, 0, 0); + } else if ((((pte & PTE_R) && (pte & PTE_W)) || (pte & PTE_X)) && ss_access) { + // shadow stack access cause store access fault if xwr!=010 and xwr!=001 + throw trap_store_access_fault(virt, addr, 0, 0); } else if (type == FETCH || hlvx ? !(pte & PTE_X) : type == LOAD ? !(pte & PTE_R) && !(mxr && (pte & PTE_X)) : - !((pte & PTE_R) && (pte & PTE_W))) { + !(pte & PTE_W)) { break; } else if ((ppn & ((reg_t(1) << ptshift) - 1)) != 0) { break; |