mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 18:21:39 +01:00
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>
153 lines
4.0 KiB
C
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;
|
|
}
|