Skip to contentSkip to conversation

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

PATCH In review Daniel Henrique Barboza 2 participants 5 messages Nov 11 RISC-V

lore
Share & tools
lore
#0 lore raw

v5 cover target/riscv: raise access fault for Zicbom MMIO-like accesses

Hi,

In this v5 a 'Fixes' tag in the commit msg of patch 2 was added. This was detected by Sashiko.

No other changes made.

Changes in v5:
- patch 2:
- added "Fixes" tag in commit msg
- v4 link: https://lore.kernel.org/qemu-devel/[email protected]/

Daniel Henrique Barboza (1):
target/riscv/tcg/op_helper: avoid env_archcpu() to access
cbom_blocksize

ZhengXiang Qin (1):
target/riscv: raise access fault for Zicbom MMIO-like accesses

 target/riscv/tcg/op_helper.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
Signature · 1 line
2.43.0
#1 lore raw

PATCH v5 1/2 target/riscv/tcg/op_helper: avoid env_archcpu() to access cbom_blocksize

There is no other use for the RISCVCPU* pointer aside from accessing cpu->cfg. Use the riscv_cpu_cfg(env) inline to retrieve cfg.cbom_blocksize instead.

---
 target/riscv/tcg/op_helper.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
target/riscv/tcg/op_helper.c +1 -2
index f9c79fe6b9..d7af56ef61 100644
@@ -229,9 +229,8 @@ static void check_zicbom_access(CPURISCVState *env,
                                 target_ulong address,
                                 uintptr_t ra)
 {
-    RISCVCPU *cpu = env_archcpu(env);
+    uint16_t cbomlen = riscv_cpu_cfg(env)->cbom_blocksize;
     int mmu_idx = riscv_env_mmu_index(env, false);
-    uint16_t cbomlen = cpu->cfg.cbom_blocksize;
     void *phost;
     int ret;
 
Signature · 1 line
2.43.0
Reviewed-by on v5 1/2
#2 lore raw

Re: [PATCH v5 1/2] target/riscv/tcg/op_helper: avoid env_archcpu() to access cbom_blocksize

Quoted 5 lines · Daniel Henrique Barboza

There is no other use for the RISCVCPU* pointer aside from accessing cpu->cfg. Use the riscv_cpu_cfg(env) inline to retrieve cfg.cbom_blocksize instead.

Thanks,
Nutty

Quoted 19 lines
---
  target/riscv/tcg/op_helper.c | 3 +--
  1 file changed, 1 insertion(+), 2 deletions(-)
target/riscv/tcg/op_helper.c +1 -2
index f9c79fe6b9..d7af56ef61 100644
@@ -229,9 +229,8 @@ static void check_zicbom_access(CPURISCVState *env,
                                  target_ulong address,
                                  uintptr_t ra)
  {
-    RISCVCPU *cpu = env_archcpu(env);
+    uint16_t cbomlen = riscv_cpu_cfg(env)->cbom_blocksize;
      int mmu_idx = riscv_env_mmu_index(env, false);
-    uint16_t cbomlen = cpu->cfg.cbom_blocksize;
      void *phost;
      int ret;
 
#3 lore raw

PATCH v5 2/2 target/riscv: raise access fault for Zicbom MMIO-like accesses

In reply to Daniel Henrique Barboza

From: ZhengXiang Qin <[email protected]>

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

---
 target/riscv/tcg/op_helper.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
target/riscv/tcg/op_helper.c +5 -1
index d7af56ef61..52aa545eec 100644
@@ -231,6 +231,7 @@ static void check_zicbom_access(CPURISCVState *env,
 {
     uint16_t cbomlen = riscv_cpu_cfg(env)->cbom_blocksize;
     int mmu_idx = riscv_env_mmu_index(env, false);
+    uint64_t fault_addr = address;
     void *phost;
     int ret;
 
@@ -251,7 +252,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;
     }
Signature · 1 line
2.43.0
Reviewed-by on v5 2/2
#4 lore raw
Quoted 11 lines · Daniel Henrique Barboza

From: ZhengXiang Qin <[email protected]>

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.

Quoted 7 lines

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3501

Thanks,
Nutty

Quoted 28 lines
---
  target/riscv/tcg/op_helper.c | 6 +++++-
  1 file changed, 5 insertions(+), 1 deletion(-)
target/riscv/tcg/op_helper.c +5 -1
index d7af56ef61..52aa545eec 100644
@@ -231,6 +231,7 @@ static void check_zicbom_access(CPURISCVState *env,
  {
      uint16_t cbomlen = riscv_cpu_cfg(env)->cbom_blocksize;
      int mmu_idx = riscv_env_mmu_index(env, false);
+    uint64_t fault_addr = address;
      void *phost;
      int ret;
 
@@ -251,7 +252,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;
      }