On 5/11/2026 11:25 PM, Zongmin Zhou wrote:
From: Zongmin Zhou <[email protected]>

When the Zicbop extension is available expose it to the KVM guest.
Also read and validate cbop_blocksize from the host via KVM interface.

Signed-off-by: Zongmin Zhou <[email protected]>
---
  target/riscv/kvm/kvm-cpu.c | 38 ++++++++++++++++++++++++++++++++++++--
  1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index b047ffa9c0..a46737f934 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -293,6 +293,7 @@ static void kvm_cpu_csr_set_u64(RISCVCPU *cpu, KVMCPUConfig 
*csr_cfg,
static KVMCPUConfig kvm_multi_ext_cfgs[] = {
      KVM_EXT_CFG("zicbom", ext_zicbom, KVM_RISCV_ISA_EXT_ZICBOM),
+    KVM_EXT_CFG("zicbop", ext_zicbop, KVM_RISCV_ISA_EXT_ZICBOP),
      KVM_EXT_CFG("zicboz", ext_zicboz, KVM_RISCV_ISA_EXT_ZICBOZ),
      KVM_EXT_CFG("ziccrse", ext_ziccrse, KVM_RISCV_ISA_EXT_ZICCRSE),
      KVM_EXT_CFG("zicntr", ext_zicntr, KVM_RISCV_ISA_EXT_ZICNTR),
@@ -439,6 +440,12 @@ static KVMCPUConfig kvm_cboz_blocksize = {
      .kvm_reg_id = KVM_REG_RISCV_CONFIG_REG(zicboz_block_size)
  };
+static KVMCPUConfig kvm_cbop_blocksize = {
+    .name = "cbop_blocksize",
+    .offset = CPU_CFG_OFFSET(cbop_blocksize),
+    .kvm_reg_id = KVM_REG_RISCV_CONFIG_REG(zicbop_block_size)
+};
+
  static KVMCPUConfig kvm_v_vlenb = {
      .name = "vlenb",
      .offset = CPU_CFG_OFFSET(vlenb),
@@ -1114,6 +1121,10 @@ static void kvm_riscv_read_multiext_legacy(RISCVCPU *cpu,
          kvm_riscv_read_cbomz_blksize(cpu, kvmcpu, &kvm_cbom_blocksize);
      }
+ if (cpu->cfg.ext_zicbop) {
+        kvm_riscv_read_cbomz_blksize(cpu, kvmcpu, &kvm_cbop_blocksize);
+    }
+

We don't need to add any new KVM regs/properties to 
kvm_riscv_read_multiext_legacy().
This is a legacy function aimed at kernels < 6.6 that doesn't support 
KVM_GET_REG_LIST.
There's no scenario where this function needs to read zicbop because
KVM_RISCV_ISA_EXT_ZICBOP didn't exist back then.

Patch LGTM otherwise.  Thanks,

Daniel


      if (cpu->cfg.ext_zicboz) {
          kvm_riscv_read_cbomz_blksize(cpu, kvmcpu, &kvm_cboz_blocksize);
      }
@@ -1293,6 +1304,10 @@ static void kvm_riscv_init_cfg(RISCVCPU *cpu, 
KVMScratchCPU *kvmcpu)
          kvm_riscv_read_cbomz_blksize(cpu, kvmcpu, &kvm_cbom_blocksize);
      }
+ if (cpu->cfg.ext_zicbop) {
+        kvm_riscv_read_cbomz_blksize(cpu, kvmcpu, &kvm_cbop_blocksize);
+    }
+
      if (cpu->cfg.ext_zicboz) {
          kvm_riscv_read_cbomz_blksize(cpu, kvmcpu, &kvm_cboz_blocksize);
      }
@@ -2014,8 +2029,8 @@ void riscv_kvm_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
      int ret;
/* short-circuit without spinning the scratch CPU */
-    if (!cpu->cfg.ext_zicbom && !cpu->cfg.ext_zicboz &&
-        !riscv_has_ext(env, RVV)) {
+    if (!cpu->cfg.ext_zicbom && !cpu->cfg.ext_zicbop &&
+        !cpu->cfg.ext_zicboz && !riscv_has_ext(env, RVV)) {
          return;
      }
@@ -2062,6 +2077,25 @@ void riscv_kvm_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
          }
      }
+ if (cpu->cfg.ext_zicbop &&
+        riscv_cpu_option_set(kvm_cbop_blocksize.name)) {
+
+        reg.id = KVM_RISCV_REG_ID_ULONG(KVM_REG_RISCV_CONFIG,
+                                        kvm_cbop_blocksize.kvm_reg_id);
+        reg.addr = (uint64_t)&val;
+        ret = ioctl(kvmcpu.cpufd, KVM_GET_ONE_REG, &reg);
+        if (ret != 0) {
+            error_setg_errno(errp, errno, "Unable to read cbop_blocksize");
+            return;
+        }
+
+        if (cpu->cfg.cbop_blocksize != val) {
+            error_setg(errp, "Unable to set cbop_blocksize to a different "
+                       "value than the host (%lu)", val);
+            return;
+        }
+    }
+
      /* Users are setting vlen, not vlenb */
      if (riscv_has_ext(env, RVV) && riscv_cpu_option_set("vlen")) {
          if (!kvm_v_vlenb.supported) {


Reply via email to