check_zicbom_access() probes the cache block with MMU_DATA_LOAD and returns early for any result other than TLB_INVALID_MASK. This treats TLB_MMIO as a successful load access.
For Zicbom, a TLB_MMIO result does not provide a RAM host pointer for the cache block operation and should not be treated as a successful access. Raise a store/AMO access fault instead of silently completing the CBO instruction. This fixes sv39_zicbom_exceptions_Smode.S, where cbo.clean/cbo.flush and cbo.inval access a block mapped to a physical address without PMA permissions. Before this change, the CBO instruction completed and the following addi was executed. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3501 Signed-off-by: ZhengXiang Qin <[email protected]> --- target/riscv/op_helper.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index 81873014cb..6c9bd5c102 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -218,6 +218,7 @@ static void check_zicbom_access(CPURISCVState *env, void *phost; int ret; + target_ulong fault_addr = address; /* Mask off low-bits to align-down to the cache-block. */ address &= ~(cbomlen - 1); @@ -235,6 +236,10 @@ static void check_zicbom_access(CPURISCVState *env, */ ret = probe_access_flags(env, address, cbomlen, MMU_DATA_LOAD, mmu_idx, true, &phost, ra); + if (ret == TLB_MMIO) { + env->badaddr = fault_addr; + riscv_raise_exception(env, RISCV_EXCP_STORE_AMO_ACCESS_FAULT, ra); + } if (ret != TLB_INVALID_MASK) { /* Success: readable */ return; -- 2.43.0
