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;
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:
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);
{
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;
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);