diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 4ac2d00..9fbf962 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -54,8 +54,9 @@ int xics_get_cpu_index_by_dt_id(int cpu_dt_id)
 void xics_cpu_destroy(XICSState *xics, PowerPCCPU *cpu)
 {
     CPUState *cs = CPU(cpu);
-    ICPState *ss = &xics->ss[cs->cpu_index];
+    ICPState *ss;
 
+    ss = xics->ss + sizeof(ICPState) * cs->cpu_index;
     assert(cs->cpu_index < xics->nr_servers);
     assert(cs == ss->cs);
 
@@ -67,9 +68,10 @@ void xics_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
 {
     CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
-    ICPState *ss = &xics->ss[cs->cpu_index];
+    ICPState *ss;
     XICSStateClass *info = XICS_COMMON_GET_CLASS(xics);
 
+    ss = xics->ss + sizeof(ICPState) * cs->cpu_index;
     assert(cs->cpu_index < xics->nr_servers);
 
     ss->cs = cs;
@@ -101,10 +103,12 @@ static void xics_common_reset(DeviceState *d)
 {
     XICSState *xics = XICS_COMMON(d);
     ICSState *ics;
+    ICPState *ss;
     int i;
 
     for (i = 0; i < xics->nr_servers; i++) {
-        device_reset(DEVICE(&xics->ss[i]));
+        ss = xics->ss + sizeof(ICPState) * i;
+        device_reset(DEVICE(ss));
     }
 
     QLIST_FOREACH(ics, &xics->ics, list) {
@@ -193,6 +197,7 @@ static void xics_common_initfn(Object *obj)
     XICSState *xics = XICS_COMMON(obj);
 
     QLIST_INIT(&xics->ics);
+    xics->ss_class = object_class_by_name(TYPE_ICP);
     object_property_add(obj, "nr_irqs", "int",
                         xics_prop_get_nr_irqs, xics_prop_set_nr_irqs,
                         NULL, NULL, NULL);
@@ -201,7 +206,15 @@ static void xics_common_initfn(Object *obj)
                         NULL, NULL, NULL);
 
     /* For exclusive use of monitor command */
-    g_xics = XICS_COMMON(obj);
+    g_xics = xics;
+}
+
+static void xics_common_realize(DeviceState *dev, Error **errp)
+{
+    XICSState *xics = XICS_COMMON(dev);
+    XICSStateClass *xsc = XICS_COMMON_GET_CLASS(xics);
+
+    xsc->realize(dev, errp);
 }
 
 static void xics_common_class_init(ObjectClass *oc, void *data)
@@ -209,6 +222,7 @@ static void xics_common_class_init(ObjectClass *oc, void *data)
     DeviceClass *dc = DEVICE_CLASS(oc);
 
     dc->reset = xics_common_reset;
+    dc->realize = xics_common_realize;
 }
 
 static const TypeInfo xics_common_info = {
@@ -277,7 +291,7 @@ static void icp_check_ipi(ICPState *ss)
 
 static void icp_resend(XICSState *xics, int server)
 {
-    ICPState *ss = xics->ss + server;
+    ICPState *ss = xics->ss + server * sizeof(ICPState);
     ICSState *ics;
 
     if (ss->mfrr < CPPR(ss)) {
@@ -290,7 +304,7 @@ static void icp_resend(XICSState *xics, int server)
 
 void icp_set_cppr(XICSState *xics, int server, uint8_t cppr)
 {
-    ICPState *ss = xics->ss + server;
+    ICPState *ss = xics->ss + server * sizeof(ICPState);
     uint8_t old_cppr;
     uint32_t old_xisr;
 
@@ -317,7 +331,7 @@ void icp_set_cppr(XICSState *xics, int server, uint8_t cppr)
 
 void icp_set_mfrr(XICSState *xics, int server, uint8_t mfrr)
 {
-    ICPState *ss = xics->ss + server;
+    ICPState *ss = xics->ss + server * sizeof(ICPState);
 
     ss->mfrr = mfrr;
     if (mfrr < CPPR(ss)) {
@@ -349,7 +363,7 @@ uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr)
 
 void icp_eoi(XICSState *xics, int server, uint32_t xirr)
 {
-    ICPState *ss = xics->ss + server;
+    ICPState *ss = xics->ss + server * sizeof(ICPState);
     ICSState *ics;
     uint32_t irq;
 
@@ -370,7 +384,7 @@ void icp_eoi(XICSState *xics, int server, uint32_t xirr)
 static void icp_irq(ICSState *ics, int server, int nr, uint8_t priority)
 {
     XICSState *xics = ics->xics;
-    ICPState *ss = xics->ss + server;
+    ICPState *ss = xics->ss + server * sizeof(ICPState);
 
     trace_xics_icp_irq(server, nr, priority);
 
@@ -488,6 +502,14 @@ static const TypeInfo icp_info = {
     .class_size = sizeof(ICPStateClass),
 };
 
+static const TypeInfo icp_native_info = {
+    .name = TYPE_NATIVE_ICP,
+    .parent = TYPE_ICP,
+    .instance_size = sizeof(ICPNative),
+    .class_init = icp_class_init,
+    .class_size = sizeof(ICPStateClass),
+};
+
 /*
  * ICS: Source layer
  */
@@ -689,7 +711,7 @@ void xics_hmp_info_pic(Monitor *mon, const QDict *qdict)
     uint32_t i;
 
     for (i = 0; i < g_xics->nr_servers; i++) {
-        ICPState *icp = &g_xics->ss[i];
+        ICPState *icp = g_xics->ss + i * sizeof(ICPState);
 
         if (!icp->output) {
             continue;
@@ -829,12 +851,44 @@ void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
         lsi ? XICS_FLAGS_IRQ_LSI : XICS_FLAGS_IRQ_MSI;
 }
 
+void xics_set_nr_irqs(XICSState *xics, uint32_t nr_irqs, Error **errp)
+{
+    ICSState *ics = QLIST_FIRST(&xics->ics);
+
+    /* This needs to be deprecated ... */
+    xics->nr_irqs = nr_irqs;
+    if (ics) {
+        ics->nr_irqs = nr_irqs;
+    }
+}
+
+void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers, Error **errp)
+{
+    int i;
+    const char *typename = object_class_get_name(xics->ss_class);
+    size_t size = object_type_get_instance_size(typename);
+
+    xics->nr_servers = nr_servers;
+
+    xics->ss = g_malloc0(xics->nr_servers * size);
+    for (i = 0; i < xics->nr_servers; i++) {
+        char buffer[32];
+        void *obj;
+
+        obj = xics->ss + size * i;
+        object_initialize(obj, size, typename);
+        snprintf(buffer, sizeof(buffer), "icp[%d]", i);
+        object_property_add_child(OBJECT(xics), buffer, obj, errp);
+    }
+}
+
 static void xics_register_types(void)
 {
     type_register_static(&xics_common_info);
     type_register_static(&ics_simple_info);
     type_register_static(&ics_base_info);
     type_register_static(&icp_info);
+    type_register_static(&icp_native_info);
 }
 
 type_init(xics_register_types)
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 89862df..b095b9e 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -362,35 +362,6 @@ static void xics_kvm_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
     }
 }
 
-static void xics_kvm_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
-                                 Error **errp)
-{
-    ICSState *ics = QLIST_FIRST(&xics->ics);
-
-    /* This needs to be deprecated ... */
-    xics->nr_irqs = nr_irqs;
-    if (ics) {
-        ics->nr_irqs = nr_irqs;
-    }
-}
-
-static void xics_kvm_set_nr_servers(XICSState *xics, uint32_t nr_servers,
-                                    Error **errp)
-{
-    int i;
-
-    xics->nr_servers = nr_servers;
-
-    xics->ss = g_malloc0(xics->nr_servers * sizeof(ICPState));
-    for (i = 0; i < xics->nr_servers; i++) {
-        char buffer[32];
-        object_initialize(&xics->ss[i], sizeof(xics->ss[i]), TYPE_KVM_ICP);
-        snprintf(buffer, sizeof(buffer), "icp[%d]", i);
-        object_property_add_child(OBJECT(xics), buffer, OBJECT(&xics->ss[i]),
-                                  errp);
-    }
-}
-
 static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                        uint32_t token,
                        uint32_t nargs, target_ulong args,
@@ -492,6 +463,7 @@ static void xics_kvm_initfn(Object *obj)
     XICSState *xics = XICS_COMMON(obj);
     ICSState *ics;
 
+    xics->ss_class = object_class_by_name(TYPE_KVM_ICP);
     ics = ICS_SIMPLE(object_new(TYPE_ICS_KVM));
     object_property_add_child(obj, "ics", OBJECT(ics), NULL);
     ics->xics = xics;
@@ -505,8 +477,8 @@ static void xics_kvm_class_init(ObjectClass *oc, void *data)
 
     dc->realize = xics_kvm_realize;
     xsc->cpu_setup = xics_kvm_cpu_setup;
-    xsc->set_nr_irqs = xics_kvm_set_nr_irqs;
-    xsc->set_nr_servers = xics_kvm_set_nr_servers;
+    xsc->set_nr_irqs = xics_set_nr_irqs;
+    xsc->set_nr_servers = xics_set_nr_servers;
 }
 
 static const TypeInfo xics_spapr_kvm_info = {
diff --git a/hw/intc/xics_native.c b/hw/intc/xics_native.c
index 26e45cc..db2fd4d 100644
--- a/hw/intc/xics_native.c
+++ b/hw/intc/xics_native.c
@@ -38,11 +38,19 @@
 /* #define DEBUG_MM(fmt...)      printf(fmt) */
 #define DEBUG_MM(fmt...)        do { } while (0)
 
+typedef struct XICSNative {
+    /*< private >*/
+    XICSState xics;
+
+    /*< public >*/
+    MemoryRegion icp_mmio;
+} XICSNative;
+
 static void xics_native_initfn(Object *obj)
 {
-    XICSState *xics = XICS_NATIVE(obj);
+    XICSState *xics = XICS_COMMON(obj);
 
-    QLIST_INIT(&xics->ics);
+    xics->ss_class = object_class_by_name(TYPE_NATIVE_ICP);
 }
 
 static uint64_t icp_mm_read(void *opaque, hwaddr addr, unsigned width)
@@ -51,6 +59,7 @@ static uint64_t icp_mm_read(void *opaque, hwaddr addr, unsigned width)
     int32_t cpu_id, server;
     uint32_t val;
     ICPState *ss;
+    ICPNative *icpn;
     bool byte0 = (width == 1 && (addr & 0x3) == 0);
 
     cpu_id = (addr & (ICP_MM_SIZE - 1)) >> 12;
@@ -59,7 +68,8 @@ static uint64_t icp_mm_read(void *opaque, hwaddr addr, unsigned width)
         fprintf(stderr, "XICS: Bad ICP server %d\n", server);
         goto bad_access;
     }
-    ss = &s->ss[server];
+    icpn = s->ss + server * sizeof(ICPNative);
+    ss = &icpn->icp;
 
     switch (addr & 0xffc) {
     case 0: /* poll */
@@ -88,21 +98,21 @@ static uint64_t icp_mm_read(void *opaque, hwaddr addr, unsigned width)
         break;
     case 16:
         if (width == 4) {
-            val = ss->links[0];
+            val = icpn->links[0];
         } else {
             goto bad_access;
         }
         break;
     case 20:
         if (width == 4) {
-            val = ss->links[1];
+            val = icpn->links[1];
         } else {
             goto bad_access;
         }
         break;
     case 24:
         if (width == 4) {
-            val = ss->links[2];
+            val = icpn->links[2];
         } else {
             goto bad_access;
         }
@@ -125,7 +135,7 @@ static void icp_mm_write(void *opaque, hwaddr addr, uint64_t val,
 {
     XICSState *s = opaque;
     int32_t cpu_id, server;
-    ICPState *ss;
+    ICPNative *icpn;
     bool byte0 = (width == 1 && (addr & 0x3) == 0);
 
     cpu_id = (addr & (ICP_MM_SIZE - 1)) >> 12;
@@ -134,7 +144,8 @@ static void icp_mm_write(void *opaque, hwaddr addr, uint64_t val,
         fprintf(stderr, "XICS: Bad ICP server %d\n", server);
         goto bad_access;
     }
-    ss = &s->ss[server];
+    icpn = s->ss + server * sizeof(ICPNative);
+    ss = &icpn->icp;
 
     DEBUG_MM("icp_mm_write(addr=%016llx,serv=0x%x/%d,off=%d,w=%d,val=0x%08x)\n",
              (unsigned long long)addr, cpu_id, server,
@@ -159,21 +170,21 @@ static void icp_mm_write(void *opaque, hwaddr addr, uint64_t val,
         break;
     case 16:
         if (width == 4) {
-            ss->links[0] = val;
+            icpn->links[0] = val;
         } else {
             goto bad_access;
         }
         break;
     case 20:
         if (width == 4) {
-            ss->links[1] = val;
+            icpn->links[1] = val;
         } else {
             goto bad_access;
         }
         break;
     case 24:
         if (width == 4) {
-            ss->links[2] = val;
+            icpn->links[2] = val;
         } else {
             goto bad_access;
         }
@@ -245,8 +256,9 @@ void xics_create_native_icp_node(XICSState *s, void *fdt,
 
 static void xics_native_realize(DeviceState *dev, Error **errp)
 {
-    XICSState *s = XICS_NATIVE(dev);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    XICSNative *n = XICS_NATIVE(dev);
+    XICSState *s = XICS_COMMON(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(s);
     Error *error = NULL;
     int i;
 
@@ -256,13 +268,14 @@ static void xics_native_realize(DeviceState *dev, Error **errp)
     }
 
     /* Register MMIO regions */
-    memory_region_init_io(&s->icp_mmio, OBJECT(s), &icp_mm_ops, s, "icp",
+    memory_region_init_io(&n->icp_mmio, OBJECT(s), &icp_mm_ops, s, "icp",
                           ICP_MM_SIZE);
-    sysbus_init_mmio(sbd, &s->icp_mmio);
+    sysbus_init_mmio(sbd, &n->icp_mmio);
     sysbus_mmio_map(sbd, 0, ICP_MM_BASE);
 
     for (i = 0; i < s->nr_servers; i++) {
-        object_property_set_bool(OBJECT(&s->ss[i]), true, "realized", &error);
+        ICPNative *icpn = s->ss + i * sizeof(ICPNative);
+        object_property_set_bool(OBJECT(icpn), true, "realized", &error);
         if (error) {
             error_propagate(errp, error);
             return;
@@ -272,20 +285,18 @@ static void xics_native_realize(DeviceState *dev, Error **errp)
 
 static void xics_native_class_init(ObjectClass *oc, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(oc);
     XICSStateClass *xsc = XICS_NATIVE_CLASS(oc);
 
-    dc->realize = xics_native_realize;
+    xsc->realize = xics_native_realize;
     xsc->set_nr_servers = xics_set_nr_servers;
 }
 
 static const TypeInfo xics_native_info = {
     .name          = TYPE_XICS_NATIVE,
     .parent        = TYPE_XICS_COMMON,
-    .instance_size = sizeof(XICSState),
+    .instance_size = sizeof(XICSNative),
     .class_size = sizeof(XICSStateClass),
     .class_init    = xics_native_class_init,
-    .instance_init = xics_native_initfn,
 };
 
 static void xics_native_register_types(void)
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 4dd1399..0644942 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -67,7 +67,8 @@ static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                            target_ulong opcode, target_ulong *args)
 {
     CPUState *cs = CPU(cpu);
-    uint32_t xirr = icp_accept(spapr->xics->ss + cs->cpu_index);
+    uint32_t xirr = icp_accept(spapr->xics->ss +
+                               cs->cpu_index * sizeof(ICPState));
 
     args[0] = xirr;
     return H_SUCCESS;
@@ -77,9 +78,11 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                              target_ulong opcode, target_ulong *args)
 {
     CPUState *cs = CPU(cpu);
-    ICPState *ss = &spapr->xics->ss[cs->cpu_index];
-    uint32_t xirr = icp_accept(ss);
+    ICPState *ss;
+    uint32_t xirr;
 
+    ss = spapr->xics->ss + cs->cpu_index * sizeof(ICPState);
+    xirr = icp_accept(ss);
     args[0] = xirr;
     args[1] = cpu_get_host_ticks();
     return H_SUCCESS;
@@ -100,7 +103,8 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 {
     CPUState *cs = CPU(cpu);
     uint32_t mfrr;
-    uint32_t xirr = icp_ipoll(spapr->xics->ss + cs->cpu_index, &mfrr);
+    uint32_t xirr = icp_ipoll(spapr->xics->ss +
+                              cs->cpu_index * sizeof(ICPState), &mfrr);
 
     args[0] = xirr;
     args[1] = mfrr;
@@ -234,35 +238,6 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
 
-static void xics_spapr_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
-                                   Error **errp)
-{
-    ICSState *ics = QLIST_FIRST(&xics->ics);
-
-    /* This needs to be deprecated ... */
-    xics->nr_irqs = nr_irqs;
-    if (ics) {
-        ics->nr_irqs = nr_irqs;
-    }
-}
-
-static void xics_spapr_set_nr_servers(XICSState *xics, uint32_t nr_servers,
-                                      Error **errp)
-{
-    int i;
-
-    xics->nr_servers = nr_servers;
-
-    xics->ss = g_malloc0(xics->nr_servers * sizeof(ICPState));
-    for (i = 0; i < xics->nr_servers; i++) {
-        char buffer[32];
-        object_initialize(&xics->ss[i], sizeof(xics->ss[i]), TYPE_ICP);
-        snprintf(buffer, sizeof(buffer), "icp[%d]", i);
-        object_property_add_child(OBJECT(xics), buffer, OBJECT(&xics->ss[i]),
-                                  errp);
-    }
-}
-
 static void xics_spapr_realize(DeviceState *dev, Error **errp)
 {
     XICSState *xics = XICS_SPAPR(dev);
@@ -297,8 +272,8 @@ static void xics_spapr_realize(DeviceState *dev, Error **errp)
     }
 
     for (i = 0; i < xics->nr_servers; i++) {
-        object_property_set_bool(OBJECT(&xics->ss[i]), true, "realized",
-                                 &error);
+        ICPState *ss = xics->ss + i * sizeof(ICPState);
+        object_property_set_bool(OBJECT(ss), true, "realized", &error);
         if (error) {
             error_propagate(errp, error);
             return;
@@ -319,8 +294,8 @@ static void xics_spapr_class_init(ObjectClass *oc, void *data)
     XICSStateClass *xsc = XICS_SPAPR_CLASS(oc);
 
     dc->realize = xics_spapr_realize;
-    xsc->set_nr_irqs = xics_spapr_set_nr_irqs;
-    xsc->set_nr_servers = xics_spapr_set_nr_servers;
+    xsc->set_nr_irqs = xics_set_nr_irqs;
+    xsc->set_nr_servers = xics_set_nr_servers;
 }
 
 static const TypeInfo xics_spapr_info = {
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 58bb7c6..0a427d7 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -45,7 +45,7 @@
      OBJECT_CHECK(KVMXICSState, (obj), TYPE_XICS_SPAPR_KVM)
 
 #define TYPE_XICS_NATIVE "xics-native"
-#define XICS_NATIVE(obj) OBJECT_CHECK(XICSState, (obj), TYPE_XICS_NATIVE)
+#define XICS_NATIVE(obj) OBJECT_CHECK(XICSNative, (obj), TYPE_XICS_NATIVE)
 
 #define XICS_COMMON_CLASS(klass) \
      OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_COMMON)
@@ -71,6 +71,7 @@ typedef struct XICSStateClass XICSStateClass;
 typedef struct XICSState XICSState;
 typedef struct ICPStateClass ICPStateClass;
 typedef struct ICPState ICPState;
+typedef struct ICPNative ICPNative;
 typedef struct ICSStateClass ICSStateClass;
 typedef struct ICSState ICSState;
 typedef struct ICSIRQState ICSIRQState;
@@ -78,6 +79,7 @@ typedef struct ICSIRQState ICSIRQState;
 struct XICSStateClass {
     DeviceClass parent_class;
 
+    DeviceRealize realize;
     void (*cpu_setup)(XICSState *icp, PowerPCCPU *cpu);
     void (*set_nr_irqs)(XICSState *icp, uint32_t nr_irqs, Error **errp);
     void (*set_nr_servers)(XICSState *icp, uint32_t nr_servers, Error **errp);
@@ -89,9 +91,9 @@ struct XICSState {
     /*< public >*/
     uint32_t nr_servers;
     uint32_t nr_irqs;
-    ICPState *ss;
+    void *ss;
+    ObjectClass *ss_class;
     QLIST_HEAD(, ICSState) ics;
-    MemoryRegion icp_mmio;
 };
 
 #define TYPE_ICP "icp"
@@ -100,6 +102,9 @@ struct XICSState {
 #define TYPE_KVM_ICP "icp-kvm"
 #define KVM_ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_KVM_ICP)
 
+#define TYPE_NATIVE_ICP "icp-native"
+#define NATIVE_ICP(obj) OBJECT_CHECK(ICPNative, (obj), TYPE_NATIVE_ICP)
+
 #define ICP_CLASS(klass) \
      OBJECT_CLASS_CHECK(ICPStateClass, (klass), TYPE_ICP)
 #define ICP_GET_CLASS(obj) \
@@ -123,6 +128,12 @@ struct ICPState {
     uint8_t mfrr;
     qemu_irq output;
     bool cap_irq_xics_enabled;
+};
+
+struct ICPNative {
+    /*<private>*/
+    ICPState icp;
+    /*<public>*/
     uint32_t links[3];
 };
 
@@ -199,6 +210,8 @@ void xics_spapr_free(XICSState *icp, int irq, int num);
 
 void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu);
 void xics_cpu_destroy(XICSState *icp, PowerPCCPU *cpu);
+void xics_set_nr_irqs(XICSState *xics, uint32_t nr_irqs, Error **errp);
+void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers, Error **errp);
 
 void xics_create_native_icp_node(XICSState *s, void *fdt,
                                  uint32_t base, uint32_t count);
