diff options
author | Ben Hutchings <ben@decadent.org.uk> | 2022-01-24 16:11:18 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-01-27 09:04:34 +0100 |
commit | 294c7a9fb608c29a9e49010b515228e20ccbec8f (patch) | |
tree | 72323c946bf09b443edf16556f728c84504e92fd /arch/mips | |
parent | 1550a97e4a5d8bf29071bd6c17355ca173e90f73 (diff) | |
download | linux-stable-294c7a9fb608c29a9e49010b515228e20ccbec8f.tar.gz linux-stable-294c7a9fb608c29a9e49010b515228e20ccbec8f.tar.bz2 linux-stable-294c7a9fb608c29a9e49010b515228e20ccbec8f.zip |
mips,s390,sh,sparc: gup: Work around the "COW can break either way" issue
In Linux 4.14 and 4.19 these architectures still have their own
implementations of get_user_pages_fast(). These also need to force
the write flag on when taking the fast path.
Fixes: 407faed92b4a ("gup: document and work around "COW can break either way" issue")
Fixes: 5e24029791e8 ("gup: document and work around "COW can break either way" issue")
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/mm/gup.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c index 5a4875cac1ec..2e7a0d201c09 100644 --- a/arch/mips/mm/gup.c +++ b/arch/mips/mm/gup.c @@ -274,7 +274,14 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, next = pgd_addr_end(addr, end); if (pgd_none(pgd)) goto slow; - if (!gup_pud_range(pgd, addr, next, write, pages, &nr)) + /* + * The FAST_GUP case requires FOLL_WRITE even for pure reads, + * because get_user_pages() may need to cause an early COW in + * order to avoid confusing the normal COW routines. So only + * targets that are already writable are safe to do by just + * looking at the page tables. + */ + if (!gup_pud_range(pgd, addr, next, 1, pages, &nr)) goto slow; } while (pgdp++, addr = next, addr != end); local_irq_enable(); |