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

Re: [Xen-devel] [PATCH v11 6/8] xen/arm: introduce GNTTABOP_cache_flush



On Thu, 23 Oct 2014, Jan Beulich wrote:
> >>> On 22.10.14 at 18:40, <stefano.stabellini@xxxxxxxxxxxxx> wrote:
> > Introduce a new hypercall to perform cache maintenance operation on
> > behalf of the guest. The argument is a machine address and a size. The
> > implementation checks that the memory range is owned by the guest or the
> > guest has been granted access to it by another domain.
> > 
> > Introduce grant_map_exists: an internal grant table function to check
> > whether an mfn has been granted to a given domain on a target grant
> > table. Check hypercall_preempt_check() every 4096 iterations in the
> > implementation of grant_map_exists.
> > Use the top 20 bits of the GNTTABOP cmd encoding to save the last ref
> > across the hypercall continuation.
> > 
> > Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
> 
> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
> albeit the subject still says "arm" while there isn't anything ARM-specific
> in here and ...
> 
> > +static int __gnttab_cache_flush(gnttab_cache_flush_t *cflush,
> > +                                unsigned int *ref_count)
> > +{
> > +    struct domain *d, *owner;
> > +    struct page_info *page;
> > +    unsigned long mfn;
> > +    void *v;
> > +    int ret;
> > +
> > +    if ( (cflush->offset >= PAGE_SIZE) ||
> > +         (cflush->length > PAGE_SIZE) ||
> > +         (cflush->offset + cflush->length > PAGE_SIZE) )
> > +        return -EINVAL;
> > +
> > +    if ( cflush->length == 0 || cflush->op == 0 )
> > +        return 0;
> > +
> > +    /* currently unimplemented */
> > +    if ( cflush->op & GNTTAB_CACHE_SOURCE_GREF )
> > +        return -EOPNOTSUPP;
> > +
> > +    if ( !(cflush->op & (GNTTAB_CACHE_INVAL|GNTTAB_CACHE_CLEAN)) ||
> 
> ... I think we should drop this because ...
> 
> > +         (cflush->op & ~(GNTTAB_CACHE_INVAL|GNTTAB_CACHE_CLEAN)) )
> > +        return -EINVAL;
> > +
> > +    d = rcu_lock_current_domain();
> > +    mfn = cflush->a.dev_bus_addr >> PAGE_SHIFT;
> > +
> > +    if ( !mfn_valid(mfn) )
> > +    {
> > +        rcu_unlock_domain(d);
> > +        return -EINVAL;
> > +    }
> > +
> > +    page = mfn_to_page(mfn);
> > +    owner = page_get_owner_and_reference(page);
> > +    if ( !owner )
> > +    {
> > +        rcu_unlock_domain(d);
> > +        return -EPERM;
> > +    }
> > +
> > +    if ( d != owner )
> > +    {
> > +        spin_lock(&owner->grant_table->lock);
> > +
> > +        ret = grant_map_exists(d, owner->grant_table, mfn, ref_count);
> > +        if ( ret != 0 )
> > +        {
> > +            spin_unlock(&owner->grant_table->lock);
> > +            rcu_unlock_domain(d);
> > +            put_page(page);
> > +            return ret;
> > +        }
> > +    }
> > +
> > +    v = map_domain_page(mfn);
> > +    v += cflush->offset;
> > +
> > +    if ( (cflush->op & GNTTAB_CACHE_INVAL) && (cflush->op & 
> > GNTTAB_CACHE_CLEAN) )
> > +        ret = clean_and_invalidate_dcache_va_range(v, cflush->length);
> > +    else if ( cflush->op & GNTTAB_CACHE_INVAL )
> > +        ret = invalidate_dcache_va_range(v, cflush->length);
> > +    else if ( cflush->op & GNTTAB_CACHE_CLEAN )
> > +        ret = clean_dcache_va_range(v, cflush->length);
> > +    else
> > +        BUG();
> 
> ... now that I think about it again it was a bad suggestion to BUG()
> here - there's nothing wrong with the caller requesting an expensive
> NOP.
> 
> Both could be fixed up while committing.

Sure.
Given that the series already has all the required acks, are you up for
committing it yourself?
Do I need to do anything else?

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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