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_andrushche...@epam.com> > > > > Make required updates to run on u-boot. > > > > Signed-off-by: Oleksandr Andrushchenko < > > oleksandr_andrushche...@epam.com> > > Signed-off-by: Anastasiia Lukianenko < > > anastasiia_lukiane...@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 (so...@cam.ac.uk) > > + * Changes: Grzegorz Milos (gm...@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