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

Re: [Minios-devel] [UNIKRAFT PATCH v3 01/17] plat/xen: Update grants fields



Reviewed-by: Costin Lupu <costin.lupu@xxxxxxxxx>

On 10/30/19 5:54 PM, Roxana Nicolescu wrote:
> 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);
>  
> 

_______________________________________________
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®.