[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] tools/libxc: rename all libxenguest sources to xg_*
commit f55893171feb64f712d2892a288e3f3dc70f39d8 Author: Juergen Gross <jgross@xxxxxxxx> AuthorDate: Fri Aug 28 17:07:28 2020 +0200 Commit: Wei Liu <wl@xxxxxxx> CommitDate: Wed Sep 9 10:57:25 2020 +0000 tools/libxc: rename all libxenguest sources to xg_* Some sources of libxenguest are named xg_*.c and some xc_*.c. Rename the xc_*.c files to xg_*.c. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> Acked-by: Wei Liu <wl@xxxxxxx> --- tools/libxc/Makefile | 59 +- tools/libxc/xc_cpuid_x86.c | 665 --------- tools/libxc/xc_dom_arm.c | 552 -------- tools/libxc/xc_dom_armzimageloader.c | 271 ---- tools/libxc/xc_dom_binloader.c | 329 ----- tools/libxc/xc_dom_boot.c | 451 ------ tools/libxc/xc_dom_bzimageloader.c | 812 ----------- tools/libxc/xc_dom_compat_linux.c | 97 -- tools/libxc/xc_dom_core.c | 1272 ----------------- tools/libxc/xc_dom_decompress_lz4.c | 141 -- tools/libxc/xc_dom_decompress_unsafe.c | 48 - tools/libxc/xc_dom_decompress_unsafe_bzip2.c | 14 - tools/libxc/xc_dom_decompress_unsafe_lzma.c | 14 - tools/libxc/xc_dom_decompress_unsafe_lzo1x.c | 50 - tools/libxc/xc_dom_decompress_unsafe_xz.c | 46 - tools/libxc/xc_dom_elfloader.c | 249 ---- tools/libxc/xc_dom_hvmloader.c | 264 ---- tools/libxc/xc_dom_x86.c | 1945 -------------------------- tools/libxc/xc_nomigrate.c | 50 - tools/libxc/xc_offline_page.c | 708 ---------- tools/libxc/xc_sr_common.c | 167 --- tools/libxc/xc_sr_common_x86.c | 173 --- tools/libxc/xc_sr_common_x86_pv.c | 193 --- tools/libxc/xc_sr_restore.c | 986 ------------- tools/libxc/xc_sr_restore_x86_hvm.c | 274 ---- tools/libxc/xc_sr_restore_x86_pv.c | 1210 ---------------- tools/libxc/xc_sr_save.c | 1059 -------------- tools/libxc/xc_sr_save_x86_hvm.c | 251 ---- tools/libxc/xc_sr_save_x86_pv.c | 1156 --------------- tools/libxc/xc_suspend.c | 202 --- tools/libxc/xg_cpuid_x86.c | 665 +++++++++ tools/libxc/xg_dom_arm.c | 552 ++++++++ tools/libxc/xg_dom_armzimageloader.c | 271 ++++ tools/libxc/xg_dom_binloader.c | 329 +++++ tools/libxc/xg_dom_boot.c | 451 ++++++ tools/libxc/xg_dom_bzimageloader.c | 812 +++++++++++ tools/libxc/xg_dom_compat_linux.c | 97 ++ tools/libxc/xg_dom_core.c | 1272 +++++++++++++++++ tools/libxc/xg_dom_decompress_lz4.c | 141 ++ tools/libxc/xg_dom_decompress_unsafe.c | 48 + tools/libxc/xg_dom_decompress_unsafe_bzip2.c | 14 + tools/libxc/xg_dom_decompress_unsafe_lzma.c | 14 + tools/libxc/xg_dom_decompress_unsafe_lzo1x.c | 50 + tools/libxc/xg_dom_decompress_unsafe_xz.c | 46 + tools/libxc/xg_dom_elfloader.c | 249 ++++ tools/libxc/xg_dom_hvmloader.c | 264 ++++ tools/libxc/xg_dom_x86.c | 1945 ++++++++++++++++++++++++++ tools/libxc/xg_nomigrate.c | 50 + tools/libxc/xg_offline_page.c | 708 ++++++++++ tools/libxc/xg_sr_common.c | 167 +++ tools/libxc/xg_sr_common_x86.c | 173 +++ tools/libxc/xg_sr_common_x86_pv.c | 193 +++ tools/libxc/xg_sr_restore.c | 986 +++++++++++++ tools/libxc/xg_sr_restore_x86_hvm.c | 274 ++++ tools/libxc/xg_sr_restore_x86_pv.c | 1210 ++++++++++++++++ tools/libxc/xg_sr_save.c | 1059 ++++++++++++++ tools/libxc/xg_sr_save_x86_hvm.c | 251 ++++ tools/libxc/xg_sr_save_x86_pv.c | 1156 +++++++++++++++ tools/libxc/xg_suspend.c | 202 +++ 59 files changed, 13679 insertions(+), 13678 deletions(-) diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index 7b81f8c193..0fd5511143 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -54,20 +54,20 @@ CTRL_SRCS-y += xc_devicemodel_compat.c GUEST_SRCS-y := GUEST_SRCS-y += xg_private.c GUEST_SRCS-y += xg_domain.c -GUEST_SRCS-y += xc_suspend.c +GUEST_SRCS-y += xg_suspend.c ifeq ($(CONFIG_MIGRATE),y) -GUEST_SRCS-y += xc_sr_common.c -GUEST_SRCS-$(CONFIG_X86) += xc_sr_common_x86.c -GUEST_SRCS-$(CONFIG_X86) += xc_sr_common_x86_pv.c -GUEST_SRCS-$(CONFIG_X86) += xc_sr_restore_x86_pv.c -GUEST_SRCS-$(CONFIG_X86) += xc_sr_restore_x86_hvm.c -GUEST_SRCS-$(CONFIG_X86) += xc_sr_save_x86_pv.c -GUEST_SRCS-$(CONFIG_X86) += xc_sr_save_x86_hvm.c -GUEST_SRCS-y += xc_sr_restore.c -GUEST_SRCS-y += xc_sr_save.c -GUEST_SRCS-y += xc_offline_page.c +GUEST_SRCS-y += xg_sr_common.c +GUEST_SRCS-$(CONFIG_X86) += xg_sr_common_x86.c +GUEST_SRCS-$(CONFIG_X86) += xg_sr_common_x86_pv.c +GUEST_SRCS-$(CONFIG_X86) += xg_sr_restore_x86_pv.c +GUEST_SRCS-$(CONFIG_X86) += xg_sr_restore_x86_hvm.c +GUEST_SRCS-$(CONFIG_X86) += xg_sr_save_x86_pv.c +GUEST_SRCS-$(CONFIG_X86) += xg_sr_save_x86_hvm.c +GUEST_SRCS-y += xg_sr_restore.c +GUEST_SRCS-y += xg_sr_save.c +GUEST_SRCS-y += xg_offline_page.c else -GUEST_SRCS-y += xc_nomigrate.c +GUEST_SRCS-y += xg_nomigrate.c endif vpath %.c ../../xen/common/libelf @@ -88,25 +88,26 @@ GUEST_SRCS-y += cpuid.c msr.c endif # new domain builder -GUEST_SRCS-y += xc_dom_core.c xc_dom_boot.c -GUEST_SRCS-y += xc_dom_elfloader.c -GUEST_SRCS-$(CONFIG_X86) += xc_dom_bzimageloader.c -GUEST_SRCS-$(CONFIG_X86) += xc_dom_decompress_lz4.c -GUEST_SRCS-$(CONFIG_X86) += xc_dom_hvmloader.c -GUEST_SRCS-$(CONFIG_ARM) += xc_dom_armzimageloader.c -GUEST_SRCS-y += xc_dom_binloader.c -GUEST_SRCS-y += xc_dom_compat_linux.c - -GUEST_SRCS-$(CONFIG_X86) += xc_dom_x86.c -GUEST_SRCS-$(CONFIG_X86) += xc_cpuid_x86.c -GUEST_SRCS-$(CONFIG_ARM) += xc_dom_arm.c +GUEST_SRCS-y += xg_dom_core.c +GUEST_SRCS-y += xg_dom_boot.c +GUEST_SRCS-y += xg_dom_elfloader.c +GUEST_SRCS-$(CONFIG_X86) += xg_dom_bzimageloader.c +GUEST_SRCS-$(CONFIG_X86) += xg_dom_decompress_lz4.c +GUEST_SRCS-$(CONFIG_X86) += xg_dom_hvmloader.c +GUEST_SRCS-$(CONFIG_ARM) += xg_dom_armzimageloader.c +GUEST_SRCS-y += xg_dom_binloader.c +GUEST_SRCS-y += xg_dom_compat_linux.c + +GUEST_SRCS-$(CONFIG_X86) += xg_dom_x86.c +GUEST_SRCS-$(CONFIG_X86) += xg_cpuid_x86.c +GUEST_SRCS-$(CONFIG_ARM) += xg_dom_arm.c ifeq ($(CONFIG_LIBXC_MINIOS),y) -GUEST_SRCS-y += xc_dom_decompress_unsafe.c -GUEST_SRCS-y += xc_dom_decompress_unsafe_bzip2.c -GUEST_SRCS-y += xc_dom_decompress_unsafe_lzma.c -GUEST_SRCS-y += xc_dom_decompress_unsafe_lzo1x.c -GUEST_SRCS-y += xc_dom_decompress_unsafe_xz.c +GUEST_SRCS-y += xg_dom_decompress_unsafe.c +GUEST_SRCS-y += xg_dom_decompress_unsafe_bzip2.c +GUEST_SRCS-y += xg_dom_decompress_unsafe_lzma.c +GUEST_SRCS-y += xg_dom_decompress_unsafe_lzo1x.c +GUEST_SRCS-y += xg_dom_decompress_unsafe_xz.c endif -include $(XEN_TARGET_ARCH)/Makefile diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c deleted file mode 100644 index 0f24d6dd08..0000000000 --- a/tools/libxc/xc_cpuid_x86.c +++ /dev/null @@ -1,665 +0,0 @@ -/****************************************************************************** - * xc_cpuid_x86.c - * - * Compute cpuid of a domain. - * - * Copyright (c) 2008, Citrix Systems, Inc. - * - * 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. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; If not, see <http://www.gnu.org/licenses/>. - */ - -#include <stdlib.h> -#include <stdbool.h> -#include <limits.h> -#include "xc_private.h" -#include "xc_bitops.h" -#include <xen/hvm/params.h> -#include <xen-tools/libs.h> - -enum { -#define XEN_CPUFEATURE(name, value) X86_FEATURE_##name = value, -#include <xen/arch-x86/cpufeatureset.h> -}; - -#include <xen/asm/x86-vendors.h> - -#include <xen/lib/x86/cpu-policy.h> - -#define bitmaskof(idx) (1u << ((idx) & 31)) -#define featureword_of(idx) ((idx) >> 5) - -int xc_get_cpu_levelling_caps(xc_interface *xch, uint32_t *caps) -{ - DECLARE_SYSCTL; - int ret; - - sysctl.cmd = XEN_SYSCTL_get_cpu_levelling_caps; - ret = do_sysctl(xch, &sysctl); - - if ( !ret ) - *caps = sysctl.u.cpu_levelling_caps.caps; - - return ret; -} - -int xc_get_cpu_featureset(xc_interface *xch, uint32_t index, - uint32_t *nr_features, uint32_t *featureset) -{ - DECLARE_SYSCTL; - DECLARE_HYPERCALL_BOUNCE(featureset, - *nr_features * sizeof(*featureset), - XC_HYPERCALL_BUFFER_BOUNCE_OUT); - int ret; - - if ( xc_hypercall_bounce_pre(xch, featureset) ) - return -1; - - sysctl.cmd = XEN_SYSCTL_get_cpu_featureset; - sysctl.u.cpu_featureset.index = index; - sysctl.u.cpu_featureset.nr_features = *nr_features; - set_xen_guest_handle(sysctl.u.cpu_featureset.features, featureset); - - ret = do_sysctl(xch, &sysctl); - - xc_hypercall_bounce_post(xch, featureset); - - if ( !ret ) - *nr_features = sysctl.u.cpu_featureset.nr_features; - - return ret; -} - -uint32_t xc_get_cpu_featureset_size(void) -{ - return FEATURESET_NR_ENTRIES; -} - -const uint32_t *xc_get_static_cpu_featuremask( - enum xc_static_cpu_featuremask mask) -{ - static const uint32_t masks[][FEATURESET_NR_ENTRIES] = { -#define MASK(x) [XC_FEATUREMASK_ ## x] = INIT_ ## x ## _FEATURES - - MASK(KNOWN), - MASK(SPECIAL), - MASK(PV_MAX), - MASK(PV_DEF), - MASK(HVM_SHADOW_MAX), - MASK(HVM_SHADOW_DEF), - MASK(HVM_HAP_MAX), - MASK(HVM_HAP_DEF), - -#undef MASK - }; - - if ( (unsigned int)mask >= ARRAY_SIZE(masks) ) - return NULL; - - return masks[mask]; -} - -int xc_get_cpu_policy_size(xc_interface *xch, uint32_t *nr_leaves, - uint32_t *nr_msrs) -{ - struct xen_sysctl sysctl = {}; - int ret; - - sysctl.cmd = XEN_SYSCTL_get_cpu_policy; - - ret = do_sysctl(xch, &sysctl); - - if ( !ret ) - { - *nr_leaves = sysctl.u.cpu_policy.nr_leaves; - *nr_msrs = sysctl.u.cpu_policy.nr_msrs; - } - - return ret; -} - -int xc_get_system_cpu_policy(xc_interface *xch, uint32_t index, - uint32_t *nr_leaves, xen_cpuid_leaf_t *leaves, - uint32_t *nr_msrs, xen_msr_entry_t *msrs) -{ - struct xen_sysctl sysctl = {}; - DECLARE_HYPERCALL_BOUNCE(leaves, - *nr_leaves * sizeof(*leaves), - XC_HYPERCALL_BUFFER_BOUNCE_OUT); - DECLARE_HYPERCALL_BOUNCE(msrs, - *nr_msrs * sizeof(*msrs), - XC_HYPERCALL_BUFFER_BOUNCE_OUT); - int ret; - - if ( xc_hypercall_bounce_pre(xch, leaves) || - xc_hypercall_bounce_pre(xch, msrs) ) - return -1; - - sysctl.cmd = XEN_SYSCTL_get_cpu_policy; - sysctl.u.cpu_policy.index = index; - sysctl.u.cpu_policy.nr_leaves = *nr_leaves; - set_xen_guest_handle(sysctl.u.cpu_policy.cpuid_policy, leaves); - sysctl.u.cpu_policy.nr_msrs = *nr_msrs; - set_xen_guest_handle(sysctl.u.cpu_policy.msr_policy, msrs); - - ret = do_sysctl(xch, &sysctl); - - xc_hypercall_bounce_post(xch, leaves); - xc_hypercall_bounce_post(xch, msrs); - - if ( !ret ) - { - *nr_leaves = sysctl.u.cpu_policy.nr_leaves; - *nr_msrs = sysctl.u.cpu_policy.nr_msrs; - } - - return ret; -} - -int xc_get_domain_cpu_policy(xc_interface *xch, uint32_t domid, - uint32_t *nr_leaves, xen_cpuid_leaf_t *leaves, - uint32_t *nr_msrs, xen_msr_entry_t *msrs) -{ - DECLARE_DOMCTL; - DECLARE_HYPERCALL_BOUNCE(leaves, - *nr_leaves * sizeof(*leaves), - XC_HYPERCALL_BUFFER_BOUNCE_OUT); - DECLARE_HYPERCALL_BOUNCE(msrs, - *nr_msrs * sizeof(*msrs), - XC_HYPERCALL_BUFFER_BOUNCE_OUT); - int ret; - - if ( xc_hypercall_bounce_pre(xch, leaves) || - xc_hypercall_bounce_pre(xch, msrs) ) - return -1; - - domctl.cmd = XEN_DOMCTL_get_cpu_policy; - domctl.domain = domid; - domctl.u.cpu_policy.nr_leaves = *nr_leaves; - set_xen_guest_handle(domctl.u.cpu_policy.cpuid_policy, leaves); - domctl.u.cpu_policy.nr_msrs = *nr_msrs; - set_xen_guest_handle(domctl.u.cpu_policy.msr_policy, msrs); - - ret = do_domctl(xch, &domctl); - - xc_hypercall_bounce_post(xch, leaves); - xc_hypercall_bounce_post(xch, msrs); - - if ( !ret ) - { - *nr_leaves = domctl.u.cpu_policy.nr_leaves; - *nr_msrs = domctl.u.cpu_policy.nr_msrs; - } - - return ret; -} - -int xc_set_domain_cpu_policy(xc_interface *xch, uint32_t domid, - uint32_t nr_leaves, xen_cpuid_leaf_t *leaves, - uint32_t nr_msrs, xen_msr_entry_t *msrs, - uint32_t *err_leaf_p, uint32_t *err_subleaf_p, - uint32_t *err_msr_p) -{ - DECLARE_DOMCTL; - DECLARE_HYPERCALL_BOUNCE(leaves, - nr_leaves * sizeof(*leaves), - XC_HYPERCALL_BUFFER_BOUNCE_IN); - DECLARE_HYPERCALL_BOUNCE(msrs, - nr_msrs * sizeof(*msrs), - XC_HYPERCALL_BUFFER_BOUNCE_IN); - int ret; - - if ( err_leaf_p ) - *err_leaf_p = -1; - if ( err_subleaf_p ) - *err_subleaf_p = -1; - if ( err_msr_p ) - *err_msr_p = -1; - - if ( xc_hypercall_bounce_pre(xch, leaves) ) - return -1; - - if ( xc_hypercall_bounce_pre(xch, msrs) ) - return -1; - - domctl.cmd = XEN_DOMCTL_set_cpu_policy; - domctl.domain = domid; - domctl.u.cpu_policy.nr_leaves = nr_leaves; - set_xen_guest_handle(domctl.u.cpu_policy.cpuid_policy, leaves); - domctl.u.cpu_policy.nr_msrs = nr_msrs; - set_xen_guest_handle(domctl.u.cpu_policy.msr_policy, msrs); - domctl.u.cpu_policy.err_leaf = -1; - domctl.u.cpu_policy.err_subleaf = -1; - domctl.u.cpu_policy.err_msr = -1; - - ret = do_domctl(xch, &domctl); - - xc_hypercall_bounce_post(xch, leaves); - xc_hypercall_bounce_post(xch, msrs); - - if ( err_leaf_p ) - *err_leaf_p = domctl.u.cpu_policy.err_leaf; - if ( err_subleaf_p ) - *err_subleaf_p = domctl.u.cpu_policy.err_subleaf; - if ( err_msr_p ) - *err_msr_p = domctl.u.cpu_policy.err_msr; - - return ret; -} - -static int compare_leaves(const void *l, const void *r) -{ - const xen_cpuid_leaf_t *lhs = l; - const xen_cpuid_leaf_t *rhs = r; - - if ( lhs->leaf != rhs->leaf ) - return lhs->leaf < rhs->leaf ? -1 : 1; - - if ( lhs->subleaf != rhs->subleaf ) - return lhs->subleaf < rhs->subleaf ? -1 : 1; - - return 0; -} - -static xen_cpuid_leaf_t *find_leaf( - xen_cpuid_leaf_t *leaves, unsigned int nr_leaves, - const struct xc_xend_cpuid *xend) -{ - const xen_cpuid_leaf_t key = { xend->leaf, xend->subleaf }; - - return bsearch(&key, leaves, nr_leaves, sizeof(*leaves), compare_leaves); -} - -static int xc_cpuid_xend_policy( - xc_interface *xch, uint32_t domid, const struct xc_xend_cpuid *xend) -{ - int rc; - xc_dominfo_t di; - unsigned int nr_leaves, nr_msrs; - uint32_t err_leaf = -1, err_subleaf = -1, err_msr = -1; - /* - * Three full policies. The host, domain max, and domain current for the - * domain type. - */ - xen_cpuid_leaf_t *host = NULL, *max = NULL, *cur = NULL; - unsigned int nr_host, nr_max, nr_cur; - - if ( xc_domain_getinfo(xch, domid, 1, &di) != 1 || - di.domid != domid ) - { - ERROR("Failed to obtain d%d info", domid); - rc = -ESRCH; - goto fail; - } - - rc = xc_get_cpu_policy_size(xch, &nr_leaves, &nr_msrs); - if ( rc ) - { - PERROR("Failed to obtain policy info size"); - rc = -errno; - goto fail; - } - - rc = -ENOMEM; - if ( (host = calloc(nr_leaves, sizeof(*host))) == NULL || - (max = calloc(nr_leaves, sizeof(*max))) == NULL || - (cur = calloc(nr_leaves, sizeof(*cur))) == NULL ) - { - ERROR("Unable to allocate memory for %u CPUID leaves", nr_leaves); - goto fail; - } - - /* Get the domain's current policy. */ - nr_msrs = 0; - nr_cur = nr_leaves; - rc = xc_get_domain_cpu_policy(xch, domid, &nr_cur, cur, &nr_msrs, NULL); - if ( rc ) - { - PERROR("Failed to obtain d%d current policy", domid); - rc = -errno; - goto fail; - } - - /* Get the domain's max policy. */ - nr_msrs = 0; - nr_max = nr_leaves; - rc = xc_get_system_cpu_policy(xch, di.hvm ? XEN_SYSCTL_cpu_policy_hvm_max - : XEN_SYSCTL_cpu_policy_pv_max, - &nr_max, max, &nr_msrs, NULL); - if ( rc ) - { - PERROR("Failed to obtain %s max policy", di.hvm ? "hvm" : "pv"); - rc = -errno; - goto fail; - } - - /* Get the host policy. */ - nr_msrs = 0; - nr_host = nr_leaves; - rc = xc_get_system_cpu_policy(xch, XEN_SYSCTL_cpu_policy_host, - &nr_host, host, &nr_msrs, NULL); - if ( rc ) - { - PERROR("Failed to obtain host policy"); - rc = -errno; - goto fail; - } - - rc = -EINVAL; - for ( ; xend->leaf != XEN_CPUID_INPUT_UNUSED; ++xend ) - { - xen_cpuid_leaf_t *cur_leaf = find_leaf(cur, nr_cur, xend); - const xen_cpuid_leaf_t *max_leaf = find_leaf(max, nr_max, xend); - const xen_cpuid_leaf_t *host_leaf = find_leaf(host, nr_host, xend); - - if ( cur_leaf == NULL || max_leaf == NULL || host_leaf == NULL ) - { - ERROR("Missing leaf %#x, subleaf %#x", xend->leaf, xend->subleaf); - goto fail; - } - - for ( unsigned int i = 0; i < ARRAY_SIZE(xend->policy); i++ ) - { - uint32_t *cur_reg = &cur_leaf->a + i; - const uint32_t *max_reg = &max_leaf->a + i; - const uint32_t *host_reg = &host_leaf->a + i; - - if ( xend->policy[i] == NULL ) - continue; - - for ( unsigned int j = 0; j < 32; j++ ) - { - bool val; - - if ( xend->policy[i][j] == '1' ) - val = true; - else if ( xend->policy[i][j] == '0' ) - val = false; - else if ( xend->policy[i][j] == 'x' ) - val = test_bit(31 - j, max_reg); - else if ( xend->policy[i][j] == 'k' || - xend->policy[i][j] == 's' ) - val = test_bit(31 - j, host_reg); - else - { - ERROR("Bad character '%c' in policy[%d] string '%s'", - xend->policy[i][j], i, xend->policy[i]); - goto fail; - } - - clear_bit(31 - j, cur_reg); - if ( val ) - set_bit(31 - j, cur_reg); - } - } - } - - /* Feed the transformed currrent policy back up to Xen. */ - rc = xc_set_domain_cpu_policy(xch, domid, nr_cur, cur, 0, NULL, - &err_leaf, &err_subleaf, &err_msr); - if ( rc ) - { - PERROR("Failed to set d%d's policy (err leaf %#x, subleaf %#x, msr %#x)", - domid, err_leaf, err_subleaf, err_msr); - rc = -errno; - goto fail; - } - - /* Success! */ - - fail: - free(cur); - free(max); - free(host); - - return rc; -} - -int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore, - const uint32_t *featureset, unsigned int nr_features, - bool pae, - const struct xc_xend_cpuid *xend) -{ - int rc; - xc_dominfo_t di; - unsigned int i, nr_leaves, nr_msrs; - xen_cpuid_leaf_t *leaves = NULL; - struct cpuid_policy *p = NULL; - uint32_t err_leaf = -1, err_subleaf = -1, err_msr = -1; - uint32_t host_featureset[FEATURESET_NR_ENTRIES] = {}; - uint32_t len = ARRAY_SIZE(host_featureset); - - if ( xc_domain_getinfo(xch, domid, 1, &di) != 1 || - di.domid != domid ) - { - ERROR("Failed to obtain d%d info", domid); - rc = -ESRCH; - goto out; - } - - rc = xc_get_cpu_policy_size(xch, &nr_leaves, &nr_msrs); - if ( rc ) - { - PERROR("Failed to obtain policy info size"); - rc = -errno; - goto out; - } - - rc = -ENOMEM; - if ( (leaves = calloc(nr_leaves, sizeof(*leaves))) == NULL || - (p = calloc(1, sizeof(*p))) == NULL ) - goto out; - - /* Get the host policy. */ - rc = xc_get_cpu_featureset(xch, XEN_SYSCTL_cpu_featureset_host, - &len, host_featureset); - if ( rc ) - { - /* Tolerate "buffer too small", as we've got the bits we need. */ - if ( errno == ENOBUFS ) - rc = 0; - else - { - PERROR("Failed to obtain host featureset"); - rc = -errno; - goto out; - } - } - - /* Get the domain's default policy. */ - nr_msrs = 0; - rc = xc_get_system_cpu_policy(xch, di.hvm ? XEN_SYSCTL_cpu_policy_hvm_default - : XEN_SYSCTL_cpu_policy_pv_default, - &nr_leaves, leaves, &nr_msrs, NULL); - if ( rc ) - { - PERROR("Failed to obtain %s default policy", di.hvm ? "hvm" : "pv"); - rc = -errno; - goto out; - } - - rc = x86_cpuid_copy_from_buffer(p, leaves, nr_leaves, - &err_leaf, &err_subleaf); - if ( rc ) - { - ERROR("Failed to deserialise CPUID (err leaf %#x, subleaf %#x) (%d = %s)", - err_leaf, err_subleaf, -rc, strerror(-rc)); - goto out; - } - - /* - * Account for feature which have been disabled by default since Xen 4.13, - * so migrated-in VM's don't risk seeing features disappearing. - */ - if ( restore ) - { - p->basic.rdrand = test_bit(X86_FEATURE_RDRAND, host_featureset); - - if ( di.hvm ) - { - p->feat.mpx = test_bit(X86_FEATURE_MPX, host_featureset); - } - } - - if ( featureset ) - { - uint32_t disabled_features[FEATURESET_NR_ENTRIES], - feat[FEATURESET_NR_ENTRIES] = {}; - static const uint32_t deep_features[] = INIT_DEEP_FEATURES; - unsigned int i, b; - - /* - * The user supplied featureset may be shorter or longer than - * FEATURESET_NR_ENTRIES. Shorter is fine, and we will zero-extend. - * Longer is fine, so long as it only padded with zeros. - */ - unsigned int user_len = min(FEATURESET_NR_ENTRIES + 0u, nr_features); - - /* Check for truncated set bits. */ - rc = -EOPNOTSUPP; - for ( i = user_len; i < nr_features; ++i ) - if ( featureset[i] != 0 ) - goto out; - - memcpy(feat, featureset, sizeof(*featureset) * user_len); - - /* Disable deep dependencies of disabled features. */ - for ( i = 0; i < ARRAY_SIZE(disabled_features); ++i ) - disabled_features[i] = ~feat[i] & deep_features[i]; - - for ( b = 0; b < sizeof(disabled_features) * CHAR_BIT; ++b ) - { - const uint32_t *dfs; - - if ( !test_bit(b, disabled_features) || - !(dfs = x86_cpuid_lookup_deep_deps(b)) ) - continue; - - for ( i = 0; i < ARRAY_SIZE(disabled_features); ++i ) - { - feat[i] &= ~dfs[i]; - disabled_features[i] &= ~dfs[i]; - } - } - - cpuid_featureset_to_policy(feat, p); - } - else - { - if ( di.hvm ) - p->basic.pae = pae; - } - - if ( !di.hvm ) - { - /* - * On hardware without CPUID Faulting, PV guests see real topology. - * As a consequence, they also need to see the host htt/cmp fields. - */ - p->basic.htt = test_bit(X86_FEATURE_HTT, host_featureset); - p->extd.cmp_legacy = test_bit(X86_FEATURE_CMP_LEGACY, host_featureset); - } - else - { - /* - * Topology for HVM guests is entirely controlled by Xen. For now, we - * hardcode APIC_ID = vcpu_id * 2 to give the illusion of no SMT. - */ - p->basic.htt = true; - p->extd.cmp_legacy = false; - - /* - * Leaf 1 EBX[23:16] is Maximum Logical Processors Per Package. - * Update to reflect vLAPIC_ID = vCPU_ID * 2, but make sure to avoid - * overflow. - */ - if ( !(p->basic.lppp & 0x80) ) - p->basic.lppp *= 2; - - switch ( p->x86_vendor ) - { - case X86_VENDOR_INTEL: - for ( i = 0; (p->cache.subleaf[i].type && - i < ARRAY_SIZE(p->cache.raw)); ++i ) - { - p->cache.subleaf[i].cores_per_package = - (p->cache.subleaf[i].cores_per_package << 1) | 1; - p->cache.subleaf[i].threads_per_cache = 0; - } - break; - - case X86_VENDOR_AMD: - case X86_VENDOR_HYGON: - /* - * Leaf 0x80000008 ECX[15:12] is ApicIdCoreSize. - * Leaf 0x80000008 ECX[7:0] is NumberOfCores (minus one). - * Update to reflect vLAPIC_ID = vCPU_ID * 2. But avoid - * - overflow, - * - going out of sync with leaf 1 EBX[23:16], - * - incrementing ApicIdCoreSize when it's zero (which changes the - * meaning of bits 7:0). - * - * UPDATE: I addition to avoiding overflow, some - * proprietary operating systems have trouble with - * apic_id_size values greater than 7. Limit the value to - * 7 for now. - */ - if ( p->extd.nc < 0x7f ) - { - if ( p->extd.apic_id_size != 0 && p->extd.apic_id_size < 0x7 ) - p->extd.apic_id_size++; - - p->extd.nc = (p->extd.nc << 1) | 1; - } - break; - } - - /* - * These settings are necessary to cause earlier HVM_PARAM_NESTEDHVM / - * XEN_DOMCTL_disable_migrate settings to be reflected correctly in - * CPUID. Xen will discard these bits if configuration hasn't been - * set for the domain. - */ - p->extd.itsc = true; - p->basic.vmx = true; - p->extd.svm = true; - } - - rc = x86_cpuid_copy_to_buffer(p, leaves, &nr_leaves); - if ( rc ) - { - ERROR("Failed to serialise CPUID (%d = %s)", -rc, strerror(-rc)); - goto out; - } - - rc = xc_set_domain_cpu_policy(xch, domid, nr_leaves, leaves, 0, NULL, - &err_leaf, &err_subleaf, &err_msr); - if ( rc ) - { - PERROR("Failed to set d%d's policy (err leaf %#x, subleaf %#x, msr %#x)", - domid, err_leaf, err_subleaf, err_msr); - rc = -errno; - goto out; - } - - if ( xend && (rc = xc_cpuid_xend_policy(xch, domid, xend)) ) - goto out; - - rc = 0; - -out: - free(p); - free(leaves); - - return rc; -} diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c deleted file mode 100644 index 931404c222..0000000000 --- a/tools/libxc/xc_dom_arm.c +++ /dev/null @@ -1,552 +0,0 @@ -/* - * Xen domain builder -- ARM - * - * 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. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; If not, see <http://www.gnu.org/licenses/>. - * - * Copyright (c) 2011, Citrix Systems - */ -#include <inttypes.h> -#include <assert.h> - -#include <xen/xen.h> -#include <xen/io/protocols.h> -#include <xen-tools/libs.h> - -#include "xg_private.h" -#include "xc_dom.h" - -#define NR_MAGIC_PAGES 4 -#define CONSOLE_PFN_OFFSET 0 -#define XENSTORE_PFN_OFFSET 1 -#define MEMACCESS_PFN_OFFSET 2 -#define VUART_PFN_OFFSET 3 - -#define LPAE_SHIFT 9 - -#define PFN_4K_SHIFT (0) -#define PFN_2M_SHIFT (PFN_4K_SHIFT+LPAE_SHIFT) -#define PFN_1G_SHIFT (PFN_2M_SHIFT+LPAE_SHIFT) -#define PFN_512G_SHIFT (PFN_1G_SHIFT+LPAE_SHIFT) - -/* get guest IO ABI protocol */ -const char *xc_domain_get_native_protocol(xc_interface *xch, - uint32_t domid) -{ - return XEN_IO_PROTO_ABI_ARM; -} - -/* ------------------------------------------------------------------------ */ - -static int alloc_magic_pages(struct xc_dom_image *dom) -{ - int rc, i; - const xen_pfn_t base = GUEST_MAGIC_BASE >> XC_PAGE_SHIFT; - xen_pfn_t p2m[NR_MAGIC_PAGES]; - - BUILD_BUG_ON(NR_MAGIC_PAGES > GUEST_MAGIC_SIZE >> XC_PAGE_SHIFT); - - DOMPRINTF_CALLED(dom->xch); - - for (i = 0; i < NR_MAGIC_PAGES; i++) - p2m[i] = base + i; - - rc = xc_domain_populate_physmap_exact( - dom->xch, dom->guest_domid, NR_MAGIC_PAGES, - 0, 0, p2m); - if ( rc < 0 ) - return rc; - - dom->console_pfn = base + CONSOLE_PFN_OFFSET; - dom->xenstore_pfn = base + XENSTORE_PFN_OFFSET; - dom->vuart_gfn = base + VUART_PFN_OFFSET; - - xc_clear_domain_page(dom->xch, dom->guest_domid, dom->console_pfn); - xc_clear_domain_page(dom->xch, dom->guest_domid, dom->xenstore_pfn); - xc_clear_domain_page(dom->xch, dom->guest_domid, base + MEMACCESS_PFN_OFFSET); - xc_clear_domain_page(dom->xch, dom->guest_domid, dom->vuart_gfn); - - xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_CONSOLE_PFN, - dom->console_pfn); - xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_STORE_PFN, - dom->xenstore_pfn); - xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_MONITOR_RING_PFN, - base + MEMACCESS_PFN_OFFSET); - /* allocated by toolstack */ - xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_CONSOLE_EVTCHN, - dom->console_evtchn); - xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_STORE_EVTCHN, - dom->xenstore_evtchn); - - return 0; -} - -/* ------------------------------------------------------------------------ */ - -static int start_info_arm(struct xc_dom_image *dom) -{ - DOMPRINTF_CALLED(dom->xch); - return 0; -} - -static int shared_info_arm(struct xc_dom_image *dom, void *ptr) -{ - DOMPRINTF_CALLED(dom->xch); - return 0; -} - -/* ------------------------------------------------------------------------ */ - -static int vcpu_arm32(struct xc_dom_image *dom) -{ - vcpu_guest_context_any_t any_ctx; - vcpu_guest_context_t *ctxt = &any_ctx.c; - int rc; - - DOMPRINTF_CALLED(dom->xch); - - /* clear everything */ - memset(ctxt, 0, sizeof(*ctxt)); - - ctxt->user_regs.pc32 = dom->parms.virt_entry; - - /* Linux boot protocol. See linux.Documentation/arm/Booting. */ - ctxt->user_regs.r0_usr = 0; /* SBZ */ - /* Machine ID: We use DTB therefore no machine id */ - ctxt->user_regs.r1_usr = 0xffffffff; - /* ATAGS/DTB: We currently require that the guest kernel to be - * using CONFIG_ARM_APPENDED_DTB. Ensure that r2 does not look - * like a valid pointer to a set of ATAGS or a DTB. - */ - ctxt->user_regs.r2_usr = dom->devicetree_blob ? - dom->devicetree_seg.vstart : 0xffffffff; - - ctxt->sctlr = SCTLR_GUEST_INIT; - - ctxt->ttbr0 = 0; - ctxt->ttbr1 = 0; - ctxt->ttbcr = 0; /* Defined Reset Value */ - - ctxt->user_regs.cpsr = PSR_GUEST32_INIT; - - ctxt->flags = VGCF_online; - - DOMPRINTF("Initial state CPSR %#"PRIx32" PC %#"PRIx32, - ctxt->user_regs.cpsr, ctxt->user_regs.pc32); - - rc = xc_vcpu_setcontext(dom->xch, dom->guest_domid, 0, &any_ctx); - if ( rc != 0 ) - xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, - "%s: SETVCPUCONTEXT failed (rc=%d)", __func__, rc); - - return rc; -} - -static int vcpu_arm64(struct xc_dom_image *dom) -{ - vcpu_guest_context_any_t any_ctx; - vcpu_guest_context_t *ctxt = &any_ctx.c; - int rc; - - DOMPRINTF_CALLED(dom->xch); - /* clear everything */ - memset(ctxt, 0, sizeof(*ctxt)); - - ctxt->user_regs.pc64 = dom->parms.virt_entry; - - /* Linux boot protocol. See linux.Documentation/arm64/booting.txt. */ - ctxt->user_regs.x0 = dom->devicetree_blob ? - dom->devicetree_seg.vstart : 0xffffffff; - ctxt->user_regs.x1 = 0; - ctxt->user_regs.x2 = 0; - ctxt->user_regs.x3 = 0; - - DOMPRINTF("DTB %"PRIx64, ctxt->user_regs.x0); - - ctxt->sctlr = SCTLR_GUEST_INIT; - - ctxt->ttbr0 = 0; - ctxt->ttbr1 = 0; - ctxt->ttbcr = 0; /* Defined Reset Value */ - - ctxt->user_regs.cpsr = PSR_GUEST64_INIT; - - ctxt->flags = VGCF_online; - - DOMPRINTF("Initial state CPSR %#"PRIx32" PC %#"PRIx64, - ctxt->user_regs.cpsr, ctxt->user_regs.pc64); - - rc = xc_vcpu_setcontext(dom->xch, dom->guest_domid, 0, &any_ctx); - if ( rc != 0 ) - xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, - "%s: SETVCPUCONTEXT failed (rc=%d)", __func__, rc); - - return rc; -} - -/* ------------------------------------------------------------------------ */ - -static int set_mode(xc_interface *xch, uint32_t domid, char *guest_type) -{ - static const struct { - char *guest; - uint32_t size; - } types[] = { - { "xen-3.0-aarch64", 64 }, - { "xen-3.0-armv7l", 32 }, - }; - DECLARE_DOMCTL; - int i,rc; - - domctl.domain = domid; - domctl.cmd = XEN_DOMCTL_set_address_size; - domctl.u.address_size.size = 0; - - for ( i = 0; i < ARRAY_SIZE(types); i++ ) - if ( !strcmp(types[i].guest, guest_type) ) - domctl.u.address_size.size = types[i].size; - if ( domctl.u.address_size.size == 0 ) - { - xc_dom_printf(xch, "%s: warning: unknown guest type %s", - __FUNCTION__, guest_type); - return -EINVAL; - } - - xc_dom_printf(xch, "%s: guest %s, address size %" PRId32 "", __FUNCTION__, - guest_type, domctl.u.address_size.size); - rc = do_domctl(xch, &domctl); - if ( rc != 0 ) - xc_dom_printf(xch, "%s: warning: failed (rc=%d)", - __FUNCTION__, rc); - return rc; -} - -/* >0: success, *nr_pfns set to number actually populated - * 0: didn't try with this pfn shift (e.g. misaligned base etc) - * <0: ERROR - */ -static int populate_one_size(struct xc_dom_image *dom, int pfn_shift, - xen_pfn_t base_pfn, xen_pfn_t *nr_pfns, - xen_pfn_t *extents) -{ - /* The mask for this level */ - const uint64_t mask = ((uint64_t)1<<(pfn_shift))-1; - /* The shift, mask and next boundary for the level above this one */ - const int next_shift = pfn_shift + LPAE_SHIFT; - const uint64_t next_mask = ((uint64_t)1<<next_shift)-1; - const xen_pfn_t next_boundary - = (base_pfn + ((uint64_t)1<<next_shift)) & ~next_mask; - - int nr, i, count; - xen_pfn_t end_pfn = base_pfn + *nr_pfns; - - /* No level zero super pages with current hardware */ - if ( pfn_shift == PFN_512G_SHIFT ) - return 0; - - /* base is misaligned for this level */ - if ( mask & base_pfn ) - return 0; - - /* - * If base is not aligned at the next level up then try and make - * it so for next time around. - */ - if ( (base_pfn & next_mask) && end_pfn > next_boundary ) - end_pfn = next_boundary; - - count = ( end_pfn - base_pfn ) >> pfn_shift; - - /* Nothing to allocate */ - if ( !count ) - return 0; - - for ( i = 0 ; i < count ; i ++ ) - extents[i] = base_pfn + (i<<pfn_shift); - - nr = xc_domain_populate_physmap(dom->xch, dom->guest_domid, count, - pfn_shift, 0, extents); - if ( nr <= 0 ) return nr; - DOMPRINTF("%s: populated %#x/%#x entries with shift %d", - __FUNCTION__, nr, count, pfn_shift); - - *nr_pfns = nr << pfn_shift; - - return 1; -} - -static int populate_guest_memory(struct xc_dom_image *dom, - xen_pfn_t base_pfn, xen_pfn_t nr_pfns) -{ - int rc = 0; - xen_pfn_t allocsz, pfn, *extents; - - extents = calloc(1024*1024,sizeof(xen_pfn_t)); - if ( extents == NULL ) - { - DOMPRINTF("%s: Unable to allocate extent array", __FUNCTION__); - return -1; - } - - DOMPRINTF("%s: populating RAM @ %016"PRIx64"-%016"PRIx64" (%"PRId64"MB)", - __FUNCTION__, - (uint64_t)base_pfn << XC_PAGE_SHIFT, - (uint64_t)(base_pfn + nr_pfns) << XC_PAGE_SHIFT, - (uint64_t)nr_pfns >> (20-XC_PAGE_SHIFT)); - - for ( pfn = 0; pfn < nr_pfns; pfn += allocsz ) - { - allocsz = min_t(int, 1024*1024, nr_pfns - pfn); -#if 0 /* Enable this to exercise/debug the code which tries to realign - * to a superpage boundary, by misaligning at the start. */ - if ( pfn == 0 ) - { - allocsz = 1; - rc = populate_one_size(dom, PFN_4K_SHIFT, - base_pfn + pfn, &allocsz, extents); - if (rc < 0) break; - if (rc > 0) continue; - /* Failed to allocate a single page? */ - break; - } -#endif - - rc = populate_one_size(dom, PFN_512G_SHIFT, - base_pfn + pfn, &allocsz, extents); - if ( rc < 0 ) break; - if ( rc > 0 ) continue; - - rc = populate_one_size(dom, PFN_1G_SHIFT, - base_pfn + pfn, &allocsz, extents); - if ( rc < 0 ) break; - if ( rc > 0 ) continue; - - rc = populate_one_size(dom, PFN_2M_SHIFT, - base_pfn + pfn, &allocsz, extents); - if ( rc < 0 ) break; - if ( rc > 0 ) continue; - - rc = populate_one_size(dom, PFN_4K_SHIFT, - base_pfn + pfn, &allocsz, extents); - if ( rc < 0 ) break; - if ( rc == 0 ) - { - DOMPRINTF("%s: Not enough RAM", __FUNCTION__); - errno = ENOMEM; - rc = -1; - goto out; - } - } - -out: - free(extents); - return rc < 0 ? rc : 0; -} - -static int meminit(struct xc_dom_image *dom) -{ - int i, rc; - uint64_t modbase; - - uint64_t ramsize = (uint64_t)dom->total_pages << XC_PAGE_SHIFT; - - const uint64_t bankbase[] = GUEST_RAM_BANK_BASES; - const uint64_t bankmax[] = GUEST_RAM_BANK_SIZES; - - /* Convenient */ - const uint64_t kernbase = dom->kernel_seg.vstart; - const uint64_t kernend = ROUNDUP(dom->kernel_seg.vend, 21/*2MB*/); - const uint64_t kernsize = kernend - kernbase; - const uint64_t dtb_size = dom->devicetree_blob ? - ROUNDUP(dom->devicetree_size, XC_PAGE_SHIFT) : 0; - const uint64_t ramdisk_size = dom->modules[0].blob ? - ROUNDUP(dom->modules[0].size, XC_PAGE_SHIFT) : 0; - const uint64_t modsize = dtb_size + ramdisk_size; - const uint64_t ram128mb = bankbase[0] + (128<<20); - - xen_pfn_t p2m_size; - uint64_t bank0end; - - assert(dom->rambase_pfn << XC_PAGE_SHIFT == bankbase[0]); - - if ( modsize + kernsize > bankmax[0] ) - { - DOMPRINTF("%s: Not enough memory for the kernel+dtb+initrd", - __FUNCTION__); - return -1; - } - - if ( ramsize == 0 ) - { - DOMPRINTF("%s: ram size is 0", __FUNCTION__); - return -1; - } - - if ( ramsize > GUEST_RAM_MAX ) - { - DOMPRINTF("%s: ram size is too large for guest address space: " - "%"PRIx64" > %llx", - __FUNCTION__, ramsize, GUEST_RAM_MAX); - return -1; - } - - rc = set_mode(dom->xch, dom->guest_domid, dom->guest_type); - if ( rc ) - return rc; - - for ( i = 0; ramsize && i < GUEST_RAM_BANKS; i++ ) - { - uint64_t banksize = ramsize > bankmax[i] ? bankmax[i] : ramsize; - - ramsize -= banksize; - - p2m_size = ( bankbase[i] + banksize - bankbase[0] ) >> XC_PAGE_SHIFT; - - dom->rambank_size[i] = banksize >> XC_PAGE_SHIFT; - } - - assert(dom->rambank_size[0] != 0); - assert(ramsize == 0); /* Too much RAM is rejected above */ - - dom->p2m_size = p2m_size; - - /* setup initial p2m and allocate guest memory */ - for ( i = 0; i < GUEST_RAM_BANKS && dom->rambank_size[i]; i++ ) - { - if ((rc = populate_guest_memory(dom, - bankbase[i] >> XC_PAGE_SHIFT, - dom->rambank_size[i]))) - return rc; - } - - /* - * We try to place dtb+initrd at 128MB or if we have less RAM - * as high as possible. If there is no space then fallback to - * just before the kernel. - * - * If changing this then consider - * xen/arch/arm/kernel.c:place_modules as well. - */ - bank0end = bankbase[0] + ((uint64_t)dom->rambank_size[0] << XC_PAGE_SHIFT); - - if ( bank0end >= ram128mb + modsize && kernend < ram128mb ) - modbase = ram128mb; - else if ( bank0end - modsize > kernend ) - modbase = bank0end - modsize; - else if (kernbase - bankbase[0] > modsize ) - modbase = kernbase - modsize; - else - return -1; - - DOMPRINTF("%s: placing boot modules at 0x%" PRIx64, __FUNCTION__, modbase); - - /* - * Must map DTB *after* initrd, to satisfy order of calls to - * xc_dom_alloc_segment in xc_dom_build_image, which must map - * things at monotonolically increasing addresses. - */ - if ( ramdisk_size ) - { - dom->modules[0].seg.vstart = modbase; - dom->modules[0].seg.vend = modbase + ramdisk_size; - - DOMPRINTF("%s: ramdisk: 0x%" PRIx64 " -> 0x%" PRIx64 "", - __FUNCTION__, - dom->modules[0].seg.vstart, dom->modules[0].seg.vend); - - modbase += ramdisk_size; - } - - if ( dtb_size ) - { - dom->devicetree_seg.vstart = modbase; - dom->devicetree_seg.vend = modbase + dtb_size; - - DOMPRINTF("%s: devicetree: 0x%" PRIx64 " -> 0x%" PRIx64 "", - __FUNCTION__, - dom->devicetree_seg.vstart, dom->devicetree_seg.vend); - - modbase += dtb_size; - } - - return 0; -} - -bool xc_dom_translated(const struct xc_dom_image *dom) -{ - return true; -} - -/* ------------------------------------------------------------------------ */ - -static int bootearly(struct xc_dom_image *dom) -{ - DOMPRINTF("%s: doing nothing", __FUNCTION__); - return 0; -} - -static int bootlate(struct xc_dom_image *dom) -{ - /* XXX - * map shared info - * map grant tables - * setup shared info - */ - return 0; -} - -/* ------------------------------------------------------------------------ */ - -static struct xc_dom_arch xc_dom_32 = { - .guest_type = "xen-3.0-armv7l", - .native_protocol = XEN_IO_PROTO_ABI_ARM, - .page_shift = PAGE_SHIFT_ARM, - .sizeof_pfn = 8, - .alloc_magic_pages = alloc_magic_pages, - .start_info = start_info_arm, - .shared_info = shared_info_arm, - .vcpu = vcpu_arm32, - .meminit = meminit, - .bootearly = bootearly, - .bootlate = bootlate, -}; - -static struct xc_dom_arch xc_dom_64 = { - .guest_type = "xen-3.0-aarch64", - .native_protocol = XEN_IO_PROTO_ABI_ARM, - .page_shift = PAGE_SHIFT_ARM, - .sizeof_pfn = 8, - .alloc_magic_pages = alloc_magic_pages, - .start_info = start_info_arm, - .shared_info = shared_info_arm, - .vcpu = vcpu_arm64, - .meminit = meminit, - .bootearly = bootearly, - .bootlate = bootlate, -}; - -static void __init register_arch_hooks(void) -{ - xc_dom_register_arch_hooks(&xc_dom_32); - xc_dom_register_arch_hooks(&xc_dom_64); -} - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/tools/libxc/xc_dom_armzimageloader.c b/tools/libxc/xc_dom_armzimageloader.c deleted file mode 100644 index 0df8c2a4b1..0000000000 --- a/tools/libxc/xc_dom_armzimageloader.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Xen domain builder -- ARM zImage bits - * - * Parse and load ARM zImage kernel images. - * - * Copyright (C) 2012, Citrix Systems. - * - * 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. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; If not, see <http://www.gnu.org/licenses/>. - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <inttypes.h> - -#include "xg_private.h" -#include "xc_dom.h" - -#include <arpa/inet.h> /* XXX ntohl is not the right function... */ - -struct minimal_dtb_header { - uint32_t magic; - uint32_t total_size; - /* There are other fields but we don't use them yet. */ -}; - -#define DTB_MAGIC 0xd00dfeed - -/* ------------------------------------------------------------ */ -/* 32-bit zImage Support */ -/* ------------------------------------------------------------ */ - -#define ZIMAGE32_MAGIC_OFFSET 0x24 -#define ZIMAGE32_START_OFFSET 0x28 -#define ZIMAGE32_END_OFFSET 0x2c - -#define ZIMAGE32_MAGIC 0x016f2818 - -static int xc_dom_probe_zimage32_kernel(struct xc_dom_image *dom) -{ - uint32_t *zimage; - - if ( dom->kernel_blob == NULL ) - { - xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, - "%s: no kernel image loaded", __FUNCTION__); - return -EINVAL; - } - - if ( dom->kernel_size < 0x30 /*sizeof(struct setup_header)*/ ) - { - xc_dom_printf(dom->xch, "%s: kernel image too small", __FUNCTION__); - return -EINVAL; - } - - zimage = (uint32_t *)dom->kernel_blob; - if ( zimage[ZIMAGE32_MAGIC_OFFSET/4] != ZIMAGE32_MAGIC ) - { - xc_dom_printf(dom->xch, "%s: kernel is not an arm32 zImage", __FUNCTION__); - return -EINVAL; - } - - return 0; -} - -static int xc_dom_parse_zimage32_kernel(struct xc_dom_image *dom) -{ - uint32_t *zimage; - uint32_t start, entry_addr; - uint64_t v_start, v_end; - uint64_t rambase = dom->rambase_pfn << XC_PAGE_SHIFT; - - DOMPRINTF_CALLED(dom->xch); - - zimage = (uint32_t *)dom->kernel_blob; - - /* Do not load kernel at the very first RAM address */ - v_start = rambase + 0x8000; - - if ( dom->kernel_size > UINT64_MAX - v_start ) - { - DOMPRINTF("%s: kernel is too large\n", __FUNCTION__); - return -EINVAL; - } - - v_end = v_start + dom->kernel_size; - - /* - * If start is invalid then the guest will start at some invalid - * address and crash, but this happens in guest context so doesn't - * concern us here. - */ - start = zimage[ZIMAGE32_START_OFFSET/4]; - - if (start == 0) - entry_addr = v_start; - else - entry_addr = start; - - /* find kernel segment */ - dom->kernel_seg.vstart = v_start; - dom->kernel_seg.vend = v_end; - - dom->parms.virt_entry = entry_addr; - dom->parms.virt_base = rambase; - - dom->guest_type = "xen-3.0-armv7l"; - DOMPRINTF("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "", - __FUNCTION__, dom->guest_type, - dom->kernel_seg.vstart, dom->kernel_seg.vend); - return 0; -} - -/* ------------------------------------------------------------ */ -/* 64-bit zImage Support */ -/* ------------------------------------------------------------ */ - -#define ZIMAGE64_MAGIC_V0 0x14000008 -#define ZIMAGE64_MAGIC_V1 0x644d5241 /* "ARM\x64" */ - -/* linux/Documentation/arm64/booting.txt */ -struct zimage64_hdr { - uint32_t magic0; - uint32_t res0; - uint64_t text_offset; /* Image load offset */ - uint64_t res1; - uint64_t res2; - /* zImage V1 only from here */ - uint64_t res3; - uint64_t res4; - uint64_t res5; - uint32_t magic1; - uint32_t res6; -}; -static int xc_dom_probe_zimage64_kernel(struct xc_dom_image *dom) -{ - struct zimage64_hdr *zimage; - - if ( dom->kernel_blob == NULL ) - { - xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, - "%s: no kernel image loaded", __FUNCTION__); - return -EINVAL; - } - - if ( dom->kernel_size < sizeof(*zimage) ) - { - xc_dom_printf(dom->xch, "%s: kernel image too small", __FUNCTION__); - return -EINVAL; - } - - zimage = dom->kernel_blob; - if ( zimage->magic0 != ZIMAGE64_MAGIC_V0 && - zimage->magic1 != ZIMAGE64_MAGIC_V1 ) - { - xc_dom_printf(dom->xch, "%s: kernel is not an arm64 Image", __FUNCTION__); - return -EINVAL; - } - - return 0; -} - -static int xc_dom_parse_zimage64_kernel(struct xc_dom_image *dom) -{ - struct zimage64_hdr *zimage; - uint64_t v_start, v_end; - uint64_t rambase = dom->rambase_pfn << XC_PAGE_SHIFT; - - DOMPRINTF_CALLED(dom->xch); - - zimage = dom->kernel_blob; - - if ( zimage->text_offset > UINT64_MAX - rambase ) - { - DOMPRINTF("%s: kernel text offset is too large\n", __FUNCTION__); - return -EINVAL; - } - - v_start = rambase + zimage->text_offset; - - if ( dom->kernel_size > UINT64_MAX - v_start ) - { - DOMPRINTF("%s: kernel is too large\n", __FUNCTION__); - return -EINVAL; - } - - v_end = v_start + dom->kernel_size; - - dom->kernel_seg.vstart = v_start; - dom->kernel_seg.vend = v_end; - - /* Call the kernel at offset 0 */ - dom->parms.virt_entry = v_start; - dom->parms.virt_base = rambase; - - dom->guest_type = "xen-3.0-aarch64"; - DOMPRINTF("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "", - __FUNCTION__, dom->guest_type, - dom->kernel_seg.vstart, dom->kernel_seg.vend); - - return 0; -} - -/* ------------------------------------------------------------ */ -/* Common zImage Support */ -/* ------------------------------------------------------------ */ - -static int xc_dom_load_zimage_kernel(struct xc_dom_image *dom) -{ - void *dst; - - DOMPRINTF_CALLED(dom->xch); - - dst = xc_dom_seg_to_ptr(dom, &dom->kernel_seg); - if ( dst == NULL ) - { - DOMPRINTF("%s: xc_dom_seg_to_ptr(dom, &dom->kernel_seg) => NULL", - __func__); - return -1; - } - - DOMPRINTF("%s: kernel seg %#"PRIx64"-%#"PRIx64, - __func__, dom->kernel_seg.vstart, dom->kernel_seg.vend); - DOMPRINTF("%s: copy %zd bytes from blob %p to dst %p", - __func__, dom->kernel_size, dom->kernel_blob, dst); - - memcpy(dst, dom->kernel_blob, dom->kernel_size); - - return 0; -} - -static struct xc_dom_loader zimage32_loader = { - .name = "Linux zImage (ARM32)", - .probe = xc_dom_probe_zimage32_kernel, - .parser = xc_dom_parse_zimage32_kernel, - .loader = xc_dom_load_zimage_kernel, -}; - -static struct xc_dom_loader zimage64_loader = { - .name = "Linux zImage (ARM64)", - .probe = xc_dom_probe_zimage64_kernel, - .parser = xc_dom_parse_zimage64_kernel, - .loader = xc_dom_load_zimage_kernel, -}; - -static void __init register_loader(void) -{ - xc_dom_register_loader(&zimage32_loader); - xc_dom_register_loader(&zimage64_loader); -} - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/tools/libxc/xc_dom_binloader.c b/tools/libxc/xc_dom_binloader.c deleted file mode 100644 index d6f7f2a500..0000000000 --- a/tools/libxc/xc_dom_binloader.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * 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. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; If not, see <http://www.gnu.org/licenses/>. - * - * Some of the field descriptions were copied from "The Multiboot - * Specification", Copyright 1995, 96 Bryan Ford <baford@xxxxxxxxxxx>, - * Erich Stefan Boleyn <erich@xxxxxxxx> Copyright 1999, 2000, 2001, 2002 - * Free Software Foundation, Inc. - */ - -/****************************************************************************** - * - * Loads simple binary images. It's like a .COM file in MS-DOS. No headers are - * present. The only requirement is that it must have a xen_bin_image table - * somewhere in the first 8192 bytes, starting on a 32-bit aligned address. - * Those familiar with the multiboot specification should recognize this, it's - * (almost) the same as the multiboot header. - * The layout of the xen_bin_image table is: - * - * Offset Type Name Note - * 0 uint32_t magic required - * 4 uint32_t flags required - * 8 uint32_t checksum required - * 12 uint32_t header_addr required - * 16 uint32_t load_addr required - * 20 uint32_t load_end_addr required - * 24 uint32_t bss_end_addr required - * 28 uint32_t entry_addr required - * - * - magic - * Magic number identifying the table. For images to be loaded by Xen 3, the - * magic value is 0x336ec578 ("xEn3" with the 0x80 bit of the "E" set). - * - flags - * bit 0: indicates whether the image needs to be loaded on a page boundary - * bit 1: reserved, must be 0 (the multiboot spec uses this bit to indicate - * that memory info should be passed to the image) - * bit 2: reserved, must be 0 (the multiboot spec uses this bit to indicate - * that the bootloader should pass video mode info to the image) - * bit 16: reserved, must be 1 (the multiboot spec uses this bit to indicate - * that the values in the fields header_addr - entry_addr are - * valid) - * All other bits should be set to 0. - * - checksum - * When added to "magic" and "flags", the resulting value should be 0. - * - header_addr - * Contains the virtual address corresponding to the beginning of the - * table - the memory location at which the magic value is supposed to be - * loaded. This field serves to synchronize the mapping between OS image - * offsets and virtual memory addresses. - * - load_addr - * Contains the virtual address of the beginning of the text segment. The - * offset in the OS image file at which to start loading is defined by the - * offset at which the table was found, minus (header addr - load addr). - * load addr must be less than or equal to header addr. - * - load_end_addr - * Contains the virtual address of the end of the data segment. - * (load_end_addr - load_addr) specifies how much data to load. This implies - * that the text and data segments must be consecutive in the OS image. If - * this field is zero, the domain builder assumes that the text and data - * segments occupy the whole OS image file. - * - bss_end_addr - * Contains the virtual address of the end of the bss segment. The domain - * builder initializes this area to zero, and reserves the memory it occupies - * to avoid placing boot modules and other data relevant to the loaded image - * in that area. If this field is zero, the domain builder assumes that no bss - * segment is present. - * - entry_addr - * The virtual address at which to start execution of the loaded image. - * - */ - -#include <stdlib.h> -#include <inttypes.h> - -#include "xg_private.h" -#include "xc_dom.h" - -#define round_pgup(_p) (((_p)+(PAGE_SIZE_X86-1))&PAGE_MASK_X86) -#define round_pgdown(_p) ((_p)&PAGE_MASK_X86) - -struct xen_bin_image_table -{ - uint32_t magic; - uint32_t flags; - uint32_t checksum; - uint32_t header_addr; - uint32_t load_addr; - uint32_t load_end_addr; - uint32_t bss_end_addr; - uint32_t entry_addr; -}; - -#define XEN_MULTIBOOT_MAGIC3 0x336ec578 - -#define XEN_MULTIBOOT_FLAG_ALIGN4K 0x00000001 -#define XEN_MULTIBOOT_FLAG_NEEDMEMINFO 0x00000002 -#define XEN_MULTIBOOT_FLAG_NEEDVIDINFO 0x00000004 -#define XEN_MULTIBOOT_FLAG_ADDRSVALID 0x00010000 -#define XEN_MULTIBOOT_FLAG_PAE_SHIFT 14 -#define XEN_MULTIBOOT_FLAG_PAE_MASK (3 << XEN_MULTIBOOT_FLAG_PAE_SHIFT) - -/* Flags we test for */ -#define FLAGS_MASK ((~ 0) & (~ XEN_MULTIBOOT_FLAG_ALIGN4K) & \ - (~ XEN_MULTIBOOT_FLAG_PAE_MASK)) -#define FLAGS_REQUIRED XEN_MULTIBOOT_FLAG_ADDRSVALID - -/* --------------------------------------------------------------------- */ - -static struct xen_bin_image_table *find_table(struct xc_dom_image *dom) -{ - struct xen_bin_image_table *table; - uint32_t *probe_ptr; - uint32_t *probe_end; - - if ( dom->kernel_size < sizeof(*table) ) - return NULL; - probe_ptr = dom->kernel_blob; - if ( dom->kernel_size > (8192 + sizeof(*table)) ) - probe_end = dom->kernel_blob + 8192; - else - probe_end = dom->kernel_blob + dom->kernel_size - sizeof(*table); - - for ( table = NULL; probe_ptr < probe_end; probe_ptr++ ) - { - if ( *probe_ptr == XEN_MULTIBOOT_MAGIC3 ) - { - table = (struct xen_bin_image_table *) probe_ptr; - /* Checksum correct? */ - if ( (table->magic + table->flags + table->checksum) == 0 ) - return table; - } - } - return NULL; -} - -static int xc_dom_probe_bin_kernel(struct xc_dom_image *dom) -{ - return find_table(dom) ? 0 : -EINVAL; -} - -static int xc_dom_parse_bin_kernel(struct xc_dom_image *dom) -{ - struct xen_bin_image_table *image_info; - char *image = dom->kernel_blob; - size_t image_size = dom->kernel_size; - uint32_t start_addr; - uint32_t load_end_addr; - uint32_t bss_end_addr; - uint32_t pae_flags; - - image_info = find_table(dom); - if ( !image_info ) - return -EINVAL; - - DOMPRINTF("%s: multiboot header fields", __FUNCTION__); - DOMPRINTF(" flags: 0x%" PRIx32 "", image_info->flags); - DOMPRINTF(" header_addr: 0x%" PRIx32 "", image_info->header_addr); - DOMPRINTF(" load_addr: 0x%" PRIx32 "", image_info->load_addr); - DOMPRINTF(" load_end_addr: 0x%" PRIx32 "", image_info->load_end_addr); - DOMPRINTF(" bss_end_addr: 0x%" PRIx32 "", image_info->bss_end_addr); - DOMPRINTF(" entry_addr: 0x%" PRIx32 "", image_info->entry_addr); - - /* Check the flags */ - if ( (image_info->flags & FLAGS_MASK) != FLAGS_REQUIRED ) - { - xc_dom_panic(dom->xch, XC_INVALID_KERNEL, - "%s: xen_bin_image_table flags required " - "0x%08" PRIx32 " found 0x%08" PRIx32 "", - __FUNCTION__, FLAGS_REQUIRED, image_info->flags & FLAGS_MASK); - return -EINVAL; - } - - /* Sanity check on the addresses */ - if ( (image_info->header_addr < image_info->load_addr) || - ((char *) image_info - image) < - (image_info->header_addr - image_info->load_addr) ) - { - xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: Invalid header_addr.", - __FUNCTION__); - return -EINVAL; - } - - start_addr = image_info->header_addr - ((char *)image_info - image); - load_end_addr = image_info->load_end_addr ?: start_addr + image_size; - bss_end_addr = image_info->bss_end_addr ?: load_end_addr; - - DOMPRINTF("%s: calculated addresses", __FUNCTION__); - DOMPRINTF(" start_addr: 0x%" PRIx32 "", start_addr); - DOMPRINTF(" load_end_addr: 0x%" PRIx32 "", load_end_addr); - DOMPRINTF(" bss_end_addr: 0x%" PRIx32 "", bss_end_addr); - - if ( (start_addr + image_size) < load_end_addr ) - { - xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: Invalid load_end_addr.", - __FUNCTION__); - return -EINVAL; - } - - if ( bss_end_addr < load_end_addr) - { - xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: Invalid bss_end_addr.", - __FUNCTION__); - return -EINVAL; - } - - dom->kernel_seg.vstart = image_info->load_addr; - dom->kernel_seg.vend = bss_end_addr; - dom->parms.virt_base = start_addr; - dom->parms.virt_entry = image_info->entry_addr; - - pae_flags = image_info->flags & XEN_MULTIBOOT_FLAG_PAE_MASK; - switch (pae_flags >> XEN_MULTIBOOT_FLAG_PAE_SHIFT) { - case 0: - dom->guest_type = "xen-3.0-x86_32"; - break; - case 1: - dom->guest_type = "xen-3.0-x86_32p"; - break; - case 2: - dom->guest_type = "xen-3.0-x86_64"; - break; - case 3: - /* Kernel detects PAE at runtime. So try to figure whenever - * xen supports PAE and advertise a PAE-capable kernel in case - * it does. */ - dom->guest_type = "xen-3.0-x86_32"; - if ( strstr(dom->xen_caps, "xen-3.0-x86_32p") ) - { - DOMPRINTF("%s: PAE fixup", __FUNCTION__); - dom->guest_type = "xen-3.0-x86_32p"; - dom->parms.pae = XEN_PAE_EXTCR3; - } - break; - } - return 0; -} - -static int xc_dom_load_bin_kernel(struct xc_dom_image *dom) -{ - struct xen_bin_image_table *image_info; - char *image = dom->kernel_blob; - char *dest; - size_t image_size = dom->kernel_size; - size_t dest_size; - uint32_t start_addr; - uint32_t load_end_addr; - uint32_t bss_end_addr; - uint32_t skip, text_size, bss_size; - - image_info = find_table(dom); - if ( !image_info ) - return -EINVAL; - - start_addr = image_info->header_addr - ((char *)image_info - image); - load_end_addr = image_info->load_end_addr ?: start_addr + image_size; - bss_end_addr = image_info->bss_end_addr ?: load_end_addr; - - /* It's possible that we need to skip the first part of the image */ - skip = image_info->load_addr - start_addr; - text_size = load_end_addr - image_info->load_addr; - bss_size = bss_end_addr - load_end_addr; - - DOMPRINTF("%s: calculated sizes", __FUNCTION__); - DOMPRINTF(" skip: 0x%" PRIx32 "", skip); - DOMPRINTF(" text_size: 0x%" PRIx32 "", text_size); - DOMPRINTF(" bss_size: 0x%" PRIx32 "", bss_size); - - dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart, &dest_size); - if ( dest == NULL ) - { - DOMPRINTF("%s: xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart)" - " => NULL", __FUNCTION__); - return -EINVAL; - } - - if ( dest_size < text_size || - dest_size - text_size < bss_size ) - { - DOMPRINTF("%s: mapped region is too small for image", __FUNCTION__); - return -EINVAL; - } - - if ( image_size < skip || - image_size - skip < text_size ) - { - DOMPRINTF("%s: image is too small for declared text size", - __FUNCTION__); - return -EINVAL; - } - - memcpy(dest, image + skip, text_size); - memset(dest + text_size, 0, bss_size); - - return 0; -} - -/* ------------------------------------------------------------------------ */ - -static struct xc_dom_loader bin_loader = { - .name = "multiboot-binary", - .probe = xc_dom_probe_bin_kernel, - .parser = xc_dom_parse_bin_kernel, - .loader = xc_dom_load_bin_kernel, -}; - -static void __init register_loader(void) -{ - xc_dom_register_loader(&bin_loader); -} - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c deleted file mode 100644 index bb599b33ba..0000000000 --- a/tools/libxc/xc_dom_boot.c +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Xen domain builder -- xen booter. - * - * This is the code which actually boots a fresh - * prepared domain image as xen guest domain. - * - * ==> this is the only domain builder code piece - * where xen hypercalls are allowed <== - * - * 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. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; If not, see <http://www.gnu.org/licenses/>. - * - * written 2006 by Gerd Hoffmann <kraxel@xxxxxxx>. - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> -#include <zlib.h> - -#include "xg_private.h" -#include "xc_dom.h" -#include "xc_core.h" -#include <xen/hvm/params.h> -#include <xen/grant_table.h> - -/* ------------------------------------------------------------------------ */ - -static int setup_hypercall_page(struct xc_dom_image *dom) -{ - DECLARE_DOMCTL; - xen_pfn_t pfn; - int rc; - - if ( dom->parms.virt_hypercall == -1 ) - return 0; - pfn = (dom->parms.virt_hypercall - dom->parms.virt_base) - >> XC_DOM_PAGE_SHIFT(dom); - - DOMPRINTF("%s: vaddr=0x%" PRIx64 " pfn=0x%" PRIpfn "", __FUNCTION__, - dom->parms.virt_hypercall, pfn); - domctl.cmd = XEN_DOMCTL_hypercall_init; - domctl.domain = dom->guest_domid; - domctl.u.hypercall_init.gmfn = xc_dom_p2m(dom, pfn); - rc = do_domctl(dom->xch, &domctl); - if ( rc != 0 ) - xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, - "%s: HYPERCALL_INIT failed: %d - %s)", - __FUNCTION__, errno, strerror(errno)); - return rc; -} - - -/* ------------------------------------------------------------------------ */ - -int xc_dom_compat_check(struct xc_dom_image *dom) -{ - xen_capabilities_info_t xen_caps; - char *item, *ptr; - int match, found = 0; - - strncpy(xen_caps, dom->xen_caps, XEN_CAPABILITIES_INFO_LEN - 1); - xen_caps[XEN_CAPABILITIES_INFO_LEN - 1] = '\0'; - - for ( item = strtok_r(xen_caps, " ", &ptr); - item != NULL ; item = strtok_r(NULL, " ", &ptr) ) - { - match = !strcmp(dom->guest_type, item); - DOMPRINTF("%s: supported guest type: %s%s", __FUNCTION__, - item, match ? " <= matches" : ""); - if ( match ) - found++; - } - if ( !found ) - xc_dom_panic(dom->xch, XC_INVALID_KERNEL, - "%s: guest type %s not supported by xen kernel, sorry", - __FUNCTION__, dom->guest_type); - - return found; -} - -int xc_dom_boot_xen_init(struct xc_dom_image *dom, xc_interface *xch, uint32_t domid) -{ - dom->xch = xch; - dom->guest_domid = domid; - - dom->xen_version = xc_version(xch, XENVER_version, NULL); - if ( xc_version(xch, XENVER_capabilities, &dom->xen_caps) < 0 ) - { - xc_dom_panic(xch, XC_INTERNAL_ERROR, "can't get xen capabilities"); - return -1; - } - DOMPRINTF("%s: ver %d.%d, caps %s", __FUNCTION__, - dom->xen_version >> 16, dom->xen_version & 0xff, - dom->xen_caps); - return 0; -} - -int xc_dom_boot_mem_init(struct xc_dom_image *dom) -{ - long rc; - - DOMPRINTF_CALLED(dom->xch); - - rc = dom->arch_hooks->meminit(dom); - if ( rc != 0 ) - { - xc_dom_panic(dom->xch, XC_OUT_OF_MEMORY, - "%s: can't allocate low memory for domain", - __FUNCTION__); - return rc; - } - - return 0; -} - -void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn, - xen_pfn_t count) -{ - int page_shift = XC_DOM_PAGE_SHIFT(dom); - privcmd_mmap_entry_t *entries; - void *ptr; - int i; - int err; - - entries = xc_dom_malloc(dom, count * sizeof(privcmd_mmap_entry_t)); - if ( entries == NULL ) - { - xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, - "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn - " [malloc]", __FUNCTION__, pfn, count); - return NULL; - } - - for ( i = 0; i < count; i++ ) - entries[i].mfn = xc_dom_p2m(dom, pfn + i); - - ptr = xc_map_foreign_ranges(dom->xch, dom->guest_domid, - count << page_shift, PROT_READ | PROT_WRITE, 1 << page_shift, - entries, count); - if ( ptr == NULL ) - { - err = errno; - xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, - "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn - " [mmap, errno=%i (%s)]", __FUNCTION__, pfn, count, - err, strerror(err)); - return NULL; - } - - return ptr; -} - -int xc_dom_boot_image(struct xc_dom_image *dom) -{ - xc_dominfo_t info; - int rc; - - DOMPRINTF_CALLED(dom->xch); - - /* misc stuff*/ - if ( (rc = dom->arch_hooks->bootearly(dom)) != 0 ) - return rc; - - /* collect some info */ - rc = xc_domain_getinfo(dom->xch, dom->guest_domid, 1, &info); - if ( rc < 0 ) - { - xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, - "%s: getdomaininfo failed (rc=%d)", __FUNCTION__, rc); - return rc; - } - if ( rc == 0 || info.domid != dom->guest_domid ) - { - xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, - "%s: Huh? No domains found (nr_domains=%d) " - "or domid mismatch (%d != %d)", __FUNCTION__, - rc, info.domid, dom->guest_domid); - return -1; - } - dom->shared_info_mfn = info.shared_info_frame; - - /* sanity checks */ - if ( !xc_dom_compat_check(dom) ) - return -1; - - /* initial mm setup */ - if ( dom->arch_hooks->setup_pgtables && - (rc = dom->arch_hooks->setup_pgtables(dom)) != 0 ) - return rc; - - /* start info page */ - if ( dom->arch_hooks->start_info ) - dom->arch_hooks->start_info(dom); - - /* hypercall page */ - if ( (rc = setup_hypercall_page(dom)) != 0 ) - return rc; - xc_dom_log_memory_footprint(dom); - - /* misc x86 stuff */ - if ( (rc = dom->arch_hooks->bootlate(dom)) != 0 ) - return rc; - - /* let the vm run */ - if ( (rc = dom->arch_hooks->vcpu(dom)) != 0 ) - return rc; - xc_dom_unmap_all(dom); - - return rc; -} - -static xen_pfn_t xc_dom_gnttab_setup(xc_interface *xch, uint32_t domid) -{ - gnttab_setup_table_t setup; - DECLARE_HYPERCALL_BUFFER(xen_pfn_t, gmfnp); - int rc; - xen_pfn_t gmfn; - - gmfnp = xc_hypercall_buffer_alloc(xch, gmfnp, sizeof(*gmfnp)); - if (gmfnp == NULL) - return -1; - - setup.dom = domid; - setup.nr_frames = 1; - set_xen_guest_handle(setup.frame_list, gmfnp); - setup.status = 0; - - rc = xc_gnttab_op(xch, GNTTABOP_setup_table, &setup, sizeof(setup), 1); - gmfn = *gmfnp; - xc_hypercall_buffer_free(xch, gmfnp); - - if ( rc != 0 || setup.status != GNTST_okay ) - { - xc_dom_panic(xch, XC_INTERNAL_ERROR, - "%s: failed to setup domU grant table " - "[errno=%d, status=%" PRId16 "]\n", - __FUNCTION__, rc != 0 ? errno : 0, setup.status); - return -1; - } - - return gmfn; -} - -static void xc_dom_set_gnttab_entry(xc_interface *xch, - grant_entry_v1_t *gnttab, - unsigned int idx, - uint32_t guest_domid, - uint32_t backend_domid, - xen_pfn_t guest_gfn) -{ - if ( guest_domid == backend_domid || guest_gfn == -1 ) - return; - - xc_dom_printf(xch, "%s: d%d gnt[%u] -> d%d 0x%"PRI_xen_pfn, - __func__, guest_domid, idx, backend_domid, guest_gfn); - - gnttab[idx].flags = GTF_permit_access; - gnttab[idx].domid = backend_domid; - gnttab[idx].frame = guest_gfn; -} - -static int compat_gnttab_seed(xc_interface *xch, uint32_t domid, - xen_pfn_t console_gfn, - xen_pfn_t xenstore_gfn, - uint32_t console_domid, - uint32_t xenstore_domid) -{ - - xen_pfn_t gnttab_gfn; - grant_entry_v1_t *gnttab; - - gnttab_gfn = xc_dom_gnttab_setup(xch, domid); - if ( gnttab_gfn == -1 ) - return -1; - - gnttab = xc_map_foreign_range(xch, - domid, - PAGE_SIZE, - PROT_READ|PROT_WRITE, - gnttab_gfn); - if ( gnttab == NULL ) - { - xc_dom_panic(xch, XC_INTERNAL_ERROR, - "%s: failed to map d%d grant table " - "[errno=%d]\n", - __func__, domid, errno); - return -1; - } - - xc_dom_set_gnttab_entry(xch, gnttab, GNTTAB_RESERVED_CONSOLE, - domid, console_domid, console_gfn); - xc_dom_set_gnttab_entry(xch, gnttab, GNTTAB_RESERVED_XENSTORE, - domid, xenstore_domid, xenstore_gfn); - - if ( munmap(gnttab, PAGE_SIZE) == -1 ) - { - xc_dom_panic(xch, XC_INTERNAL_ERROR, - "%s: failed to unmap d%d grant table " - "[errno=%d]\n", - __func__, domid, errno); - return -1; - } - - /* Guest shouldn't really touch its grant table until it has - * enabled its caches. But lets be nice. */ - xc_domain_cacheflush(xch, domid, gnttab_gfn, 1); - - return 0; -} - -static int compat_gnttab_hvm_seed(xc_interface *xch, uint32_t domid, - xen_pfn_t console_gfn, - xen_pfn_t xenstore_gfn, - uint32_t console_domid, - uint32_t xenstore_domid) -{ - int rc; - xen_pfn_t scratch_gfn; - struct xen_add_to_physmap xatp = { - .domid = domid, - .space = XENMAPSPACE_grant_table, - .idx = 0, - }; - struct xen_remove_from_physmap xrfp = { - .domid = domid, - }; - - rc = xc_core_arch_get_scratch_gpfn(xch, domid, &scratch_gfn); - if ( rc < 0 ) - { - xc_dom_panic(xch, XC_INTERNAL_ERROR, - "%s: failed to get a scratch gfn from d%d" - "[errno=%d]\n", - __func__, domid, errno); - return -1; - } - xatp.gpfn = scratch_gfn; - xrfp.gpfn = scratch_gfn; - - xc_dom_printf(xch, "%s: d%d: pfn=0x%"PRI_xen_pfn, __func__, - domid, scratch_gfn); - - rc = do_memory_op(xch, XENMEM_add_to_physmap, &xatp, sizeof(xatp)); - if ( rc != 0 ) - { - xc_dom_panic(xch, XC_INTERNAL_ERROR, - "%s: failed to add gnttab to d%d physmap " - "[errno=%d]\n", - __func__, domid, errno); - return -1; - } - - rc = compat_gnttab_seed(xch, domid, - console_gfn, xenstore_gfn, - console_domid, xenstore_domid); - if (rc != 0) - { - xc_dom_panic(xch, XC_INTERNAL_ERROR, - "%s: failed to seed gnttab entries for d%d\n", - __func__, domid); - (void) do_memory_op(xch, XENMEM_remove_from_physmap, &xrfp, - sizeof(xrfp)); - return -1; - } - - rc = do_memory_op(xch, XENMEM_remove_from_physmap, &xrfp, sizeof(xrfp)); - if (rc != 0) - { - xc_dom_panic(xch, XC_INTERNAL_ERROR, - "%s: failed to remove gnttab from d%d physmap " - "[errno=%d]\n", - __func__, domid, errno); - return -1; - } - - return 0; -} - -int xc_dom_gnttab_seed(xc_interface *xch, uint32_t guest_domid, - bool is_hvm, xen_pfn_t console_gfn, - xen_pfn_t xenstore_gfn, uint32_t console_domid, - uint32_t xenstore_domid) -{ - xenforeignmemory_handle* fmem = xch->fmem; - xenforeignmemory_resource_handle *fres; - void *addr = NULL; - - fres = xenforeignmemory_map_resource( - fmem, guest_domid, XENMEM_resource_grant_table, - XENMEM_resource_grant_table_id_shared, 0, 1, &addr, - PROT_READ | PROT_WRITE, 0); - if ( !fres ) - { - if ( errno == EOPNOTSUPP ) - return is_hvm ? - compat_gnttab_hvm_seed(xch, guest_domid, - console_gfn, xenstore_gfn, - console_domid, xenstore_domid) : - compat_gnttab_seed(xch, guest_domid, - console_gfn, xenstore_gfn, - console_domid, xenstore_domid); - - xc_dom_panic(xch, XC_INTERNAL_ERROR, - "%s: failed to acquire d%d grant table [errno=%d]\n", - __func__, guest_domid, errno); - return -1; - } - - xc_dom_set_gnttab_entry(xch, addr, GNTTAB_RESERVED_CONSOLE, - guest_domid, console_domid, console_gfn); - xc_dom_set_gnttab_entry(xch, addr, GNTTAB_RESERVED_XENSTORE, - guest_domid, xenstore_domid, xenstore_gfn); - - xenforeignmemory_unmap_resource(fmem, fres); - - return 0; -} - -int xc_dom_gnttab_init(struct xc_dom_image *dom) -{ - bool is_hvm = xc_dom_translated(dom); - xen_pfn_t console_gfn = xc_dom_p2m(dom, dom->console_pfn); - xen_pfn_t xenstore_gfn = xc_dom_p2m(dom, dom->xenstore_pfn); - - return xc_dom_gnttab_seed(dom->xch, dom->guest_domid, is_hvm, - console_gfn, xenstore_gfn, - dom->console_domid, dom->xenstore_domid); -} - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/tools/libxc/xc_dom_bzimageloader.c b/tools/libxc/xc_dom_bzimageloader.c deleted file mode 100644 index a7d70cc7c6..0000000000 --- a/tools/libxc/xc_dom_bzimageloader.c +++ /dev/null @@ -1,812 +0,0 @@ -/* - * Xen domain builder -- bzImage bits - * - * Parse and load bzImage kernel images. - * - * This relies on version 2.08 of the boot protocol, which contains an - * ELF file embedded in the bzImage. The loader extracts this ELF - * image and passes it off to the standard ELF loader. - * - * 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. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; If not, see <http://www.gnu.org/licenses/>. - * - * written 2006 by Gerd Hoffmann <kraxel@xxxxxxx>. - * written 2007 by Jeremy Fitzhardinge <jeremy@xxxxxxxxxxxxx> - * written 2008 by Ian Campbell <ijc@xxxxxxxxxxxxxx> - * written 2009 by Chris Lalancette <clalance@xxxxxxxxxx> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <inttypes.h> - -#include "xg_private.h" -#include "xc_dom_decompress.h" - -#include <xen-tools/libs.h> - -#ifndef __MINIOS__ - -#if defined(HAVE_BZLIB) - -#include <bzlib.h> - -static int xc_try_bzip2_decode( - struct xc_dom_image *dom, void **blob, size_t *size) -{ - bz_stream stream; - int ret; - char *out_buf; - char *tmp_buf; - int retval = -1; - unsigned int outsize; - uint64_t total; - - stream.bzalloc = NULL; - stream.bzfree = NULL; - stream.opaque = NULL; - - if ( dom->kernel_size == 0) - { - DOMPRINTF("BZIP2: Input is 0 size"); - return -1; - } - - ret = BZ2_bzDecompressInit(&stream, 0, 0); - if ( ret != BZ_OK ) - { - DOMPRINTF("BZIP2: Error initting stream"); - return -1; - } - - /* sigh. We don't know up-front how much memory we are going to need - * for the output buffer. Allocate the output buffer to be equal - * the input buffer to start, and we'll realloc as needed. - */ - outsize = dom->kernel_size; - - /* - * stream.avail_in and outsize are unsigned int, while kernel_size - * is a size_t. Check we aren't overflowing. - */ - if ( outsize != dom->kernel_size ) - { - DOMPRINTF("BZIP2: Input too large"); - goto bzip2_cleanup; - } - - out_buf = malloc(outsize); - if ( out_buf == NULL ) - { - DOMPRINTF("BZIP2: Failed to alloc memory"); - goto bzip2_cleanup; - } - - stream.next_in = dom->kernel_blob; - stream.avail_in = dom->kernel_size; - - stream.next_out = out_buf; - stream.avail_out = dom->kernel_size; - - for ( ; ; ) - { - ret = BZ2_bzDecompress(&stream); - if ( ret == BZ_STREAM_END ) - { - DOMPRINTF("BZIP2: Saw data stream end"); - retval = 0; - break; - } - if ( ret != BZ_OK ) - { - DOMPRINTF("BZIP2: error %d", ret); - free(out_buf); - goto bzip2_cleanup; - } - - if ( stream.avail_out == 0 ) - { - /* Protect against output buffer overflow */ - if ( outsize > UINT_MAX / 2 ) - { - DOMPRINTF("BZIP2: output buffer overflow"); - free(out_buf); - goto bzip2_cleanup; - } - - if ( xc_dom_kernel_check_size(dom, outsize * 2) ) - { - DOMPRINTF("BZIP2: output too large"); - free(out_buf); - goto bzip2_cleanup; - } - - tmp_buf = realloc(out_buf, outsize * 2); - if ( tmp_buf == NULL ) - { - DOMPRINTF("BZIP2: Failed to realloc memory"); - free(out_buf); - goto bzip2_cleanup; - } - out_buf = tmp_buf; - - stream.next_out = out_buf + outsize; - stream.avail_out = (outsize * 2) - outsize; - outsize *= 2; - } - else if ( stream.avail_in == 0 ) - { - /* - * If there is output buffer available then this indicates - * that BZ2_bzDecompress would like more input data to be - * provided. However our complete input buffer is in - * memory and provided upfront so if avail_in is zero this - * actually indicates a truncated input. - */ - DOMPRINTF("BZIP2: not enough input"); - free(out_buf); - goto bzip2_cleanup; - } - } - - total = (((uint64_t)stream.total_out_hi32) << 32) | stream.total_out_lo32; - - if ( xc_dom_register_external(dom, out_buf, total) ) - { - DOMPRINTF("BZIP2: Error registering stream output"); - free(out_buf); - goto bzip2_cleanup; - } - - DOMPRINTF("%s: BZIP2 decompress OK, 0x%zx -> 0x%lx", - __FUNCTION__, *size, (long unsigned int) total); - - *blob = out_buf; - *size = total; - - bzip2_cleanup: - BZ2_bzDecompressEnd(&stream); - - return retval; -} - -#else /* !defined(HAVE_BZLIB) */ - -static int xc_try_bzip2_decode( - struct xc_dom_image *dom, void **blob, size_t *size) -{ - xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, - "%s: BZIP2 decompress support unavailable", - __FUNCTION__); - return -1; -} - -#endif - -#if defined(HAVE_LZMA) - -#include <lzma.h> - -static int _xc_try_lzma_decode( - struct xc_dom_image *dom, void **blob, size_t *size, - lzma_stream *stream, const char *what) -{ - lzma_ret ret; - lzma_action action = LZMA_RUN; - unsigned char *out_buf; - unsigned char *tmp_buf; - int retval = -1; - size_t outsize; - const char *msg; - - if ( dom->kernel_size == 0) - { - DOMPRINTF("%s: Input is 0 size", what); - return -1; - } - - /* sigh. We don't know up-front how much memory we are going to need - * for the output buffer. Allocate the output buffer to be equal - * the input buffer to start, and we'll realloc as needed. - */ - outsize = dom->kernel_size; - out_buf = malloc(outsize); - if ( out_buf == NULL ) - { - DOMPRINTF("%s: Failed to alloc memory", what); - goto lzma_cleanup; - } - - stream->next_in = dom->kernel_blob; - stream->avail_in = dom->kernel_size; - - stream->next_out = out_buf; - stream->avail_out = dom->kernel_size; - - for ( ; ; ) - { - ret = lzma_code(stream, action); - if ( ret == LZMA_STREAM_END ) - { - DOMPRINTF("%s: Saw data stream end", what); - retval = 0; - break; - } - if ( ret != LZMA_OK ) - { - switch ( ret ) - { - case LZMA_MEM_ERROR: - msg = strerror(ENOMEM); - break; - - case LZMA_MEMLIMIT_ERROR: - msg = "Memory usage limit reached"; - break; - - case LZMA_FORMAT_ERROR: - msg = "File format not recognized"; - break; - - case LZMA_OPTIONS_ERROR: - // FIXME: Better message? - msg = "Unsupported compression options"; - break; - - case LZMA_DATA_ERROR: - msg = "File is corrupt"; - break; - - case LZMA_BUF_ERROR: - msg = "Unexpected end of input"; - break; - - default: - msg = "Internal program error (bug)"; - break; - } - DOMPRINTF("%s: %s decompression error: %s", - __FUNCTION__, what, msg); - free(out_buf); - goto lzma_cleanup; - } - - if ( stream->avail_out == 0 ) - { - /* Protect against output buffer overflow */ - if ( outsize > SIZE_MAX / 2 ) - { - DOMPRINTF("%s: output buffer overflow", what); - free(out_buf); - goto lzma_cleanup; - } - - if ( xc_dom_kernel_check_size(dom, outsize * 2) ) - { - DOMPRINTF("%s: output too large", what); - free(out_buf); - goto lzma_cleanup; - } - - tmp_buf = realloc(out_buf, outsize * 2); - if ( tmp_buf == NULL ) - { - DOMPRINTF("%s: Failed to realloc memory", what); - free(out_buf); - goto lzma_cleanup; - } - out_buf = tmp_buf; - - stream->next_out = out_buf + outsize; - stream->avail_out = (outsize * 2) - outsize; - outsize *= 2; - } - } - - if ( xc_dom_register_external(dom, out_buf, stream->total_out) ) - { - DOMPRINTF("%s: Error registering stream output", what); - free(out_buf); - goto lzma_cleanup; - } - - DOMPRINTF("%s: %s decompress OK, 0x%zx -> 0x%zx", - __FUNCTION__, what, *size, (size_t)stream->total_out); - - *blob = out_buf; - *size = stream->total_out; - - lzma_cleanup: - lzma_end(stream); - - return retval; -} - -/* 128 Mb is the minimum size (half-way) documented to work for all inputs. */ -#define LZMA_BLOCK_SIZE (128*1024*1024) - -static int xc_try_xz_decode( - struct xc_dom_image *dom, void **blob, size_t *size) -{ - lzma_stream stream = LZMA_STREAM_INIT; - - if ( lzma_stream_decoder(&stream, LZMA_BLOCK_SIZE, 0) != LZMA_OK ) - { - DOMPRINTF("XZ: Failed to init decoder"); - return -1; - } - - return _xc_try_lzma_decode(dom, blob, size, &stream, "XZ"); -} - -static int xc_try_lzma_decode( - struct xc_dom_image *dom, void **blob, size_t *size) -{ - lzma_stream stream = LZMA_STREAM_INIT; - - if ( lzma_alone_decoder(&stream, LZMA_BLOCK_SIZE) != LZMA_OK ) - { - DOMPRINTF("LZMA: Failed to init decoder"); - return -1; - } - - return _xc_try_lzma_decode(dom, blob, size, &stream, "LZMA"); -} - -#else /* !defined(HAVE_LZMA) */ - -static int xc_try_xz_decode( - struct xc_dom_image *dom, void **blob, size_t *size) -{ - xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, - "%s: XZ decompress support unavailable", - __FUNCTION__); - return -1; -} - -static int xc_try_lzma_decode( - struct xc_dom_image *dom, void **blob, size_t *size) -{ - xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, - "%s: LZMA decompress support unavailable", - __FUNCTION__); - return -1; -} - -#endif - -#if defined(HAVE_LZO1X) - -#include <lzo/lzo1x.h> - -#define LZOP_HEADER_HAS_FILTER 0x00000800 -#define LZOP_MAX_BLOCK_SIZE (64*1024*1024) - -static inline uint_fast16_t lzo_read_16(const unsigned char *buf) -{ - return buf[1] | (buf[0] << 8); -} - -static inline uint_fast32_t lzo_read_32(const unsigned char *buf) -{ - return lzo_read_16(buf + 2) | ((uint32_t)lzo_read_16(buf) << 16); -} - -static int xc_try_lzo1x_decode( - struct xc_dom_image *dom, void **blob, size_t *size) -{ - int ret; - const unsigned char *cur = dom->kernel_blob; - unsigned char *out_buf = NULL; - size_t left = dom->kernel_size; - const char *msg; - unsigned version; - static const unsigned char magic[] = { - 0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a - }; - - /* - * lzo_uint should match size_t. Check that this is the case to be - * sure we won't overflow various lzo_uint fields. - */ - BUILD_BUG_ON(sizeof(lzo_uint) != sizeof(size_t)); - - ret = lzo_init(); - if ( ret != LZO_E_OK ) - { - DOMPRINTF("LZO1x: Failed to init library (%d)\n", ret); - return -1; - } - - if ( left < 16 || memcmp(cur, magic, 9) ) - { - DOMPRINTF("LZO1x: Unrecognized magic\n"); - return -1; - } - - /* get version (2bytes), skip library version (2), - * 'need to be extracted' version (2) and method (1) */ - version = lzo_read_16(cur + 9); - cur += 16; - left -= 16; - - if ( version >= 0x0940 ) - { - /* skip level */ - ++cur; - if ( left ) - --left; - } - - if ( left >= 4 && (lzo_read_32(cur) & LZOP_HEADER_HAS_FILTER) ) - ret = 8; /* flags + filter info */ - else - ret = 4; /* flags */ - - /* skip mode and mtime_low */ - ret += 8; - if ( version >= 0x0940 ) - ret += 4; /* skip mtime_high */ - - /* don't care about the file name, and skip checksum */ - if ( left > ret ) - ret += 1 + cur[ret] + 4; - - if ( left < ret ) - { - DOMPRINTF("LZO1x: Incomplete header\n"); - return -1; - } - cur += ret; - left -= ret; - - for ( *size = 0; ; ) - { - lzo_uint src_len, dst_len, out_len; - unsigned char *tmp_buf; - - msg = "Short input"; - if ( left < 4 ) - break; - - dst_len = lzo_read_32(cur); - if ( !dst_len ) - { - msg = "Error registering stream output"; - if ( xc_dom_register_external(dom, out_buf, *size) ) - break; - - return 0; - } - - if ( dst_len > LZOP_MAX_BLOCK_SIZE ) - { - msg = "Block size too large"; - break; - } - - if ( left < 12 ) - break; - - src_len = lzo_read_32(cur + 4); - cur += 12; /* also skip block checksum info */ - left -= 12; - - msg = "Bad source length"; - if ( src_len <= 0 || src_len > dst_len || src_len > left ) - break; - - msg = "Output buffer overflow"; - if ( *size > SIZE_MAX - dst_len ) - break; - - msg = "Decompressed image too large"; - if ( xc_dom_kernel_check_size(dom, *size + dst_len) ) - break; - - msg = "Failed to (re)alloc memory"; - tmp_buf = realloc(out_buf, *size + dst_len); - if ( tmp_buf == NULL ) - break; - - out_buf = tmp_buf; - out_len = dst_len; - - ret = lzo1x_decompress_safe(cur, src_len, - out_buf + *size, &out_len, NULL); - switch ( ret ) - { - case LZO_E_OK: - msg = "Input underrun"; - if ( out_len != dst_len ) - break; - - *blob = out_buf;
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |