|
[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 |