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] Save/restore context of all online VCPUs

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Save/restore context of all online VCPUs in PV save/restore/migrate.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 01 Mar 2007 14:50:08 -0800
Delivery-date: Thu, 01 Mar 2007 14:49:51 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1172771957 0
# Node ID 139794d55898642e3f0bef2f771a83979333ee1e
# Parent  33d733c3649df6e6713de5852892d7ffd74f3170
Save/restore context of all online VCPUs in PV save/restore/migrate.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 tools/libxc/xc_linux_restore.c |  167 +++++++++++++++++++++++------------------
 tools/libxc/xc_linux_save.c    |   85 +++++++++++++-------
 2 files changed, 153 insertions(+), 99 deletions(-)

diff -r 33d733c3649d -r 139794d55898 tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c    Thu Mar 01 17:28:31 2007 +0000
+++ b/tools/libxc/xc_linux_restore.c    Thu Mar 01 17:59:17 2007 +0000
@@ -144,7 +144,7 @@ int xc_linux_restore(int xc_handle, int 
                      unsigned int console_evtchn, unsigned long *console_mfn)
 {
     DECLARE_DOMCTL;
-    int rc = 1, i, n, m, pae_extended_cr3 = 0;
+    int rc = 1, i, j, n, m, pae_extended_cr3 = 0;
     unsigned long mfn, pfn;
     unsigned int prev_pc, this_pc;
     int verify = 0;
@@ -187,6 +187,8 @@ int xc_linux_restore(int xc_handle, int 
     struct mmuext_op pin[MAX_PIN_BATCH];
     unsigned int nr_pins;
 
+    uint64_t vcpumap = 1ULL;
+    unsigned int max_vcpu_id = 0;
 
     max_pfn = nr_pfns;
 
@@ -366,6 +368,16 @@ int xc_linux_restore(int xc_handle, int 
         if (j == -1) {
             verify = 1;
             DPRINTF("Entering page verify mode\n");
+            continue;
+        }
+
+        if (j == -2) {
+            if (!read_exact(io_fd, &max_vcpu_id, sizeof(int)) ||
+                (max_vcpu_id >= 64) ||
+                !read_exact(io_fd, &vcpumap, sizeof(uint64_t))) {
+                ERROR("Error when reading max_vcpu_id");
+                goto out;
+            }
             continue;
         }
 
@@ -776,64 +788,90 @@ int xc_linux_restore(int xc_handle, int 
         }
     }
 
-    if (!read_exact(io_fd, &ctxt, sizeof(ctxt)) ||
-        !read_exact(io_fd, shared_info_page, PAGE_SIZE)) {
-        ERROR("Error when reading ctxt or shared info page");
-        goto out;
-    }
-
-    /* Uncanonicalise the suspend-record frame number and poke resume rec. */
-    pfn = ctxt.user_regs.edx;
-    if ((pfn >= max_pfn) || (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB)) {
-        ERROR("Suspend record frame number is bad");
-        goto out;
-    }
-    ctxt.user_regs.edx = mfn = p2m[pfn];
-    start_info = xc_map_foreign_range(
-        xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
-    start_info->nr_pages    = max_pfn;
-    start_info->shared_info = shared_info_frame << PAGE_SHIFT;
-    start_info->flags       = 0;
-    *store_mfn = start_info->store_mfn       = p2m[start_info->store_mfn];
-    start_info->store_evtchn                 = store_evtchn;
-    start_info->console.domU.mfn    = p2m[start_info->console.domU.mfn];
-    start_info->console.domU.evtchn = console_evtchn;
-    *console_mfn                    = start_info->console.domU.mfn;
-    munmap(start_info, PAGE_SIZE);
-
-    /* Uncanonicalise each GDT frame number. */
-    if (ctxt.gdt_ents > 8192) {
-        ERROR("GDT entry count out of range");
-        goto out;
-    }
-
-    for (i = 0; (512*i) < ctxt.gdt_ents; i++) {
-        pfn = ctxt.gdt_frames[i];
-        if ((pfn >= max_pfn) || (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB)) {
-            ERROR("GDT frame number is bad");
-            goto out;
-        }
-        ctxt.gdt_frames[i] = p2m[pfn];
-    }
-
-    /* Uncanonicalise the page table base pointer. */
-    pfn = xen_cr3_to_pfn(ctxt.ctrlreg[3]);
-
-    if (pfn >= max_pfn) {
-        ERROR("PT base is bad: pfn=%lu max_pfn=%lu type=%08lx",
-            pfn, max_pfn, pfn_type[pfn]);
-        goto out;
-    }
-
-    if ( (pfn_type[pfn] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK) !=
-         ((unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT) ) {
-        ERROR("PT base is bad. pfn=%lu nr=%lu type=%08lx %08lx",
-            pfn, max_pfn, pfn_type[pfn],
-            (unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT);
-        goto out;
-    }
-
-    ctxt.ctrlreg[3] = xen_pfn_to_cr3(p2m[pfn]);
+    for (i = 0; i <= max_vcpu_id; i++) {
+        if (!(vcpumap & (1ULL << i)))
+            continue;
+
+        if (!read_exact(io_fd, &ctxt, sizeof(ctxt))) {
+            ERROR("Error when reading ctxt %d", i);
+            goto out;
+        }
+
+        if (i == 0) {
+            /*
+             * Uncanonicalise the suspend-record frame number and poke
+             * resume record.
+             */
+            pfn = ctxt.user_regs.edx;
+            if ((pfn >= max_pfn) ||
+                (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB)) {
+                ERROR("Suspend record frame number is bad");
+                goto out;
+            }
+            ctxt.user_regs.edx = mfn = p2m[pfn];
+            start_info = xc_map_foreign_range(
+                xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
+            start_info->nr_pages = max_pfn;
+            start_info->shared_info = shared_info_frame << PAGE_SHIFT;
+            start_info->flags = 0;
+            *store_mfn = start_info->store_mfn = p2m[start_info->store_mfn];
+            start_info->store_evtchn = store_evtchn;
+            start_info->console.domU.mfn = p2m[start_info->console.domU.mfn];
+            start_info->console.domU.evtchn = console_evtchn;
+            *console_mfn = start_info->console.domU.mfn;
+            munmap(start_info, PAGE_SIZE);
+        }
+
+        /* Uncanonicalise each GDT frame number. */
+        if (ctxt.gdt_ents > 8192) {
+            ERROR("GDT entry count out of range");
+            goto out;
+        }
+
+        for (j = 0; (512*j) < ctxt.gdt_ents; j++) {
+            pfn = ctxt.gdt_frames[j];
+            if ((pfn >= max_pfn) ||
+                (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB)) {
+                ERROR("GDT frame number is bad");
+                goto out;
+            }
+            ctxt.gdt_frames[j] = p2m[pfn];
+        }
+
+        /* Uncanonicalise the page table base pointer. */
+        pfn = xen_cr3_to_pfn(ctxt.ctrlreg[3]);
+
+        if (pfn >= max_pfn) {
+            ERROR("PT base is bad: pfn=%lu max_pfn=%lu type=%08lx",
+                  pfn, max_pfn, pfn_type[pfn]);
+            goto out;
+        }
+
+        if ( (pfn_type[pfn] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK) !=
+             ((unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT) ) {
+            ERROR("PT base is bad. pfn=%lu nr=%lu type=%08lx %08lx",
+                  pfn, max_pfn, pfn_type[pfn],
+                  (unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT);
+            goto out;
+        }
+
+        ctxt.ctrlreg[3] = xen_pfn_to_cr3(p2m[pfn]);
+
+        domctl.cmd = XEN_DOMCTL_setvcpucontext;
+        domctl.domain = (domid_t)dom;
+        domctl.u.vcpucontext.vcpu = i;
+        set_xen_guest_handle(domctl.u.vcpucontext.ctxt, &ctxt);
+        rc = xc_domctl(xc_handle, &domctl);
+        if (rc != 0) {
+            ERROR("Couldn't build vcpu%d", i);
+            goto out;
+        }
+    }
+
+    if (!read_exact(io_fd, shared_info_page, PAGE_SIZE)) {
+        ERROR("Error when reading shared info page");
+        goto out;
+    }
 
     /* clear any pending events and the selector */
     memset(&(shared_info->evtchn_pending[0]), 0,
@@ -869,17 +907,6 @@ int xc_linux_restore(int xc_handle, int 
     munmap(live_p2m, P2M_SIZE);
 
     DPRINTF("Domain ready to be built.\n");
-
-    domctl.cmd = XEN_DOMCTL_setvcpucontext;
-    domctl.domain = (domid_t)dom;
-    domctl.u.vcpucontext.vcpu   = 0;
-    set_xen_guest_handle(domctl.u.vcpucontext.ctxt, &ctxt);
-    rc = xc_domctl(xc_handle, &domctl);
-
-    if (rc != 0) {
-        ERROR("Couldn't build the domain");
-        goto out;
-    }
 
  out:
     if ( (rc != 0) && (dom != 0) )
diff -r 33d733c3649d -r 139794d55898 tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c       Thu Mar 01 17:28:31 2007 +0000
+++ b/tools/libxc/xc_linux_save.c       Thu Mar 01 17:59:17 2007 +0000
@@ -696,6 +696,7 @@ int xc_linux_save(int xc_handle, int io_
     unsigned long needed_to_fix = 0;
     unsigned long total_sent    = 0;
 
+    uint64_t vcpumap = 1ULL;
 
     /* If no explicit control parameters given, use defaults */
     if(!max_iters)
@@ -716,24 +717,11 @@ int xc_linux_save(int xc_handle, int io_
         return 1;
     }
 
-    if (lock_pages(&ctxt, sizeof(ctxt))) {
-        ERROR("Unable to lock ctxt");
-        return 1;
-    }
-
-    /* Only have to worry about vcpu 0 even for SMP */
     if (xc_vcpu_getcontext(xc_handle, dom, 0, &ctxt)) {
         ERROR("Could not get vcpu context");
         goto out;
     }
     shared_info_frame = info.shared_info_frame;
-
-    /* A cheesy test to see whether the domain contains valid state. */
-    if (ctxt.ctrlreg[3] == 0)
-    {
-        ERROR("Domain is not in a valid Linux guest OS state");
-        goto out;
-    }
 
     /* Map the shared info frame */
     if(!(live_shinfo = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
@@ -1194,6 +1182,32 @@ int xc_linux_save(int xc_handle, int io_
 
     DPRINTF("All memory is saved\n");
 
+    {
+        struct {
+            int minustwo;
+            int max_vcpu_id;
+            uint64_t vcpumap;
+        } chunk = { -2, info.max_vcpu_id };
+
+        if (info.max_vcpu_id >= 64) {
+            ERROR("Too many VCPUS in guest!");
+            goto out;
+        }
+
+        for (i = 1; i <= info.max_vcpu_id; i++) {
+            xc_vcpuinfo_t vinfo;
+            if ((xc_vcpu_getinfo(xc_handle, dom, i, &vinfo) == 0) &&
+                vinfo.online)
+                vcpumap |= 1ULL << i;
+        }
+
+        chunk.vcpumap = vcpumap;
+        if(!write_exact(io_fd, &chunk, sizeof(chunk))) {
+            ERROR("Error when writing to state file (errno %d)", errno);
+            goto out;
+        }
+    }
+
     /* Zero terminate */
     i = 0;
     if (!write_exact(io_fd, &i, sizeof(int))) {
@@ -1240,30 +1254,43 @@ int xc_linux_save(int xc_handle, int io_
         goto out;
     }
 
-    /* Canonicalise each GDT frame number. */
-    for ( i = 0; (512*i) < ctxt.gdt_ents; i++ ) {
-        if ( !translate_mfn_to_pfn(&ctxt.gdt_frames[i]) ) {
-            ERROR("GDT frame is not in range of pseudophys map");
+    for (i = 0; i <= info.max_vcpu_id; i++) {
+        if (!(vcpumap & (1ULL << i)))
+            continue;
+
+        if ((i != 0) && xc_vcpu_getcontext(xc_handle, dom, i, &ctxt)) {
+            ERROR("No context for VCPU%d", i);
             goto out;
         }
-    }
-
-    /* Canonicalise the page table base pointer. */
-    if ( !MFN_IS_IN_PSEUDOPHYS_MAP(xen_cr3_to_pfn(ctxt.ctrlreg[3])) ) {
-        ERROR("PT base is not in range of pseudophys map");
-        goto out;
-    }
-    ctxt.ctrlreg[3] = 
-        xen_pfn_to_cr3(mfn_to_pfn(xen_cr3_to_pfn(ctxt.ctrlreg[3])));
+
+        /* Canonicalise each GDT frame number. */
+        for ( j = 0; (512*j) < ctxt.gdt_ents; j++ ) {
+            if ( !translate_mfn_to_pfn(&ctxt.gdt_frames[j]) ) {
+                ERROR("GDT frame is not in range of pseudophys map");
+                goto out;
+            }
+        }
+
+        /* Canonicalise the page table base pointer. */
+        if ( !MFN_IS_IN_PSEUDOPHYS_MAP(xen_cr3_to_pfn(ctxt.ctrlreg[3])) ) {
+            ERROR("PT base is not in range of pseudophys map");
+            goto out;
+        }
+        ctxt.ctrlreg[3] = 
+            xen_pfn_to_cr3(mfn_to_pfn(xen_cr3_to_pfn(ctxt.ctrlreg[3])));
+
+        if (!write_exact(io_fd, &ctxt, sizeof(ctxt))) {
+            ERROR("Error when writing to state file (1) (errno %d)", errno);
+            goto out;
+        }
+    }
 
     /*
      * Reset the MFN to be a known-invalid value. See map_frame_list_list().
      */
     memcpy(page, live_shinfo, PAGE_SIZE);
     ((shared_info_t *)page)->arch.pfn_to_mfn_frame_list_list = 0;
-
-    if (!write_exact(io_fd, &ctxt, sizeof(ctxt)) ||
-        !write_exact(io_fd, page, PAGE_SIZE)) {
+    if (!write_exact(io_fd, page, PAGE_SIZE)) {
         ERROR("Error when writing to state file (1) (errno %d)", errno);
         goto out;
     }

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Save/restore context of all online VCPUs in PV save/restore/migrate., Xen patchbot-unstable <=