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

[Minios-devel] [UNIKRAFT PATCH] plat/xen: Update grants fields



Update mfn, domain id and permission on grants if reusing them.
Resetting the flags is mandatory in order to avoid race conditions when
changing all the above. If the grant is used during resetting then the
whole operation is canceled.

Signed-off-by: Roxana Nicolescu <nicolescu.roxana1996@xxxxxxxxx>
---
 plat/xen/gnttab.c                | 72 +++++++++++++++++++++++++++++++---------
 plat/xen/include/common/gnttab.h |  3 ++
 2 files changed, 60 insertions(+), 15 deletions(-)

diff --git a/plat/xen/gnttab.c b/plat/xen/gnttab.c
index edc3341e..f48fa44d 100644
--- a/plat/xen/gnttab.c
+++ b/plat/xen/gnttab.c
@@ -86,51 +86,93 @@ static void put_free_entry(grant_ref_t gref)
        uk_semaphore_up(&gnttab.sem);
 }
 
-grant_ref_t gnttab_grant_access(domid_t domid, unsigned long mfn,
-               int readonly)
+static void gnttab_grant_init(grant_ref_t gref, domid_t domid,
+               unsigned long mfn)
 {
-       grant_ref_t gref;
-
-       gref = get_free_entry();
        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;
+       grant_ref_t gref = get_free_entry();
 
-       gref = get_free_entry();
-       gnttab.table[gref].frame = mfn;
-       gnttab.table[gref].domid = domid;
-       wmb();
+       gnttab_grant_init(gref, domid, mfn);
        gnttab.table[gref].flags = GTF_accept_transfer;
 
        return gref;
 }
 
-int gnttab_end_access(grant_ref_t 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;
 
-       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_pr_warn("gref=%u still in use! (0x%x)\n",
                                   gref, flags);
                        return 0;
                }
-       } while ((nflags = ukarch_compare_exchange_sync(pflags, flags, 0)) != 
flags);
+       } while ((nflags = ukarch_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);
 
diff --git a/plat/xen/include/common/gnttab.h b/plat/xen/include/common/gnttab.h
index f5cde5c5..5a830ed6 100644
--- a/plat/xen/include/common/gnttab.h
+++ b/plat/xen/include/common/gnttab.h
@@ -42,6 +42,9 @@ 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);
 
-- 
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®.