
Hi Julien,
On Wed, 2020-07-01 at 17:59 +0100, Julien Grall wrote:
On 01/07/2020 17:29, Anastasiia Lukianenko wrote:
From: Oleksandr Andrushchenko oleksandr_andrushchenko@epam.com
Make required updates to run on u-boot.
Signed-off-by: Oleksandr Andrushchenko < oleksandr_andrushchenko@epam.com> Signed-off-by: Anastasiia Lukianenko < anastasiia_lukianenko@epam.com>
board/xen/xenguest_arm64/xenguest_arm64.c | 13 ++ drivers/xen/Makefile | 1 + drivers/xen/gnttab.c | 258 ++++++++++++++++++++++ drivers/xen/hypervisor.c | 2 + include/xen/gnttab.h | 25 +++ 5 files changed, 299 insertions(+) create mode 100644 drivers/xen/gnttab.c create mode 100644 include/xen/gnttab.h
diff --git a/board/xen/xenguest_arm64/xenguest_arm64.c b/board/xen/xenguest_arm64/xenguest_arm64.c index e8621f7174..b4e1650f99 100644 --- a/board/xen/xenguest_arm64/xenguest_arm64.c +++ b/board/xen/xenguest_arm64/xenguest_arm64.c @@ -22,6 +22,7 @@
#include <linux/compiler.h>
+#include <xen/gnttab.h> #include <xen/hvm.h>
DECLARE_GLOBAL_DATA_PTR; @@ -64,6 +65,8 @@ static int setup_mem_map(void) struct fdt_resource res; const void *blob = gd->fdt_blob; u64 gfn;
phys_addr_t gnttab_base;
phys_size_t gnttab_sz;
/*
- Add "magic" region which is used by Xen to provide some
essentials @@ -97,6 +100,16 @@ static int setup_mem_map(void) PTE_BLOCK_INNER_SHARE); i++;
- /* Get Xen's suggested physical page assignments for the grant
table. */
- get_gnttab_base(&gnttab_base, &gnttab_sz);
- xen_mem_map[i].virt = gnttab_base;
- xen_mem_map[i].phys = gnttab_base;
- xen_mem_map[i].size = gnttab_sz;
- xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE);
- i++;
- mem = get_next_memory_node(blob, -1); if (mem < 0) { printf("%s: Missing /memory node\n", __func__);
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 9d0f604aaa..243b13277a 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -5,3 +5,4 @@ obj-y += hypervisor.o obj-y += events.o obj-y += xenbus.o +obj-y += gnttab.o diff --git a/drivers/xen/gnttab.c b/drivers/xen/gnttab.c new file mode 100644 index 0000000000..b18102e329 --- /dev/null +++ b/drivers/xen/gnttab.c @@ -0,0 +1,258 @@ +/*
- (C) 2006 - Cambridge University
- (C) 2020 - EPAM Systems Inc.
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 <common.h> +#include <linux/compiler.h> +#include <log.h> +#include <malloc.h>
+#include <asm/armv8/mmu.h> +#include <asm/io.h> +#include <asm/xen/system.h>
+#include <linux/bug.h>
+#include <xen/gnttab.h> +#include <xen/hvm.h>
+#include <xen/interface/memory.h>
+DECLARE_GLOBAL_DATA_PTR;
+#define NR_RESERVED_ENTRIES 8
+/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */ +#define NR_GRANT_FRAMES 1 +#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(struct grant_entry_v1))
+static struct grant_entry_v1 *gnttab_table; +static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
+static void put_free_entry(grant_ref_t ref) +{
- unsigned long flags;
- local_irq_save(flags);
- gnttab_list[ref] = gnttab_list[0];
- gnttab_list[0] = ref;
- local_irq_restore(flags);
+}
+static grant_ref_t get_free_entry(void) +{
- unsigned int ref;
- unsigned long flags;
- local_irq_save(flags);
- ref = gnttab_list[0];
- BUG_ON(ref < NR_RESERVED_ENTRIES || ref >= NR_GRANT_ENTRIES);
- gnttab_list[0] = gnttab_list[ref];
- local_irq_restore(flags);
- return ref;
+}
+grant_ref_t gnttab_grant_access(domid_t domid, unsigned long frame, int readonly) +{
- grant_ref_t ref;
- ref = get_free_entry();
- gnttab_table[ref].frame = frame;
- gnttab_table[ref].domid = domid;
- wmb();
- readonly *= GTF_readonly;
- gnttab_table[ref].flags = GTF_permit_access | readonly;
- return ref;
+}
+grant_ref_t gnttab_grant_transfer(domid_t domid, unsigned long pfn)
It is not possible to transfer grant on Arm. So I would suggest to remove the code related to it.
[...]
Makes sense, will remove.
+unsigned long gnttab_end_transfer(grant_ref_t ref)
likewise.
Same above.
+{
- unsigned long frame;
- u16 flags;
- BUG_ON(ref >= NR_GRANT_ENTRIES || ref < NR_RESERVED_ENTRIES);
- while (!((flags = gnttab_table[ref].flags) &
GTF_transfer_committed)) {
if (synch_cmpxchg(&gnttab_table[ref].flags, flags, 0)
== flags) {
printf("Release unused transfer grant.\n");
put_free_entry(ref);
return 0;
}
- }
- /* If a transfer is in progress then wait until it is
completed. */
- while (!(flags & GTF_transfer_completed))
flags = gnttab_table[ref].flags;
- /* Read the frame number /after/ reading completion status. */
- rmb();
- frame = gnttab_table[ref].frame;
- put_free_entry(ref);
- return frame;
+}
+grant_ref_t gnttab_alloc_and_grant(void **map) +{
- unsigned long mfn;
- grant_ref_t gref;
- *map = (void *)memalign(PAGE_SIZE, PAGE_SIZE);
- mfn = virt_to_mfn(*map);
- gref = gnttab_grant_access(0, mfn, 0);
- return gref;
+}
+static const char * const gnttabop_error_msgs[] = GNTTABOP_error_msgs;
+const char *gnttabop_error(int16_t status) +{
- status = -status;
- if (status < 0 || status >= ARRAY_SIZE(gnttabop_error_msgs))
return "bad status";
- else
return gnttabop_error_msgs[status];
+}
+/* Get Xen's suggested physical page assignments for the grant table. */ +void get_gnttab_base(phys_addr_t *gnttab_base, phys_size_t *gnttab_sz) +{
- const void *blob = gd->fdt_blob;
- struct fdt_resource res;
- int mem;
- mem = fdt_node_offset_by_compatible(blob, -1, "xen,xen");
- if (mem < 0) {
printf("No xen,xen compatible found\n");
BUG();
- }
- mem = fdt_get_resource(blob, mem, "reg", 0, &res);
- if (mem == -FDT_ERR_NOTFOUND) {
printf("No grant table base in the device tree\n");
BUG();
- }
- *gnttab_base = (phys_addr_t)res.start;
- if (gnttab_sz)
*gnttab_sz = (phys_size_t)(res.end - res.start + 1);
- debug("FDT suggests grant table base at %llx\n",
*gnttab_base);
+}
+void init_gnttab(void) +{
- struct xen_add_to_physmap xatp;
- struct gnttab_setup_table setup;
- xen_pfn_t frames[NR_GRANT_FRAMES];
- int i, rc;
- debug("%s\n", __func__);
- for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
put_free_entry(i);
- get_gnttab_base((phys_addr_t *)&gnttab_table, NULL);
- for (i = 0; i < NR_GRANT_FRAMES; i++) {
xatp.domid = DOMID_SELF;
xatp.size = 0;
xatp.space = XENMAPSPACE_grant_table;
xatp.idx = i;
xatp.gpfn = PFN_DOWN((unsigned long)gnttab_table) + i;
rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap,
&xatp);
if (rc)
printf("XENMEM_add_to_physmap failed; status =
%d\n",
rc);
BUG_ON(rc != 0);
- }
- setup.dom = DOMID_SELF;
- setup.nr_frames = NR_GRANT_FRAMES;
- set_xen_guest_handle(setup.frame_list, frames);
- rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup,
1);
- if (rc || setup.status) {
printf("GNTTABOP_setup_table failed; status = %s\n",
gnttabop_error(setup.status));
BUG();
- }
GNTTAOP_grant_table_op is not needed on Arm.
Ok, will remove.
+}
+void fini_gnttab(void) +{
- struct xen_remove_from_physmap xrtp;
- struct gnttab_setup_table setup;
- int i, rc;
- debug("%s\n", __func__);
- for (i = 0; i < NR_GRANT_FRAMES; i++) {
xrtp.domid = DOMID_SELF;
xrtp.gpfn = PFN_DOWN((unsigned long)gnttab_table) + i;
rc = HYPERVISOR_memory_op(XENMEM_remove_from_physmap,
&xrtp);
if (rc)
printf("XENMEM_remove_from_physmap failed;
status = %d\n",
rc);
BUG_ON(rc != 0);
- }
- setup.dom = DOMID_SELF;
- setup.nr_frames = 0;
- HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
- if (setup.status) {
printf("GNTTABOP_setup_table failed; status = %s\n",
gnttabop_error(setup.status));
BUG();
- }
The hypercall doesn't do any clean-up in Xen. So why are you calling this from fini_gnttab()?
Will remove.
Cheers,
Best regards, Anastasiia