[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH V6 08/10] xen: Add arch_domain_preinit to initialise vGIC before evtchn_init



From: Chen Baozi <baozich@xxxxxxxxx>

evtchn_init will call domain_max_vcpus to allocate poll_mask. On
arm/arm64 platform, this number is determined by the vGIC the guest
is going to use, which won't be initialised until arch_domain_create
is called in current implementation. However, moving arch_domain_create
means that we will allocate memory before checking the XSM policy,
which seems not to be acceptable because if the domain is not allowed
to boot by XSM policy the expensive execution of arch_domain_create
is wasteful. Thus, we create the arch_domain_preinit to make vgic_ops
initialisation be done earlier.

Signed-off-by: Chen Baozi <baozich@xxxxxxxxx>
Cc: Julien Grall <julien.grall@xxxxxxxxxx>
Cc: Ian Campbell <ian.campbell@xxxxxxxxxx>
Cc: Stefano Stabellini <stefano.stabellini@xxxxxxxxxx>
Cc: Tim Deegan <tim@xxxxxxx>
Cc: Keir Fraser <keir@xxxxxxx>
Cc: Jan Beulich <jbeulich@xxxxxxxx>
Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 xen/arch/arm/domain.c    | 73 +++++++++++++++++++++++++++++++++---------------
 xen/arch/arm/vgic.c      | 14 ----------
 xen/arch/x86/domain.c    |  6 ++++
 xen/common/domain.c      |  3 ++
 xen/include/xen/domain.h |  2 ++
 5 files changed, 61 insertions(+), 37 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 0cf147c..63c34fd 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -527,37 +527,16 @@ void vcpu_destroy(struct vcpu *v)
     free_xenheap_pages(v->arch.stack, STACK_ORDER);
 }
 
-int arch_domain_create(struct domain *d, unsigned int domcr_flags,
-                       struct xen_arch_domainconfig *config)
+int arch_domain_preinit(struct domain *d,
+                        struct xen_arch_domainconfig *config)
 {
     int rc;
 
-    d->arch.relmem = RELMEM_not_started;
-
     /* Idle domains do not need this setup */
     if ( is_idle_domain(d) )
         return 0;
 
     ASSERT(config != NULL);
-    if ( (rc = p2m_init(d)) != 0 )
-        goto fail;
-
-    rc = -ENOMEM;
-    if ( (d->shared_info = alloc_xenheap_pages(0, 0)) == NULL )
-        goto fail;
-
-    /* Default the virtual ID to match the physical */
-    d->arch.vpidr = boot_cpu_data.midr.bits;
-
-    clear_page(d->shared_info);
-    share_xen_page_with_guest(
-        virt_to_page(d->shared_info), d, XENSHARE_writable);
-
-    if ( (rc = domain_io_init(d)) != 0 )
-        goto fail;
-
-    if ( (rc = p2m_alloc_table(d)) != 0 )
-        goto fail;
 
     switch ( config->gic_version )
     {
@@ -567,12 +546,16 @@ int arch_domain_create(struct domain *d, unsigned int 
domcr_flags,
         case GIC_V2:
             config->gic_version = XEN_DOMCTL_CONFIG_GIC_V2;
             d->arch.vgic.version = GIC_V2;
+            d->arch.vgic.handler = &vgic_v2_ops;
             break;
 
+#ifdef CONFIG_ARM_64
         case GIC_V3:
             config->gic_version = XEN_DOMCTL_CONFIG_GIC_V3;
             d->arch.vgic.version = GIC_V3;
+            d->arch.vgic.handler = &vgic_v3_ops;
             break;
+#endif
 
         default:
             BUG();
@@ -581,17 +564,61 @@ int arch_domain_create(struct domain *d, unsigned int 
domcr_flags,
 
     case XEN_DOMCTL_CONFIG_GIC_V2:
         d->arch.vgic.version = GIC_V2;
+        d->arch.vgic.handler = &vgic_v2_ops;
         break;
 
+#ifdef CONFIG_ARM_64
     case XEN_DOMCTL_CONFIG_GIC_V3:
         d->arch.vgic.version = GIC_V3;
+        d->arch.vgic.handler = &vgic_v3_ops;
         break;
+#endif
 
     default:
         rc = -EOPNOTSUPP;
         goto fail;
     }
 
+    return 0;
+
+fail:
+    d->is_dying = DOMDYING_dead;
+
+    return rc;
+}
+
+int arch_domain_create(struct domain *d, unsigned int domcr_flags,
+                       struct xen_arch_domainconfig *config)
+{
+    int rc;
+
+    d->arch.relmem = RELMEM_not_started;
+
+    /* Idle domains do not need this setup */
+    if ( is_idle_domain(d) )
+        return 0;
+
+    ASSERT(config != NULL);
+    if ( (rc = p2m_init(d)) != 0 )
+        goto fail;
+
+    rc = -ENOMEM;
+    if ( (d->shared_info = alloc_xenheap_pages(0, 0)) == NULL )
+        goto fail;
+
+    /* Default the virtual ID to match the physical */
+    d->arch.vpidr = boot_cpu_data.midr.bits;
+
+    clear_page(d->shared_info);
+    share_xen_page_with_guest(
+        virt_to_page(d->shared_info), d, XENSHARE_writable);
+
+    if ( (rc = domain_io_init(d)) != 0 )
+        goto fail;
+
+    if ( (rc = p2m_alloc_table(d)) != 0 )
+        goto fail;
+
     if ( (rc = domain_vgic_init(d, config->nr_spis)) != 0 )
         goto fail;
 
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 1bd86f8..08b487b 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -88,20 +88,6 @@ int domain_vgic_init(struct domain *d, unsigned int nr_spis)
         return -ENODEV;
     }
 
-    switch ( d->arch.vgic.version )
-    {
-#ifdef CONFIG_ARM_64
-    case GIC_V3:
-        d->arch.vgic.handler = &vgic_v3_ops;
-        break;
-#endif
-    case GIC_V2:
-        d->arch.vgic.handler = &vgic_v2_ops;
-        break;
-    default:
-        return -ENODEV;
-    }
-
     spin_lock_init(&d->arch.vgic.lock);
 
     d->arch.vgic.shared_irqs =
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 1f1550e..82c4368 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -507,6 +507,12 @@ void vcpu_destroy(struct vcpu *v)
         xfree(v->arch.pv_vcpu.trap_ctxt);
 }
 
+int arch_domain_preinit(struct domain *d,
+                        struct xen_arch_domainconfig *config)
+{
+    return 0;
+}
+
 int arch_domain_create(struct domain *d, unsigned int domcr_flags,
                        struct xen_arch_domainconfig *config)
 {
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 6803c4d..965a214 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -316,6 +316,9 @@ struct domain *domain_create(domid_t domid, unsigned int 
domcr_flags,
     if ( domcr_flags & DOMCRF_dummy )
         return d;
 
+    if ( (err = arch_domain_preinit(d, config)) != 0 )
+        goto fail;
+
     if ( !is_idle_domain(d) )
     {
         if ( (err = xsm_domain_create(XSM_HOOK, d, ssidref)) != 0 )
diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h
index 848db8a..7a3533e 100644
--- a/xen/include/xen/domain.h
+++ b/xen/include/xen/domain.h
@@ -56,6 +56,8 @@ void vcpu_destroy(struct vcpu *v);
 int map_vcpu_info(struct vcpu *v, unsigned long gfn, unsigned offset);
 void unmap_vcpu_info(struct vcpu *v);
 
+int arch_domain_preinit(struct domain *d,
+                        struct xen_arch_domainconfig *config);
 int arch_domain_create(struct domain *d, unsigned int domcr_flags,
                        struct xen_arch_domainconfig *config);
 
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.