mm/gup: Move permission checks into helpers

This is a preparation patch for the transition of x86 to the generic GUP_fast()
implementation.

On x86, we would need to do additional permission checks to determine if
access is allowed.

Let's abstract it out into separate helpers.

Signed-off-by: Kirill A. Shutemov <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Aneesh Kumar K . V <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Catalin Marinas <[email protected]>
Cc: Dann Frazier <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Rik van Riel <[email protected]>
Cc: Steve Capper <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: [email protected]
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
This commit is contained in:
Kirill A. Shutemov 2017-03-16 18:26:50 +03:00 • committed by Ingo Molnar
commit e7884f8ead
2 changed files with 35 additions and 5 deletions

View file

@ -1212,8 +1212,13 @@ static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end,
* Similar to the PMD case below, NUMA hinting must take slow
* path using the pte_protnone check.
*/
if (!pte_present(pte) || pte_special(pte) ||
pte_protnone(pte) || (write && !pte_write(pte)))
if (pte_protnone(pte))
goto pte_unmap;
if (!pte_access_permitted(pte, write))
goto pte_unmap;
if (pte_special(pte))
goto pte_unmap;
VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
@ -1264,7 +1269,7 @@ static int gup_huge_pmd(pmd_t orig, pmd_t *pmdp, unsigned long addr,
struct page *head, *page;
int refs;
if (write && !pmd_write(orig))
if (!pmd_access_permitted(orig, write))
return 0;
refs = 0;
@ -1299,7 +1304,7 @@ static int gup_huge_pud(pud_t orig, pud_t *pudp, unsigned long addr,
struct page *head, *page;
int refs;
if (write && !pud_write(orig))
if (!pud_access_permitted(orig, write))
return 0;
refs = 0;
@ -1335,7 +1340,7 @@ static int gup_huge_pgd(pgd_t orig, pgd_t *pgdp, unsigned long addr,
int refs;
struct page *head, *page;
if (write && !pgd_write(orig))
if (!pgd_access_permitted(orig, write))
return 0;
refs = 0;