]> xenbits.xensource.com Git - people/vhanquez/xen.git/commitdiff
save/restore: Use page-aligned allocations for hypercall args that are
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 9 Apr 2008 15:56:05 +0000 (16:56 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 9 Apr 2008 15:56:05 +0000 (16:56 +0100)
mlock()ed across other hypercall invocations, to avoid aliasing with
other hypercall arguments, causing spurious unlocking.

Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
xen-unstable changeset:   17424:f410fa7f379c3a2fc8d4117188f36899e63e6053
xen-unstable date:        Wed Apr 09 16:31:16 2008 +0100

tools/libxc/xc_domain_restore.c
tools/libxc/xc_domain_save.c
tools/libxc/xg_private.h

index 52fc1155d22cf0fd433de2f316bbc73c314e0643..b7b74352e1ac60f819199365176dd16e6ea90ddc 100644 (file)
@@ -284,7 +284,8 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
     /* The new domain's shared-info frame number. */
     unsigned long shared_info_frame;
     unsigned char shared_info_page[PAGE_SIZE]; /* saved contents from file */
-    shared_info_either_t *old_shared_info = (shared_info_either_t *)shared_info_page;
+    shared_info_either_t *old_shared_info = 
+        (shared_info_either_t *)shared_info_page;
     shared_info_either_t *new_shared_info;
 
     /* A copy of the CPU context of the guest. */
@@ -349,13 +350,6 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
     guest_width = sizeof(unsigned long);
     pt_levels = (guest_width == 8) ? 4 : (pt_levels == 2) ? 2 : 3; 
     
-    if ( lock_pages(&ctxt, sizeof(ctxt)) )
-    {
-        /* needed for build domctl, but might as well do early */
-        ERROR("Unable to lock ctxt");
-        return 1;
-    }
-
     if ( !hvm ) 
     {
         /* Load the p2m frame list, plus potential extended info chunk */
@@ -380,8 +374,11 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
     /* We want zeroed memory so use calloc rather than malloc. */
     p2m        = calloc(p2m_size, MAX(guest_width, sizeof (xen_pfn_t))); 
     pfn_type   = calloc(p2m_size, sizeof(unsigned long));
-    region_mfn = calloc(MAX_BATCH_SIZE, sizeof(xen_pfn_t));
-    p2m_batch  = calloc(MAX_BATCH_SIZE, sizeof(xen_pfn_t));
+
+    region_mfn = xg_memalign(PAGE_SIZE, ROUNDUP(
+                              MAX_BATCH_SIZE * sizeof(xen_pfn_t), PAGE_SHIFT));
+    p2m_batch  = xg_memalign(PAGE_SIZE, ROUNDUP(
+                              MAX_BATCH_SIZE * sizeof(xen_pfn_t), PAGE_SHIFT));
 
     if ( (p2m == NULL) || (pfn_type == NULL) ||
          (region_mfn == NULL) || (p2m_batch == NULL) )
@@ -391,6 +388,11 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
         goto out;
     }
 
+    memset(region_mfn, 0,
+           ROUNDUP(MAX_BATCH_SIZE * sizeof(xen_pfn_t), PAGE_SHIFT)); 
+    memset(p2m_batch, 0,
+           ROUNDUP(MAX_BATCH_SIZE * sizeof(xen_pfn_t), PAGE_SHIFT)); 
+
     if ( lock_pages(region_mfn, sizeof(xen_pfn_t) * MAX_BATCH_SIZE) )
     {
         ERROR("Could not lock region_mfn");
@@ -976,6 +978,12 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
         }
     }
 
+    if ( lock_pages(&ctxt, sizeof(ctxt)) )
+    {
+        ERROR("Unable to lock ctxt");
+        return 1;
+    }
+
     for ( i = 0; i <= max_vcpu_id; i++ )
     {
         if ( !(vcpumap & (1ULL << i)) )
index 34f554cb905d18a657d80f6e7caa15a8d5e821eb..5fec32a3c9576c19ec200fdec77e073ec712e3b9 100644 (file)
@@ -939,9 +939,9 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
     sent_last_iter = p2m_size;
 
     /* Setup to_send / to_fix and to_skip bitmaps */
-    to_send = malloc(BITMAP_SIZE);
+    to_send = xg_memalign(PAGE_SIZE, ROUNDUP(BITMAP_SIZE, PAGE_SHIFT)); 
     to_fix  = calloc(1, BITMAP_SIZE);
-    to_skip = malloc(BITMAP_SIZE);
+    to_skip = xg_memalign(PAGE_SIZE, ROUNDUP(BITMAP_SIZE, PAGE_SHIFT)); 
 
     if ( !to_send || !to_fix || !to_skip )
     {
@@ -983,8 +983,8 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
 
     analysis_phase(xc_handle, dom, p2m_size, to_skip, 0);
 
-    /* We want zeroed memory so use calloc rather than malloc. */
-    pfn_type   = calloc(MAX_BATCH_SIZE, sizeof(*pfn_type));
+    pfn_type   = xg_memalign(PAGE_SIZE, ROUNDUP(
+                              MAX_BATCH_SIZE * sizeof(*pfn_type), PAGE_SHIFT));
     pfn_batch  = calloc(MAX_BATCH_SIZE, sizeof(*pfn_batch));
     if ( (pfn_type == NULL) || (pfn_batch == NULL) )
     {
@@ -992,10 +992,12 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
         errno = ENOMEM;
         goto out;
     }
+    memset(pfn_type, 0,
+           ROUNDUP(MAX_BATCH_SIZE * sizeof(*pfn_type), PAGE_SHIFT));
 
     if ( lock_pages(pfn_type, MAX_BATCH_SIZE * sizeof(*pfn_type)) )
     {
-        ERROR("Unable to lock");
+        ERROR("Unable to lock pfn_type array");
         goto out;
     }
 
index 2ed3f55849d382fb1c6305b4e5f9a3f3b7c613a4..563585793a3bee427f9024f3ce428002f660f40d 100644 (file)
@@ -7,6 +7,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <malloc.h>
 #include <sys/mman.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -176,4 +177,21 @@ int xc_copy_to_domain_page(int xc_handle, uint32_t domid,
 int pin_table(int xc_handle, unsigned int type, unsigned long mfn,
               domid_t dom);
 
+/* Grrr portability */
+static inline void *xg_memalign(size_t alignment, size_t size)
+{
+#if (_POSIX_C_SOURCE - 0) >= 200112L || (_XOPEN_SOURCE - 0) >= 600
+    int ret;
+    void *ptr;
+    ret = posix_memalign(&ptr, alignment, size);
+    if (ret != 0)
+        return NULL;
+    return ptr;
+#elif defined(_BSD)
+    return valloc(size);
+#else
+    return memalign(alignment, size);
+#endif
+}
+
 #endif /* XG_PRIVATE_H */