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

[Xen-devel] [PATCH 13 of 24] libxc: convert shadow domctl interfaces and save/restore over to hypercall buffers



# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxx>
# Date 1283779691 -3600
# Node ID 2a5e84fe718ae25e91785643388411b70d4c013b
# Parent  7f735088ac1d169d140d978441c772b62083fae0
libxc: convert shadow domctl interfaces and save/restore over to hypercall 
buffers

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

diff -r 7f735088ac1d -r 2a5e84fe718a tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Mon Sep 06 14:28:11 2010 +0100
+++ b/tools/libxc/xc_domain.c   Mon Sep 06 14:28:11 2010 +0100
@@ -404,7 +404,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,
@@ -412,14 +412,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 7f735088ac1d -r 2a5e84fe718a tools/libxc/xc_domain_restore.c
--- a/tools/libxc/xc_domain_restore.c   Mon Sep 06 14:28:11 2010 +0100
+++ b/tools/libxc/xc_domain_restore.c   Mon Sep 06 14:28:11 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 lock ctxt");
+        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++ )
+        for ( j = 0; (512*j) < GET_FIELD(ctxt, gdt_ents); j++ )
         {
-            pfn = GET_FIELD(&ctxt, gdt_frames[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) )
+        if ( (ctx->pt_levels == 4) && (ctxt->x64.ctrlreg[1] & 1) )
         {
-            pfn = UNFOLD_CR3(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 7f735088ac1d -r 2a5e84fe718a tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c      Mon Sep 06 14:28:11 2010 +0100
+++ b/tools/libxc/xc_domain_save.c      Mon Sep 06 14:28:11 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;
@@ -915,7 +915,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;
 
@@ -1034,9 +1036,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 )
     {
@@ -1046,20 +1048,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);
@@ -1076,7 +1065,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));
@@ -1188,7 +1177,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 )
                 {
@@ -1528,8 +1517,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");
@@ -1857,7 +1846,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");
@@ -1888,12 +1877,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 7f735088ac1d -r 2a5e84fe718a tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Mon Sep 06 14:28:11 2010 +0100
+++ b/tools/libxc/xenctrl.h     Mon Sep 06 14:28:11 2010 +0100
@@ -610,7 +610,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 7f735088ac1d -r 2a5e84fe718a tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h  Mon Sep 06 14:28:11 2010 +0100
+++ b/tools/libxc/xg_private.h  Mon Sep 06 14:28:11 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-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

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