Skip to content

Commit

Permalink
CHERI riscv: optionally trap on PTE_{A,D,CD} clear
Browse files Browse the repository at this point in the history
These are `#if 0`-ed out, but has proven useful in testing, as our FPGA cores
trap rather than atomically update the PTE.
  • Loading branch information
nwf-msr committed May 5, 2021
1 parent 3185dfe commit c8f3eeb
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions target/riscv/cpu_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,17 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
extern bool rvfi_debug_output;
#endif

#ifndef RISCV_PTE_TRAPPY
/*
* The PTW logic below supports trapping on any subset of PTE_A, PTE_D, PTE_CD
* being clear during an access that would have them be set. The RISC-V spec
* says that PTE_A and PTE_D always go together, and it's probably most sensible
* that PTE_CD implies PTE_A and PTE_D. So, sensible values for this constant
* are 0, (PTE_A | PTE_D), or (PTE_A | PTE_D | PTE_CD).
*/
#define RISCV_PTE_TRAPPY 0
#endif

/* get_physical_address - get the physical address for this virtual address
*
* Do a page table walk to obtain the physical address corresponding to a
Expand Down Expand Up @@ -618,6 +629,28 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
} else if (access_type == MMU_DATA_CAP_STORE && !(pte & PTE_CW)) {
/* CW inhibited */
return TRANSLATE_CHERI_FAIL;
#endif
#if RISCV_PTE_TRAPPY & PTE_A
} else if (!(pte & PTE_A)) {
/* PTE not marked as accessed */
return TRANSLATE_FAIL;
#endif
#if RISCV_PTE_TRAPPY & PTE_D
} else if ((access_type == MMU_DATA_STORE) && !(pte & PTE_D)) {
/* PTE not marked as dirty */
return TRANSLATE_FAIL;
#endif
#if defined(TARGET_CHERI) && !defined(TARGET_RISCV32)
#if RISCV_PTE_TRAPPY & PTE_D
} else if (access_type == MMU_DATA_CAP_STORE && !(pte & PTE_D)) {
/* PTE not marked as dirty for cap store */
return TRANSLATE_FAIL;
#endif
#if RISCV_PTE_TRAPPY & PTE_CD
} else if (access_type == MMU_DATA_CAP_STORE && !(pte & PTE_CD)) {
/* CD clear; force the software trap handler to get involved */
return TRANSLATE_CHERI_FAIL;
#endif
#endif
} else {
/* if necessary, set accessed and dirty bits. */
Expand Down

0 comments on commit c8f3eeb

Please sign in to comment.