[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |