[PATCH] target/riscv: raise access fault for Zicbom MMIO-like accesses

ZhengXiang Qin posted 1 patch 1 month, 1 week ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/tencent._5FAFB2247001B0C72775E3DE202C43F5126107@qq.com
Maintainers: Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>, Chao Liu <chao.liu.zevorn@gmail.com>
There is a newer version of this series
target/riscv/op_helper.c | 5 +++++
1 file changed, 5 insertions(+)
[PATCH] target/riscv: raise access fault for Zicbom MMIO-like accesses
Posted by ZhengXiang Qin 1 month, 1 week ago
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 <qinzhengxiang@foxmail.com>
---
 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
Re: [PATCH] target/riscv: raise access fault for Zicbom MMIO-like accesses
Posted by Chao Liu 1 month, 1 week ago
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 <qinzhengxiang@foxmail.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>

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
>
Re: [PATCH] target/riscv: raise access fault for Zicbom MMIO-like accesses
Posted by Daniel Henrique Barboza 1 month, 1 week ago

On 6/16/2026 12:33 PM, 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 <qinzhengxiang@foxmail.com>
> ---

Thanks for taking care of this one.

Without this patch:

$ ./build/qemu-system-riscv64 -d in_asm,int,mmu,unimp,cpu,fpu,vpu,exec,nochain \
	-D sv39_zicbom_access_fault.elf.trace.log -nographic -semihosting -icount shift=1 \
	-machine virt -cpu max,pmu-mask=0xfffffff8 \
	-bios ~/Downloads/sv39_zicbom_access_fault.elf

RVCP-SUMMARY: TEST FAILED - Test File "sv39_zicbom_exceptions_Smode.S"
RVCP: DEBUG INFORMATION FOLLOWS
RVCP: Test Info: "Mismatch during cbo.clean in Test Case 1!"
RVCP: Instruction: 0x0017a00f
RVCP: Approximate address (failure may be slightly after this): 0x0000000080000250
RVCP: Register: x12
RVCP: Bad Value:      0x0000000000000814
RVCP: Expected Value: 0x0000000000000810
RVCP: END OF DEBUG INFORMATION


With the patch, same cmd line:

$ ./build/qemu-system-riscv64 (...)

RVCP-SUMMARY: TEST PASSED - Test File "sv39_zicbom_exceptions_Smode.S"





Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Tested-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>



>   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;
Re: [PATCH] target/riscv: raise access fault for Zicbom MMIO-like accesses
Posted by Richard Henderson 1 month, 1 week ago
On 6/16/26 08:33, ZhengXiang Qin wrote:
> @@ -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) {

flags are a bitmask -- you'd use "& TLB_MMIO" not equality.


r~