diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index 448e958..579d266 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -67,6 +67,7 @@ int xc_domain_create(xc_interface *xch,
     /* No arch-specific configuration for now */
 #elif defined (__arm__) || defined(__aarch64__)
     config.gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
+    config.nr_spis = 0;
 #else
     errno = ENOSYS;
     return -1;
diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
index dc0919a..2407c2e 100644
--- a/tools/libxl/libxl_arm.c
+++ b/tools/libxl/libxl_arm.c
@@ -39,6 +39,27 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
                                       libxl_domain_config *d_config,
                                       xc_domain_configuration_t *xc_config)
 {
+    uint32_t nr_spis = 0;
+    unsigned int i;
+
+    for (i = 0; i < d_config->b_info.num_irqs; i++) {
+        uint32_t irq = d_config->b_info.irqs[i];
+        uint32_t spi;
+
+        if (irq < 32)
+            continue;
+
+        spi = irq - 32;
+
+        if (nr_spis <= spi)
+            nr_spis = spi + 1;
+    }
+
+    LOG(DEBUG, "Configure the domain");
+
+    xc_config->nr_spis = nr_spis;
+    LOG(DEBUG, " - Allocate %u SPIs", nr_spis);
+
     xc_config->gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
 
     return 0;
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index ce9f349..7c5bf9f 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -562,7 +562,7 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
     if ( (rc = gicv_setup(d)) != 0 )
         goto fail;
 
-    if ( (rc = domain_vgic_init(d)) != 0 )
+    if ( (rc = domain_vgic_init(d, config->nr_spis)) != 0 )
         goto fail;
 
     if ( (rc = domain_vtimer_init(d)) != 0 )
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index defe39e..c935266 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -830,6 +830,7 @@ void __init start_xen(unsigned long boot_phys_offset,
     /* Create initial domain 0. */
     /* The vGIC for DOM0 is exactly emulated the hardware GIC */
     config.gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
+    config.nr_spis = gic_number_lines() - 32;
 
     dom0 = domain_create(0, 0, 0, &config);
     if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) )
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index c07822f..74751e0 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -68,16 +68,17 @@ static void vgic_init_pending_irq(struct pending_irq *p, unsigned int virq)
     p->irq = virq;
 }
 
-int domain_vgic_init(struct domain *d)
+int domain_vgic_init(struct domain *d, unsigned int nr_spis)
 {
     int i;
 
     d->arch.vgic.ctlr = 0;
 
-    if ( is_hardware_domain(d) )
-        d->arch.vgic.nr_spis = gic_number_lines() - 32;
-    else
-        d->arch.vgic.nr_spis = 0; /* We don't need SPIs for the guest */
+    /* Limit the number of SPIs supported base on the hardware */
+    if ( nr_spis > (gic_number_lines() - NR_LOCAL_IRQS) )
+        return -EINVAL;
+
+    d->arch.vgic.nr_spis = nr_spis;
 
     switch ( gic_hw_version() )
     {
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index 9e0419e..6dacfef 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -125,6 +125,8 @@ struct arch_domain
     unsigned int evtchn_irq;
 }  __cacheline_aligned;
 
+#define domain_is_configured(d) ((d)->arch.is_configured)
+
 struct arch_vcpu
 {
     struct {
diff --git a/xen/include/asm-arm/setup.h b/xen/include/asm-arm/setup.h
index ba5a67d..254cc17 100644
--- a/xen/include/asm-arm/setup.h
+++ b/xen/include/asm-arm/setup.h
@@ -54,6 +54,7 @@ void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
 void arch_get_xen_caps(xen_capabilities_info_t *info);
 
 int construct_dom0(struct domain *d);
+int configure_dom0(struct domain *d);
 
 void discard_initial_modules(void);
 
diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
index aba0d80..647f2fe 100644
--- a/xen/include/asm-arm/vgic.h
+++ b/xen/include/asm-arm/vgic.h
@@ -177,7 +177,7 @@ enum gic_sgi_mode;
 
 #define vgic_num_irqs(d)        ((d)->arch.vgic.nr_spis + 32)
 
-extern int domain_vgic_init(struct domain *d);
+extern int domain_vgic_init(struct domain *d, unsigned int nr_spis);
 extern void domain_vgic_free(struct domain *d);
 extern int vcpu_vgic_init(struct vcpu *v);
 extern struct vcpu *vgic_get_target_vcpu(struct vcpu *v, unsigned int irq);
diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
index ed7e98f..c029e0f 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -315,6 +315,8 @@ typedef uint64_t xen_callback_t;
 struct xen_arch_domainconfig {
     /* IN/OUT */
     uint8_t gic_version;
+    /* IN */
+    uint32_t nr_spis;
 };
 
 #endif
