diff --git a/target/cheri-common/cheri_tagmem.c b/target/cheri-common/cheri_tagmem.c index ed25865e91f..5b601a646f5 100644 --- a/target/cheri-common/cheri_tagmem.c +++ b/target/cheri-common/cheri_tagmem.c @@ -553,10 +553,13 @@ void cheri_tag_set(CPUArchState *env, target_ulong vaddr, int reg, } bool cheri_tag_get(CPUArchState *env, target_ulong vaddr, int reg, - hwaddr *ret_paddr, int *prot, uintptr_t pc, int mmu_idx) + hwaddr *ret_paddr, int *prot, uintptr_t pc, int mmu_idx, + void *host_addr) { - void *host_addr = probe_read(env, vaddr, 1, mmu_idx, pc); + if (host_addr == NULL) { + host_addr = probe_read(env, vaddr, 1, mmu_idx, pc); + } handle_paddr_return(read); uintptr_t tagmem_flags; diff --git a/target/cheri-common/cheri_tagmem.h b/target/cheri-common/cheri_tagmem.h index e54185fbc6b..0da0232e731 100644 --- a/target/cheri-common/cheri_tagmem.h +++ b/target/cheri-common/cheri_tagmem.h @@ -56,8 +56,13 @@ void cheri_tag_invalidate(CPUArchState *env, target_ulong vaddr, int32_t size, */ void cheri_tag_invalidate_aligned(CPUArchState *env, target_ulong vaddr, uintptr_t pc, int mmu_idx); +/** + * If probe_read() has already been called, the result can be passed as the + * @p host_addr argument to avoid another (expensive) probe_read() call. + */ bool cheri_tag_get(CPUArchState *env, target_ulong vaddr, int reg, - hwaddr *ret_paddr, int *prot, uintptr_t pc, int mmu_idx); + hwaddr *ret_paddr, int *prot, uintptr_t pc, int mmu_idx, + void *host_addr); /* * Get/set many currently don't have an mmu_idx because no targets currently * require it. diff --git a/target/cheri-common/op_helper_cheri_common.c b/target/cheri-common/op_helper_cheri_common.c index d84fa4c7beb..d2e81ff953a 100644 --- a/target/cheri-common/op_helper_cheri_common.c +++ b/target/cheri-common/op_helper_cheri_common.c @@ -1276,7 +1276,8 @@ bool load_cap_from_memory_raw_tag_mmu_idx( *cursor = cpu_ld_cap_word_ra(env, vaddr + CHERI_MEM_OFFSET_CURSOR, retpc); } int prot; - bool tag = cheri_tag_get(env, vaddr, cb, physaddr, &prot, retpc, mmu_idx); + bool tag = + cheri_tag_get(env, vaddr, cb, physaddr, &prot, retpc, mmu_idx, host); if (raw_tag) { *raw_tag = tag; }