diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 0cd534df55f8..a8153448c4d4 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -820,9 +820,9 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
         PowerPCCPU *cpu;
         CPUState *cs;
         qemu_irq *input;
 
-        cpu = cpu_ppc_init(machine->cpu_model);
+        cpu = ppc_cpu_init(machine->cpu_model, NULL);
         if (cpu == NULL) {
             fprintf(stderr, "Unable to initialize CPU!\n");
             exit(1);
         }
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 32e88b378687..5d4c28cdb5b2 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -192,9 +192,9 @@ static void ppc_core99_init(MachineState *machine)
         machine->cpu_model = "G4";
 #endif
     }
     for (i = 0; i < smp_cpus; i++) {
-        cpu = cpu_ppc_init(machine->cpu_model);
+        cpu = ppc_cpu_init(machine->cpu_model, NULL);
         if (cpu == NULL) {
             fprintf(stderr, "Unable to find PowerPC CPU definition\n");
             exit(1);
         }
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 447948746b1a..3ebabd7f203b 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -112,9 +112,9 @@ static void ppc_heathrow_init(MachineState *machine)
     /* init CPUs */
     if (machine->cpu_model == NULL)
         machine->cpu_model = "G3";
     for (i = 0; i < smp_cpus; i++) {
-        cpu = cpu_ppc_init(machine->cpu_model);
+        cpu = ppc_cpu_init(machine->cpu_model, NULL);
         if (cpu == NULL) {
             fprintf(stderr, "Unable to find PowerPC CPU definition\n");
             exit(1);
         }
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index e4252528a69d..c234b7adfd43 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -36,8 +36,9 @@
 #include "hw/loader.h"
 #include "sysemu/kvm.h"
 #include "kvm_ppc.h"
 #include "trace.h"
+#include "qapi/error.h"
 
 //#define PPC_DEBUG_IRQ
 //#define PPC_DEBUG_TB
 
@@ -1349,4 +1350,63 @@ PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id)
     }
 
     return NULL;
 }
+
+void ppc_cpu_compute_dt_id_generic(PowerPCCPU *cpu, Error **errp)
+{
+    CPUState *cs = CPU(cpu);
+    int max_smt = kvm_enabled() ? kvmppc_smt_threads() : 1;
+
+    if (smp_threads > max_smt) {
+        error_setg(errp, "Cannot support more than %d threads on PPC with %s",
+                   max_smt, kvm_enabled() ? "KVM" : "TCG");
+        return;
+    }
+    if (!is_power_of_2(smp_threads)) {
+        error_setg(errp, "Cannot support %d threads on PPC with %s, "
+                   "threads count must be a power of 2.",
+                   smp_threads, kvm_enabled() ? "KVM" : "TCG");
+        return;
+    }
+
+    if (kvm_enabled() && !kvm_vcpu_id_is_valid(cpu->cpu_dt_id)) {
+        error_setg(errp, "Can't create CPU with id %d in KVM", cpu->cpu_dt_id);
+        error_append_hint(errp, "Adjust the number of cpus to %d "
+                          "or try to raise the number of threads per core\n",
+                          cpu->cpu_dt_id * smp_threads / max_smt);
+        return;
+    }
+
+    cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt
+        + (cs->cpu_index % smp_threads);
+}
+
+PowerPCCPU *ppc_cpu_init(const char *cpu_model, cpu_compute_dt_id_fn compute_fn)
+{
+    PowerPCCPU *cpu;
+    Error *err = NULL;
+
+    cpu = POWERPC_CPU(cpu_generic_init_no_realize(TYPE_POWERPC_CPU, cpu_model));
+    if (cpu == NULL) {
+        return NULL;
+    }
+
+    if (compute_fn) {
+        compute_fn(cpu, &err);
+    } else {
+        ppc_cpu_compute_dt_id_generic(cpu, &err);
+    }
+    if (err != NULL) {
+        goto out;
+    }
+
+    object_property_set_bool(OBJECT(cpu), true, "realized", &err);
+out:
+    if (err != NULL) {
+        error_report_err(err);
+        object_unref(OBJECT(cpu));
+        return NULL;
+    }
+
+    return cpu;
+}
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 5c535b18a20d..c5ea15b1f732 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -185,9 +185,9 @@ static void bamboo_init(MachineState *machine)
     /* Setup CPU. */
     if (machine->cpu_model == NULL) {
         machine->cpu_model = "440EP";
     }
