aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-01-19 17:55:29 +0000
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-01-19 17:55:29 +0000
commitbbb6a715dc15f4fd9c320998384e60e032b4250f (patch)
treeed2330a72847e99ce986818ef0c5689a8ddc480b /xen/common
parent115209d91bcd3734ddaaf58a4a1cdbb4c44cd4fa (diff)
downloadxen-bbb6a715dc15f4fd9c320998384e60e032b4250f.tar.gz
xen-bbb6a715dc15f4fd9c320998384e60e032b4250f.tar.bz2
xen-bbb6a715dc15f4fd9c320998384e60e032b4250f.zip
[XEN] Support VCPU reset via DOMCTL_setvcpucontext.
Signed-off-by: Andrei Petrov <andrei.petrov@xensource.com>
Diffstat (limited to 'xen/common')
-rw-r--r--xen/common/domain.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/xen/common/domain.c b/xen/common/domain.c
index aa232585c8..9203e837a7 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -5,6 +5,7 @@
*/
#include <xen/config.h>
+#include <xen/compat.h>
#include <xen/init.h>
#include <xen/lib.h>
#include <xen/errno.h>
@@ -467,7 +468,12 @@ int set_info_guest(struct domain *d,
if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) )
return -EINVAL;
-
+
+ if ( IS_COMPAT(v->domain)
+ ? compat_handle_is_null(vcpucontext.cmp->ctxt)
+ : guest_handle_is_null(vcpucontext.nat->ctxt) )
+ return vcpu_reset(v);
+
#ifdef CONFIG_COMPAT
BUILD_BUG_ON(sizeof(struct vcpu_guest_context)
< sizeof(struct compat_vcpu_guest_context));
@@ -521,6 +527,36 @@ int boot_vcpu(struct domain *d, int vcpuid, vcpu_guest_context_u ctxt)
return arch_set_info_guest(v, ctxt);
}
+int vcpu_reset(struct vcpu *v)
+{
+ struct domain *d = v->domain;
+ int rc;
+
+ domain_pause(d);
+ LOCK_BIGLOCK(d);
+
+ rc = arch_vcpu_reset(v);
+ if ( rc != 0 )
+ goto out;
+
+ set_bit(_VCPUF_down, &v->vcpu_flags);
+
+ clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
+ clear_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags);
+ clear_bit(_VCPUF_blocked, &v->vcpu_flags);
+ clear_bit(_VCPUF_initialised, &v->vcpu_flags);
+ clear_bit(_VCPUF_nmi_pending, &v->vcpu_flags);
+ clear_bit(_VCPUF_nmi_masked, &v->vcpu_flags);
+ clear_bit(_VCPUF_polling, &v->vcpu_flags);
+
+ out:
+ UNLOCK_BIGLOCK(v->domain);
+ domain_unpause(d);
+
+ return rc;
+}
+
+
long do_vcpu_op(int cmd, int vcpuid, XEN_GUEST_HANDLE(void) arg)
{
struct domain *d = current->domain;