diff --git a/xen/arch/arm/arm64/smpboot.c b/xen/arch/arm/arm64/smpboot.c
index 8696ed6..6a34bd4 100644
--- a/xen/arch/arm/arm64/smpboot.c
+++ b/xen/arch/arm/arm64/smpboot.c
@@ -38,7 +38,7 @@ static int __init smp_spin_table_cpu_up(int cpu)
 
     sev();
 
-    return 0;
+    return cpu_up_send_sgi(cpu);
 }
 
 static void __init smp_spin_table_init(int cpu, struct dt_device_node *dn)
diff --git a/xen/arch/arm/platform.c b/xen/arch/arm/platform.c
index 5ed8eb2..e13a354 100644
--- a/xen/arch/arm/platform.c
+++ b/xen/arch/arm/platform.c
@@ -112,7 +112,7 @@ int __init platform_cpu_up(int cpu)
     if ( platform && platform->cpu_up )
         return platform->cpu_up(cpu);
 
-    return -EAGAIN;
+    return -ENODEV;
 }
 
 int __init platform_smp_init(void)
diff --git a/xen/arch/arm/platforms/exynos5.c b/xen/arch/arm/platforms/exynos5.c
index fa6b465..65e584f 100644
--- a/xen/arch/arm/platforms/exynos5.c
+++ b/xen/arch/arm/platforms/exynos5.c
@@ -85,15 +85,6 @@ static int __init exynos5_smp_init(void)
     return 0;
 }
 
-static int __init exynos5_cpu_up(int cpu)
-{
-    /* Nothing to do here, the generic sev() will suffice to kick CPUs
-     * out of either the firmware or our own smp_up_cpu gate,
-     * depending on where they have ended up. */
-
-    return 0;
-}
-
 static void exynos5_reset(void)
 {
     void __iomem *pmu;
@@ -132,7 +123,7 @@ PLATFORM_START(exynos5, "SAMSUNG EXYNOS5")
     .init_time = exynos5_init_time,
     .specific_mapping = exynos5_specific_mapping,
     .smp_init = exynos5_smp_init,
-    .cpu_up = exynos5_cpu_up,
+    .cpu_up = cpu_up_send_sgi,
     .reset = exynos5_reset,
     .blacklist_dev = exynos5_blacklist_dev,
 PLATFORM_END
diff --git a/xen/arch/arm/platforms/omap5.c b/xen/arch/arm/platforms/omap5.c
index 3a3b16b..423d11b 100644
--- a/xen/arch/arm/platforms/omap5.c
+++ b/xen/arch/arm/platforms/omap5.c
@@ -144,15 +144,6 @@ static int __init omap5_smp_init(void)
     return 0;
 }
 
-static int __init omap5_cpu_up(int cpu)
-{
-    /* Nothing to do here, the generic sev() will suffice to kick CPUs
-     * out of either the firmware or our own smp_up_cpu gate,
-     * depending on where they have ended up. */
-
-    return 0;
-}
-
 static const char const *omap5_dt_compat[] __initconst =
 {
     "ti,omap5",
@@ -164,7 +155,7 @@ PLATFORM_START(omap5, "TI OMAP5")
     .init_time = omap5_init_time,
     .specific_mapping = omap5_specific_mapping,
     .smp_init = omap5_smp_init,
-    .cpu_up = omap5_cpu_up,
+    .cpu_up = cpu_up_send_sgi,
 PLATFORM_END
 
 /*
diff --git a/xen/arch/arm/platforms/vexpress.c b/xen/arch/arm/platforms/vexpress.c
index 9056366..6132056 100644
--- a/xen/arch/arm/platforms/vexpress.c
+++ b/xen/arch/arm/platforms/vexpress.c
@@ -144,14 +144,6 @@ static int __init vexpress_smp_init(void)
     return 0;
 }
 
-static int __init vexpress_cpu_up(int cpu)
-{
-    /* Nothing to do here, the generic sev() will suffice to kick CPUs
-     * out of either the firmware or our own smp_up_cpu gate,
-     * depending on where they have ended up. */
-
-    return 0;
-}
 #endif
 
 static const char * const vexpress_dt_compat[] __initconst =
@@ -180,7 +172,7 @@ PLATFORM_START(vexpress, "VERSATILE EXPRESS")
     .compatible = vexpress_dt_compat,
 #ifdef CONFIG_ARM_32
     .smp_init = vexpress_smp_init,
-    .cpu_up = vexpress_cpu_up,
+    .cpu_up = cpu_up_send_sgi,
 #endif
     .reset = vexpress_reset,
     .blacklist_dev = vexpress_blacklist_dev,
diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c
index bd76d14..8d96c17 100644
--- a/xen/arch/arm/smpboot.c
+++ b/xen/arch/arm/smpboot.c
@@ -343,6 +343,16 @@ void stop_cpu(void)
         wfi();
 }
 
+int __init cpu_up_send_sgi(int cpu)
+{
+    /* We don't know the GIC ID of the CPU until it has woken up, so just
+     * signal everyone and rely on our own smp_up_cpu gate to ensure only
+     * the one we want gets through. */
+    send_SGI_allbutself(GIC_SGI_EVENT_CHECK);
+
+    return 0;
+}
+
 /* Bring up a remote CPU */
 int __cpu_up(unsigned int cpu)
 {
@@ -376,11 +386,6 @@ int __cpu_up(unsigned int cpu)
         return rc;
     }
 
-    /* We don't know the GIC ID of the CPU until it has woken up, so just signal
-     * everyone and rely on our own smp_up_cpu gate to ensure only the one we
-     * want gets through. */
-    send_SGI_allbutself(GIC_SGI_EVENT_CHECK);
-
     while ( !cpu_online(cpu) )
     {
         cpu_relax();
diff --git a/xen/include/asm-arm/smp.h b/xen/include/asm-arm/smp.h
index 1485cc6..a1de03c 100644
--- a/xen/include/asm-arm/smp.h
+++ b/xen/include/asm-arm/smp.h
@@ -21,6 +21,8 @@ extern int arch_smp_init(void);
 extern int arch_cpu_init(int cpu, struct dt_device_node *dn);
 extern int arch_cpu_up(int cpu);
 
+int cpu_up_send_sgi(int cpu);
+
 /* Secondary CPU entry point */
 extern void init_secondary(void);
 