-    cpu = cpu_ppc_init(machine->cpu_model);
+    cpu = ppc_cpu_init(machine->cpu_model, NULL);
     if (cpu == NULL) {
         fprintf(stderr, "Unable to initialize CPU!\n");
         exit(1);
     }
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index e7f413e49d08..b28bca1b797b 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -55,9 +55,9 @@ PowerPCCPU *ppc4xx_init(const char *cpu_model,
     PowerPCCPU *cpu;
     CPUPPCState *env;
 
     /* init CPUs */
-    cpu = cpu_ppc_init(cpu_model);
+    cpu = ppc_cpu_init(cpu_model, NULL);
     if (cpu == NULL) {
         fprintf(stderr, "Unable to find PowerPC %s CPU definition\n",
                 cpu_model);
         exit(1);
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 054af1e8b481..1bd3ede62114 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -508,9 +508,9 @@ static void ppc_prep_init(MachineState *machine)
     /* init CPUs */
     if (machine->cpu_model == NULL)
         machine->cpu_model = "602";
     for (i = 0; i < smp_cpus; i++) {
-        cpu = cpu_ppc_init(machine->cpu_model);
+        cpu = ppc_cpu_init(machine->cpu_model, NULL);
         if (cpu == NULL) {
             fprintf(stderr, "Unable to find PowerPC CPU definition\n");
             exit(1);
         }
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 0771c93f6550..040c9158cce4 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1834,9 +1834,9 @@ static void ppc_spapr_init(MachineState *machine)
         }
         g_free(type);
     } else {
         for (i = 0; i < smp_cpus; i++) {
-            PowerPCCPU *cpu = cpu_ppc_init(machine->cpu_model);
+            PowerPCCPU *cpu = ppc_cpu_init(machine->cpu_model, NULL);
             if (cpu == NULL) {
                 error_report("Unable to find PowerPC CPU definition");
                 exit(1);
             }
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index a15dc010626d..56f360cb6c7f 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -12,8 +12,9 @@
 #include "hw/ppc/spapr.h"
 #include "hw/boards.h"
 #include "qapi/error.h"
 #include <sysemu/cpus.h>
+#include <sysemu/kvm.h>
 #include "target-ppc/kvm_ppc.h"
 #include "hw/ppc/ppc.h"
 #include "target-ppc/mmu-hash64.h"
 #include <sysemu/numa.h>
@@ -265,8 +266,14 @@ static int spapr_cpu_core_realize_child(Object *child, void *opaque)
     sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
     CPUState *cs = CPU(child);
     PowerPCCPU *cpu = POWERPC_CPU(cs);
 
+    ppc_cpu_compute_dt_id_generic(cpu, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return 1;
+    }
+
     object_property_set_bool(child, true, "realized", &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return 1;
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index b97d96685cf1..cf3e71b9f2cc 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -95,9 +95,9 @@ static PowerPCCPU *ppc440_init_xilinx(ram_addr_t *ram_size,
     PowerPCCPU *cpu;
     CPUPPCState *env;
     qemu_irq *irqs;
 
-    cpu = cpu_ppc_init(cpu_model);
+    cpu = ppc_cpu_init(cpu_model, NULL);
     if (cpu == NULL) {
         fprintf(stderr, "Unable to initialize CPU!\n");
         exit(1);
     }
diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h
index 5617dc4a2c04..3e6aa7e7720f 100644
--- a/include/hw/ppc/ppc.h
+++ b/include/hw/ppc/ppc.h
@@ -105,5 +105,9 @@ enum {
 
 /* ppc_booke.c */
 void ppc_booke_timers_init(PowerPCCPU *cpu, uint32_t freq, uint32_t flags);
 
+typedef void (*cpu_compute_dt_id_fn)(PowerPCCPU *cpu, Error **errp);
+PowerPCCPU *ppc_cpu_init(const char *cpu_model,
+                         cpu_compute_dt_id_fn compute_fn);
+void ppc_cpu_compute_dt_id_generic(PowerPCCPU *cpu, Error **errp);
 #endif
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index f7571f34d6ac..f9d1ee8b12f9 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -9522,45 +9522,15 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
     CPUState *cs = CPU(dev);
     PowerPCCPU *cpu = POWERPC_CPU(dev);
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
     Error *local_err = NULL;
-#if !defined(CONFIG_USER_ONLY)
-    int max_smt = kvm_enabled() ? kvmppc_smt_threads() : 1;
-#endif
-
-#if !defined(CONFIG_USER_ONLY)
-    if (smp_threads > max_smt) {
-        error_setg(errp, "Cannot support more than %d threads on PPC with %s",
-                   max_smt, kvm_enabled() ? "KVM" : "TCG");
-        return;
-    }
-    if (!is_power_of_2(smp_threads)) {
-        error_setg(errp, "Cannot support %d threads on PPC with %s, "
-                   "threads count must be a power of 2.",
-                   smp_threads, kvm_enabled() ? "KVM" : "TCG");
-        return;
-    }
-#endif
 
     cpu_exec_realize(cs, &local_err);
     if (local_err != NULL) {
         error_propagate(errp, local_err);
         return;
     }
 
-#if !defined(CONFIG_USER_ONLY)
-    cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt
-        + (cs->cpu_index % smp_threads);
-
-    if (kvm_enabled() && !kvm_vcpu_id_is_valid(cpu->cpu_dt_id)) {
-        error_setg(errp, "Can't create CPU with id %d in KVM", cpu->cpu_dt_id);
-        error_append_hint(errp, "Adjust the number of cpus to %d "
-                          "or try to raise the number of threads per core\n",
-                          cpu->cpu_dt_id * smp_threads / max_smt);
-        return;
-    }
-#endif
-
     if (tcg_enabled()) {
         if (ppc_fixup_cpu(cpu) != 0) {
             error_setg(errp, "Unable to emulate selected CPU with TCG");
             return;
