Andrew Waterman
1 year ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with
12 additions and
3 deletions
-
riscv/csrs.cc
-
riscv/insns/mnret.h
-
riscv/insns/ssrdp.h
-
riscv/mmu.cc
-
riscv/zicfiss.h
|
|
@ -585,6 +585,7 @@ bool mnstatus_csr_t::unlogged_write(const reg_t val) noexcept { |
|
|
// NMIE can be set but not cleared
|
|
|
// NMIE can be set but not cleared
|
|
|
const reg_t mask = (~read() & MNSTATUS_NMIE) |
|
|
const reg_t mask = (~read() & MNSTATUS_NMIE) |
|
|
| (proc->extension_enabled('H') ? MNSTATUS_MNPV : 0) |
|
|
| (proc->extension_enabled('H') ? MNSTATUS_MNPV : 0) |
|
|
|
|
|
| (proc->extension_enabled(EXT_ZICFILP) ? MNSTATUS_MNPELP : 0) |
|
|
| MNSTATUS_MNPP; |
|
|
| MNSTATUS_MNPP; |
|
|
|
|
|
|
|
|
const reg_t requested_mnpp = proc->legalize_privilege(get_field(val, MNSTATUS_MNPP)); |
|
|
const reg_t requested_mnpp = proc->legalize_privilege(get_field(val, MNSTATUS_MNPP)); |
|
|
|
|
|
@ -10,5 +10,11 @@ if (prev_prv != PRV_M) { |
|
|
STATE.mstatus->write(mstatus); |
|
|
STATE.mstatus->write(mstatus); |
|
|
} |
|
|
} |
|
|
s = set_field(s, MNSTATUS_NMIE, 1); |
|
|
s = set_field(s, MNSTATUS_NMIE, 1); |
|
|
|
|
|
if (ZICFILP_xLPE(prev_virt, prev_prv)) { |
|
|
|
|
|
STATE.elp = static_cast<elp_t>(get_field(s, MNSTATUS_MNPELP)); |
|
|
|
|
|
} |
|
|
|
|
|
if (p->extension_enabled(EXT_ZICFILP)) { |
|
|
|
|
|
s = set_field(s, MNSTATUS_MNPELP, elp_t::NO_LP_EXPECTED); |
|
|
|
|
|
} |
|
|
STATE.mnstatus->write(s); |
|
|
STATE.mnstatus->write(s); |
|
|
p->set_privilege(prev_prv, prev_virt); |
|
|
p->set_privilege(prev_prv, prev_virt); |
|
|
|
|
|
@ -1,7 +1,7 @@ |
|
|
#include "zicfiss.h" |
|
|
#include "zicfiss.h" |
|
|
|
|
|
|
|
|
if (xSSE()) { |
|
|
if (xSSE()) { |
|
|
WRITE_RD(STATE.ssp->read()); |
|
|
WRITE_RD(sext_xlen(STATE.ssp->read())); |
|
|
} else { |
|
|
} else { |
|
|
#include "mop_r_N.h" |
|
|
#include "mop_r_N.h" |
|
|
} |
|
|
} |
|
|
|
|
|
@ -215,7 +215,9 @@ void mmu_t::load_slow_path_intrapage(reg_t len, uint8_t* bytes, mem_access_info_ |
|
|
refill_tlb(addr, paddr, host_addr, LOAD); |
|
|
refill_tlb(addr, paddr, host_addr, LOAD); |
|
|
|
|
|
|
|
|
} else if (!mmio_load(paddr, len, bytes)) { |
|
|
} else if (!mmio_load(paddr, len, bytes)) { |
|
|
throw trap_load_access_fault(access_info.effective_virt, transformed_addr, 0, 0); |
|
|
(access_info.flags.ss_access)? |
|
|
|
|
|
throw trap_store_access_fault(access_info.effective_virt, transformed_addr, 0, 0) : |
|
|
|
|
|
throw trap_load_access_fault(access_info.effective_virt, transformed_addr, 0, 0); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (access_info.flags.lr) { |
|
|
if (access_info.flags.lr) { |
|
|
|
|
|
@ -25,7 +25,7 @@ |
|
|
shadow_return_addr = MMU.ss_load<uint32_t>(STATE.ssp->read()); \ |
|
|
shadow_return_addr = MMU.ss_load<uint32_t>(STATE.ssp->read()); \ |
|
|
else \ |
|
|
else \ |
|
|
shadow_return_addr = MMU.ss_load<uint64_t>(STATE.ssp->read()); \ |
|
|
shadow_return_addr = MMU.ss_load<uint64_t>(STATE.ssp->read()); \ |
|
|
software_check(value == shadow_return_addr, SHADOW_STACK_FAULT); \ |
|
|
software_check(zext_xlen(value) == shadow_return_addr, SHADOW_STACK_FAULT); \ |
|
|
STATE.ssp->write(STATE.ssp->read() + xlen / 8); |
|
|
STATE.ssp->write(STATE.ssp->read() + xlen / 8); |
|
|
|
|
|
|
|
|
#endif |
|
|
#endif |
|
|
|