[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.