Message ID | 20190611144102.8848-2-hch@lst.de (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [01/16] mm: use untagged_addr() for get_user_pages_fast addresses | expand |
On 6/11/19 8:40 AM, 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@lst.de> > --- Commit message is sparc64 specific but the goal here is to allow any architecture with memory tagging to use this. So I would suggest rewording the commit log. Other than that: Reviewed-by: Khalid Aziz <khalid.aziz@oracle.com> > 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 > --- a/mm/gup.c > +++ 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; > > @@ -2219,7 +2219,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, > unsigned long addr, len, end; > int nr = 0, ret = 0; > > - start &= PAGE_MASK; > + start = untagged_addr(start) & PAGE_MASK; > addr = start; > len = (unsigned long) nr_pages << PAGE_SHIFT; > end = start + len; >
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@lst.de> > --- > mm/gup.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) Reviewed-by: Jason Gunthorpe <jgg@mellanox.com>
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@lst.de> > 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? 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.
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@lst.de> >> 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. >
On Fri, Jun 21, 2019 at 09:35:11AM -0600, Khalid Aziz wrote: > 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@lst.de> > >> 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. I understand the current ARM and SPARC implementations don't do much with the tags, but it feels like a really big assumption for the core code that all future uses of tags will be fine to have them stripped out of 'void __user *' pointers. IMHO that is something we should not be doing in the core kernel.. Jason
On Fri, Jun 21, 2019 at 10:39:11AM -0300, Jason Gunthorpe wrote: > > 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? The patch doesn't really work as-as an misses the main get_user_pages_fast fast path, but I'll add something equivalent.
On Fri, Jun 21, 2019 at 10:39:11AM -0300, Jason Gunthorpe wrote: > 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? Actually.. I we reorder this we'd need to to duplicate a few things due to the zero/negative length checking. Given the feedback from Khalid I'd thus rather skip the reorder for now. If we have a good reason we could add it back, but it would be a bit involved.
diff --git a/mm/gup.c b/mm/gup.c index ddde097cf9e4..6bb521db67ec 100644 --- a/mm/gup.c +++ 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; @@ -2219,7 +2219,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, unsigned long addr, len, end; int nr = 0, ret = 0; - start &= PAGE_MASK; + start = untagged_addr(start) & PAGE_MASK; addr = start; len = (unsigned long) nr_pages << PAGE_SHIFT; end = start + len;
This will allow sparc64 to override its ADI tags for get_user_pages and get_user_pages_fast. Signed-off-by: Christoph Hellwig <hch@lst.de> --- mm/gup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)