Acked-by: Pankaj Gupta <pankaj.gupta.linux@xxxxxxxxx> On Thu, 28 May 2020 at 00:32, John Hubbard <jhubbard@xxxxxxxxxx> wrote: > > Introduce pin_user_pages_locked(), which is nearly identical to > get_user_pages_locked() except that it sets FOLL_PIN and rejects > FOLL_GET. > > Signed-off-by: John Hubbard <jhubbard@xxxxxxxxxx> > --- > include/linux/mm.h | 2 ++ > mm/gup.c | 30 ++++++++++++++++++++++++++++++ > 2 files changed, 32 insertions(+) > > diff --git a/include/linux/mm.h b/include/linux/mm.h > index 98be7289d7e9..d16951087c93 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -1700,6 +1700,8 @@ long pin_user_pages(unsigned long start, unsigned long nr_pages, > struct vm_area_struct **vmas); > long get_user_pages_locked(unsigned long start, unsigned long nr_pages, > unsigned int gup_flags, struct page **pages, int *locked); > +long pin_user_pages_locked(unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, int *locked); > long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages, > struct page **pages, unsigned int gup_flags); > long pin_user_pages_unlocked(unsigned long start, unsigned long nr_pages, > diff --git a/mm/gup.c b/mm/gup.c > index 2f0a0b497c23..17418a949067 100644 > --- a/mm/gup.c > +++ b/mm/gup.c > @@ -2992,3 +2992,33 @@ long pin_user_pages_unlocked(unsigned long start, unsigned long nr_pages, > return get_user_pages_unlocked(start, nr_pages, pages, gup_flags); > } > EXPORT_SYMBOL(pin_user_pages_unlocked); > + > +/* > + * pin_user_pages_locked() is the FOLL_PIN variant of get_user_pages_locked(). > + * Behavior is the same, except that this one sets FOLL_PIN and rejects > + * FOLL_GET. > + */ > +long pin_user_pages_locked(unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + int *locked) > +{ > + /* > + * FIXME: Current FOLL_LONGTERM behavior is incompatible with > + * FAULT_FLAG_ALLOW_RETRY because of the FS DAX check requirement on > + * vmas. As there are no users of this flag in this call we simply > + * disallow this option for now. > + */ > + if (WARN_ON_ONCE(gup_flags & FOLL_LONGTERM)) > + return -EINVAL; > + > + /* FOLL_GET and FOLL_PIN are mutually exclusive. */ > + if (WARN_ON_ONCE(gup_flags & FOLL_GET)) > + return -EINVAL; > + > + gup_flags |= FOLL_PIN; > + return __get_user_pages_locked(current, current->mm, start, nr_pages, > + pages, NULL, locked, > + gup_flags | FOLL_TOUCH); > +} > +EXPORT_SYMBOL(pin_user_pages_locked); > + > -- > 2.26.2 > >