[Xen-devel] [PATCH 3/3] libxc: add API for kexec hypercall

Ian Campbell Ian.Campbell at citrix.com
Wed Jan 16 11:59:59 EST 2013


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.




More information about the kexec mailing list