[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 53/62] xen/pvshim: support vCPU hotplug
From: Roger Pau Monne <roger.pau@xxxxxxxxxx> Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- Changes since v1: - Fix hotplug so that v->initialized is checked before attempting to bring up the physical CPU. - Fix ARM compilation. --- xen/arch/x86/pv/shim.c | 63 +++++++++++++++++++++++++++++++++++++++++++ xen/common/domain.c | 38 +++++++++++++++++--------- xen/include/asm-x86/pv/shim.h | 12 +++++++++ xen/include/xen/domain.h | 1 + 4 files changed, 102 insertions(+), 12 deletions(-) diff --git a/xen/arch/x86/pv/shim.c b/xen/arch/x86/pv/shim.c index e3e101a5b1..68ec7bed8e 100644 --- a/xen/arch/x86/pv/shim.c +++ b/xen/arch/x86/pv/shim.c @@ -751,6 +751,69 @@ static long pv_shim_grant_table_op(unsigned int cmd, return rc; } +long pv_shim_cpu_up(void *data) +{ + struct vcpu *v = data; + struct domain *d = v->domain; + bool wake; + + BUG_ON(smp_processor_id() != 0); + + domain_lock(d); + if ( !v->is_initialised ) + { + domain_unlock(d); + return -EINVAL; + } + + if ( !cpu_online(v->vcpu_id) ) + { + long rc = cpu_up_helper((void *)(unsigned long)v->vcpu_id); + + if ( rc ) + { + domain_unlock(d); + gprintk(XENLOG_ERR, "Failed to bring up CPU#%u: %ld\n", + v->vcpu_id, rc); + return rc; + } + } + + wake = test_and_clear_bit(_VPF_down, &v->pause_flags); + domain_unlock(d); + if ( wake ) + vcpu_wake(v); + + return 0; +} + +long pv_shim_cpu_down(void *data) +{ + struct vcpu *v = data; + long rc; + + BUG_ON(smp_processor_id() != 0); + + if ( !test_and_set_bit(_VPF_down, &v->pause_flags) ) + vcpu_sleep_sync(v); + + if ( cpu_online(v->vcpu_id) ) + { + rc = cpu_down_helper((void *)(unsigned long)v->vcpu_id); + if ( rc ) + gprintk(XENLOG_ERR, "Failed to bring down CPU#%u: %ld\n", + v->vcpu_id, rc); + /* + * NB: do not propagate errors from cpu_down_helper failing. The shim + * is going to run with extra CPUs, but that's not going to prevent + * normal operation. OTOH most guests are not prepared to handle an + * error on VCPUOP_down failing, and will likely panic. + */ + } + + return 0; +} + domid_t get_initial_domain_id(void) { uint32_t eax, ebx, ecx, edx; diff --git a/xen/common/domain.c b/xen/common/domain.c index 6ed21b2536..558318e852 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -1301,22 +1301,36 @@ long do_vcpu_op(int cmd, unsigned int vcpuid, XEN_GUEST_HANDLE_PARAM(void) arg) break; - case VCPUOP_up: { - bool_t wake = 0; - domain_lock(d); - if ( !v->is_initialised ) - rc = -EINVAL; + case VCPUOP_up: +#ifdef CONFIG_X86 + if ( pv_shim ) + rc = continue_hypercall_on_cpu(0, pv_shim_cpu_up, v); else - wake = test_and_clear_bit(_VPF_down, &v->pause_flags); - domain_unlock(d); - if ( wake ) - vcpu_wake(v); +#endif + { + bool wake = false; + + domain_lock(d); + if ( !v->is_initialised ) + rc = -EINVAL; + else + wake = test_and_clear_bit(_VPF_down, &v->pause_flags); + domain_unlock(d); + if ( wake ) + vcpu_wake(v); + } + break; - } case VCPUOP_down: - if ( !test_and_set_bit(_VPF_down, &v->pause_flags) ) - vcpu_sleep_nosync(v); +#ifdef CONFIG_X86 + if ( pv_shim ) + rc = continue_hypercall_on_cpu(0, pv_shim_cpu_down, v); + else +#endif + if ( !test_and_set_bit(_VPF_down, &v->pause_flags) ) + vcpu_sleep_nosync(v); + break; case VCPUOP_is_up: diff --git a/xen/include/asm-x86/pv/shim.h b/xen/include/asm-x86/pv/shim.h index 0ef452158e..eb59ddd38a 100644 --- a/xen/include/asm-x86/pv/shim.h +++ b/xen/include/asm-x86/pv/shim.h @@ -37,6 +37,8 @@ void pv_shim_setup_dom(struct domain *d, l4_pgentry_t *l4start, start_info_t *si); int pv_shim_shutdown(uint8_t reason); void pv_shim_inject_evtchn(unsigned int port); +long pv_shim_cpu_up(void *data); +long pv_shim_cpu_down(void *data); domid_t get_initial_domain_id(void); uint64_t pv_shim_mem(uint64_t avail); @@ -60,6 +62,16 @@ static inline void pv_shim_inject_evtchn(unsigned int port) { ASSERT_UNREACHABLE(); } +static inline long pv_shim_cpu_up(void *data) +{ + ASSERT_UNREACHABLE(); + return 0; +} +static inline long pv_shim_cpu_down(void *data) +{ + ASSERT_UNREACHABLE(); + return 0; +} static inline domid_t get_initial_domain_id(void) { return 0; diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h index 347f264047..eb62f1dab1 100644 --- a/xen/include/xen/domain.h +++ b/xen/include/xen/domain.h @@ -17,6 +17,7 @@ struct vcpu *alloc_vcpu( struct domain *d, unsigned int vcpu_id, unsigned int cpu_id); struct vcpu *alloc_dom0_vcpu0(struct domain *dom0); int vcpu_reset(struct vcpu *); +int vcpu_up(struct vcpu *v); struct xen_domctl_getdomaininfo; void getdomaininfo(struct domain *d, struct xen_domctl_getdomaininfo *info); -- 2.11.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |