From: Keir Fraser Date: Wed, 9 Apr 2008 15:56:05 +0000 (+0100) Subject: save/restore: Use page-aligned allocations for hypercall args that are X-Git-Tag: 3.2.1-rc4~2 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=398c492b83f47c679d497efa5dedbbd4a344ca43;p=people%2Fvhanquez%2Fxen.git 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 xen-unstable changeset: 17424:f410fa7f379c3a2fc8d4117188f36899e63e6053 xen-unstable date: Wed Apr 09 16:31:16 2008 +0100 --- diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c index 52fc1155d..b7b74352e 100644 --- a/tools/libxc/xc_domain_restore.c +++ b/tools/libxc/xc_domain_restore.c @@ -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)) ) diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c index 34f554cb9..5fec32a3c 100644 --- a/tools/libxc/xc_domain_save.c +++ b/tools/libxc/xc_domain_save.c @@ -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; } diff --git a/tools/libxc/xg_private.h b/tools/libxc/xg_private.h index 2ed3f5584..563585793 100644 --- a/tools/libxc/xg_private.h +++ b/tools/libxc/xg_private.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -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 */