#endif
#include <xen/io/9pfs.h>
#include <common/events.h>
-#include <common/gnttab.h>
+#include <uk/xen/gnttab.h>
struct p9front_dev_ring {
/* Backpointer to the p9front device. */
bool "9pfront: Xen 9pfs volumes"
select LIBXENBUS
select LIBXENHEADERS
+ select LIBXENGNTTAB
depends on HAVE_XENBUS
depends on LIBUK9P
help
UK_DRIV_XEN_BASE := $(UK_DRIV_BASE)/xen
$(eval $(call import_lib,$(UK_DRIV_XEN_BASE)/xenheaders))
+$(eval $(call import_lib,$(UK_DRIV_XEN_BASE)/xengnttab))
$(eval $(call import_lib,$(UK_DRIV_XEN_BASE)/9pfront))
$(eval $(call import_lib,$(UK_DRIV_XEN_BASE)/blkfront))
$(eval $(call import_lib,$(UK_DRIV_XEN_BASE)/netfront))
bool "blkfront: Xen block devices"
select LIBXENHEADERS
select LIBXENBUS
+ select LIBXENGNTTAB
depends on HAVE_XENBUS
depends on LIBUKBLKDEV
help
#endif
#include <xen/io/blkif.h>
-#include <common/gnttab.h>
+#include <uk/xen/gnttab.h>
#include <common/events.h>
#define BLK_RING_PAGES_NUM 1
bool "netfront: Xen network interfaces"
select LIBXENHEADERS
select LIBXENBUS
- depends on XEN_GNTTAB
+ select LIBXENGNTTAB
depends on HAVE_XENBUS
depends on LIBUKNETDEV
help
#include <uk/netbuf.h>
#include <uk/semaphore.h>
#include <xen/io/netif.h>
-#include <common/gnttab.h>
+#include <uk/xen/gnttab.h>
#include <common/events.h>
#if defined(__aarch64__)
#include <xen-arm/mm.h>
--- /dev/null
+config LIBXENGNTTAB
+ bool "xengnttab: Xen Grant Table"
+ select LIBXENHEADERS
+ select LIBXENBUS
+ select LIBUKALLOC
+ select LIBUKLOCK
+ select LIBUKLOCK_SEMAPHORE
+ depends on (ARCH_X86_64 || ARCH_ARM_64)
+ depends on HAVE_XENBUS
+ help
+ Support grant table operations
--- /dev/null
+$(eval $(call addlib_s,libxengnttab,$(CONFIG_LIBXENGNTTAB)))
+
+CINCLUDES-$(CONFIG_LIBXENGNTTAB) += -I$(LIBXENGNTTAB_BASE)/include
+
+LIBXENGNTTAB_SRCS-y += $(LIBXENGNTTAB_BASE)/gnttab.c
+LIBXENGNTTAB_SRCS-$(CONFIG_ARCH_X86_64) += $(LIBXENGNTTAB_BASE)/arch/x86_64/gnttab.c|x86_64
+LIBXENGNTTAB_SRCS-$(CONFIG_ARCH_ARM_64) += $(LIBXENGNTTAB_BASE)/arch/arm64/gnttab.c|arm64
--- /dev/null
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/* Taken from Mini-OS */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <uk/print.h>
+#include <xen/memory.h>
+#include <xen/xen.h>
+#include <libfdt.h>
+#include <xen/grant_table.h>
+#include <common/hypervisor.h>
+#include <xen-arm/os.h>
+#include <xen-arm/mm.h>
+
+extern lpae_t fixmap_pgtable[512];
+
+/* Get Xen's suggested physical page assignments for the grant table. */
+static paddr_t get_gnttab_base(void)
+{
+ int hypervisor;
+ int len = 0;
+ const uint64_t *regs;
+ paddr_t gnttab_base;
+
+ hypervisor =
+ fdt_node_offset_by_compatible(HYPERVISOR_dtb, -1, "xen,xen");
+ if (hypervisor < 0)
+ BUG();
+
+ regs = fdt_getprop(HYPERVISOR_dtb, hypervisor, "reg", &len);
+ /* The property contains the address and size, 8-bytes each. */
+ if (regs == NULL || len < 16) {
+ uk_pr_debug("Bad 'reg' property: %p %d\n", regs, len);
+ BUG();
+ }
+
+ gnttab_base = fdt64_ld(regs);
+
+ uk_pr_debug("FDT suggests grant table base %llx\n",
+ (unsigned long long) gnttab_base);
+
+ return gnttab_base;
+}
+
+static paddr_t map_gnttab(paddr_t phys)
+{
+ uk_pr_debug("%s, phys = 0x%lx\n", __func__, phys);
+
+ set_pgt_entry(&fixmap_pgtable[l2_pgt_idx(FIX_GNT_START)],
+ ((phys & L2_MASK) | BLOCK_DEF_ATTR | L2_BLOCK));
+
+ return (paddr_t)(FIX_GNT_START + (phys & L2_OFFSET));
+}
+
+grant_entry_v1_t *gnttab_arch_init(int nr_grant_frames)
+{
+ struct xen_add_to_physmap xatp;
+ paddr_t gnttab_table;
+ int i;
+
+ gnttab_table = get_gnttab_base();
+
+ for (i = 0; i < nr_grant_frames; i++) {
+ xatp.domid = DOMID_SELF;
+ xatp.size = 0; // Seems to be unused
+ xatp.space = XENMAPSPACE_grant_table;
+ xatp.idx = i;
+ xatp.gpfn = (gnttab_table >> PAGE_SHIFT) + i;
+ if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp) != 0)
+ BUG();
+ }
+
+ return (grant_entry_v1_t *)map_gnttab(gnttab_table);
+}
--- /dev/null
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/* Taken from Mini-OS */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <uk/print.h>
+#include <xen/xen.h>
+#include <xen/grant_table.h>
+#include <common/hypervisor.h>
+#include <xen-x86/mm.h>
+
+
+grant_entry_v1_t *gnttab_arch_init(int grant_frames_num)
+{
+ grant_entry_v1_t *gnte = NULL;
+ struct gnttab_setup_table setup;
+ unsigned long frames[grant_frames_num];
+ int rc;
+
+ setup.dom = DOMID_SELF;
+ setup.nr_frames = grant_frames_num;
+ set_xen_guest_handle(setup.frame_list, frames);
+
+ rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
+ if (rc) {
+ uk_pr_err("Hypercall error: %d\n", rc);
+ goto out;
+ }
+ if (setup.status != GNTST_okay) {
+ uk_pr_err("Hypercall status: %d\n", setup.status);
+ goto out;
+ }
+
+ gnte = map_frames(frames, grant_frames_num, ukplat_memallocator_get());
+
+out:
+ return gnte;
+}
--- /dev/null
+gnttab_init
+gnttab_fini
+gnttab_alloc_and_grant
+gnttab_grant_access
+gnttab_grant_transfer
+gnttab_update_grant
+gnttab_end_transfer
+gnttab_end_access
+gnttabop_error
+gnttab_arch_init
--- /dev/null
+/* SPDX-License-Identifier: MIT */
+/*
+ ****************************************************************************
+ * (C) 2006 - Cambridge University
+ ****************************************************************************
+ *
+ * File: gnttab.c
+ * Author: Steven Smith (sos22@cam.ac.uk)
+ * Changes: Grzegorz Milos (gm281@cam.ac.uk)
+ *
+ * Date: July 2006
+ *
+ * Environment: Xen Minimal OS
+ * Description: Simple grant tables implementation. About as stupid as it's
+ * possible to be and still work.
+ *
+ ****************************************************************************
+ */
+#include <stdint.h>
+#include <stddef.h>
+#ifdef DBGGNT
+#include <string.h>
+#endif
+#include <uk/arch/limits.h>
+#include <uk/atomic.h>
+#include <uk/plat/lcpu.h>
+#include <uk/semaphore.h>
+#include <uk/xen/gnttab.h>
+#if defined(__i386__) || defined(__x86_64__)
+#include <xen-x86/mm.h>
+
+#include <xen-x86/hypercall.h>
+#elif defined(__aarch64__)
+#include <xen-arm/mm.h>
+
+#include <xen-arm/hypercall.h>
+#else
+#error "Unsupported architecture"
+#endif
+
+/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
+#define NR_GRANT_FRAMES 4
+#define NR_GRANT_ENTRIES \
+ (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_v1_t))
+
+static struct gnttab {
+ int initialized;
+ struct uk_semaphore sem;
+ grant_entry_v1_t *table;
+ grant_ref_t gref_list[NR_GRANT_ENTRIES];
+#ifdef DBGGNT
+ char inuse[NR_GRANT_ENTRIES];
+#endif
+} gnttab;
+
+
+static grant_ref_t get_free_entry(void)
+{
+ grant_ref_t gref;
+ unsigned long flags;
+
+ uk_semaphore_down(&gnttab.sem);
+
+ flags = ukplat_lcpu_save_irqf();
+
+ gref = gnttab.gref_list[0];
+ UK_ASSERT(gref >= GNTTAB_NR_RESERVED_ENTRIES &&
+ gref < NR_GRANT_ENTRIES);
+ gnttab.gref_list[0] = gnttab.gref_list[gref];
+#ifdef DBGGNT
+ UK_ASSERT(!gnttab.inuse[gref]);
+ gnttab.inuse[gref] = 1;
+#endif
+
+ ukplat_lcpu_restore_irqf(flags);
+
+ return gref;
+}
+
+static void put_free_entry(grant_ref_t gref)
+{
+ unsigned long flags;
+
+ flags = ukplat_lcpu_save_irqf();
+
+#ifdef DBGGNT
+ UK_ASSERT(gnttab.inuse[gref]);
+ gnttab.inuse[gref] = 0;
+#endif
+ gnttab.gref_list[gref] = gnttab.gref_list[0];
+ gnttab.gref_list[0] = gref;
+
+ ukplat_lcpu_restore_irqf(flags);
+
+ uk_semaphore_up(&gnttab.sem);
+}
+
+static void gnttab_grant_init(grant_ref_t gref, domid_t domid,
+ unsigned long mfn)
+{
+ gnttab.table[gref].frame = mfn;
+ gnttab.table[gref].domid = domid;
+
+ /* Memory barrier */
+ wmb();
+}
+
+static void gnttab_grant_permit_access(grant_ref_t gref, domid_t domid,
+ unsigned long mfn, int readonly)
+{
+ gnttab_grant_init(gref, domid, mfn);
+ readonly *= GTF_readonly;
+ gnttab.table[gref].flags = GTF_permit_access | readonly;
+}
+
+grant_ref_t gnttab_grant_access(domid_t domid, unsigned long mfn,
+ int readonly)
+{
+ grant_ref_t gref = get_free_entry();
+
+ gnttab_grant_permit_access(gref, domid, mfn, readonly);
+
+ return gref;
+}
+
+grant_ref_t gnttab_grant_transfer(domid_t domid, unsigned long mfn)
+{
+ grant_ref_t gref = get_free_entry();
+
+ gnttab_grant_init(gref, domid, mfn);
+ gnttab.table[gref].flags = GTF_accept_transfer;
+
+ return gref;
+}
+
+/* Reset flags to zero in order to stop using the grant */
+static int gnttab_reset_flags(grant_ref_t gref)
+{
+ __u16 flags, nflags;
+ __u16 *pflags;
+
+ pflags = &gnttab.table[gref].flags;
+ nflags = *pflags;
+
+ do {
+ if ((flags = nflags) & (GTF_reading | GTF_writing)) {
+ uk_pr_warn("gref=%u still in use! (0x%x)\n",
+ gref, flags);
+ return 0;
+ }
+ } while ((nflags = uk_compare_exchange_sync(pflags, flags, 0))
+ != flags);
+
+ return 1;
+}
+
+int gnttab_update_grant(grant_ref_t gref,
+ domid_t domid, unsigned long mfn,
+ int readonly)
+{
+ int rc;
+
+ UK_ASSERT(gref >= GNTTAB_NR_RESERVED_ENTRIES &&
+ gref < NR_GRANT_ENTRIES);
+
+ rc = gnttab_reset_flags(gref);
+ if (!rc)
+ return rc;
+
+ gnttab_grant_permit_access(gref, domid, mfn, readonly);
+
+ return 1;
+}
+
+int gnttab_end_access(grant_ref_t gref)
+{
+ int rc;
+
+ UK_ASSERT(gref >= GNTTAB_NR_RESERVED_ENTRIES &&
+ gref < NR_GRANT_ENTRIES);
+
+ rc = gnttab_reset_flags(gref);
+ if (!rc)
+ return rc;
+
+ put_free_entry(gref);
+
+ return 1;
+}
+
+unsigned long gnttab_end_transfer(grant_ref_t gref)
+{
+ unsigned long frame;
+ __u16 flags;
+ __u16 *pflags;
+
+ UK_ASSERT(gref >= GNTTAB_NR_RESERVED_ENTRIES &&
+ gref < NR_GRANT_ENTRIES);
+
+ pflags = &gnttab.table[gref].flags;
+ while (!((flags = *pflags) & GTF_transfer_committed)) {
+ if (uk_compare_exchange_sync(pflags, flags, 0) == flags) {
+ uk_pr_info("Release unused transfer grant.\n");
+ put_free_entry(gref);
+ return 0;
+ }
+ }
+
+ /* If a transfer is in progress then wait until it is completed. */
+ while (!(flags & GTF_transfer_completed))
+ flags = *pflags;
+
+ /* Read the frame number /after/ reading completion status. */
+ rmb();
+ frame = gnttab.table[gref].frame;
+
+ put_free_entry(gref);
+
+ return frame;
+}
+
+grant_ref_t gnttab_alloc_and_grant(void **map, struct uk_alloc *a)
+{
+ void *page;
+ unsigned long mfn;
+ grant_ref_t gref;
+
+ UK_ASSERT(map != NULL);
+ UK_ASSERT(a != NULL);
+
+ page = uk_palloc(a, 1);
+ if (page == NULL)
+ return GRANT_INVALID_REF;
+
+ mfn = virt_to_mfn(page);
+ gref = gnttab_grant_access(0, mfn, 0);
+
+ *map = page;
+
+ return gref;
+}
+
+static const char * const gnttabop_error_msgs[] = GNTTABOP_error_msgs;
+
+const char *gnttabop_error(__s16 status)
+{
+ status = -status;
+ if (status < 0 || (__u16) status >= ARRAY_SIZE(gnttabop_error_msgs))
+ return "bad status";
+ else
+ return gnttabop_error_msgs[status];
+}
+
+void gnttab_init(void)
+{
+ grant_ref_t gref;
+
+ UK_ASSERT(gnttab.initialized == 0);
+
+ uk_semaphore_init(&gnttab.sem, 0);
+
+#ifdef DBGGNT
+ memset(gnttab.inuse, 1, sizeof(gnttab.inuse));
+#endif
+ for (gref = GNTTAB_NR_RESERVED_ENTRIES; gref < NR_GRANT_ENTRIES; gref++)
+ put_free_entry(gref);
+
+ gnttab.table = gnttab_arch_init(NR_GRANT_FRAMES);
+ if (gnttab.table == NULL)
+ UK_CRASH("Failed to initialize grant table\n");
+
+ uk_pr_info("Grant table mapped at %p.\n", gnttab.table);
+
+ gnttab.initialized = 1;
+}
+
+void gnttab_fini(void)
+{
+ struct gnttab_setup_table setup;
+ int rc;
+
+ setup.dom = DOMID_SELF;
+ setup.nr_frames = 0;
+
+ rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
+ if (rc) {
+ uk_pr_err("Hypercall error: %d\n", rc);
+ return;
+ }
+
+ gnttab.initialized = 0;
+}
--- /dev/null
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/* Taken from Mini-OS */
+
+#ifndef __UK_XEN_GNTTAB_H__
+#define __UK_XEN_GNTTAB_H__
+
+#include <uk/config.h>
+#include <uk/alloc.h>
+#include <xen/grant_table.h>
+
+#define GRANT_INVALID_REF 0
+
+void gnttab_init(void);
+void gnttab_fini(void);
+
+grant_ref_t gnttab_alloc_and_grant(void **map, struct uk_alloc *a);
+grant_ref_t gnttab_grant_access(domid_t domid, unsigned long pfn,
+ int readonly);
+grant_ref_t gnttab_grant_transfer(domid_t domid, unsigned long pfn);
+int gnttab_update_grant(grant_ref_t gref,
+ domid_t domid, unsigned long pfn,
+ int readonly);
+unsigned long gnttab_end_transfer(grant_ref_t gref);
+int gnttab_end_access(grant_ref_t gref);
+
+const char *gnttabop_error(__s16 status);
+
+grant_entry_v1_t *gnttab_arch_init(int nr_grant_frames);
+
+#endif /* !__UK_XEN_GNTTAB_H__ */
Create and initialize physical to machine (p2m) table on a PV
xen host
-config XEN_GNTTAB
- bool "Grant table support"
- default y if (XEN_PV || ARCH_ARM_64)
- depends on (ARCH_X86_64 || ARCH_ARM_64)
- select LIBXENBUS
- select LIBUKALLOC
- select LIBUKLOCK
- select LIBUKLOCK_SEMAPHORE
- select LIBUKSCHED
- help
- Support grant table operations
-
endif
LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/lcpu.c
LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/shutdown.c
LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/events.c
-
-ifeq ($(CONFIG_XEN_GNTTAB),y)
-LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/gnttab.c
-LIBXENPLAT_SRCS-$(CONFIG_ARCH_X86_64) += $(LIBXENPLAT_BASE)/x86/gnttab.c|x86
-LIBXENPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(LIBXENPLAT_BASE)/arm/gnttab.c|arm64
-endif
+++ /dev/null
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-/* Taken from Mini-OS */
-
-#include <stdint.h>
-#include <stddef.h>
-#include <uk/print.h>
-#include <xen/memory.h>
-#include <xen/xen.h>
-#include <libfdt.h>
-#include <xen/grant_table.h>
-#include <common/hypervisor.h>
-#include <xen-arm/os.h>
-#include <xen-arm/mm.h>
-
-extern lpae_t fixmap_pgtable[512];
-
-/* Get Xen's suggested physical page assignments for the grant table. */
-static paddr_t get_gnttab_base(void)
-{
- int hypervisor;
- int len = 0;
- const uint64_t *regs;
- paddr_t gnttab_base;
-
- hypervisor =
- fdt_node_offset_by_compatible(HYPERVISOR_dtb, -1, "xen,xen");
- if (hypervisor < 0)
- BUG();
-
- regs = fdt_getprop(HYPERVISOR_dtb, hypervisor, "reg", &len);
- /* The property contains the address and size, 8-bytes each. */
- if (regs == NULL || len < 16) {
- uk_pr_debug("Bad 'reg' property: %p %d\n", regs, len);
- BUG();
- }
-
- gnttab_base = fdt64_ld(regs);
-
- uk_pr_debug("FDT suggests grant table base %llx\n",
- (unsigned long long) gnttab_base);
-
- return gnttab_base;
-}
-
-static paddr_t map_gnttab(paddr_t phys)
-{
- uk_pr_debug("%s, phys = 0x%lx\n", __func__, phys);
-
- set_pgt_entry(&fixmap_pgtable[l2_pgt_idx(FIX_GNT_START)],
- ((phys & L2_MASK) | BLOCK_DEF_ATTR | L2_BLOCK));
-
- return (paddr_t)(FIX_GNT_START + (phys & L2_OFFSET));
-}
-
-grant_entry_v1_t *gnttab_arch_init(int nr_grant_frames)
-{
- struct xen_add_to_physmap xatp;
- paddr_t gnttab_table;
- int i;
-
- gnttab_table = get_gnttab_base();
-
- for (i = 0; i < nr_grant_frames; i++) {
- xatp.domid = DOMID_SELF;
- xatp.size = 0; // Seems to be unused
- xatp.space = XENMAPSPACE_grant_table;
- xatp.idx = i;
- xatp.gpfn = (gnttab_table >> PAGE_SHIFT) + i;
- if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp) != 0)
- BUG();
- }
-
- return (grant_entry_v1_t *)map_gnttab(gnttab_table);
-}
+++ /dev/null
-/* SPDX-License-Identifier: MIT */
-/*
- ****************************************************************************
- * (C) 2006 - Cambridge University
- ****************************************************************************
- *
- * File: gnttab.c
- * Author: Steven Smith (sos22@cam.ac.uk)
- * Changes: Grzegorz Milos (gm281@cam.ac.uk)
- *
- * Date: July 2006
- *
- * Environment: Xen Minimal OS
- * Description: Simple grant tables implementation. About as stupid as it's
- * possible to be and still work.
- *
- ****************************************************************************
- */
-#include <stdint.h>
-#include <stddef.h>
-#ifdef DBGGNT
-#include <string.h>
-#endif
-#include <uk/arch/limits.h>
-#include <uk/atomic.h>
-#include <uk/plat/lcpu.h>
-#include <uk/semaphore.h>
-#include <common/gnttab.h>
-#if defined(__i386__) || defined(__x86_64__)
-#include <xen-x86/mm.h>
-
-#include <xen-x86/hypercall.h>
-#elif defined(__aarch64__)
-#include <xen-arm/mm.h>
-
-#include <xen-arm/hypercall.h>
-#else
-#error "Unsupported architecture"
-#endif
-
-/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
-#define NR_GRANT_FRAMES 4
-#define NR_GRANT_ENTRIES \
- (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_v1_t))
-
-static struct gnttab {
- int initialized;
- struct uk_semaphore sem;
- grant_entry_v1_t *table;
- grant_ref_t gref_list[NR_GRANT_ENTRIES];
-#ifdef DBGGNT
- char inuse[NR_GRANT_ENTRIES];
-#endif
-} gnttab;
-
-
-static grant_ref_t get_free_entry(void)
-{
- grant_ref_t gref;
- unsigned long flags;
-
- uk_semaphore_down(&gnttab.sem);
-
- flags = ukplat_lcpu_save_irqf();
-
- gref = gnttab.gref_list[0];
- UK_ASSERT(gref >= GNTTAB_NR_RESERVED_ENTRIES &&
- gref < NR_GRANT_ENTRIES);
- gnttab.gref_list[0] = gnttab.gref_list[gref];
-#ifdef DBGGNT
- UK_ASSERT(!gnttab.inuse[gref]);
- gnttab.inuse[gref] = 1;
-#endif
-
- ukplat_lcpu_restore_irqf(flags);
-
- return gref;
-}
-
-static void put_free_entry(grant_ref_t gref)
-{
- unsigned long flags;
-
- flags = ukplat_lcpu_save_irqf();
-
-#ifdef DBGGNT
- UK_ASSERT(gnttab.inuse[gref]);
- gnttab.inuse[gref] = 0;
-#endif
- gnttab.gref_list[gref] = gnttab.gref_list[0];
- gnttab.gref_list[0] = gref;
-
- ukplat_lcpu_restore_irqf(flags);
-
- uk_semaphore_up(&gnttab.sem);
-}
-
-static void gnttab_grant_init(grant_ref_t gref, domid_t domid,
- unsigned long mfn)
-{
- gnttab.table[gref].frame = mfn;
- gnttab.table[gref].domid = domid;
-
- /* Memory barrier */
- wmb();
-}
-
-static void gnttab_grant_permit_access(grant_ref_t gref, domid_t domid,
- unsigned long mfn, int readonly)
-{
- gnttab_grant_init(gref, domid, mfn);
- readonly *= GTF_readonly;
- gnttab.table[gref].flags = GTF_permit_access | readonly;
-}
-
-grant_ref_t gnttab_grant_access(domid_t domid, unsigned long mfn,
- int readonly)
-{
- grant_ref_t gref = get_free_entry();
-
- gnttab_grant_permit_access(gref, domid, mfn, readonly);
-
- return gref;
-}
-
-grant_ref_t gnttab_grant_transfer(domid_t domid, unsigned long mfn)
-{
- grant_ref_t gref = get_free_entry();
-
- gnttab_grant_init(gref, domid, mfn);
- gnttab.table[gref].flags = GTF_accept_transfer;
-
- return gref;
-}
-
-/* Reset flags to zero in order to stop using the grant */
-static int gnttab_reset_flags(grant_ref_t gref)
-{
- __u16 flags, nflags;
- __u16 *pflags;
-
- pflags = &gnttab.table[gref].flags;
- nflags = *pflags;
-
- do {
- if ((flags = nflags) & (GTF_reading | GTF_writing)) {
- uk_pr_warn("gref=%u still in use! (0x%x)\n",
- gref, flags);
- return 0;
- }
- } while ((nflags = uk_compare_exchange_sync(pflags, flags, 0))
- != flags);
-
- return 1;
-}
-
-int gnttab_update_grant(grant_ref_t gref,
- domid_t domid, unsigned long mfn,
- int readonly)
-{
- int rc;
-
- UK_ASSERT(gref >= GNTTAB_NR_RESERVED_ENTRIES &&
- gref < NR_GRANT_ENTRIES);
-
- rc = gnttab_reset_flags(gref);
- if (!rc)
- return rc;
-
- gnttab_grant_permit_access(gref, domid, mfn, readonly);
-
- return 1;
-}
-
-int gnttab_end_access(grant_ref_t gref)
-{
- int rc;
-
- UK_ASSERT(gref >= GNTTAB_NR_RESERVED_ENTRIES &&
- gref < NR_GRANT_ENTRIES);
-
- rc = gnttab_reset_flags(gref);
- if (!rc)
- return rc;
-
- put_free_entry(gref);
-
- return 1;
-}
-
-unsigned long gnttab_end_transfer(grant_ref_t gref)
-{
- unsigned long frame;
- __u16 flags;
- __u16 *pflags;
-
- UK_ASSERT(gref >= GNTTAB_NR_RESERVED_ENTRIES &&
- gref < NR_GRANT_ENTRIES);
-
- pflags = &gnttab.table[gref].flags;
- while (!((flags = *pflags) & GTF_transfer_committed)) {
- if (uk_compare_exchange_sync(pflags, flags, 0) == flags) {
- uk_pr_info("Release unused transfer grant.\n");
- put_free_entry(gref);
- return 0;
- }
- }
-
- /* If a transfer is in progress then wait until it is completed. */
- while (!(flags & GTF_transfer_completed))
- flags = *pflags;
-
- /* Read the frame number /after/ reading completion status. */
- rmb();
- frame = gnttab.table[gref].frame;
-
- put_free_entry(gref);
-
- return frame;
-}
-
-grant_ref_t gnttab_alloc_and_grant(void **map, struct uk_alloc *a)
-{
- void *page;
- unsigned long mfn;
- grant_ref_t gref;
-
- UK_ASSERT(map != NULL);
- UK_ASSERT(a != NULL);
-
- page = uk_palloc(a, 1);
- if (page == NULL)
- return GRANT_INVALID_REF;
-
- mfn = virt_to_mfn(page);
- gref = gnttab_grant_access(0, mfn, 0);
-
- *map = page;
-
- return gref;
-}
-
-static const char * const gnttabop_error_msgs[] = GNTTABOP_error_msgs;
-
-const char *gnttabop_error(__s16 status)
-{
- status = -status;
- if (status < 0 || (__u16) status >= ARRAY_SIZE(gnttabop_error_msgs))
- return "bad status";
- else
- return gnttabop_error_msgs[status];
-}
-
-void gnttab_init(void)
-{
- grant_ref_t gref;
-
- UK_ASSERT(gnttab.initialized == 0);
-
- uk_semaphore_init(&gnttab.sem, 0);
-
-#ifdef DBGGNT
- memset(gnttab.inuse, 1, sizeof(gnttab.inuse));
-#endif
- for (gref = GNTTAB_NR_RESERVED_ENTRIES; gref < NR_GRANT_ENTRIES; gref++)
- put_free_entry(gref);
-
- gnttab.table = gnttab_arch_init(NR_GRANT_FRAMES);
- if (gnttab.table == NULL)
- UK_CRASH("Failed to initialize grant table\n");
-
- uk_pr_info("Grant table mapped at %p.\n", gnttab.table);
-
- gnttab.initialized = 1;
-}
-
-void gnttab_fini(void)
-{
- struct gnttab_setup_table setup;
- int rc;
-
- setup.dom = DOMID_SELF;
- setup.nr_frames = 0;
-
- rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
- if (rc) {
- uk_pr_err("Hypercall error: %d\n", rc);
- return;
- }
-
- gnttab.initialized = 0;
-}
+++ /dev/null
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-/* Taken from Mini-OS */
-
-#ifndef __GNTTAB_H__
-#define __GNTTAB_H__
-
-#include <uk/config.h>
-
-#ifdef CONFIG_XEN_GNTTAB
-
-#include <uk/alloc.h>
-#include <xen/grant_table.h>
-
-#define GRANT_INVALID_REF 0
-
-void gnttab_init(void);
-void gnttab_fini(void);
-
-grant_ref_t gnttab_alloc_and_grant(void **map, struct uk_alloc *a);
-grant_ref_t gnttab_grant_access(domid_t domid, unsigned long pfn,
- int readonly);
-grant_ref_t gnttab_grant_transfer(domid_t domid, unsigned long pfn);
-int gnttab_update_grant(grant_ref_t gref,
- domid_t domid, unsigned long pfn,
- int readonly);
-unsigned long gnttab_end_transfer(grant_ref_t gref);
-int gnttab_end_access(grant_ref_t gref);
-
-const char *gnttabop_error(__s16 status);
-
-grant_entry_v1_t *gnttab_arch_init(int nr_grant_frames);
-
-#endif /* CONFIG_XEN_GNTTAB */
-
-#endif /* !__GNTTAB_H__ */
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <uk/config.h>
#include <stdint.h>
-#include <common/gnttab.h>
+#if CONFIG_LIBXENGNTTAB
+#include <uk/xen/gnttab.h>
+#endif /* CONFIG_LIBXENGNTTAB */
#if (defined __X86_32__) || (defined __X86_64__)
#include <xen-x86/setup.h>
#include <xen-x86/mm_pv.h>
int _ukplat_mem_mappings_init(void)
{
mm_init();
-#ifdef CONFIG_XEN_GNTTAB
+#ifdef CONFIG_LIBXENGNTTAB
+ /* TODO: Move `gnttab_init()` to (early) ctortab */
gnttab_init();
#endif
return 0;
+++ /dev/null
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-/* Taken from Mini-OS */
-
-#include <stdint.h>
-#include <stddef.h>
-#include <uk/print.h>
-#include <xen/xen.h>
-#include <xen/grant_table.h>
-#include <common/hypervisor.h>
-#include <xen-x86/mm.h>
-
-
-grant_entry_v1_t *gnttab_arch_init(int grant_frames_num)
-{
- grant_entry_v1_t *gnte = NULL;
- struct gnttab_setup_table setup;
- unsigned long frames[grant_frames_num];
- int rc;
-
- setup.dom = DOMID_SELF;
- setup.nr_frames = grant_frames_num;
- set_xen_guest_handle(setup.frame_list, frames);
-
- rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
- if (rc) {
- uk_pr_err("Hypercall error: %d\n", rc);
- goto out;
- }
- if (setup.status != GNTST_okay) {
- uk_pr_err("Hypercall status: %d\n", setup.status);
- goto out;
- }
-
- gnte = map_frames(frames, grant_frames_num, ukplat_memallocator_get());
-
-out:
- return gnte;
-}