Files
xen/tools/libs/ctrl/xc_kexec.c
T
Juergen Gross af6c78d9dc tools: move libxenctrl below tools/libs
Today tools/libxc needs to be built after tools/libs as libxenctrl is
depending on some libraries in tools/libs. This in turn blocks moving
other libraries depending on libxenctrl below tools/libs.

So carve out libxenctrl from tools/libxc and move it into
tools/libs/ctrl.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org> (stubdom parts)
Acked-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com> (python parts)
Acked-by: Wei Liu <wl@xen.org>
2020-09-09 10:57:25 +00:00

153 lines
4.0 KiB
C

/******************************************************************************
* 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_exec(xc_interface *xch, int type)
{
DECLARE_HYPERCALL_BUFFER(xen_kexec_exec_t, exec);
int ret = -1;
exec = xc_hypercall_buffer_alloc(xch, exec, sizeof(*exec));
if ( exec == NULL )
{
PERROR("Could not alloc bounce buffer for kexec_exec hypercall");
goto out;
}
exec->type = type;
ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
KEXEC_CMD_kexec,
HYPERCALL_BUFFER_AS_ARG(exec));
out:
xc_hypercall_buffer_free(xch, exec);
return ret;
}
int xc_kexec_get_range(xc_interface *xch, int range, int nr,
uint64_t *size, uint64_t *start)
{
DECLARE_HYPERCALL_BUFFER(xen_kexec_range_t, get_range);
int ret = -1;
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");
goto out;
}
get_range->range = range;
get_range->nr = nr;
ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
KEXEC_CMD_kexec_get_range,
HYPERCALL_BUFFER_AS_ARG(get_range));
*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, uint8_t type, uint16_t arch,
uint64_t entry_maddr,
uint32_t nr_segments, xen_kexec_segment_t *segments)
{
int ret = -1;
DECLARE_HYPERCALL_BOUNCE(segments, sizeof(*segments) * nr_segments,
XC_HYPERCALL_BUFFER_BOUNCE_IN);
DECLARE_HYPERCALL_BUFFER(xen_kexec_load_t, load);
if ( xc_hypercall_bounce_pre(xch, segments) )
{
PERROR("Could not allocate bounce buffer for kexec load hypercall");
goto out;
}
load = xc_hypercall_buffer_alloc(xch, load, sizeof(*load));
if ( load == NULL )
{
PERROR("Could not allocate buffer for kexec load hypercall");
goto out;
}
load->type = type;
load->arch = arch;
load->entry_maddr = entry_maddr;
load->nr_segments = nr_segments;
set_xen_guest_handle(load->segments.h, segments);
ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
KEXEC_CMD_kexec_load,
HYPERCALL_BUFFER_AS_ARG(load));
out:
xc_hypercall_buffer_free(xch, load);
xc_hypercall_bounce_post(xch, segments);
return ret;
}
int xc_kexec_unload(xc_interface *xch, int type)
{
DECLARE_HYPERCALL_BUFFER(xen_kexec_unload_t, unload);
int ret = -1;
unload = xc_hypercall_buffer_alloc(xch, unload, sizeof(*unload));
if ( unload == NULL )
{
PERROR("Could not alloc buffer for kexec unload hypercall");
goto out;
}
unload->type = type;
ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
KEXEC_CMD_kexec_unload,
HYPERCALL_BUFFER_AS_ARG(unload));
out:
xc_hypercall_buffer_free(xch, unload);
return ret;
}
int xc_kexec_status(xc_interface *xch, int type)
{
DECLARE_HYPERCALL_BUFFER(xen_kexec_status_t, status);
int ret = -1;
status = xc_hypercall_buffer_alloc(xch, status, sizeof(*status));
if ( status == NULL )
{
PERROR("Could not alloc buffer for kexec status hypercall");
goto out;
}
status->type = type;
ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
KEXEC_CMD_kexec_status,
HYPERCALL_BUFFER_AS_ARG(status));
out:
xc_hypercall_buffer_free(xch, status);
return ret;
}