From 966f62a31afed5ca423b8c62f51a5d87a1a4da83 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Thu, 3 Aug 2023 10:05:07 -0700 Subject: [PATCH] CLoadTags: Try accessing the first and last capability-size chunk Check that we can access the first and last capability-size chunk. This also ensures that the bad access address is updated correctly in case any of these addresses are not accessible. In theory we should try to access the entire memory region (to match what sail does), but first and last will be equivalent for trapping/RVFI. Previously we were just checking the tag memory, which returns 0 for unmapped memory regions, but we should trap if these accesses are prevent e.g. by the PMP. TestRIG-generated and annotated trace: ```` .4byte 0x0108185b # cincoffsetimmediate x16, x16, 16 .4byte 0xfb08185b # cincoffsetimmediate x16, x16, 4016 .assert rd_wdata == 0xffffffffffffffc0 "expected addr" .4byte 0xff2808db # cloadtags x17, x16 .assert trap == 1 "Bad addr" .assert mem_addr == 0xffffffffffffffc0 "Should be initial aligned address not last address" .4byte 0x342020f3 # csrrs x1, mcause (0x342), x0 .assert rd_wdata == 5 "RISCV_EXCP_LOAD_ACCESS_FAULT" .4byte 0x343020f3 # csrrs x1, mtval (0x343), x0 .assert rd_wdata == 0xffffffffffffffc0 "Tval should be bad addr" ``` --- target/cheri-common/op_helper_cheri_common.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/target/cheri-common/op_helper_cheri_common.c b/target/cheri-common/op_helper_cheri_common.c index c200aadb24..397322bfdb 100644 --- a/target/cheri-common/op_helper_cheri_common.c +++ b/target/cheri-common/op_helper_cheri_common.c @@ -1607,13 +1607,16 @@ target_ulong CHERI_HELPER_IMPL(cloadtags(CPUArchState *env, uint32_t cb)) cbp, sizealign, raise_unaligned_load_exception); target_ulong result = cheri_tag_get_many(env, addr, cb, NULL, GETPC()); -#if defined(TARGET_RISCV) && defined(CONFIG_RVFI_DII) - /* For RVFI tracing, sail reports the valu of th last capability read. */ - target_ulong unused1, unused2; - (void)load_cap_from_memory_raw(env, &unused1, &unused2, cb, cbp, - addr + sizealign - CHERI_CAP_SIZE, - _host_return_address, NULL); -#endif + /* + * Check that we can access the first and last capability-size chunk. + * This also ensures that the bad access address is updated correctly + * in case any of these addresses are not accessible. + * In theory we should try to access the entire memory region (to match what + * sail does), but first and last will be equivalent for trapping/RVFI. + */ + (void)cpu_ld_cap_word_ra(env, addr, _host_return_address); + (void)cpu_ld_cap_word_ra(env, addr + sizealign - CHERI_CAP_SIZE, + _host_return_address); return result; }