[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC v1 61/74] xen/pvshim: support vCPU hotplug
From: Roger Pau Monne <roger.pau@xxxxxxxxxx> Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- xen/arch/x86/pv/shim.c | 48 +++++++++++++++++++++++++++++++++++++++++++ xen/common/domain.c | 37 +++++++++++++++++++++++---------- xen/include/asm-x86/pv/shim.h | 12 +++++++++++ xen/include/xen/domain.h | 1 + 4 files changed, 87 insertions(+), 11 deletions(-) diff --git a/xen/arch/x86/pv/shim.c b/xen/arch/x86/pv/shim.c index 46f77362a7..29f343b871 100644 --- a/xen/arch/x86/pv/shim.c +++ b/xen/arch/x86/pv/shim.c @@ -766,6 +766,54 @@ long pv_shim_grant_table_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) uop, return rc; } +long pv_shim_cpu_up(void *data) +{ + struct vcpu *v = data; + long rc; + + BUG_ON(smp_processor_id() != 0); + + if ( !cpu_online(v->vcpu_id) ) + { + rc = cpu_up_helper((void *)(unsigned long)v->vcpu_id); + if ( rc ) + { + gprintk(XENLOG_ERR, "Failed to bring up CPU#%u: %ld\n", + v->vcpu_id, rc); + return rc; + } + } + + return vcpu_up(v); +} + +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_dom0_domid(void) { uint32_t eax, ebx, ecx, edx; diff --git a/xen/common/domain.c b/xen/common/domain.c index bc2ceb2d36..c30e98b24e 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -1281,6 +1281,23 @@ int default_initialise_vcpu(struct vcpu *v, XEN_GUEST_HANDLE_PARAM(void) arg) return rc; } +int vcpu_up(struct vcpu *v) +{ + bool wake = false; + int rc = 0; + + domain_lock(v->domain); + if ( !v->is_initialised ) + rc = -EINVAL; + else + wake = test_and_clear_bit(_VPF_down, &v->pause_flags); + domain_unlock(v->domain); + if ( wake ) + vcpu_wake(v); + + return rc; +} + long do_vcpu_op(int cmd, unsigned int vcpuid, XEN_GUEST_HANDLE_PARAM(void) arg) { struct domain *d = current->domain; @@ -1303,22 +1320,20 @@ 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: + 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); + rc = vcpu_up(v); + break; - } case VCPUOP_down: - if ( !test_and_set_bit(_VPF_down, &v->pause_flags) ) + if ( pv_shim ) + rc = continue_hypercall_on_cpu(0, pv_shim_cpu_down, v); + else 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 00906f884b..d107a617a7 100644 --- a/xen/include/asm-x86/pv/shim.h +++ b/xen/include/asm-x86/pv/shim.h @@ -40,6 +40,8 @@ long pv_shim_event_channel_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg); void pv_shim_inject_evtchn(unsigned int port); long pv_shim_grant_table_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) uop, unsigned int count, bool compat); +long pv_shim_cpu_up(void *data); +long pv_shim_cpu_down(void *data); domid_t get_dom0_domid(void); uint64_t pv_shim_mem(uint64_t avail); @@ -76,6 +78,16 @@ static inline long pv_shim_grant_table_op(unsigned int cmd, ASSERT_UNREACHABLE(); return 0; } +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_dom0_domid(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 |