[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] libxc: convert shadow domctl interfaces and save/restore over to hypercall buffers



# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxx>
# Date 1287756891 -3600
# Node ID 5795b64811bada7ad161982b4f47cc4c88a41a05
# Parent  60a3dfbe7e59b6af8776f3c75f1997dc1655ecb2
libxc: convert shadow domctl interfaces and save/restore over to hypercall 
buffers

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Signed-off-by: Ian Jackson <ian.jackson.citrix.com>
---
 tools/libxc/ia64/xc_ia64_linux_save.c |   29 +++++-------------
 tools/libxc/xc_domain.c               |    9 +++--
 tools/libxc/xc_domain_restore.c       |   54 ++++++++++++++++++----------------
 tools/libxc/xc_domain_save.c          |   40 +++++++++----------------
 tools/libxc/xenctrl.h                 |    2 -
 tools/libxc/xg_private.h              |    1 
 6 files changed, 61 insertions(+), 74 deletions(-)

diff -r 60a3dfbe7e59 -r 5795b64811ba tools/libxc/ia64/xc_ia64_linux_save.c
--- a/tools/libxc/ia64/xc_ia64_linux_save.c     Fri Oct 22 15:14:51 2010 +0100
+++ b/tools/libxc/ia64/xc_ia64_linux_save.c     Fri Oct 22 15:14:51 2010 +0100
@@ -432,9 +432,9 @@ xc_domain_save(xc_interface *xch, int io
     int last_iter = 0;
 
     /* Bitmap of pages to be sent.  */
-    unsigned long *to_send = NULL;
+    DECLARE_HYPERCALL_BUFFER(unsigned long, to_send);
     /* Bitmap of pages not to be sent (because dirtied).  */
-    unsigned long *to_skip = NULL;
+    DECLARE_HYPERCALL_BUFFER(unsigned long, to_skip);
 
     char *mem;
 
@@ -542,8 +542,8 @@ xc_domain_save(xc_interface *xch, int io
         last_iter = 0;
 
         bitmap_size = ((p2m_size + BITS_PER_LONG-1) & ~(BITS_PER_LONG-1)) / 8;
-        to_send = malloc(bitmap_size);
-        to_skip = malloc(bitmap_size);
+        to_send = xc_hypercall_buffer_alloc(xch, to_send, bitmap_size);
+        to_skip = xc_hypercall_buffer_alloc(xch, to_skip, bitmap_size);
 
         if (!to_send || !to_skip) {
             ERROR("Couldn't allocate bitmap array");
@@ -552,15 +552,6 @@ xc_domain_save(xc_interface *xch, int io
 
         /* Initially all the pages must be sent.  */
         memset(to_send, 0xff, bitmap_size);
-
-        if (lock_pages(to_send, bitmap_size)) {
-            ERROR("Unable to lock_pages to_send");
-            goto out;
-        }
-        if (lock_pages(to_skip, bitmap_size)) {
-            ERROR("Unable to lock_pages to_skip");
-            goto out;
-        }
 
         /* Enable qemu-dm logging dirty pages to xen */
         if (hvm && !callbacks->switch_qemu_logdirty(dom, 1, callbacks->data)) {
@@ -621,7 +612,7 @@ xc_domain_save(xc_interface *xch, int io
         if (!last_iter) {
             if (xc_shadow_control(xch, dom,
                                   XEN_DOMCTL_SHADOW_OP_PEEK,
-                                  to_skip, p2m_size,
+                                  HYPERCALL_BUFFER(to_skip), p2m_size,
                                   NULL, 0, NULL) != p2m_size) {
                 ERROR("Error peeking shadow bitmap");
                 goto out;
@@ -713,7 +704,7 @@ xc_domain_save(xc_interface *xch, int io
             /* Pages to be sent are pages which were dirty.  */
             if (xc_shadow_control(xch, dom,
                                   XEN_DOMCTL_SHADOW_OP_CLEAN,
-                                  to_send, p2m_size,
+                                  HYPERCALL_BUFFER(to_send), p2m_size,
                                   NULL, 0, NULL ) != p2m_size) {
                 ERROR("Error flushing shadow PT");
                 goto out;
@@ -779,7 +770,7 @@ xc_domain_save(xc_interface *xch, int io
        //print_stats(xch, dom, 0, &stats, 1);
 
        if ( xc_shadow_control(xch, dom,
-                              XEN_DOMCTL_SHADOW_OP_CLEAN, to_send,
+                              XEN_DOMCTL_SHADOW_OP_CLEAN, 
HYPERCALL_BUFFER(to_send),
                               p2m_size, NULL, 0, NULL) != p2m_size )
        {
            ERROR("Error flushing shadow PT");
@@ -799,10 +790,8 @@ xc_domain_save(xc_interface *xch, int io
         }
     }
 
-    unlock_pages(to_send, bitmap_size);
-    free(to_send);
-    unlock_pages(to_skip, bitmap_size);
-    free(to_skip);
+    xc_hypercall_buffer_free(xch, to_send);
+    xc_hypercall_buffer_free(xch, to_skip);
     if (live_shinfo)
         munmap(live_shinfo, PAGE_SIZE);
     if (memmap_info)
diff -r 60a3dfbe7e59 -r 5795b64811ba tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Fri Oct 22 15:14:51 2010 +0100
+++ b/tools/libxc/xc_domain.c   Fri Oct 22 15:14:51 2010 +0100
@@ -400,7 +400,7 @@ int xc_shadow_control(xc_interface *xch,
 int xc_shadow_control(xc_interface *xch,
                       uint32_t domid,
                       unsigned int sop,
-                      unsigned long *dirty_bitmap,
+                      xc_hypercall_buffer_t *dirty_bitmap,
                       unsigned long pages,
                       unsigned long *mb,
                       uint32_t mode,
@@ -408,14 +408,17 @@ int xc_shadow_control(xc_interface *xch,
 {
     int rc;
     DECLARE_DOMCTL;
+    DECLARE_HYPERCALL_BUFFER_ARGUMENT(dirty_bitmap);
+
     domctl.cmd = XEN_DOMCTL_shadow_op;
     domctl.domain = (domid_t)domid;
     domctl.u.shadow_op.op     = sop;
     domctl.u.shadow_op.pages  = pages;
     domctl.u.shadow_op.mb     = mb ? *mb : 0;
     domctl.u.shadow_op.mode   = mode;
-    set_xen_guest_handle(domctl.u.shadow_op.dirty_bitmap,
-                         (uint8_t *)dirty_bitmap);
+    if (dirty_bitmap != NULL)
+        xc_set_xen_guest_handle(domctl.u.shadow_op.dirty_bitmap,
+                                dirty_bitmap);
 
     rc = do_domctl(xch, &domctl);
 
diff -r 60a3dfbe7e59 -r 5795b64811ba tools/libxc/xc_domain_restore.c
--- a/tools/libxc/xc_domain_restore.c   Fri Oct 22 15:14:51 2010 +0100
+++ b/tools/libxc/xc_domain_restore.c   Fri Oct 22 15:14:51 2010 +0100
@@ -1063,7 +1063,7 @@ int xc_domain_restore(xc_interface *xch,
     shared_info_any_t *new_shared_info;
 
     /* A copy of the CPU context of the guest. */
-    vcpu_guest_context_any_t ctxt;
+    DECLARE_HYPERCALL_BUFFER(vcpu_guest_context_any_t, ctxt);
 
     /* A table containing the type of each PFN (/not/ MFN!). */
     unsigned long *pfn_type = NULL;
@@ -1112,6 +1112,15 @@ int xc_domain_restore(xc_interface *xch,
 
     if ( superpages )
         return 1;
+
+    ctxt = xc_hypercall_buffer_alloc(xch, ctxt, sizeof(*ctxt));
+
+    if ( ctxt == NULL )
+    {
+        PERROR("Unable to allocate VCPU ctxt buffer");
+        return 1;
+    }
+
 
     if ( (orig_io_fd_flags = fcntl(io_fd, F_GETFL, 0)) < 0 ) {
         PERROR("unable to read IO FD flags");
@@ -1539,26 +1548,20 @@ int xc_domain_restore(xc_interface *xch,
         }
     }
 
-    if ( lock_pages(xch, &ctxt, sizeof(ctxt)) )
-    {
-        PERROR("Unable to lock ctxt");
-        return 1;
-    }
-
     vcpup = tailbuf.u.pv.vcpubuf;
     for ( i = 0; i <= max_vcpu_id; i++ )
     {
         if ( !(vcpumap & (1ULL << i)) )
             continue;
 
-        memcpy(&ctxt, vcpup, ((dinfo->guest_width == 8) ? sizeof(ctxt.x64)
-                              : sizeof(ctxt.x32)));
-        vcpup += (dinfo->guest_width == 8) ? sizeof(ctxt.x64) : 
sizeof(ctxt.x32);
+        memcpy(ctxt, vcpup, ((dinfo->guest_width == 8) ? sizeof(ctxt->x64)
+                              : sizeof(ctxt->x32)));
+        vcpup += (dinfo->guest_width == 8) ? sizeof(ctxt->x64) : 
sizeof(ctxt->x32);
 
         DPRINTF("read VCPU %d\n", i);
 
         if ( !new_ctxt_format )
-            SET_FIELD(&ctxt, flags, GET_FIELD(&ctxt, flags) | VGCF_online);
+            SET_FIELD(ctxt, flags, GET_FIELD(ctxt, flags) | VGCF_online);
 
         if ( i == 0 )
         {
@@ -1566,7 +1569,7 @@ int xc_domain_restore(xc_interface *xch,
              * Uncanonicalise the suspend-record frame number and poke
              * resume record.
              */
-            pfn = GET_FIELD(&ctxt, user_regs.edx);
+            pfn = GET_FIELD(ctxt, user_regs.edx);
             if ( (pfn >= dinfo->p2m_size) ||
                  (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB) )
             {
@@ -1574,7 +1577,7 @@ int xc_domain_restore(xc_interface *xch,
                 goto out;
             }
             mfn = ctx->p2m[pfn];
-            SET_FIELD(&ctxt, user_regs.edx, mfn);
+            SET_FIELD(ctxt, user_regs.edx, mfn);
             start_info = xc_map_foreign_range(
                 xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
             SET_FIELD(start_info, nr_pages, dinfo->p2m_size);
@@ -1589,15 +1592,15 @@ int xc_domain_restore(xc_interface *xch,
             munmap(start_info, PAGE_SIZE);
         }
         /* Uncanonicalise each GDT frame number. */
-        if ( GET_FIELD(&ctxt, gdt_ents) > 8192 )
+        if ( GET_FIELD(ctxt, gdt_ents) > 8192 )
         {
             ERROR("GDT entry count out of range");
             goto out;
         }
 
-        for ( j = 0; (512*j) < GET_FIELD(&ctxt, gdt_ents); j++ )
-        {
-            pfn = GET_FIELD(&ctxt, gdt_frames[j]);
+        for ( j = 0; (512*j) < GET_FIELD(ctxt, gdt_ents); j++ )
+        {
+            pfn = GET_FIELD(ctxt, gdt_frames[j]);
             if ( (pfn >= dinfo->p2m_size) ||
                  (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB) )
             {
@@ -1605,10 +1608,10 @@ int xc_domain_restore(xc_interface *xch,
                       j, (unsigned long)pfn);
                 goto out;
             }
-            SET_FIELD(&ctxt, gdt_frames[j], ctx->p2m[pfn]);
+            SET_FIELD(ctxt, gdt_frames[j], ctx->p2m[pfn]);
         }
         /* Uncanonicalise the page table base pointer. */
-        pfn = UNFOLD_CR3(GET_FIELD(&ctxt, ctrlreg[3]));
+        pfn = UNFOLD_CR3(GET_FIELD(ctxt, ctrlreg[3]));
 
         if ( pfn >= dinfo->p2m_size )
         {
@@ -1625,12 +1628,12 @@ int xc_domain_restore(xc_interface *xch,
                   (unsigned long)ctx->pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT);
             goto out;
         }
-        SET_FIELD(&ctxt, ctrlreg[3], FOLD_CR3(ctx->p2m[pfn]));
+        SET_FIELD(ctxt, ctrlreg[3], FOLD_CR3(ctx->p2m[pfn]));
 
         /* Guest pagetable (x86/64) stored in otherwise-unused CR1. */
-        if ( (ctx->pt_levels == 4) && (ctxt.x64.ctrlreg[1] & 1) )
-        {
-            pfn = UNFOLD_CR3(ctxt.x64.ctrlreg[1] & ~1);
+        if ( (ctx->pt_levels == 4) && (ctxt->x64.ctrlreg[1] & 1) )
+        {
+            pfn = UNFOLD_CR3(ctxt->x64.ctrlreg[1] & ~1);
             if ( pfn >= dinfo->p2m_size )
             {
                 ERROR("User PT base is bad: pfn=%lu p2m_size=%lu",
@@ -1645,12 +1648,12 @@ int xc_domain_restore(xc_interface *xch,
                       (unsigned 
long)ctx->pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT);
                 goto out;
             }
-            ctxt.x64.ctrlreg[1] = FOLD_CR3(ctx->p2m[pfn]);
+            ctxt->x64.ctrlreg[1] = FOLD_CR3(ctx->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.c);
+        xc_set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt);
         frc = xc_domctl(xch, &domctl);
         if ( frc != 0 )
         {
@@ -1791,6 +1794,7 @@ int xc_domain_restore(xc_interface *xch,
  out:
     if ( (rc != 0) && (dom != 0) )
         xc_domain_destroy(xch, dom);
+    xc_hypercall_buffer_free(xch, ctxt);
     free(mmu);
     free(ctx->p2m);
     free(pfn_type);
diff -r 60a3dfbe7e59 -r 5795b64811ba tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c      Fri Oct 22 15:14:51 2010 +0100
+++ b/tools/libxc/xc_domain_save.c      Fri Oct 22 15:14:51 2010 +0100
@@ -411,7 +411,7 @@ static int print_stats(xc_interface *xch
 
 
 static int analysis_phase(xc_interface *xch, uint32_t domid, struct save_ctx 
*ctx,
-                          unsigned long *arr, int runs)
+                          xc_hypercall_buffer_t *arr, int runs)
 {
     long long start, now;
     xc_shadow_op_stats_t stats;
@@ -909,7 +909,9 @@ int xc_domain_save(xc_interface *xch, in
        - that should be sent this iteration (unless later marked as skip);
        - to skip this iteration because already dirty;
        - to fixup by sending at the end if not already resent; */
-    unsigned long *to_send = NULL, *to_skip = NULL, *to_fix = NULL;
+    DECLARE_HYPERCALL_BUFFER(unsigned long, to_skip);
+    DECLARE_HYPERCALL_BUFFER(unsigned long, to_send);
+    unsigned long *to_fix = NULL;
 
     xc_shadow_op_stats_t stats;
 
@@ -1038,9 +1040,9 @@ int xc_domain_save(xc_interface *xch, in
     sent_last_iter = dinfo->p2m_size;
 
     /* Setup to_send / to_fix and to_skip bitmaps */
-    to_send = xc_memalign(PAGE_SIZE, ROUNDUP(BITMAP_SIZE, PAGE_SHIFT)); 
+    to_send = xc_hypercall_buffer_alloc_pages(xch, to_send, 
NRPAGES(BITMAP_SIZE));
+    to_skip = xc_hypercall_buffer_alloc_pages(xch, to_skip, 
NRPAGES(BITMAP_SIZE));
     to_fix  = calloc(1, BITMAP_SIZE);
-    to_skip = xc_memalign(PAGE_SIZE, ROUNDUP(BITMAP_SIZE, PAGE_SHIFT)); 
 
     if ( !to_send || !to_fix || !to_skip )
     {
@@ -1050,20 +1052,7 @@ int xc_domain_save(xc_interface *xch, in
 
     memset(to_send, 0xff, BITMAP_SIZE);
 
-    if ( lock_pages(xch, to_send, BITMAP_SIZE) )
-    {
-        PERROR("Unable to lock to_send");
-        return 1;
-    }
-
-    /* (to fix is local only) */
-    if ( lock_pages(xch, to_skip, BITMAP_SIZE) )
-    {
-        PERROR("Unable to lock to_skip");
-        return 1;
-    }
-
-    if ( hvm ) 
+    if ( hvm )
     {
         /* Need another buffer for HVM context */
         hvm_buf_size = xc_domain_hvm_getcontext(xch, dom, 0, 0);
@@ -1080,7 +1069,7 @@ int xc_domain_save(xc_interface *xch, in
         }
     }
 
-    analysis_phase(xch, dom, ctx, to_skip, 0);
+    analysis_phase(xch, dom, ctx, HYPERCALL_BUFFER(to_skip), 0);
 
     pfn_type   = xc_memalign(PAGE_SIZE, ROUNDUP(
                               MAX_BATCH_SIZE * sizeof(*pfn_type), PAGE_SHIFT));
@@ -1192,7 +1181,7 @@ int xc_domain_save(xc_interface *xch, in
                 /* Slightly wasteful to peek the whole array evey time,
                    but this is fast enough for the moment. */
                 frc = xc_shadow_control(
-                    xch, dom, XEN_DOMCTL_SHADOW_OP_PEEK, to_skip, 
+                    xch, dom, XEN_DOMCTL_SHADOW_OP_PEEK, 
HYPERCALL_BUFFER(to_skip),
                     dinfo->p2m_size, NULL, 0, NULL);
                 if ( frc != dinfo->p2m_size )
                 {
@@ -1532,8 +1521,8 @@ int xc_domain_save(xc_interface *xch, in
 
             }
 
-            if ( xc_shadow_control(xch, dom, 
-                                   XEN_DOMCTL_SHADOW_OP_CLEAN, to_send, 
+            if ( xc_shadow_control(xch, dom,
+                                   XEN_DOMCTL_SHADOW_OP_CLEAN, 
HYPERCALL_BUFFER(to_send),
                                    dinfo->p2m_size, NULL, 0, &stats) != 
dinfo->p2m_size )
             {
                 PERROR("Error flushing shadow PT");
@@ -1861,7 +1850,7 @@ int xc_domain_save(xc_interface *xch, in
         print_stats(xch, dom, 0, &stats, 1);
 
         if ( xc_shadow_control(xch, dom,
-                               XEN_DOMCTL_SHADOW_OP_CLEAN, to_send,
+                               XEN_DOMCTL_SHADOW_OP_CLEAN, 
HYPERCALL_BUFFER(to_send),
                                dinfo->p2m_size, NULL, 0, &stats) != 
dinfo->p2m_size )
         {
             PERROR("Error flushing shadow PT");
@@ -1892,12 +1881,13 @@ int xc_domain_save(xc_interface *xch, in
     if ( ctx->live_m2p )
         munmap(ctx->live_m2p, M2P_SIZE(ctx->max_mfn));
 
+    xc_hypercall_buffer_free_pages(xch, to_send, NRPAGES(BITMAP_SIZE));
+    xc_hypercall_buffer_free_pages(xch, to_skip, NRPAGES(BITMAP_SIZE));
+
     free(pfn_type);
     free(pfn_batch);
     free(pfn_err);
-    free(to_send);
     free(to_fix);
-    free(to_skip);
 
     DPRINTF("Save exit rc=%d\n",rc);
 
diff -r 60a3dfbe7e59 -r 5795b64811ba tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Fri Oct 22 15:14:51 2010 +0100
+++ b/tools/libxc/xenctrl.h     Fri Oct 22 15:14:51 2010 +0100
@@ -601,7 +601,7 @@ int xc_shadow_control(xc_interface *xch,
 int xc_shadow_control(xc_interface *xch,
                       uint32_t domid,
                       unsigned int sop,
-                      unsigned long *dirty_bitmap,
+                      xc_hypercall_buffer_t *dirty_bitmap,
                       unsigned long pages,
                       unsigned long *mb,
                       uint32_t mode,
diff -r 60a3dfbe7e59 -r 5795b64811ba tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h  Fri Oct 22 15:14:51 2010 +0100
+++ b/tools/libxc/xg_private.h  Fri Oct 22 15:14:51 2010 +0100
@@ -157,6 +157,7 @@ typedef l4_pgentry_64_t l4_pgentry_t;
 #define PAGE_MASK_IA64          (~(PAGE_SIZE_IA64-1))
 
 #define ROUNDUP(_x,_w) (((unsigned long)(_x)+(1UL<<(_w))-1) & ~((1UL<<(_w))-1))
+#define NRPAGES(x) (ROUNDUP(x, PAGE_SHIFT) >> PAGE_SHIFT)
 
 
 /* XXX SMH: following skanky macros rely on variable p2m_size being set */

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


 


Rackspace

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