[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 6 of 6] Add code to track the address of the VM generation id buffer across a
# HG changeset patch # User Paul Durrant <paul.durrant@xxxxxxxxxx> # Date 1322563734 0 # Node ID 225da1242ba979ddc8c48767d3822e0c8d274ae1 # Parent acc408d667e139c6b8b96e1ec51e65d159d72b67 Add code to track the address of the VM generation id buffer across a save/restore or migrate and inject a new value. The address of the buffer is written into xenstore by hvmloader at boot time. It must be read from xenstore by the caller of xc_domain_save() and then written back again by the caller of xc_domain_restore(). Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> diff -r acc408d667e1 -r 225da1242ba9 tools/firmware/hvmloader/acpi/build.c --- a/tools/firmware/hvmloader/acpi/build.c Tue Nov 29 10:48:54 2011 +0000 +++ b/tools/firmware/hvmloader/acpi/build.c Tue Nov 29 10:48:54 2011 +0000 @@ -301,10 +301,14 @@ unsigned long new_vm_gid(void) { uint64_t gid; unsigned char *buf; + char addr[11]; buf = mem_alloc(8, 8); if (!buf) return 0; + sprintf(addr, "0x%lx", virt_to_phys(buf)); + xenstore_write("data/generation-id", addr); + gid = strtoll(xenstore_read("platform/generation-id", "0"), NULL, 0); *(uint64_t *)buf = gid; diff -r acc408d667e1 -r 225da1242ba9 tools/libxc/ia64/xc_ia64_linux_restore.c --- a/tools/libxc/ia64/xc_ia64_linux_restore.c Tue Nov 29 10:48:54 2011 +0000 +++ b/tools/libxc/ia64/xc_ia64_linux_restore.c Tue Nov 29 10:48:54 2011 +0000 @@ -548,7 +548,8 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, unsigned long *console_mfn, - unsigned int hvm, unsigned int pae, int superpages) + unsigned int hvm, unsigned int pae, int superpages, + uint64_t gid) { DECLARE_DOMCTL; int rc = 1; diff -r acc408d667e1 -r 225da1242ba9 tools/libxc/ia64/xc_ia64_linux_save.c --- a/tools/libxc/ia64/xc_ia64_linux_save.c Tue Nov 29 10:48:54 2011 +0000 +++ b/tools/libxc/ia64/xc_ia64_linux_save.c Tue Nov 29 10:48:54 2011 +0000 @@ -382,7 +382,8 @@ out: int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters, uint32_t max_factor, uint32_t flags, - struct save_callbacks* callbacks, int hvm) + struct save_callbacks* callbacks, int hvm, + unsigned long vm_gid_addr) { DECLARE_DOMCTL; xc_dominfo_t info; diff -r acc408d667e1 -r 225da1242ba9 tools/libxc/xc_domain_restore.c --- a/tools/libxc/xc_domain_restore.c Tue Nov 29 10:48:54 2011 +0000 +++ b/tools/libxc/xc_domain_restore.c Tue Nov 29 10:48:54 2011 +0000 @@ -676,6 +676,7 @@ typedef struct { uint64_t console_pfn; uint64_t acpi_ioport_location; uint64_t viridian; + uint64_t vm_gid_addr; } pagebuf_t; static int pagebuf_init(pagebuf_t* buf) @@ -820,6 +821,17 @@ static int pagebuf_get_one(xc_interface } return pagebuf_get_one(xch, ctx, buf, fd, dom); + case XC_SAVE_ID_HVM_GENERATION_ID_ADDR: + /* Skip padding 4 bytes then read the generation id buffer location. */ + if ( RDEXACT(fd, &buf->vm_gid_addr, sizeof(uint32_t)) || + RDEXACT(fd, &buf->vm_gid_addr, sizeof(uint64_t)) ) + { + PERROR("error read the generation id buffer location"); + return -1; + } + DPRINTF("read generation id buffer address"); + return pagebuf_get_one(xch, ctx, buf, fd, dom); + default: if ( (count > MAX_BATCH_SIZE) || (count < 0) ) { ERROR("Max batch size exceeded (%d). Giving up.", count); @@ -1186,7 +1198,8 @@ static int apply_batch(xc_interface *xch int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, unsigned long *console_mfn, - unsigned int hvm, unsigned int pae, int superpages) + unsigned int hvm, unsigned int pae, int superpages, + uint64_t gid, unsigned long *vm_gid_addr) { DECLARE_DOMCTL; int rc = 1, frc, i, j, n, m, pae_extended_cr3 = 0, ext_vcpucontext = 0; @@ -1386,6 +1399,33 @@ int xc_domain_restore(xc_interface *xch, xc_set_hvm_param(xch, dom, HVM_PARAM_VM86_TSS, pagebuf.vm86_tss); if ( pagebuf.console_pfn ) console_pfn = pagebuf.console_pfn; + if ( pagebuf.vm_gid_addr ) { + unsigned int offset; + unsigned char *buf; + + /* + * Map the VM generation id buffer and inject the new value. + */ + + pfn = pagebuf.vm_gid_addr >> PAGE_SHIFT; + offset = pagebuf.vm_gid_addr & (PAGE_SIZE - 1); + + if ( (pfn >= dinfo->p2m_size) || + (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB) ) + { + ERROR("generation id buffer frame is bad"); + goto out; + } + + mfn = ctx->p2m[pfn]; + buf = xc_map_foreign_range(xch, dom, PAGE_SIZE, + PROT_READ | PROT_WRITE, mfn); + *(unsigned long long *)(buf + offset) = gid; + munmap(buf, PAGE_SIZE); + + *vm_gid_addr = pagebuf.vm_gid_addr; + } + break; /* our work here is done */ } diff -r acc408d667e1 -r 225da1242ba9 tools/libxc/xc_domain_save.c --- a/tools/libxc/xc_domain_save.c Tue Nov 29 10:48:54 2011 +0000 +++ b/tools/libxc/xc_domain_save.c Tue Nov 29 10:48:54 2011 +0000 @@ -754,7 +754,8 @@ static int save_tsc_info(xc_interface *x int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters, uint32_t max_factor, uint32_t flags, - struct save_callbacks* callbacks, int hvm) + struct save_callbacks* callbacks, int hvm, + unsigned long vm_gid_addr) { xc_dominfo_t info; DECLARE_DOMCTL; @@ -1460,6 +1461,16 @@ int xc_domain_save(xc_interface *xch, in uint64_t data; } chunk = { 0, }; + chunk.id = XC_SAVE_ID_HVM_GENERATION_ID_ADDR; + chunk.data = vm_gid_addr; + + if ( (chunk.data != 0) && + wrexact(io_fd, &chunk, sizeof(chunk)) ) + { + PERROR("Error when writing the generation id buffer location for guest"); + goto out; + } + chunk.id = XC_SAVE_ID_HVM_IDENT_PT; chunk.data = 0; xc_get_hvm_param(xch, dom, HVM_PARAM_IDENT_PT, diff -r acc408d667e1 -r 225da1242ba9 tools/libxc/xenguest.h --- a/tools/libxc/xenguest.h Tue Nov 29 10:48:54 2011 +0000 +++ b/tools/libxc/xenguest.h Tue Nov 29 10:48:54 2011 +0000 @@ -57,7 +57,8 @@ struct save_callbacks { */ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters, uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */, - struct save_callbacks* callbacks, int hvm); + struct save_callbacks* callbacks, int hvm, + unsigned long vm_gid_addr); /** @@ -71,12 +72,15 @@ int xc_domain_save(xc_interface *xch, in * @parm hvm non-zero if this is a HVM restore * @parm pae non-zero if this HVM domain has PAE support enabled * @parm superpages non-zero to allocate guest memory with superpages + * @parm gid the new generation id of the VM + * @parm vm_gid_addr returned with the address of the generation id buffer * @return 0 on success, -1 on failure */ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, unsigned long *console_mfn, - unsigned int hvm, unsigned int pae, int superpages); + unsigned int hvm, unsigned int pae, int superpages, + uint64_t gid, unsigned long *vm_gid_addr); /** * xc_domain_restore writes a file to disk that contains the device * model saved state. diff -r acc408d667e1 -r 225da1242ba9 tools/libxc/xg_save_restore.h --- a/tools/libxc/xg_save_restore.h Tue Nov 29 10:48:54 2011 +0000 +++ b/tools/libxc/xg_save_restore.h Tue Nov 29 10:48:54 2011 +0000 @@ -135,6 +135,7 @@ #define XC_SAVE_ID_LAST_CHECKPOINT -9 /* Commit to restoring after completion of current iteration. */ #define XC_SAVE_ID_HVM_ACPI_IOPORTS_LOCATION -10 #define XC_SAVE_ID_HVM_VIRIDIAN -11 +#define XC_SAVE_ID_HVM_GENERATION_ID_ADDR -12 /* ** We process save/restore/migrate in batches of pages; the below diff -r acc408d667e1 -r 225da1242ba9 tools/libxl/libxl_dom.c --- a/tools/libxl/libxl_dom.c Tue Nov 29 10:48:54 2011 +0000 +++ b/tools/libxl/libxl_dom.c Tue Nov 29 10:48:54 2011 +0000 @@ -108,7 +108,7 @@ int libxl__build_post(libxl__gc *gc, uin if (info->cpuid != NULL) libxl_cpuid_set(ctx, domid, info->cpuid); - ents = libxl__calloc(gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *)); + ents = libxl__calloc(gc, 14 + (info->max_vcpus * 2) + 2, sizeof(char *)); ents[0] = "memory/static-max"; ents[1] = libxl__sprintf(gc, "%d", info->max_memkb); ents[2] = "memory/target"; @@ -121,9 +121,11 @@ int libxl__build_post(libxl__gc *gc, uin ents[9] = libxl__sprintf(gc, "%"PRIu32, state->store_port); ents[10] = "store/ring-ref"; ents[11] = libxl__sprintf(gc, "%lu", state->store_mfn); + ents[12] = "data/generation-id"; + ents[13] = libxl__sprintf(gc, "0x%lx", state->vm_gid_addr); for (i = 0; i < info->max_vcpus; i++) { - ents[12+(i*2)] = libxl__sprintf(gc, "cpu/%d/availability", i); - ents[12+(i*2)+1] = (i && info->cur_vcpus && !(info->cur_vcpus & (1 << i))) + ents[14+(i*2)] = libxl__sprintf(gc, "cpu/%d/availability", i); + ents[14+(i*2)+1] = (i && info->cur_vcpus && !(info->cur_vcpus & (1 << i))) ? "offline" : "online"; } @@ -340,16 +342,19 @@ int libxl__domain_restore_common(libxl__ /* read signature */ int rc; int hvm, pae, superpages; + uint64_t gid; switch (info->type) { case LIBXL_DOMAIN_TYPE_HVM: hvm = 1; superpages = 1; pae = info->u.hvm.pae; + gid = info->u.hvm.generation_id; break; case LIBXL_DOMAIN_TYPE_PV: hvm = 0; superpages = 0; pae = 1; + gid = 0; break; default: return ERROR_INVAL; @@ -357,7 +362,7 @@ int libxl__domain_restore_common(libxl__ rc = xc_domain_restore(ctx->xch, fd, domid, state->store_port, &state->store_mfn, state->console_port, &state->console_mfn, - hvm, pae, superpages); + hvm, pae, superpages, gid, &state->vm_gid_addr); if ( rc ) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "restoring domain"); return ERROR_FAIL; @@ -523,12 +528,22 @@ int libxl__domain_suspend_common(libxl__ struct save_callbacks callbacks; struct suspendinfo si; int hvm, rc = ERROR_FAIL; + unsigned long vm_gid_addr; switch (type) { - case LIBXL_DOMAIN_TYPE_HVM: + case LIBXL_DOMAIN_TYPE_HVM: { + char *path; + char *addr; + + path = libxl__sprintf(gc, "%s/data/generation-id", libxl__xs_get_dompath(gc, domid)); + addr = libxl__xs_read(gc, XBT_NULL, path); + + vm_gid_addr = (addr) ? strtoul(addr, NULL, 0) : 0; hvm = 1; break; + } case LIBXL_DOMAIN_TYPE_PV: + vm_gid_addr = 0; hvm = 0; break; default: @@ -566,7 +581,8 @@ int libxl__domain_suspend_common(libxl__ callbacks.switch_qemu_logdirty = libxl__domain_suspend_common_switch_qemu_logdirty; callbacks.data = &si; - rc = xc_domain_save(ctx->xch, fd, domid, 0, 0, flags, &callbacks, hvm); + rc = xc_domain_save(ctx->xch, fd, domid, 0, 0, flags, &callbacks, + hvm, vm_gid_addr); if ( rc ) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "saving domain: %s", si.guest_responded ? diff -r acc408d667e1 -r 225da1242ba9 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Tue Nov 29 10:48:54 2011 +0000 +++ b/tools/libxl/libxl_internal.h Tue Nov 29 10:48:54 2011 +0000 @@ -199,6 +199,8 @@ typedef struct { uint32_t console_port; unsigned long console_mfn; + + unsigned long vm_gid_addr; } libxl__domain_build_state; _hidden int libxl__build_pre(libxl__gc *gc, uint32_t domid, diff -r acc408d667e1 -r 225da1242ba9 tools/python/xen/lowlevel/checkpoint/libcheckpoint.c --- a/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c Tue Nov 29 10:48:54 2011 +0000 +++ b/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c Tue Nov 29 10:48:54 2011 +0000 @@ -174,6 +174,7 @@ int checkpoint_start(checkpoint_state* s { int hvm, rc; int flags = XCFLAGS_LIVE; + unsigned long vm_gid_addr; if (!s->domid) { s->errstr = "checkpoint state not opened"; @@ -184,14 +185,25 @@ int checkpoint_start(checkpoint_state* s hvm = s->domtype > dt_pv; if (hvm) { + char path[128]; + char *addr; + + sprintf(path, "/local/domain/%u/data/generation-id", s->domid); + addr = xs_read(s->xsh, XBT_NULL, path, NULL); + + vm_gid_addr = (addr) ? strtoul(addr, NULL, 0) : 0; + free(addr); + flags |= XCFLAGS_HVM; if (switch_qemu_logdirty(s, 1)) return -1; + } else { + vm_gid_addr = 0; } callbacks->switch_qemu_logdirty = noop_switch_logdirty; - rc = xc_domain_save(s->xch, fd, s->domid, 0, 0, flags, callbacks, hvm); + rc = xc_domain_save(s->xch, fd, s->domid, 0, 0, flags, callbacks, hvm, vm_gid_addr); if (hvm) switch_qemu_logdirty(s, 0); diff -r acc408d667e1 -r 225da1242ba9 tools/xcutils/xc_restore.c --- a/tools/xcutils/xc_restore.c Tue Nov 29 10:48:54 2011 +0000 +++ b/tools/xcutils/xc_restore.c Tue Nov 29 10:48:54 2011 +0000 @@ -23,7 +23,8 @@ main(int argc, char **argv) xc_interface *xch; int io_fd, ret; int superpages; - unsigned long store_mfn, console_mfn; + unsigned long store_mfn, console_mfn, vm_gid_addr; + uint64_t gid; if ( (argc != 8) && (argc != 9) ) errx(1, "usage: %s iofd domid store_evtchn " @@ -40,19 +41,25 @@ main(int argc, char **argv) hvm = atoi(argv[5]); pae = atoi(argv[6]); apic = atoi(argv[7]); - if ( argc == 9 ) + if ( argc >= 9 ) superpages = atoi(argv[8]); else superpages = !!hvm; + if ( argc >= 10 ) + gid = strtoll(argv[9], NULL, 0); + else + gid = 0; ret = xc_domain_restore(xch, io_fd, domid, store_evtchn, &store_mfn, - console_evtchn, &console_mfn, hvm, pae, superpages); + console_evtchn, &console_mfn, hvm, pae, superpages, + gid, &vm_gid_addr); if ( ret == 0 ) { printf("store-mfn %li\n", store_mfn); if ( !hvm ) printf("console-mfn %li\n", console_mfn); + printf("vm-gid-addr %lx\n", vm_gid_addr); fflush(stdout); } diff -r acc408d667e1 -r 225da1242ba9 tools/xcutils/xc_save.c --- a/tools/xcutils/xc_save.c Tue Nov 29 10:48:54 2011 +0000 +++ b/tools/xcutils/xc_save.c Tue Nov 29 10:48:54 2011 +0000 @@ -169,6 +169,10 @@ main(int argc, char **argv) unsigned int maxit, max_f; int io_fd, ret, port; struct save_callbacks callbacks; + char path[128]; + struct xs_handle *xs; + char *addr; + unsigned long vm_gid_addr; if (argc != 6) errx(1, "usage: %s iofd domid maxit maxf flags", argv[0]); @@ -207,8 +211,21 @@ main(int argc, char **argv) memset(&callbacks, 0, sizeof(callbacks)); callbacks.suspend = suspend; callbacks.switch_qemu_logdirty = switch_qemu_logdirty; + + sprintf(path, "/local/domain/%d/data/generation-id", si.domid); + + if ((xs = xs_daemon_open()) == NULL) + errx(1, "Couldn't contact xenstore"); + + addr = xs_read(xs, XBT_NULL, path, NULL); + + xs_daemon_close(xs); + + vm_gid_addr = (addr) ? strtoul(addr, NULL, 0) : 0; + free(addr); + ret = xc_domain_save(si.xch, io_fd, si.domid, maxit, max_f, si.flags, - &callbacks, !!(si.flags & XCFLAGS_HVM)); + &callbacks, !!(si.flags & XCFLAGS_HVM), vm_gid_addr); if (si.suspend_evtchn > 0) xc_suspend_evtchn_release(si.xch, si.xce, si.domid, si.suspend_evtchn); _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |