diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 2472dfef3a..2eb4ea3bfe 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -147,9 +147,22 @@ static void armsse_init(Object *obj)
     memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
 
     for (i = 0; i < info->num_cpus; i++) {
-        char *name = g_strdup_printf("armv7m%d", i);
-        sysbus_init_child_obj(obj, name, &s->armv7m[i], sizeof(s->armv7m),
-                              TYPE_ARMV7M);
+        /*
+         * We put each CPU in its own cluster as they are logically
+         * distinct and may be configured differently.
+         */
+        char *name;
+
+        name = g_strdup_printf("cluster%d", i);
+        object_initialize_child(obj, name, &s->cluster[i],
+                                sizeof(s->cluster[i]), TYPE_CPU_CLUSTER,
+                                &error_abort, NULL);
+        qdev_prop_set_uint32(DEVICE(&s->cluster[i]), "cluster-id", i);
+        g_free(name);
+
+        name = g_strdup_printf("armv7m%d", i);
+        sysbus_init_child_obj(OBJECT(&s->cluster[i]), name,
+                              &s->armv7m[i], sizeof(s->armv7m), TYPE_ARMV7M);
         qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type",
                              ARM_CPU_TYPE_NAME("cortex-m33"));
         g_free(name);
@@ -406,6 +419,18 @@ static void armsse_realize(DeviceState *dev, Error **errp)
             error_propagate(errp, err);
             return;
         }
+        /*
+         * The cluster must be realized after the armv7m container, as
+         * the container's CPU object is only created on realize, and the
+         * CPU must exist and have been parented into the cluster before
+         * the cluster is realized.
+         */
+        object_property_set_bool(OBJECT(&s->cluster[i]),
+                                 true, "realized", &err);
+        if (err) {
+            error_propagate(errp, err);
+            return;
+        }
 
         /* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
         s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
index 89f19a971f..999c2e4f7e 100644
--- a/include/hw/arm/armsse.h
+++ b/include/hw/arm/armsse.h
@@ -80,6 +80,7 @@
 #include "hw/misc/iotkit-sysinfo.h"
 #include "hw/or-irq.h"
 #include "hw/core/split-irq.h"
+#include "hw/cpu/cluster.h"
 
 #define TYPE_ARMSSE "arm-sse"
 #define ARMSSE(obj) OBJECT_CHECK(ARMSSE, (obj), TYPE_ARMSSE)
@@ -110,6 +111,7 @@ typedef struct ARMSSE {
 
     /*< public >*/
     ARMv7MState armv7m[SSE_MAX_CPUS];
+    CPUClusterState cluster[SSE_MAX_CPUS];
     IoTKitSecCtl secctl;
     TZPPC apb_ppc0;
     TZPPC apb_ppc1;