Re: [PATCH 01/16] mm: use untagged_addr() for get_user_pages_fast addresses

From: Khalid Aziz
Date: Fri Jun 21 2019 - 11:36:17 EST


On 6/21/19 7:39 AM, Jason Gunthorpe wrote:
> On Tue, Jun 11, 2019 at 04:40:47PM +0200, Christoph Hellwig wrote:
>> This will allow sparc64 to override its ADI tags for
>> get_user_pages and get_user_pages_fast.
>>
>> Signed-off-by: Christoph Hellwig <hch@xxxxxx>
>> mm/gup.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/mm/gup.c b/mm/gup.c
>> index ddde097cf9e4..6bb521db67ec 100644
>> +++ b/mm/gup.c
>> @@ -2146,7 +2146,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
>> unsigned long flags;
>> int nr = 0;
>>
>> - start &= PAGE_MASK;
>> + start = untagged_addr(start) & PAGE_MASK;
>> len = (unsigned long) nr_pages << PAGE_SHIFT;
>> end = start + len;
>
> Hmm, this function, and the other, goes on to do:
>
> if (unlikely(!access_ok((void __user *)start, len)))
> return 0;
>
> and I thought that access_ok takes in the tagged pointer?
>
> How about re-order it a bit?

access_ok() can handle tagged or untagged pointers. It just strips the
tag bits from the top bits. Current order doesn't really matter from
functionality point of view. There might be minor gain in delaying
untagging in __get_user_pages_fast() but I could go either way.

--
Khalid

>
> diff --git a/mm/gup.c b/mm/gup.c
> index ddde097cf9e410..f48747ced4723b 100644
> --- a/mm/gup.c
> +++ b/mm/gup.c
> @@ -2148,11 +2148,12 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
>
> start &= PAGE_MASK;
> len = (unsigned long) nr_pages << PAGE_SHIFT;
> - end = start + len;
> -
> if (unlikely(!access_ok((void __user *)start, len)))
> return 0;
>
> + start = untagged_ptr(start);
> + end = start + len;
> +
> /*
> * Disable interrupts. We use the nested form as we can already have
> * interrupts disabled by get_futex_key.
>