check_zicbom_access() currently treats any probe_access_flags() result other than TLB_INVALID_MASK as a successful access. However, a result with TLB_MMIO means that the target is MMIO-like and should not be treated as a normal cache block management target.
Raise a store/AMO access fault for Zicbom accesses to MMIO-like regions so that cbo.clean, cbo.flush and cbo.inval do not silently succeed on non-cacheable/MMIO-like memory. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3501 Reviewed-by: Daniel Henrique Barboza <[email protected]> Reviewed-by: Chao Liu <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Signed-off-by: ZhengXiang Qin <[email protected]> --- Changes since v2: - Add else before the success path for readability. - Keep fault_addr as target_ulong since CPURISCVState::badaddr is target_ulong. - Add Philippe's Reviewed-by tag. Changes since v1: - Use a bit test for TLB_MMIO since probe_access_flags() returns a bitmask. - Keep Reviewed-by tags from v1. target/riscv/op_helper.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index 81873014cb..50fd1b73ea 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,7 +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_INVALID_MASK) { + if (ret & TLB_MMIO) { + env->badaddr = fault_addr; + riscv_raise_exception(env, RISCV_EXCP_STORE_AMO_ACCESS_FAULT, ra); + } else if (ret != TLB_INVALID_MASK) { /* Success: readable */ return; } -- 2.43.0
