WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Merge

# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
# Date 1169292068 0
# Node ID 5dc5e6ba42d2b68edac47a39ac5e318ae1d76119
# Parent  ff4f4596cb29da5f4d672e9a99fe45603282263e
# Parent  0971f0e9461e417875c86c0b3433f99341aa3432
Merge
---
 linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c |   33 +++--
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c |   28 ++++
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c    |   16 --
 linux-2.6-xen-sparse/include/xen/xenbus.h              |    5 
 tools/libxc/Makefile                                   |    1 
 tools/libxc/xc_domain.c                                |   22 ---
 tools/libxc/xc_evtchn.c                                |    9 +
 tools/libxc/xc_resume.c                                |   35 +++++
 tools/libxc/xenctrl.h                                  |    9 -
 tools/python/xen/lowlevel/xc/xc.c                      |   24 +++
 tools/python/xen/lowlevel/xs/xs.c                      |   28 ++++
 tools/python/xen/xend/XendDomainInfo.py                |    3 
 tools/python/xen/xend/xenstore/xsutil.py               |    3 
 tools/xenstore/xenstored_core.c                        |    5 
 tools/xenstore/xenstored_domain.c                      |   52 +++++++-
 tools/xenstore/xenstored_domain.h                      |    3 
 tools/xenstore/xs.c                                    |    6 
 tools/xenstore/xs.h                                    |    5 
 xen/arch/x86/domain.c                                  |  109 +++++++++--------
 xen/arch/x86/domctl.c                                  |    1 
 xen/common/domain.c                                    |   38 +++++
 xen/common/event_channel.c                             |   31 ++++
 xen/include/public/event_channel.h                     |   13 ++
 xen/include/public/io/xs_wire.h                        |    3 
 xen/include/xen/compat.h                               |    2 
 xen/include/xen/domain.h                               |    3 
 26 files changed, 389 insertions(+), 98 deletions(-)

diff -r ff4f4596cb29 -r 5dc5e6ba42d2 
linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c    Sat Jan 20 
11:17:42 2007 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c    Sat Jan 20 
11:21:08 2007 +0000
@@ -85,13 +85,20 @@ static void pre_suspend(void)
                mfn_to_pfn(xen_start_info->console.domU.mfn);
 }
 
-static void post_suspend(void)
+static void post_suspend(int suspend_cancelled)
 {
        int i, j, k, fpp;
        extern unsigned long max_pfn;
        extern unsigned long *pfn_to_mfn_frame_list_list;
        extern unsigned long *pfn_to_mfn_frame_list[];
 
+       if (suspend_cancelled) {
+               xen_start_info->store_mfn =
+                       pfn_to_mfn(xen_start_info->store_mfn);
+               xen_start_info->console.domU.mfn =
+                       pfn_to_mfn(xen_start_info->console.domU.mfn);
+       }
+       
        set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
 
        HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
@@ -120,13 +127,13 @@ static void post_suspend(void)
 #define switch_idle_mm()       ((void)0)
 #define mm_pin_all()           ((void)0)
 #define pre_suspend()          ((void)0)
-#define post_suspend()         ((void)0)
+#define post_suspend(x)                ((void)0)
 
 #endif
 
 int __xen_suspend(void)
 {
-       int err;
+       int err, suspend_cancelled;
 
        extern void time_resume(void);
 
@@ -158,16 +165,17 @@ int __xen_suspend(void)
        pre_suspend();
 
        /*
-        * We'll stop somewhere inside this hypercall. When it returns,
-        * we'll start resuming after the restore.
+        * This hypercall returns 1 if suspend was cancelled or the domain was
+        * merely checkpointed, and 0 if it is resuming in a new domain.
         */
-       HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
+       suspend_cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
 
-       post_suspend();
+       post_suspend(suspend_cancelled);
 
        gnttab_resume();
 
-       irq_resume();
+       if (!suspend_cancelled)
+               irq_resume();
 
        time_resume();
 
@@ -175,9 +183,12 @@ int __xen_suspend(void)
 
        local_irq_enable();
 
-       xencons_resume();
-
-       xenbus_resume();
+       if (!suspend_cancelled) {
+               xencons_resume();
+               xenbus_resume();
+       } else {
+               xenbus_suspend_cancel();
+       }
 
        smp_resume();
 
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Sat Jan 20 
11:17:42 2007 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Sat Jan 20 
11:21:08 2007 +0000
@@ -672,6 +672,27 @@ static int suspend_dev(struct device *de
        return 0;
 }
 
+static int suspend_cancel_dev(struct device *dev, void *data)
+{
+       int err = 0;
+       struct xenbus_driver *drv;
+       struct xenbus_device *xdev;
+
+       DPRINTK("");
+
+       if (dev->driver == NULL)
+               return 0;
+       drv = to_xenbus_driver(dev->driver);
+       xdev = container_of(dev, struct xenbus_device, dev);
+       if (drv->suspend_cancel)
+               err = drv->suspend_cancel(xdev);
+       if (err)
+               printk(KERN_WARNING
+                      "xenbus: suspend_cancel %s failed: %i\n",
+                      dev->bus_id, err);
+       return 0;
+}
+
 static int resume_dev(struct device *dev, void *data)
 {
        int err;
@@ -736,6 +757,13 @@ void xenbus_resume(void)
 }
 EXPORT_SYMBOL_GPL(xenbus_resume);
 
+void xenbus_suspend_cancel(void)
+{
+       xs_suspend_cancel();
+       bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_cancel_dev);
+       xenbus_backend_resume(suspend_cancel_dev);
+}
+EXPORT_SYMBOL_GPL(xenbus_suspend_cancel);
 
 /* A flag to determine if xenstored is 'ready' (i.e. has started) */
 int xenstored_ready = 0;
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Sat Jan 20 
11:17:42 2007 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Sat Jan 20 
11:21:08 2007 +0000
@@ -668,17 +668,7 @@ EXPORT_SYMBOL_GPL(unregister_xenbus_watc
 
 void xs_suspend(void)
 {
-       struct xenbus_watch *watch;
-       char token[sizeof(watch) * 2 + 1];
-
        down_write(&xs_state.suspend_mutex);
-
-       /* No need for watches_lock: the suspend_mutex is sufficient. */
-       list_for_each_entry(watch, &watches, list) {
-               sprintf(token, "%lX", (long)watch);
-               xs_unwatch(watch->node, token);
-       }
-
        mutex_lock(&xs_state.request_mutex);
 }
 
@@ -695,6 +685,12 @@ void xs_resume(void)
                xs_watch(watch->node, token);
        }
 
+       up_write(&xs_state.suspend_mutex);
+}
+
+void xs_suspend_cancel(void)
+{
+       mutex_unlock(&xs_state.request_mutex);
        up_write(&xs_state.suspend_mutex);
 }
 
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 linux-2.6-xen-sparse/include/xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/xen/xenbus.h Sat Jan 20 11:17:42 2007 +0000
+++ b/linux-2.6-xen-sparse/include/xen/xenbus.h Sat Jan 20 11:21:08 2007 +0000
@@ -101,6 +101,7 @@ struct xenbus_driver {
                                 enum xenbus_state backend_state);
        int (*remove)(struct xenbus_device *dev);
        int (*suspend)(struct xenbus_device *dev);
+       int (*suspend_cancel)(struct xenbus_device *dev);
        int (*resume)(struct xenbus_device *dev);
        int (*uevent)(struct xenbus_device *, char **, int, char *, int);
        struct device_driver driver;
@@ -160,13 +161,15 @@ void unregister_xenbus_watch(struct xenb
 void unregister_xenbus_watch(struct xenbus_watch *watch);
 void xs_suspend(void);
 void xs_resume(void);
+void xs_suspend_cancel(void);
 
 /* Used by xenbus_dev to borrow kernel's store connection. */
 void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg);
 
-/* Called from xen core code. */
+/* Prepare for domain suspend: then resume or cancel the suspend. */
 void xenbus_suspend(void);
 void xenbus_resume(void);
+void xenbus_suspend_cancel(void);
 
 #define XENBUS_IS_ERR_READ(str) ({                     \
        if (!IS_ERR(str) && strlen(str) == 0) {         \
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 tools/libxc/Makefile
--- a/tools/libxc/Makefile      Sat Jan 20 11:17:42 2007 +0000
+++ b/tools/libxc/Makefile      Sat Jan 20 11:21:08 2007 +0000
@@ -15,6 +15,7 @@ CTRL_SRCS-y       += xc_sedf.c
 CTRL_SRCS-y       += xc_sedf.c
 CTRL_SRCS-y       += xc_csched.c
 CTRL_SRCS-y       += xc_tbuf.c
+CTRL_SRCS-y       += xc_resume.c
 CTRL_SRCS-$(CONFIG_X86) += xc_pagetab.c
 CTRL_SRCS-$(CONFIG_Linux) += xc_linux.c
 CTRL_SRCS-$(CONFIG_SunOS) += xc_solaris.c
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Sat Jan 20 11:17:42 2007 +0000
+++ b/tools/libxc/xc_domain.c   Sat Jan 20 11:21:08 2007 +0000
@@ -89,16 +89,6 @@ int xc_domain_shutdown(int xc_handle,
 }
 
 
-int xc_domain_resume(int xc_handle,
-                      uint32_t domid)
-{
-    DECLARE_DOMCTL;
-    domctl.cmd = XEN_DOMCTL_resumedomain;
-    domctl.domain = (domid_t)domid;
-    return do_domctl(xc_handle, &domctl);
-}
-
-
 int xc_vcpu_setaffinity(int xc_handle,
                         uint32_t domid,
                         int vcpu,
@@ -293,9 +283,9 @@ int xc_domain_hvm_setcontext(int xc_hand
 }
 
 int xc_vcpu_getcontext(int xc_handle,
-                               uint32_t domid,
-                               uint32_t vcpu,
-                               vcpu_guest_context_t *ctxt)
+                       uint32_t domid,
+                       uint32_t vcpu,
+                       vcpu_guest_context_t *ctxt)
 {
     int rc;
     DECLARE_DOMCTL;
@@ -602,15 +592,15 @@ int xc_vcpu_setcontext(int xc_handle,
     domctl.u.vcpucontext.vcpu = vcpu;
     set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt);
 
-    if ( (rc = lock_pages(ctxt, sizeof(*ctxt))) != 0 )
+    if ( (ctxt != NULL) && ((rc = lock_pages(ctxt, sizeof(*ctxt))) != 0) )
         return rc;
 
     rc = do_domctl(xc_handle, &domctl);
 
-    unlock_pages(ctxt, sizeof(*ctxt));
+    if ( ctxt != NULL )
+        unlock_pages(ctxt, sizeof(*ctxt));
 
     return rc;
-
 }
 
 int xc_domain_irq_permission(int xc_handle,
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 tools/libxc/xc_evtchn.c
--- a/tools/libxc/xc_evtchn.c   Sat Jan 20 11:17:42 2007 +0000
+++ b/tools/libxc/xc_evtchn.c   Sat Jan 20 11:21:08 2007 +0000
@@ -37,7 +37,7 @@ int xc_evtchn_alloc_unbound(int xc_handl
                             uint32_t dom,
                             uint32_t remote_dom)
 {
-    int         rc;
+    int rc;
     struct evtchn_alloc_unbound arg = {
         .dom = (domid_t)dom,
         .remote_dom = (domid_t)remote_dom
@@ -49,3 +49,10 @@ int xc_evtchn_alloc_unbound(int xc_handl
 
     return rc;
 }
+
+int xc_evtchn_reset(int xc_handle,
+                    uint32_t dom)
+{
+    struct evtchn_reset arg = { .dom = (domid_t)dom };
+    return do_evtchn_op(xc_handle, EVTCHNOP_reset, &arg, sizeof(arg));
+}
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 tools/libxc/xc_resume.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/xc_resume.c   Sat Jan 20 11:21:08 2007 +0000
@@ -0,0 +1,35 @@
+#include "xc_private.h"
+
+/*
+ * Resume execution of a domain after suspend shutdown.
+ * This can happen in one of two ways:
+ *  1. Resume with special return code.
+ *  2. Reset guest environment so it believes it is resumed in a new
+ *     domain context.
+ * (2) should be used only for guests which cannot handle the special
+ * new return code. (1) is always safe (but slower).
+ * 
+ * XXX Only (2) is implemented below. We need to use (1) by default!
+ */
+int xc_domain_resume(int xc_handle, uint32_t domid)
+{
+    vcpu_guest_context_t ctxt;
+    DECLARE_DOMCTL;
+    int rc;
+
+    /*
+     * Set hypercall return code to indicate that suspend is cancelled
+     * (rather than resuming in a new domain context).
+     */
+#if defined(__i386__) || defined(__x86_64__)
+    if ( (rc = xc_vcpu_getcontext(xc_handle, domid, 0, &ctxt)) != 0 )
+        return rc;
+    ctxt.user_regs.eax = 1;
+    if ( (rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt)) != 0 )
+        return rc;
+#endif
+
+    domctl.cmd = XEN_DOMCTL_resumedomain;
+    domctl.domain = domid;
+    return do_domctl(xc_handle, &domctl);
+}
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Sat Jan 20 11:17:42 2007 +0000
+++ b/tools/libxc/xenctrl.h     Sat Jan 20 11:21:08 2007 +0000
@@ -360,9 +360,9 @@ int xc_domain_hvm_setcontext(int xc_hand
  * @return 0 on success, -1 on failure
  */
 int xc_vcpu_getcontext(int xc_handle,
-                               uint32_t domid,
-                               uint32_t vcpu,
-                               vcpu_guest_context_t *ctxt);
+                       uint32_t domid,
+                       uint32_t vcpu,
+                       vcpu_guest_context_t *ctxt);
 
 typedef xen_domctl_getvcpuinfo_t xc_vcpuinfo_t;
 int xc_vcpu_getinfo(int xc_handle,
@@ -431,6 +431,9 @@ int xc_evtchn_alloc_unbound(int xc_handl
 int xc_evtchn_alloc_unbound(int xc_handle,
                             uint32_t dom,
                             uint32_t remote_dom);
+
+int xc_evtchn_reset(int xc_handle,
+                    uint32_t dom);
 
 int xc_physdev_pci_access_modify(int xc_handle,
                                  uint32_t domid,
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Sat Jan 20 11:17:42 2007 +0000
+++ b/tools/python/xen/lowlevel/xc/xc.c Sat Jan 20 11:21:08 2007 +0000
@@ -478,6 +478,24 @@ static PyObject *pyxc_evtchn_alloc_unbou
     return PyInt_FromLong(port);
 }
 
+static PyObject *pyxc_evtchn_reset(XcObject *self,
+                                  PyObject *args,
+                                  PyObject *kwds)
+{
+    uint32_t dom;
+
+    static char *kwd_list[] = { "dom", NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
+        return NULL;
+
+    if ( xc_evtchn_reset(self->xc_handle, dom) < 0 )
+        return pyxc_error_to_exception();
+
+    Py_INCREF(zero);
+    return zero;
+}
+
 static PyObject *pyxc_physdev_pci_access_modify(XcObject *self,
                                                 PyObject *args,
                                                 PyObject *kwds)
@@ -1201,6 +1219,12 @@ static PyMethodDef pyxc_methods[] = {
       " dom        [int]: Domain whose port space to allocate from.\n"
       " remote_dom [int]: Remote domain to accept connections from.\n\n"
       "Returns: [int] Unbound event-channel port.\n" },
+
+    { "evtchn_reset", 
+      (PyCFunction)pyxc_evtchn_reset,
+      METH_VARARGS | METH_KEYWORDS, "\n"
+      "Reset all connections.\n"
+      " dom [int]: Domain to reset.\n" },
 
     { "physdev_pci_access_modify",
       (PyCFunction)pyxc_physdev_pci_access_modify,
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 tools/python/xen/lowlevel/xs/xs.c
--- a/tools/python/xen/lowlevel/xs/xs.c Sat Jan 20 11:17:42 2007 +0000
+++ b/tools/python/xen/lowlevel/xs/xs.c Sat Jan 20 11:21:08 2007 +0000
@@ -618,6 +618,33 @@ static PyObject *xspy_introduce_domain(X
     return none(result);
 }
 
+#define xspy_resume_domain_doc "\n"                                \
+       "Tell xenstore to clear its shutdown flag for a domain.\n" \
+       "This ensures that a subsequent shutdown will fire the\n"  \
+       "appropriate watches.\n"                                   \
+       " dom [int]: domain id\n"                                  \
+        "\n"                                                      \
+        "Returns None on success.\n"                              \
+        "Raises xen.lowlevel.xs.Error on error.\n"
+
+static PyObject *xspy_resume_domain(XsHandle *self, PyObject *args)
+{
+    uint32_t dom;
+
+    struct xs_handle *xh = xshandle(self);
+    bool result = 0;
+
+    if (!xh)
+        return NULL;
+    if (!PyArg_ParseTuple(args, "i", &dom))
+        return NULL;
+
+    Py_BEGIN_ALLOW_THREADS
+    result = xs_resume_domain(xh, dom);
+    Py_END_ALLOW_THREADS
+
+    return none(result);
+}
 
 #define xspy_release_domain_doc "\n"                                   \
        "Tell xenstore to release its channel to a domain.\n"           \
@@ -789,6 +816,7 @@ static PyMethodDef xshandle_methods[] = 
     XSPY_METH(transaction_start, METH_NOARGS),
     XSPY_METH(transaction_end,   METH_VARARGS | METH_KEYWORDS),
     XSPY_METH(introduce_domain,  METH_VARARGS),
+    XSPY_METH(resume_domain,     METH_VARARGS),
     XSPY_METH(release_domain,    METH_VARARGS),
     XSPY_METH(close,             METH_NOARGS),
     XSPY_METH(get_domain_path,   METH_VARARGS),
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Sat Jan 20 11:17:42 2007 +0000
+++ b/tools/python/xen/xend/XendDomainInfo.py   Sat Jan 20 11:21:08 2007 +0000
@@ -45,7 +45,7 @@ from xen.xend.XendError import XendError
 from xen.xend.XendError import XendError, VmError
 from xen.xend.XendDevices import XendDevices
 from xen.xend.xenstore.xstransact import xstransact, complete
-from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain
+from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain, 
ResumeDomain
 from xen.xend.xenstore.xswatch import xswatch
 from xen.xend.XendConstants import *
 from xen.xend.XendAPIConstants import *
@@ -1545,6 +1545,7 @@ class XendDomainInfo:
         try:
             if self.domid is not None:
                 xc.domain_resume(self.domid)
+                ResumeDomain(self.domid)
         except:
             log.exception("XendDomainInfo.resume: xc.domain_resume failed on 
domain %s." % (str(self.domid)))
 
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 tools/python/xen/xend/xenstore/xsutil.py
--- a/tools/python/xen/xend/xenstore/xsutil.py  Sat Jan 20 11:17:42 2007 +0000
+++ b/tools/python/xen/xend/xenstore/xsutil.py  Sat Jan 20 11:21:08 2007 +0000
@@ -24,3 +24,6 @@ def IntroduceDomain(domid, page, port):
 
 def GetDomainPath(domid):
     return xshandle().get_domain_path(domid)
+
+def ResumeDomain(domid):
+    return xshandle().resume_domain(domid)
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Sat Jan 20 11:17:42 2007 +0000
+++ b/tools/xenstore/xenstored_core.c   Sat Jan 20 11:21:08 2007 +0000
@@ -164,6 +164,7 @@ static char *sockmsg_string(enum xsd_soc
        case XS_WATCH_EVENT: return "WATCH_EVENT";
        case XS_ERROR: return "ERROR";
        case XS_IS_DOMAIN_INTRODUCED: return "XS_IS_DOMAIN_INTRODUCED";
+       case XS_RESUME: return "RESUME";
        default:
                return "**UNKNOWN**";
        }
@@ -1265,6 +1266,10 @@ static void process_message(struct conne
 
        case XS_GET_DOMAIN_PATH:
                do_get_domain_path(conn, onearg(in));
+               break;
+
+       case XS_RESUME:
+               do_resume(conn, onearg(in));
                break;
 
        default:
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Sat Jan 20 11:17:42 2007 +0000
+++ b/tools/xenstore/xenstored_domain.c Sat Jan 20 11:21:08 2007 +0000
@@ -343,13 +343,14 @@ void do_introduce(struct connection *con
                fire_watches(conn, "@introduceDomain", false);
        }
        else {
-               /* Check that the given details match the ones we have
-                  previously recorded. */
-               if (port != domain->remote_port ||
-                   mfn != domain->mfn) {
-                       send_error(conn, EINVAL);
-                       return;
-               }
+               int rc;
+
+               /* Use XS_INTRODUCE for recreating the xenbus event-channel. */
+               if (domain->port)
+                       xc_evtchn_unbind(xce_handle, domain->port);
+               rc = xc_evtchn_bind_interdomain(xce_handle, domid, port);
+               domain->port = (rc == -1) ? 0 : rc;
+               domain->remote_port = port;
        }
 
        send_ack(conn, XS_INTRODUCE);
@@ -393,6 +394,43 @@ void do_release(struct connection *conn,
        fire_watches(conn, "@releaseDomain", false);
 
        send_ack(conn, XS_RELEASE);
+}
+
+void do_resume(struct connection *conn, const char *domid_str)
+{
+       struct domain *domain;
+       unsigned int domid;
+
+       if (!domid_str) {
+               send_error(conn, EINVAL);
+               return;
+       }
+
+       domid = atoi(domid_str);
+       if (!domid) {
+               send_error(conn, EINVAL);
+               return;
+       }
+
+       if (conn->id != 0) {
+               send_error(conn, EACCES);
+               return;
+       }
+
+       domain = find_domain_by_domid(domid);
+       if (!domain) {
+               send_error(conn, ENOENT);
+               return;
+       }
+
+       if (!domain->conn) {
+               send_error(conn, EINVAL);
+               return;
+       }
+
+       domain->shutdown = 0;
+       
+       send_ack(conn, XS_RESUME);
 }
 
 void do_get_domain_path(struct connection *conn, const char *domid_str)
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 tools/xenstore/xenstored_domain.h
--- a/tools/xenstore/xenstored_domain.h Sat Jan 20 11:17:42 2007 +0000
+++ b/tools/xenstore/xenstored_domain.h Sat Jan 20 11:21:08 2007 +0000
@@ -32,6 +32,9 @@ void do_release(struct connection *conn,
 void do_release(struct connection *conn, const char *domid_str);
 
 /* domid */
+void do_resume(struct connection *conn, const char *domid_str);
+
+/* domid */
 void do_get_domain_path(struct connection *conn, const char *domid_str);
 
 /* Returns the event channel handle */
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 tools/xenstore/xs.c
--- a/tools/xenstore/xs.c       Sat Jan 20 11:17:42 2007 +0000
+++ b/tools/xenstore/xs.c       Sat Jan 20 11:21:08 2007 +0000
@@ -719,6 +719,12 @@ bool xs_release_domain(struct xs_handle 
        return xs_bool(single_with_domid(h, XS_RELEASE, domid));
 }
 
+/* clear the shutdown bit for the given domain */
+bool xs_resume_domain(struct xs_handle *h, unsigned int domid)
+{
+       return xs_bool(single_with_domid(h, XS_RESUME, domid));
+}
+
 char *xs_get_domain_path(struct xs_handle *h, unsigned int domid)
 {
        char domid_str[MAX_STRLEN(domid)];
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 tools/xenstore/xs.h
--- a/tools/xenstore/xs.h       Sat Jan 20 11:17:42 2007 +0000
+++ b/tools/xenstore/xs.h       Sat Jan 20 11:21:08 2007 +0000
@@ -133,6 +133,11 @@ bool xs_introduce_domain(struct xs_handl
                         unsigned int domid,
                         unsigned long mfn,
                          unsigned int eventchn); 
+/* Resume a domain.
+ * Clear the shutdown flag for this domain in the store.
+ */
+bool xs_resume_domain(struct xs_handle *h, unsigned int domid);
+
 /* Release a domain.
  * Tells the store domain to release the memory page to the domain.
  */
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Sat Jan 20 11:17:42 2007 +0000
+++ b/xen/arch/x86/domain.c     Sat Jan 20 11:21:08 2007 +0000
@@ -50,6 +50,8 @@ static void paravirt_ctxt_switch_from(st
 static void paravirt_ctxt_switch_from(struct vcpu *v);
 static void paravirt_ctxt_switch_to(struct vcpu *v);
 
+static void vcpu_destroy_pagetables(struct vcpu *v);
+
 static void continue_idle_domain(struct vcpu *v)
 {
     reset_stack_and_jump(idle_loop);
@@ -657,6 +659,13 @@ int arch_set_info_guest(
 
     return 0;
 #undef c
+}
+
+int arch_vcpu_reset(struct vcpu *v)
+{
+    destroy_gdt(v);
+    vcpu_destroy_pagetables(v);
+    return 0;
 }
 
 long
@@ -1381,63 +1390,73 @@ static void relinquish_memory(struct dom
     spin_unlock_recursive(&d->page_alloc_lock);
 }
 
-void domain_relinquish_resources(struct domain *d)
-{
-    struct vcpu *v;
+static void vcpu_destroy_pagetables(struct vcpu *v)
+{
+    struct domain *d = v->domain;
     unsigned long pfn;
 
-    BUG_ON(!cpus_empty(d->domain_dirty_cpumask));
-
-    /* Drop the in-use references to page-table bases. */
-    for_each_vcpu ( d, v )
-    {
-        /* Drop ref to guest_table (from new_guest_cr3(), svm/vmx cr3 handling,
-         * or sh_update_paging_modes()) */
 #ifdef CONFIG_COMPAT
-        if ( IS_COMPAT(d) )
-        {
-            if ( is_hvm_vcpu(v) )
-                pfn = pagetable_get_pfn(v->arch.guest_table);
-            else
-                pfn = l4e_get_pfn(*(l4_pgentry_t 
*)__va(pagetable_get_paddr(v->arch.guest_table)));
-
-            if ( pfn != 0 )
-            {
-                if ( shadow_mode_refcounts(d) )
-                    put_page(mfn_to_page(pfn));
-                else
-                    put_page_and_type(mfn_to_page(pfn));
-            }
-            continue;
-        }
-#endif
-        pfn = pagetable_get_pfn(v->arch.guest_table);
+    if ( IS_COMPAT(d) )
+    {
+        if ( is_hvm_vcpu(v) )
+            pfn = pagetable_get_pfn(v->arch.guest_table);
+        else
+            pfn = l4e_get_pfn(*(l4_pgentry_t *)
+                              __va(pagetable_get_paddr(v->arch.guest_table)));
+
         if ( pfn != 0 )
         {
             if ( shadow_mode_refcounts(d) )
                 put_page(mfn_to_page(pfn));
             else
                 put_page_and_type(mfn_to_page(pfn));
+        }
+
+        v->arch.guest_table = pagetable_null();
+        v->arch.cr3 = 0;
+        return;
+    }
+#endif
+
+    pfn = pagetable_get_pfn(v->arch.guest_table);
+    if ( pfn != 0 )
+    {
+        if ( shadow_mode_refcounts(d) )
+            put_page(mfn_to_page(pfn));
+        else
+            put_page_and_type(mfn_to_page(pfn));
 #ifdef __x86_64__
-            if ( pfn == pagetable_get_pfn(v->arch.guest_table_user) )
-                v->arch.guest_table_user = pagetable_null();
-#endif
-            v->arch.guest_table = pagetable_null();
-        }
+        if ( pfn == pagetable_get_pfn(v->arch.guest_table_user) )
+            v->arch.guest_table_user = pagetable_null();
+#endif
+        v->arch.guest_table = pagetable_null();
+    }
 
 #ifdef __x86_64__
-        /* Drop ref to guest_table_user (from MMUEXT_NEW_USER_BASEPTR) */
-        pfn = pagetable_get_pfn(v->arch.guest_table_user);
-        if ( pfn != 0 )
-        {
-            if ( shadow_mode_refcounts(d) )
-                put_page(mfn_to_page(pfn));
-            else
-                put_page_and_type(mfn_to_page(pfn));
-            v->arch.guest_table_user = pagetable_null();
-        }
-#endif
-    }
+    /* Drop ref to guest_table_user (from MMUEXT_NEW_USER_BASEPTR) */
+    pfn = pagetable_get_pfn(v->arch.guest_table_user);
+    if ( pfn != 0 )
+    {
+        if ( shadow_mode_refcounts(d) )
+            put_page(mfn_to_page(pfn));
+        else
+            put_page_and_type(mfn_to_page(pfn));
+        v->arch.guest_table_user = pagetable_null();
+    }
+#endif
+
+    v->arch.cr3 = 0;
+}
+
+void domain_relinquish_resources(struct domain *d)
+{
+    struct vcpu *v;
+
+    BUG_ON(!cpus_empty(d->domain_dirty_cpumask));
+
+    /* Drop the in-use references to page-table bases. */
+    for_each_vcpu ( d, v )
+        vcpu_destroy_pagetables(v);
 
     /* Tear down shadow mode stuff. */
     shadow_teardown(d);
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c     Sat Jan 20 11:17:42 2007 +0000
+++ b/xen/arch/x86/domctl.c     Sat Jan 20 11:21:08 2007 +0000
@@ -326,7 +326,6 @@ _long arch_do_domctl(
     }
     break;
 
-
     case XEN_DOMCTL_gethvmcontext:
     { 
         struct hvm_domain_context *c;
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 xen/common/domain.c
--- a/xen/common/domain.c       Sat Jan 20 11:17:42 2007 +0000
+++ b/xen/common/domain.c       Sat Jan 20 11:21:08 2007 +0000
@@ -5,6 +5,7 @@
  */
 
 #include <xen/config.h>
+#include <xen/compat.h>
 #include <xen/init.h>
 #include <xen/lib.h>
 #include <xen/errno.h>
@@ -466,7 +467,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));
@@ -520,6 +526,36 @@ int boot_vcpu(struct domain *d, int vcpu
     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;
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 xen/common/event_channel.c
--- a/xen/common/event_channel.c        Sat Jan 20 11:17:42 2007 +0000
+++ b/xen/common/event_channel.c        Sat Jan 20 11:21:08 2007 +0000
@@ -735,6 +735,29 @@ static long evtchn_unmask(evtchn_unmask_
 }
 
 
+static long evtchn_reset(evtchn_reset_t *r)
+{
+    domid_t dom = r->dom;
+    struct domain *d;
+    int i;
+
+    if ( dom == DOMID_SELF )
+        dom = current->domain->domain_id;
+    else if ( !IS_PRIV(current->domain) )
+        return -EPERM;
+
+    if ( (d = find_domain_by_id(dom)) == NULL )
+        return -ESRCH;
+
+    for ( i = 0; port_is_valid(d, i); i++ )
+        (void)__evtchn_close(d, i);
+
+    put_domain(d);
+
+    return 0;
+}
+
+
 long do_event_channel_op(int cmd, XEN_GUEST_HANDLE(void) arg)
 {
     long rc;
@@ -830,6 +853,14 @@ long do_event_channel_op(int cmd, XEN_GU
         if ( copy_from_guest(&unmask, arg, 1) != 0 )
             return -EFAULT;
         rc = evtchn_unmask(&unmask);
+        break;
+    }
+
+    case EVTCHNOP_reset: {
+        struct evtchn_reset reset;
+        if ( copy_from_guest(&reset, arg, 1) != 0 )
+            return -EFAULT;
+        rc = evtchn_reset(&reset);
         break;
     }
 
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 xen/include/public/event_channel.h
--- a/xen/include/public/event_channel.h        Sat Jan 20 11:17:42 2007 +0000
+++ b/xen/include/public/event_channel.h        Sat Jan 20 11:21:08 2007 +0000
@@ -217,6 +217,19 @@ typedef struct evtchn_unmask evtchn_unma
 typedef struct evtchn_unmask evtchn_unmask_t;
 
 /*
+ * EVTCHNOP_reset: Close all event channels associated with specified domain.
+ * NOTES:
+ *  1. <dom> may be specified as DOMID_SELF.
+ *  2. Only a sufficiently-privileged domain may specify other than DOMID_SELF.
+ */
+#define EVTCHNOP_reset           10
+struct evtchn_reset {
+    /* IN parameters. */
+    domid_t dom;
+};
+typedef struct evtchn_reset evtchn_reset_t;
+
+/*
  * Argument to event_channel_op_compat() hypercall. Superceded by new
  * event_channel_op() hypercall since 0x00030202.
  */
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 xen/include/public/io/xs_wire.h
--- a/xen/include/public/io/xs_wire.h   Sat Jan 20 11:17:42 2007 +0000
+++ b/xen/include/public/io/xs_wire.h   Sat Jan 20 11:21:08 2007 +0000
@@ -45,7 +45,8 @@ enum xsd_sockmsg_type
     XS_SET_PERMS,
     XS_WATCH_EVENT,
     XS_ERROR,
-    XS_IS_DOMAIN_INTRODUCED
+    XS_IS_DOMAIN_INTRODUCED,
+    XS_RESUME
 };
 
 #define XS_WRITE_NONE "NONE"
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 xen/include/xen/compat.h
--- a/xen/include/xen/compat.h  Sat Jan 20 11:17:42 2007 +0000
+++ b/xen/include/xen/compat.h  Sat Jan 20 11:21:08 2007 +0000
@@ -173,6 +173,8 @@ int switch_native(struct domain *);
 
 #else
 
+#define compat_handle_is_null(hnd) 0
+
 #define BITS_PER_GUEST_LONG(d) BITS_PER_LONG
 
 #endif
diff -r ff4f4596cb29 -r 5dc5e6ba42d2 xen/include/xen/domain.h
--- a/xen/include/xen/domain.h  Sat Jan 20 11:17:42 2007 +0000
+++ b/xen/include/xen/domain.h  Sat Jan 20 11:21:08 2007 +0000
@@ -12,6 +12,7 @@ int boot_vcpu(
 int boot_vcpu(
     struct domain *d, int vcpuid, vcpu_guest_context_u ctxt);
 struct vcpu *alloc_idle_vcpu(unsigned int cpu_id);
+int vcpu_reset(struct vcpu *v);
 
 struct domain *alloc_domain(domid_t domid);
 void free_domain(struct domain *d);
@@ -56,4 +57,6 @@ void arch_dump_vcpu_info(struct vcpu *v)
 
 void arch_dump_domain_info(struct domain *d);
 
+int arch_vcpu_reset(struct vcpu *v);
+
 #endif /* __XEN_DOMAIN_H__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>