On Wed, 2013-01-16 at 16:29 +0000, David Vrabel wrote: > From: David Vrabel <david.vrabel at citrix.com> > > Add xc_kexec_exec(), xc_kexec_get_ranges(), xc_kexec_load(), and > xc_kexec_unload(). The load and unload calls require the v2 load and > unload ops. > > Signed-off-by: David Vrabel <david.vrabel at citrix.com> > --- > tools/libxc/Makefile | 1 + > tools/libxc/xc_kexec.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++ > tools/libxc/xenctrl.h | 53 +++++++++++++++++++++ > 3 files changed, 174 insertions(+), 0 deletions(-) > create mode 100644 tools/libxc/xc_kexec.c > > diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile > index d44abf9..39badf9 100644 > --- a/tools/libxc/Makefile > +++ b/tools/libxc/Makefile > @@ -31,6 +31,7 @@ CTRL_SRCS-y += xc_mem_access.c > CTRL_SRCS-y += xc_memshr.c > CTRL_SRCS-y += xc_hcall_buf.c > CTRL_SRCS-y += xc_foreign_memory.c > +CTRL_SRCS-y += xc_kexec.c > CTRL_SRCS-y += xtl_core.c > CTRL_SRCS-y += xtl_logger_stdio.c > CTRL_SRCS-$(CONFIG_X86) += xc_pagetab.c > diff --git a/tools/libxc/xc_kexec.c b/tools/libxc/xc_kexec.c > new file mode 100644 > index 0000000..ebd55cf > --- /dev/null > +++ b/tools/libxc/xc_kexec.c > @@ -0,0 +1,120 @@ > +/****************************************************************************** > + * xc_kexec.c > + * > + * API for loading and executing kexec images. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; > + * version 2.1 of the License. > + * > + * Copyright (C) 2013 Citrix Systems R&D Ltd. > + */ > +#include "xc_private.h" > + > +int xc_kexec(xc_interface *xch, int type) > +{ > + DECLARE_HYPERCALL; > + DECLARE_HYPERCALL_BUFFER(xen_kexec_exec_t, exec); > + int ret = -1; > + > + exec = xc_hypercall_buffer_alloc(xch, exec, sizeof(*exec)); > + if ( exec == NULL ) > + { > + PERROR("Count not alloc bounce buffer for kexec_exec hypercall"); This one isn't actually a bounce buffer. [...] > + get_range = xc_hypercall_buffer_alloc(xch, get_range, sizeof(*get_range)); > + if ( get_range == NULL ) > + { > + PERROR("Could not alloc bounce buffer for kexec_get_range hypercall"); Nor this. > + goto out; > + } > + > + hypercall.op = __HYPERVISOR_kexec_op; > + hypercall.arg[0] = KEXEC_CMD_kexec_get_range; > + hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(get_range); > + > + ret = do_xen_hypercall(xch, &hypercall); > + > + *size = get_range->size; > + *start = get_range->start; > + > +out: > + xc_hypercall_buffer_free(xch, get_range); > + > + return ret; > +} > + > +int xc_kexec_load(xc_interface *xch, xen_kexec_load_v2_t *load) > +{ > + int ret = -1; > + DECLARE_HYPERCALL; > + DECLARE_HYPERCALL_BOUNCE(load, sizeof(*load), XC_HYPERCALL_BUFFER_BOUNCE_IN); > + > + if ( xc_hypercall_bounce_pre(xch, load) ) > + { > + PERROR("Could not alloc bounce buffer for kexec_load_v2 hypercall"); > + goto out; > + } You'll also need to bounce the "segments" member of this struct. > @@ -2236,4 +2237,56 @@ int xc_compression_uncompress_page(xc_interface *xch, char *compbuf, > unsigned long compbuf_size, > unsigned long *compbuf_pos, char *dest); > > +/* > + * Execute an image previously loaded with xc_kexec_load(). > + * > + * Does not return on success. > + * > + * Fails with: > + * ENOENT if the specified image has not been loaded. > + */ > +int xc_kexec(xc_interface *xch, int type); > + > +/* > + * Find the machine address and size of certain memory areas. > + * > + * The regions are: A reference to include/public is less likely to get out of sync. Ian.