From 3942e3ccff0f270c39f90f113cc632c4cc21a3bc Mon Sep 17 00:00:00 2001 From: Dmytro Firsov Date: Thu, 27 Apr 2023 12:35:25 +0300 Subject: [PATCH] xen: add helper functions for Xen domain memory management Add wrapper functions for Xen memory managment hypercall. They can be used for unprivilaged Zephyr guest initialization and for domain management, when Zephyr is used as Xen Domain 0. Signed-off-by: Dmytro Firsov --- drivers/xen/CMakeLists.txt | 1 + drivers/xen/memory.c | 68 +++++++++++++++++++++++++++++++++++++ include/zephyr/xen/memory.h | 66 +++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 drivers/xen/memory.c create mode 100644 include/zephyr/xen/memory.h diff --git a/drivers/xen/CMakeLists.txt b/drivers/xen/CMakeLists.txt index 350c6d577b..412be7d318 100644 --- a/drivers/xen/CMakeLists.txt +++ b/drivers/xen/CMakeLists.txt @@ -4,5 +4,6 @@ zephyr_sources(hvm.c) zephyr_sources(events.c) zephyr_sources_ifdef(CONFIG_XEN_GRANT_TABLE gnttab.c) +zephyr_sources(memory.c) add_subdirectory_ifdef(CONFIG_XEN_DOM0 dom0) diff --git a/drivers/xen/memory.c b/drivers/xen/memory.c new file mode 100644 index 0000000000..6472ad74af --- /dev/null +++ b/drivers/xen/memory.c @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright (c) 2023 EPAM Systems + */ + +#include +#include +#include +#include + +#include + +int xendom_add_to_physmap(int domid, unsigned long idx, + unsigned int space, xen_pfn_t gpfn) +{ + struct xen_add_to_physmap xatp = { + .domid = domid, + .idx = idx, + .space = space, + .gpfn = gpfn, + }; + + return HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp); +} + +int xendom_add_to_physmap_batch(int domid, int foreign_domid, + unsigned int space, unsigned int size, + xen_ulong_t *idxs, xen_pfn_t *gpfns, int *errs) +{ + struct xen_add_to_physmap_batch xatpb = { + .domid = domid, + .u.foreign_domid = foreign_domid, + .space = space, + .size = size, + }; + + set_xen_guest_handle(xatpb.gpfns, gpfns); + set_xen_guest_handle(xatpb.idxs, idxs); + set_xen_guest_handle(xatpb.errs, errs); + + return HYPERVISOR_memory_op(XENMEM_add_to_physmap_batch, &xatpb); +} + +int xendom_remove_from_physmap(int domid, xen_pfn_t gpfn) +{ + struct xen_remove_from_physmap xrfp = { + .domid = domid, + .gpfn = gpfn, + }; + + return HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrfp); +} + +int xendom_populate_physmap(int domid, unsigned int extent_order, + unsigned int nr_extents, unsigned int mem_flags, + xen_pfn_t *extent_start) +{ + struct xen_memory_reservation reservation = { + .domid = domid, + .extent_order = extent_order, + .nr_extents = nr_extents, + .mem_flags = mem_flags, + }; + + set_xen_guest_handle(reservation.extent_start, extent_start); + + return HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation); +} diff --git a/include/zephyr/xen/memory.h b/include/zephyr/xen/memory.h new file mode 100644 index 0000000000..636f099885 --- /dev/null +++ b/include/zephyr/xen/memory.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright (c) 2023 EPAM Systems + */ + +#include +#include +#include + +/** + * Add mapping for specified page frame in Xen domain physmap. + * + * @param domid domain id, where mapping will be added. For unprivileged should + * be DOMID_SELF. + * @param idx index into space being mapped. + * @param space XENMAPSPACE_* mapping space identifier. + * @param gpfn page frame where the source mapping page should appear. + * @return zero on success, negative errno on error. + */ +int xendom_add_to_physmap(int domid, unsigned long idx, unsigned int space, + xen_pfn_t gpfn); + +/** + * Add mapping for specified set of page frames to Xen domain physmap. + * + * @param domid domain id, where mapping will be added. For unprivileged + * should be DOMID_SELF. + * @param foreign_domid for gmfn_foreign - domain id, whose pages being mapped, + * 0 for other. + * @param space XENMAPSPACE_* mapping space identifier. + * @param size number of page frames being mapped. + * @param idxs array of indexes into space being mapped. + * @param gpfns array of page frames where the mapping should appear. + * @param errs array of per-index error codes. + * @return zero on success, negative errno on error. + */ +int xendom_add_to_physmap_batch(int domid, int foreign_domid, + unsigned int space, unsigned int size, + xen_ulong_t *idxs, xen_pfn_t *gpfns, int *errs); + +/** + * Removes page frame from Xen domain physmap. + * + * @param domid domain id, whose page is going to be removed. For unprivileged + * should be DOMID_SELF. + * @param gpfn page frame number, that needs to be removed + * @return zero on success, negative errno on error. + */ +int xendom_remove_from_physmap(int domid, xen_pfn_t gpfn); + +/** + * Populate specified Xen domain page frames with memory. + * + * @param domid domain id, where mapping will be added. For unprivileged + * should be DOMID_SELF. + * @param extent_order size/alignment of each extent (size is 2^extent_order), + * e.g. 0 for 4K extents, 9 for 2M etc. + * @param nr_extents number of page frames being populated. + * @param mem_flags N/A, should be 0 for Arm. + * @param extent_start page frame bases of extents to populate with memory. + * @return number of populated frames success, negative errno on + * error. + */ +int xendom_populate_physmap(int domid, unsigned int extent_order, + unsigned int nr_extents, unsigned int mem_flags, + xen_pfn_t *extent_start);