|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 20/20] xen/domain: Allocate d->vcpu[] in arch_domain_create()
On the ARM side, audit config->max_vcpus after the vgic has been initialised,
at which point we have a real upper bound to test against. This allows for
the removal of the vgic_max_vcpus() juggling to cope with the call from
evtchn_init() before the vgic settings are known.
For each arch's dom0's, drop the temporary max_vcpus parameter, and allocation
of dom0->vcpu.
With arch_domain_create() now in charge of auditing config->max_vcpus, the
per-arch domain_max_vcpus() can be dropped. Finally, evtchn_init() can be
updated to allocate a poll mask suitable for the domain, rather than suitable
for the worst case setting.
From this point on, d->max_vcpus and d->vcpus[] are valid for any domain which
can be looked up by ID.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Stefano Stabellini <sstabellini@xxxxxxxxxx>
CC: Julien Grall <julien.grall@xxxxxxx>
---
xen/arch/arm/domain.c | 13 +++++++++++++
xen/arch/arm/domain_build.c | 8 +-------
xen/arch/arm/setup.c | 2 +-
xen/arch/arm/vgic.c | 14 --------------
xen/arch/x86/dom0_build.c | 8 +-------
xen/arch/x86/domain.c | 11 +++++++++++
xen/arch/x86/setup.c | 2 +-
xen/common/domctl.c | 14 --------------
xen/common/event_channel.c | 4 ++--
xen/include/asm-arm/domain.h | 6 ------
xen/include/asm-arm/vgic.h | 2 --
xen/include/asm-x86/domain.h | 2 --
xen/include/xen/domain.h | 2 +-
13 files changed, 31 insertions(+), 57 deletions(-)
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 0931ce6..ae40971 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -646,6 +646,19 @@ int arch_domain_create(struct domain *d,
if ( (rc = domain_vtimer_init(d, &config->arch)) != 0 )
goto fail;
+ rc = -EINVAL;
+ /* On ARM, the number of VCPUs is limited by the type of GIC emulated. */
+ if ( (config->max_vcpus < 1) ||
+ (config->max_vcpus > min_t(unsigned int, MAX_VIRT_CPUS,
+ d->arch.vgic.handler->max_vcpus)) )
+ goto fail;
+
+ rc = -ENOMEM;
+ d->vcpu = xzalloc_array(struct vcpu *, config->max_vcpus);
+ if ( !d->vcpu )
+ goto fail;
+ d->max_vcpus = config->max_vcpus;
+
update_domain_wallclock_time(d);
/*
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 2e145d9..b13c47e 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -76,14 +76,8 @@ unsigned int __init dom0_max_vcpus(void)
return opt_dom0_max_vcpus;
}
-struct vcpu *__init alloc_dom0_vcpu0(struct domain *dom0,
- unsigned int max_vcpus)
+struct vcpu *__init alloc_dom0_vcpu0(struct domain *dom0)
{
- dom0->vcpu = xzalloc_array(struct vcpu *, max_vcpus);
- if ( !dom0->vcpu )
- return NULL;
- dom0->max_vcpus = max_vcpus;
-
return alloc_vcpu(dom0, 0, 0);
}
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index be24f20..0ada4d5 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -859,7 +859,7 @@ void __init start_xen(unsigned long boot_phys_offset,
dom0_cfg.max_vcpus = dom0_max_vcpus();
dom0 = domain_create(0, &dom0_cfg);
- if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0, dom0_cfg.max_vcpus) == NULL) )
+ if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) )
panic("Error creating domain 0");
dom0->is_privileged = 1;
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index eb09d9c..dc89b81 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -672,20 +672,6 @@ void vgic_free_virq(struct domain *d, unsigned int virq)
clear_bit(virq, d->arch.vgic.allocated_irqs);
}
-unsigned int vgic_max_vcpus(const struct domain *d)
-{
- /*
- * Since evtchn_init would call domain_max_vcpus for poll_mask
- * allocation when the vgic_ops haven't been initialised yet,
- * we return MAX_VIRT_CPUS if d->arch.vgic.handler is null.
- */
- if ( !d->arch.vgic.handler )
- return MAX_VIRT_CPUS;
- else
- return min_t(unsigned int, MAX_VIRT_CPUS,
- d->arch.vgic.handler->max_vcpus);
-}
-
/*
* Local variables:
* mode: C
diff --git a/xen/arch/x86/dom0_build.c b/xen/arch/x86/dom0_build.c
index e82bc48..4c25789 100644
--- a/xen/arch/x86/dom0_build.c
+++ b/xen/arch/x86/dom0_build.c
@@ -200,17 +200,11 @@ unsigned int __init dom0_max_vcpus(void)
return max_vcpus;
}
-struct vcpu *__init alloc_dom0_vcpu0(struct domain *dom0,
- unsigned int max_vcpus)
+struct vcpu *__init alloc_dom0_vcpu0(struct domain *dom0)
{
dom0->node_affinity = dom0_nodes;
dom0->auto_node_affinity = !dom0_nr_pxms;
- dom0->vcpu = xzalloc_array(struct vcpu *, max_vcpus);
- if ( !dom0->vcpu )
- return NULL;
- dom0->max_vcpus = max_vcpus;
-
return dom0_setup_vcpu(dom0, 0,
cpumask_last(&dom0_cpus) /* so it wraps around to
first pcpu */);
}
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index c4c34b4..90fe50a 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -504,6 +504,17 @@ int arch_domain_create(struct domain *d,
HYPERVISOR_COMPAT_VIRT_START(d) =
is_pv_domain(d) ? __HYPERVISOR_COMPAT_VIRT_START : ~0u;
+ if ( (config->max_vcpus < 1) ||
+ (config->max_vcpus >
+ (is_hvm_domain(d) ? HVM_MAX_VCPUS : MAX_VIRT_CPUS)) )
+ return -EINVAL;
+
+ rc = -ENOMEM;
+ d->vcpu = xzalloc_array(struct vcpu *, config->max_vcpus);
+ if ( !d->vcpu )
+ goto fail;
+ d->max_vcpus = config->max_vcpus;
+
/* Need to determine if HAP is enabled before initialising paging */
if ( is_hvm_domain(d) )
d->arch.hvm_domain.hap_enabled =
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index b0e85b0..07e9893 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1649,7 +1649,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
/* Create initial domain 0. */
dom0 = domain_create(get_initial_domain_id(), &dom0_cfg);
- if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0, dom0_cfg.max_vcpus) == NULL) )
+ if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) )
panic("Error creating domain 0");
if ( !pv_shim )
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index 2f9d993..1dc19ea 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -547,23 +547,9 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t)
u_domctl)
op->domain = d->domain_id;
copyback = true;
- ret = -EINVAL;
- if ( vcpus > domain_max_vcpus(d) )
- goto createdomain_fail_late;
-
ret = -ENOMEM;
online = cpupool_domain_cpumask(d);
- BUG_ON(d->vcpu);
- BUG_ON(d->max_vcpus);
-
- d->vcpu = xzalloc_array(struct vcpu *, vcpus);
- /* Install vcpu array /then/ update max_vcpus. */
- smp_wmb();
- if ( !d->vcpu )
- goto createdomain_fail_late;
- d->max_vcpus = vcpus;
-
cpu = cpumask_any(online);
for ( i = 0; i < vcpus; ++i )
{
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 41cbbae..2e6f84b 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -1303,8 +1303,8 @@ int evtchn_init(struct domain *d, unsigned int max_port)
evtchn_from_port(d, 0)->state = ECS_RESERVED;
#if MAX_VIRT_CPUS > BITS_PER_LONG
- d->poll_mask = xzalloc_array(unsigned long,
- BITS_TO_LONGS(domain_max_vcpus(d)));
+ BUG_ON(d->max_vcpus == 0);
+ d->poll_mask = xzalloc_array(unsigned long, BITS_TO_LONGS(d->max_vcpus));
if ( !d->poll_mask )
{
free_evtchn_bucket(d, d->evtchn);
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index 7ba6528..2273b1b 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -208,12 +208,6 @@ void vcpu_show_execution_state(struct vcpu *);
void vcpu_show_registers(const struct vcpu *);
void vcpu_switch_to_aarch64_mode(struct vcpu *);
-/* On ARM, the number of VCPUs is limited by the type of GIC emulated. */
-static inline unsigned int domain_max_vcpus(const struct domain *d)
-{
- return vgic_max_vcpus(d);
-}
-
/*
* Due to the restriction of GICv3, the number of vCPUs in AFF0 is
* limited to 16, thus only the first 4 bits of AFF0 are legal. We will
diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
index 0787ba9..6357916 100644
--- a/xen/include/asm-arm/vgic.h
+++ b/xen/include/asm-arm/vgic.h
@@ -348,8 +348,6 @@ extern void vgic_clear_pending_irqs(struct vcpu *v);
extern bool vgic_emulate(struct cpu_user_regs *regs, union hsr hsr);
-unsigned int vgic_max_vcpus(const struct domain *d);
-
void vgic_v2_setup_hw(paddr_t dbase, paddr_t cbase, paddr_t csize,
paddr_t vbase, uint32_t aliased_offset);
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 47aadc2..9a21e0f 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -624,8 +624,6 @@ unsigned long pv_guest_cr4_fixup(const struct vcpu *,
unsigned long guest_cr4);
X86_CR4_OSXSAVE | X86_CR4_SMEP | \
X86_CR4_FSGSBASE | X86_CR4_SMAP))
-#define domain_max_vcpus(d) (is_hvm_domain(d) ? HVM_MAX_VCPUS : MAX_VIRT_CPUS)
-
static inline struct vcpu_guest_context *alloc_vcpu_guest_context(void)
{
return vmalloc(sizeof(struct vcpu_guest_context));
diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h
index dc022b4..3dcec06 100644
--- a/xen/include/xen/domain.h
+++ b/xen/include/xen/domain.h
@@ -17,7 +17,7 @@ struct vcpu *alloc_vcpu(
struct domain *d, unsigned int vcpu_id, unsigned int cpu_id);
unsigned int dom0_max_vcpus(void);
-struct vcpu *alloc_dom0_vcpu0(struct domain *dom0, unsigned int max_vcpus);
+struct vcpu *alloc_dom0_vcpu0(struct domain *dom0);
int vcpu_reset(struct vcpu *);
int vcpu_up(struct vcpu *v);
--
2.1.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |