diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 39ffb883fc..04500fe352 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -764,6 +764,10 @@ static Property riscv_cpu_properties[] = {
DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
+ DEFINE_PROP_BOOL("zicbom", RISCVCPU, cfg.ext_icbom, true),
+ DEFINE_PROP_BOOL("zicboz", RISCVCPU, cfg.ext_icboz, true),
+ DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64),
+ DEFINE_PROP_UINT16("cboz_blocksize", RISCVCPU, cfg.cboz_blocksize, 64),
DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
DEFINE_PROP_BOOL("Zve32f", RISCVCPU, cfg.ext_zve32f, false),
+
+/* helper_zicbom_access
+ *
+ * Check access permissions (LOAD, STORE or FETCH as specified in section
+ * 2.5.2 of the CMO specification) for Zicbom, raising either store
+ * page-fault (non-virtualised) or store guest-page fault (virtualised).
+ */
+static void helper_zicbom_access(CPURISCVState *env, target_ulong address,
+ uintptr_t ra)
+{
+ int ret;
+ void* phost;
+ int mmu_idx = cpu_mmu_index(env, false);
+
+ /* Get the size of the cache block for management instructions. */
+ RISCVCPU *cpu = env_archcpu(env);
+ uint16_t cbomlen = cpu->cfg.cbom_blocksize;
+
+ /* Mask off low-bits to align-down to the cache-block. */
+ address &= ~(cbomlen - 1);
+
+ /* A cache-block management instruction is permitted to access
+ * the specified cache block whenever a load instruction, store
+ * instruction, or instruction fetch is permitted to access the
+ * corresponding physical addresses.
+ */
+ ret = probe_access_range_flags(env, address, cbomlen, MMU_DATA_LOAD,
+ mmu_idx, true, &phost, ra);
+ if (ret == TLB_INVALID_MASK)
+ ret = probe_access_range_flags(env, address, cbomlen, MMU_INST_FETCH,
+ mmu_idx, true, &phost, ra);
+ if (ret == TLB_INVALID_MASK)
+ probe_access_range_flags(env, address, cbomlen, MMU_DATA_STORE,
+ mmu_idx, false, &phost, ra);
+}
+