[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH 6/6] plat/xen: Add grant table support for Xen (x86_64)
Costin Lupu <costin.lupu@xxxxxxxxx> writes: > Simple grant table implementation ported and adapted from Mini-OS. > > Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx> > --- > plat/xen/Makefile.uk | 2 + > plat/xen/gnttab.c | 237 > +++++++++++++++++++++++++++++++++++++++ > plat/xen/include/common/gnttab.h | 48 ++++++++ > plat/xen/memory.c | 2 + > plat/xen/x86/gnttab.c | 59 ++++++++++ > 5 files changed, 348 insertions(+) > create mode 100644 plat/xen/gnttab.c > create mode 100644 plat/xen/include/common/gnttab.h > create mode 100644 plat/xen/x86/gnttab.c > > diff --git a/plat/xen/Makefile.uk b/plat/xen/Makefile.uk > index 3305a84..45096cb 100644 > --- a/plat/xen/Makefile.uk > +++ b/plat/xen/Makefile.uk > @@ -45,6 +45,7 @@ LIBXENPLAT_SRCS-$(CONFIG_ARCH_X86_64) += > $(LIBXENPLAT_BASE)/x86/entry64.S > LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/x86/mm.c > LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/x86/arch_events.c > LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/x86/arch_time.c > +LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/x86/gnttab.c|x86 > > ifneq ($(XEN_HVMLITE),y) > LIBXENPLAT_ASFLAGS-y += -DCONFIG_PARAVIRT > @@ -70,3 +71,4 @@ LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/lcpu.c > LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/console.c > LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/shutdown.c > LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/events.c > +LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/gnttab.c > diff --git a/plat/xen/gnttab.c b/plat/xen/gnttab.c > new file mode 100644 > index 0000000..a134632 > --- /dev/null > +++ b/plat/xen/gnttab.c > @@ -0,0 +1,237 @@ > +/* SPDX-License-Identifier: MIT */ > +/* > + **************************************************************************** > + * (C) 2006 - Cambridge University > + **************************************************************************** > + * > + * File: gnttab.c > + * Author: Steven Smith (sos22@xxxxxxxxx) > + * Changes: Grzegorz Milos (gm281@xxxxxxxxx) > + * > + * 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> > +#ifdef DBGGNT > +#include <string.h> > +#endif > +#include <uk/arch/limits.h> > +#include <uk/arch/atomic.h> > +#include <uk/plat/lcpu.h> > +#include <uk/semaphore.h> This introduces libuklock dependency. I guess we need to reflect this in corresponding Config.uk > +#include <common/gnttab.h> > +#include <xen-x86/mm.h> > + > + > +#define NR_RESERVED_ENTRIES GNTTAB_NR_RESERVED_ENTRIES Can we use GNTTAB_NR_RESERVED_ENTRIES directly instead? > +/* 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 >= 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); > +} > + > +grant_ref_t gnttab_grant_access(domid_t domid, unsigned long pfn, > + int readonly) Is it supposed to be a mfn, not pfn? > +{ > + grant_ref_t gref; > + > + gref = get_free_entry(); > + gnttab.table[gref].frame = pfn; > + gnttab.table[gref].domid = domid; > + wmb(); Why the barrier is here not after setting the readonly flag? MiniOS and Linux are doing the same, so I assume that is the right way. Maybe you could enlighten me? :) > + readonly *= GTF_readonly; > + gnttab.table[gref].flags = GTF_permit_access | readonly; > + > + return gref; > +} > + > +grant_ref_t gnttab_grant_transfer(domid_t domid, unsigned long pfn) > +{ > + grant_ref_t gref; > + > + gref = get_free_entry(); > + gnttab.table[gref].frame = pfn; > + gnttab.table[gref].domid = domid; > + wmb(); > + gnttab.table[gref].flags = GTF_accept_transfer; > + > + return gref; > +} > + > +int gnttab_end_access(grant_ref_t gref) > +{ > + __u16 flags, nflags; > + __u16 *pflags; > + > + UK_ASSERT(gref >= NR_RESERVED_ENTRIES && gref < NR_GRANT_ENTRIES); > + > + pflags = &gnttab.table[gref].flags; > + nflags = *pflags; > + do { > + if ((flags = nflags) & (GTF_reading | GTF_writing)) { > + uk_printd(DLVL_WARN, "g.e. still in use! (%x)\n", > flags); Over 80 chars, and not hard to fix. Could please consult to checkpatch.pl? > + return 0; > + } > + } while ((nflags = ukarch_compare_exchange_sync(pflags, flags, 0)) != > flags); Let's use a similar while loop as in gnttab_end_transfer here > + > + 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 >= NR_RESERVED_ENTRIES && gref < NR_GRANT_ENTRIES); > + > + pflags = &gnttab.table[gref].flags; > + while (!((flags = *pflags) & GTF_transfer_committed)) { > + if (ukarch_compare_exchange_sync(pflags, flags, 0) == flags) { > + uk_printd(DLVL_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_malloc_page(a); > + 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 = 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_printd(DLVL_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_printd(DLVL_ERR, "Hypercall error: %d\n", rc); > + return; > + } > + > + gnttab.initialized = 0; > +} > diff --git a/plat/xen/include/common/gnttab.h > b/plat/xen/include/common/gnttab.h > new file mode 100644 > index 0000000..d4bb417 > --- /dev/null > +++ b/plat/xen/include/common/gnttab.h > @@ -0,0 +1,48 @@ > +/* 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/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); > +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 /* !__GNTTAB_H__ */ > diff --git a/plat/xen/memory.c b/plat/xen/memory.c > index 6ae92f4..f84dca7 100644 > --- a/plat/xen/memory.c > +++ b/plat/xen/memory.c > @@ -35,6 +35,7 @@ > > #include <string.h> > > +#include <common/gnttab.h> > #if (defined __X86_32__) || (defined __X86_64__) > #include <xen-x86/setup.h> > #elif (defined __ARM_32__) || (defined __ARM_64__) > @@ -122,5 +123,6 @@ int ukplat_memregion_get(int i, struct > ukplat_memregion_desc *m) > > int _ukplat_mem_mappings_init(void) > { > + gnttab_init(); > return 0; > } > diff --git a/plat/xen/x86/gnttab.c b/plat/xen/x86/gnttab.c > new file mode 100644 > index 0000000..add3444 > --- /dev/null > +++ b/plat/xen/x86/gnttab.c > @@ -0,0 +1,59 @@ > +/* 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 <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_printd(DLVL_ERR, "Hypercall error: %d\n", rc); > + goto out; > + } > + if (setup.status != GNTST_okay) { > + uk_printd(DLVL_ERR, "Hypercall status: %d\n", setup.status); > + goto out; > + } > + > + gnte = map_frames(frames, grant_frames_num, ukplat_memallocator_get()); > + > +out: > + return gnte; > +} > -- > 2.11.0 > -- Yuri Volchkov Software Specialist NEC Europe Ltd Kurfürsten-Anlage 36 D-69115 Heidelberg _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |