diff --git a/include/hw/riscv/riscv_hart.h b/include/hw/riscv/riscv_hart.h
index 71747bf37c..65ac0d2bc4 100644
--- a/include/hw/riscv/riscv_hart.h
+++ b/include/hw/riscv/riscv_hart.h
@@ -21,7 +21,7 @@
 #ifndef HW_RISCV_HART_H
 #define HW_RISCV_HART_H
 
-#include "hw/sysbus.h"
+#include "hw/cpu/cpus.h"
 #include "target/riscv/cpu.h"
 #include "qom/object.h"
 
@@ -31,30 +31,29 @@ OBJECT_DECLARE_SIMPLE_TYPE(RISCVHartArrayState, RISCV_HART_ARRAY)
 
 struct RISCVHartArrayState {
     /*< private >*/
-    SysBusDevice parent_obj;
+    CpusState parent_obj;
 
     /*< public >*/
-    uint32_t num_harts;
     uint32_t hartid_base;
-    char *cpu_type;
     uint64_t resetvec;
-    RISCVCPU *harts;
 };
 
 /**
  * riscv_array_get_hart:
+ * Helper to get an hart from the container.
  */
-static inline RISCVCPU *riscv_array_get_hart(RISCVHartArrayState *harts, int i)
+static inline RISCVCPU *riscv_array_get_hart(RISCVHartArrayState *s, int i)
 {
-    return &harts->harts[i];
+    return RISCV_CPU(CPUS(s)->cpus[i]);
 }
 
 /**
  * riscv_array_get_num_harts:
+ * Helper to get the number of harts in the container.
  */
-static inline unsigned riscv_array_get_num_harts(RISCVHartArrayState *harts)
+static inline unsigned riscv_array_get_num_harts(RISCVHartArrayState *s)
 {
-    return harts->num_harts;
+    return CPUS(s)->topology.cpus;
 }
 
 /* Temporary function until we migrated the riscv hart array to simple device */
diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
index 780fd3a59a..1b4ff7e3c6 100644
--- a/hw/riscv/riscv_hart.c
+++ b/hw/riscv/riscv_hart.c
@@ -22,67 +22,58 @@
 #include "qapi/error.h"
 #include "qemu/module.h"
 #include "sysemu/reset.h"
-#include "hw/sysbus.h"
 #include "target/riscv/cpu.h"
 #include "hw/qdev-properties.h"
 #include "hw/riscv/riscv_hart.h"
+#include "hw/cpu/cpus.h"
 
 void riscv_hart_array_realize(RISCVHartArrayState *state, Error **errp)
 {
-    sysbus_realize(SYS_BUS_DEVICE(state), errp);
+    /* disable the clustering */
+    cpus_disable_clustering(CPUS(state));
+    qdev_realize(DEVICE(state), NULL, errp);
 }
 
 static Property riscv_harts_props[] = {
-    DEFINE_PROP_UINT32("num-harts", RISCVHartArrayState, num_harts, 1),
     DEFINE_PROP_UINT32("hartid-base", RISCVHartArrayState, hartid_base, 0),
-    DEFINE_PROP_STRING("cpu-type", RISCVHartArrayState, cpu_type),
     DEFINE_PROP_UINT64("resetvec", RISCVHartArrayState, resetvec,
                        DEFAULT_RSTVEC),
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static void riscv_harts_cpu_reset(void *opaque)
+static void riscv_harts_configure_cpu(CpusState *base, CPUState *cpu,
+                                      unsigned i)
 {
-    RISCVCPU *cpu = opaque;
-    cpu_reset(CPU(cpu));
-}
+    RISCVHartArrayState *s = RISCV_HART_ARRAY(base);
+    DeviceState *cpudev = DEVICE(cpu);
+    CPURISCVState *cpuenv = cpu->env_ptr;
 
-static bool riscv_hart_realize(RISCVHartArrayState *s, int idx,
-                               char *cpu_type, Error **errp)
-{
-    object_initialize_child(OBJECT(s), "harts[*]", &s->harts[idx], cpu_type);
-    qdev_prop_set_uint64(DEVICE(&s->harts[idx]), "resetvec", s->resetvec);
-    s->harts[idx].env.mhartid = s->hartid_base + idx;
-    qemu_register_reset(riscv_harts_cpu_reset, &s->harts[idx]);
-    return qdev_realize(DEVICE(&s->harts[idx]), NULL, errp);
+    qdev_prop_set_uint64(cpudev, "resetvec", s->resetvec);
+    cpuenv->mhartid = s->hartid_base + i;
 }
 
-static void riscv_harts_realize(DeviceState *dev, Error **errp)
+static void riscv_harts_init(Object *obj)
 {
-    RISCVHartArrayState *s = RISCV_HART_ARRAY(dev);
-    int n;
-
-    s->harts = g_new0(RISCVCPU, s->num_harts);
-
-    for (n = 0; n < s->num_harts; n++) {
-        if (!riscv_hart_realize(s, n, s->cpu_type, errp)) {
-            return;
-        }
-    }
+    /* add a temporary property to keep num-harts */
+    object_property_add_alias(obj, "num-harts", obj, "num-cpus");
 }
 
 static void riscv_harts_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    CpusClass *cc = CPUS_CLASS(klass);
 
     device_class_set_props(dc, riscv_harts_props);
-    dc->realize = riscv_harts_realize;
+
+    cc->base_cpu_type = TYPE_RISCV_CPU;
+    cc->configure_cpu = riscv_harts_configure_cpu;
 }
 
 static const TypeInfo riscv_harts_info = {
     .name          = TYPE_RISCV_HART_ARRAY,
-    .parent        = TYPE_SYS_BUS_DEVICE,
+    .parent        = TYPE_CPUS,
     .instance_size = sizeof(RISCVHartArrayState),
+    .instance_init = riscv_harts_init,
     .class_init    = riscv_harts_class_init,
 };
 
