|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen stable-4.10] xen/pvshim: support vCPU hotplug
commit 5b6c3ffa1d291724a329b57658783fc30b93b479
Author: Roger Pau Monne <roger.pau@xxxxxxxxxx>
AuthorDate: Thu Jan 11 11:41:20 2018 +0000
Commit: Roger Pau Monne <roger.pau@xxxxxxxxxx>
CommitDate: Fri Jan 12 15:47:32 2018 +0000
xen/pvshim: support vCPU hotplug
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 9a703734eb..8fbd33d4c6 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -1293,22 +1293,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);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10
_______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |