On Mon, Oct 05, 2020 at 12:50:49AM +0300, Jarkko Sakkinen wrote:
> What is shoukd take is encl->lock.
> 
> The loop was pre-v36 like:
> 
>       idx_start = PFN_DOWN(start);
>       idx_end = PFN_DOWN(end - 1);
> 
>       for (idx = idx_start; idx <= idx_end; ++idx) {
>               mutex_lock(&encl->lock);
>               page = radix_tree_lookup(&encl->page_tree, idx);
>               mutex_unlock(&encl->lock);
> 
>               if (!page || (~page->vm_max_prot_bits & vm_prot_bits))
>                       return -EACCES;
>       }
> 
> Looking at xarray.h and filemap.c, I'm thinking something along the
> lines of:
> 
>       for (idx = idx_start; idx <= idx_end; ++idx) {
>               mutex_lock(&encl->lock);
>               page = xas_find(&xas, idx + 1);
>               mutex_unlock(&encl->lock);
> 
>               if (!page || (~page->vm_max_prot_bits & vm_prot_bits))
>                       return -EACCES;
>       }
> 
> Does this look about right?

Not really ...

        int ret = 0;

        mutex_lock(&encl->lock);
        rcu_read_lock();
        while (xas.index < idx_end) {
                page = xas_next(&xas);
                if (!page || (~page->vm_max_prot_bits & vm_prot_bits))
                        ret = -EACCESS;
                        break;
                }
        }
        rcu_read_unlock();
        mutex_unlock(&encl->lock);

        return ret;

... or you could rework to use the xa_lock instead of encl->lock.
I don't know how feasible that is for you.

Reply via email to