ia64/xen-unstable
changeset 17426:f410fa7f379c
save/restore: Use page-aligned allocations for hypercall args that are
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>
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>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Wed Apr 09 16:31:16 2008 +0100 (2008-04-09) |
parents | c99dee5e44d6 |
children | e63b48242116 |
files | tools/libxc/xc_domain_restore.c tools/libxc/xc_domain_save.c tools/libxc/xg_private.h |
line diff
1.1 --- a/tools/libxc/xc_domain_restore.c Wed Apr 09 16:24:46 2008 +0100 1.2 +++ b/tools/libxc/xc_domain_restore.c Wed Apr 09 16:31:16 2008 +0100 1.3 @@ -284,7 +284,8 @@ int xc_domain_restore(int xc_handle, int 1.4 /* The new domain's shared-info frame number. */ 1.5 unsigned long shared_info_frame; 1.6 unsigned char shared_info_page[PAGE_SIZE]; /* saved contents from file */ 1.7 - shared_info_either_t *old_shared_info = (shared_info_either_t *)shared_info_page; 1.8 + shared_info_either_t *old_shared_info = 1.9 + (shared_info_either_t *)shared_info_page; 1.10 shared_info_either_t *new_shared_info; 1.11 1.12 /* A copy of the CPU context of the guest. */ 1.13 @@ -349,13 +350,6 @@ int xc_domain_restore(int xc_handle, int 1.14 guest_width = sizeof(unsigned long); 1.15 pt_levels = (guest_width == 8) ? 4 : (pt_levels == 2) ? 2 : 3; 1.16 1.17 - if ( lock_pages(&ctxt, sizeof(ctxt)) ) 1.18 - { 1.19 - /* needed for build domctl, but might as well do early */ 1.20 - ERROR("Unable to lock ctxt"); 1.21 - return 1; 1.22 - } 1.23 - 1.24 if ( !hvm ) 1.25 { 1.26 /* Load the p2m frame list, plus potential extended info chunk */ 1.27 @@ -380,8 +374,11 @@ int xc_domain_restore(int xc_handle, int 1.28 /* We want zeroed memory so use calloc rather than malloc. */ 1.29 p2m = calloc(p2m_size, MAX(guest_width, sizeof (xen_pfn_t))); 1.30 pfn_type = calloc(p2m_size, sizeof(unsigned long)); 1.31 - region_mfn = calloc(MAX_BATCH_SIZE, sizeof(xen_pfn_t)); 1.32 - p2m_batch = calloc(MAX_BATCH_SIZE, sizeof(xen_pfn_t)); 1.33 + 1.34 + region_mfn = xg_memalign(PAGE_SIZE, ROUNDUP( 1.35 + MAX_BATCH_SIZE * sizeof(xen_pfn_t), PAGE_SHIFT)); 1.36 + p2m_batch = xg_memalign(PAGE_SIZE, ROUNDUP( 1.37 + MAX_BATCH_SIZE * sizeof(xen_pfn_t), PAGE_SHIFT)); 1.38 1.39 if ( (p2m == NULL) || (pfn_type == NULL) || 1.40 (region_mfn == NULL) || (p2m_batch == NULL) ) 1.41 @@ -391,6 +388,11 @@ int xc_domain_restore(int xc_handle, int 1.42 goto out; 1.43 } 1.44 1.45 + memset(region_mfn, 0, 1.46 + ROUNDUP(MAX_BATCH_SIZE * sizeof(xen_pfn_t), PAGE_SHIFT)); 1.47 + memset(p2m_batch, 0, 1.48 + ROUNDUP(MAX_BATCH_SIZE * sizeof(xen_pfn_t), PAGE_SHIFT)); 1.49 + 1.50 if ( lock_pages(region_mfn, sizeof(xen_pfn_t) * MAX_BATCH_SIZE) ) 1.51 { 1.52 ERROR("Could not lock region_mfn"); 1.53 @@ -976,6 +978,12 @@ int xc_domain_restore(int xc_handle, int 1.54 } 1.55 } 1.56 1.57 + if ( lock_pages(&ctxt, sizeof(ctxt)) ) 1.58 + { 1.59 + ERROR("Unable to lock ctxt"); 1.60 + return 1; 1.61 + } 1.62 + 1.63 for ( i = 0; i <= max_vcpu_id; i++ ) 1.64 { 1.65 if ( !(vcpumap & (1ULL << i)) )
2.1 --- a/tools/libxc/xc_domain_save.c Wed Apr 09 16:24:46 2008 +0100 2.2 +++ b/tools/libxc/xc_domain_save.c Wed Apr 09 16:31:16 2008 +0100 2.3 @@ -939,9 +939,9 @@ int xc_domain_save(int xc_handle, int io 2.4 sent_last_iter = p2m_size; 2.5 2.6 /* Setup to_send / to_fix and to_skip bitmaps */ 2.7 - to_send = malloc(BITMAP_SIZE); 2.8 + to_send = xg_memalign(PAGE_SIZE, ROUNDUP(BITMAP_SIZE, PAGE_SHIFT)); 2.9 to_fix = calloc(1, BITMAP_SIZE); 2.10 - to_skip = malloc(BITMAP_SIZE); 2.11 + to_skip = xg_memalign(PAGE_SIZE, ROUNDUP(BITMAP_SIZE, PAGE_SHIFT)); 2.12 2.13 if ( !to_send || !to_fix || !to_skip ) 2.14 { 2.15 @@ -983,8 +983,8 @@ int xc_domain_save(int xc_handle, int io 2.16 2.17 analysis_phase(xc_handle, dom, p2m_size, to_skip, 0); 2.18 2.19 - /* We want zeroed memory so use calloc rather than malloc. */ 2.20 - pfn_type = calloc(MAX_BATCH_SIZE, sizeof(*pfn_type)); 2.21 + pfn_type = xg_memalign(PAGE_SIZE, ROUNDUP( 2.22 + MAX_BATCH_SIZE * sizeof(*pfn_type), PAGE_SHIFT)); 2.23 pfn_batch = calloc(MAX_BATCH_SIZE, sizeof(*pfn_batch)); 2.24 if ( (pfn_type == NULL) || (pfn_batch == NULL) ) 2.25 { 2.26 @@ -992,10 +992,12 @@ int xc_domain_save(int xc_handle, int io 2.27 errno = ENOMEM; 2.28 goto out; 2.29 } 2.30 + memset(pfn_type, 0, 2.31 + ROUNDUP(MAX_BATCH_SIZE * sizeof(*pfn_type), PAGE_SHIFT)); 2.32 2.33 if ( lock_pages(pfn_type, MAX_BATCH_SIZE * sizeof(*pfn_type)) ) 2.34 { 2.35 - ERROR("Unable to lock"); 2.36 + ERROR("Unable to lock pfn_type array"); 2.37 goto out; 2.38 } 2.39
3.1 --- a/tools/libxc/xg_private.h Wed Apr 09 16:24:46 2008 +0100 3.2 +++ b/tools/libxc/xg_private.h Wed Apr 09 16:31:16 2008 +0100 3.3 @@ -7,6 +7,7 @@ 3.4 #include <stdio.h> 3.5 #include <stdlib.h> 3.6 #include <string.h> 3.7 +#include <malloc.h> 3.8 #include <sys/mman.h> 3.9 #include <sys/types.h> 3.10 #include <sys/stat.h> 3.11 @@ -176,4 +177,21 @@ int xc_copy_to_domain_page(int xc_handle 3.12 int pin_table(int xc_handle, unsigned int type, unsigned long mfn, 3.13 domid_t dom); 3.14 3.15 +/* Grrr portability */ 3.16 +static inline void *xg_memalign(size_t alignment, size_t size) 3.17 +{ 3.18 +#if defined(_POSIX_C_SOURCE) && !defined(__sun__) 3.19 + int ret; 3.20 + void *ptr; 3.21 + ret = posix_memalign(&ptr, alignment, size); 3.22 + if (ret != 0) 3.23 + return NULL; 3.24 + return ptr; 3.25 +#elif defined(_BSD) 3.26 + return valloc(size); 3.27 +#else 3.28 + return memalign(alignment, size); 3.29 +#endif 3.30 +} 3.31 + 3.32 #endif /* XG_PRIVATE_H */