mm/gup: adapt get_user_page_vma_remote() to never return NULL
get_user_pages_remote() will never return 0 except in the case of FOLL_NOWAIT being specified, which we explicitly disallow. This simplifies error handling for the caller and avoids the awkwardness of dealing with both errors and failing to pin. Failing to pin here is an error. Link: https://lkml.kernel.org/r/00319ce292d27b3aae76a0eb220ce3f528187508.1696288092.git.lstoakes@gmail.com Signed-off-by: Lorenzo Stoakes <lstoakes@gmail.com> Suggested-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Reviewed-by: David Hildenbrand <david@redhat.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: John Hubbard <jhubbard@nvidia.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Richard Cochran <richardcochran@gmail.com> Cc: Will Deacon <will@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
9c4b214225
commit
6a1960b8a8
@ -411,8 +411,8 @@ static int __access_remote_tags(struct mm_struct *mm, unsigned long addr,
|
|||||||
struct page *page = get_user_page_vma_remote(mm, addr,
|
struct page *page = get_user_page_vma_remote(mm, addr,
|
||||||
gup_flags, &vma);
|
gup_flags, &vma);
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(page)) {
|
if (IS_ERR(page)) {
|
||||||
err = page == NULL ? -EIO : PTR_ERR(page);
|
err = PTR_ERR(page);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2425,6 +2425,9 @@ long pin_user_pages_remote(struct mm_struct *mm,
|
|||||||
unsigned int gup_flags, struct page **pages,
|
unsigned int gup_flags, struct page **pages,
|
||||||
int *locked);
|
int *locked);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieves a single page alongside its VMA. Does not support FOLL_NOWAIT.
|
||||||
|
*/
|
||||||
static inline struct page *get_user_page_vma_remote(struct mm_struct *mm,
|
static inline struct page *get_user_page_vma_remote(struct mm_struct *mm,
|
||||||
unsigned long addr,
|
unsigned long addr,
|
||||||
int gup_flags,
|
int gup_flags,
|
||||||
@ -2432,12 +2435,15 @@ static inline struct page *get_user_page_vma_remote(struct mm_struct *mm,
|
|||||||
{
|
{
|
||||||
struct page *page;
|
struct page *page;
|
||||||
struct vm_area_struct *vma;
|
struct vm_area_struct *vma;
|
||||||
int got = get_user_pages_remote(mm, addr, 1, gup_flags, &page, NULL);
|
int got;
|
||||||
|
|
||||||
|
if (WARN_ON_ONCE(unlikely(gup_flags & FOLL_NOWAIT)))
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
|
got = get_user_pages_remote(mm, addr, 1, gup_flags, &page, NULL);
|
||||||
|
|
||||||
if (got < 0)
|
if (got < 0)
|
||||||
return ERR_PTR(got);
|
return ERR_PTR(got);
|
||||||
if (got == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
vma = vma_lookup(mm, addr);
|
vma = vma_lookup(mm, addr);
|
||||||
if (WARN_ON_ONCE(!vma)) {
|
if (WARN_ON_ONCE(!vma)) {
|
||||||
|
@ -474,8 +474,8 @@ retry:
|
|||||||
gup_flags |= FOLL_SPLIT_PMD;
|
gup_flags |= FOLL_SPLIT_PMD;
|
||||||
/* Read the page with vaddr into memory */
|
/* Read the page with vaddr into memory */
|
||||||
old_page = get_user_page_vma_remote(mm, vaddr, gup_flags, &vma);
|
old_page = get_user_page_vma_remote(mm, vaddr, gup_flags, &vma);
|
||||||
if (IS_ERR_OR_NULL(old_page))
|
if (IS_ERR(old_page))
|
||||||
return old_page ? PTR_ERR(old_page) : 0;
|
return PTR_ERR(old_page);
|
||||||
|
|
||||||
ret = verify_opcode(old_page, vaddr, &opcode);
|
ret = verify_opcode(old_page, vaddr, &opcode);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
|
@ -5815,7 +5815,7 @@ static int __access_remote_vm(struct mm_struct *mm, unsigned long addr,
|
|||||||
struct page *page = get_user_page_vma_remote(mm, addr,
|
struct page *page = get_user_page_vma_remote(mm, addr,
|
||||||
gup_flags, &vma);
|
gup_flags, &vma);
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(page)) {
|
if (IS_ERR(page)) {
|
||||||
/* We might need to expand the stack to access it */
|
/* We might need to expand the stack to access it */
|
||||||
vma = vma_lookup(mm, addr);
|
vma = vma_lookup(mm, addr);
|
||||||
if (!vma) {
|
if (!vma) {
|
||||||
@ -5829,7 +5829,6 @@ static int __access_remote_vm(struct mm_struct *mm, unsigned long addr,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if this is a VM_IO | VM_PFNMAP VMA, which
|
* Check if this is a VM_IO | VM_PFNMAP VMA, which
|
||||||
* we can access using slightly different code.
|
* we can access using slightly different code.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user