[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCH v2 6/6] plat/xen: Add grant table support for Xen (x86_64)


  • To: minios-devel@xxxxxxxxxxxxx
  • From: Costin Lupu <costin.lupu@xxxxxxxxx>
  • Date: Thu, 28 Jun 2018 15:38:35 +0300
  • Cc: simon.kuenzer@xxxxxxxxx, sharan.santhanam@xxxxxxxxx, yuri.volchkov@xxxxxxxxx
  • Delivery-date: Thu, 28 Jun 2018 12:38:48 +0000
  • Ironport-phdr: 9a23:u/X+dRJ9PzCIl96SjtmcpTZWNBhigK39O0sv0rFitYgfKfrxwZ3uMQTl6Ol3ixeRBMOHs6wC07KempujcFRI2YyGvnEGfc4EfD4+ouJSoTYdBtWYA1bwNv/gYn9yNs1DUFh44yPzahANS47xaFLIv3K98yMZFAnhOgppPOT1HZPZg9iq2+yo9JDffwRFiCChbb9uMR67sRjfus4KjIV4N60/0AHJonxGe+RXwWNnO1eelAvi68mz4ZBu7T1et+ou+MBcX6r6eb84TaFDAzQ9L281/szrugLdQgaJ+3ART38ZkhtMAwjC8RH6QpL8uTb0u+ZhxCWXO9D9QLYpUjqg8qhrUgflhicZOTAk/m/Zict+g6BVoB+6uxBz35TZbJ2POfZiYq/Qe84RS2pbXsZWUixMGp2xb4wUD+odPOZYqZT2qV0TrRumGAmnGeTixSNPhn/twa060uIhHRvC3Aw9B9IOrW/Zo8nuNKsISeC10bLHwS/Zb/NRwDrw7pXDfBM5ofyUQL59ftfdxVMsGg7FlFmct5LpMjGP2ukDq2SX8uVtWf+1h2Mkqwx9uCajy8kih4XTm44YxU7I+CNky4gvP9K4UlR0Ydu8HZtVsCGVKpV5T9s5Q2FtpCY60roGuYOnfCQSyJQo2Rrfa/uffoiW5xLsTueRITNiiH15Y7KznQ6y8VW7xeHmTMm0105GritDktbSqnAAzwHf58eaRvdn/Uqs2SyD2x7N5uxGO0w5m7LXK5s7zb4xkpoTv17DHijzmEjukKCWcV4k+vSp6+TheLnmooKcN5dpigzlLqsugdazAfwlMgcVRWSb4+O82KX5/ULlWLVKkuE2kq7BvZDfJMQboK+5AwhO0oo69hmwESmm38ocnXQcKFJFeQmHj5TyO13UL/H3E/G/j06rkDdxyPDMJqfhDYnVLnjfjLfheq5w61VcyAUp19BQ/ZRUBqsaIP3pXE/xqNzYAQU/MwOuxubqE9N92Z0CVmKLGKCWK7nevkGV5ug3OemDeJcVuCrhK/gi//Puln45mVoafamvx5cXa224EepgI0SYf3XsmMwMEWEUsQUiSOzlkkaNXSRNaHavR6g8/C00CJq6DYffQYCgmLyA3DqhHp1XfGxGFFeMEXP0eIWEWPcMbzySL9RnkjMaSbehT5Uu2gq0uADk1ro0ZtbTrygZs5Pkz5156vPekTk29CdoFIKN3mfLSHt7zU0SQDpj96dkvU17gnOeybUw1/dfDsBS4bVNTx8nHZXHifRnAZboXVSSLZ+yVF+6T4D+UnkKRdUrzopWbg==
  • List-id: Mini-os development list <minios-devel.lists.xenproject.org>

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                | 241 +++++++++++++++++++++++++++++++++++++++
 plat/xen/include/common/gnttab.h |  48 ++++++++
 plat/xen/memory.c                |   2 +
 plat/xen/x86/gnttab.c            |  59 ++++++++++
 5 files changed, 352 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..72fc075
--- /dev/null
+++ b/plat/xen/gnttab.c
@@ -0,0 +1,241 @@
+/* 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>
+#include <common/gnttab.h>
+#include <xen-x86/mm.h>
+
+
+/* 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);
+}
+
+grant_ref_t gnttab_grant_access(domid_t domid, unsigned long mfn,
+               int readonly)
+{
+       grant_ref_t gref;
+
+       gref = get_free_entry();
+       gnttab.table[gref].frame = mfn;
+       gnttab.table[gref].domid = domid;
+       wmb();
+       readonly *= GTF_readonly;
+       gnttab.table[gref].flags = GTF_permit_access | readonly;
+
+       return gref;
+}
+
+grant_ref_t gnttab_grant_transfer(domid_t domid, unsigned long mfn)
+{
+       grant_ref_t gref;
+
+       gref = get_free_entry();
+       gnttab.table[gref].frame = mfn;
+       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 >= GNTTAB_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,
+                               "gref=%u still in use! (0x%x)\n", gref, flags);
+                       return 0;
+               }
+       } while ((nflags = ukarch_compare_exchange_sync(pflags, flags, 0)) != 
flags);
+
+       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 (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 = 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_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


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.