On Tue, Jun 16, 2026 at 11:33:26PM +0800, ZhengXiang Qin wrote:
> 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]>
Reviewed-by: Chao Liu <[email protected]>
Thanks,
Chao
> ---
> 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
>