Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <kirill.shutemov@linux.intel.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Aneesh Kumar K . V <aneesh.kumar@linux.vnet.ibm.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dann Frazier <dann.frazier@canonical.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rik van Riel <riel@redhat.com>
Cc: Steve Capper <steve.capper@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-arch@vger.kernel.org
Cc: linux-mm@kvack.org
Link: http://lkml.kernel.org/r/20170316152655.37789-3-kirill.shutemov@linux.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Kirill A. Shutemov and committed by
Ingo Molnar
e7884f8e 9a804fec

+35 -5
+25
include/asm-generic/pgtable.h
··· 341 341 } 342 342 #endif 343 343 344 + #ifndef pte_access_permitted 345 + #define pte_access_permitted(pte, write) \ 346 + (pte_present(pte) && (!(write) || pte_write(pte))) 347 + #endif 348 + 349 + #ifndef pmd_access_permitted 350 + #define pmd_access_permitted(pmd, write) \ 351 + (pmd_present(pmd) && (!(write) || pmd_write(pmd))) 352 + #endif 353 + 354 + #ifndef pud_access_permitted 355 + #define pud_access_permitted(pud, write) \ 356 + (pud_present(pud) && (!(write) || pud_write(pud))) 357 + #endif 358 + 359 + #ifndef p4d_access_permitted 360 + #define p4d_access_permitted(p4d, write) \ 361 + (p4d_present(p4d) && (!(write) || p4d_write(p4d))) 362 + #endif 363 + 364 + #ifndef pgd_access_permitted 365 + #define pgd_access_permitted(pgd, write) \ 366 + (pgd_present(pgd) && (!(write) || pgd_write(pgd))) 367 + #endif 368 + 344 369 #ifndef __HAVE_ARCH_PMD_SAME 345 370 #ifdef CONFIG_TRANSPARENT_HUGEPAGE 346 371 static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)
+10 -5
mm/gup.c
··· 1212 1212 * Similar to the PMD case below, NUMA hinting must take slow 1213 1213 * path using the pte_protnone check. 1214 1214 */ 1215 - if (!pte_present(pte) || pte_special(pte) || 1216 - pte_protnone(pte) || (write && !pte_write(pte))) 1215 + if (pte_protnone(pte)) 1216 + goto pte_unmap; 1217 + 1218 + if (!pte_access_permitted(pte, write)) 1219 + goto pte_unmap; 1220 + 1221 + if (pte_special(pte)) 1217 1222 goto pte_unmap; 1218 1223 1219 1224 VM_BUG_ON(!pfn_valid(pte_pfn(pte))); ··· 1269 1264 struct page *head, *page; 1270 1265 int refs; 1271 1266 1272 - if (write && !pmd_write(orig)) 1267 + if (!pmd_access_permitted(orig, write)) 1273 1268 return 0; 1274 1269 1275 1270 refs = 0; ··· 1304 1299 struct page *head, *page; 1305 1300 int refs; 1306 1301 1307 - if (write && !pud_write(orig)) 1302 + if (!pud_access_permitted(orig, write)) 1308 1303 return 0; 1309 1304 1310 1305 refs = 0; ··· 1340 1335 int refs; 1341 1336 struct page *head, *page; 1342 1337 1343 - if (write && !pgd_write(orig)) 1338 + if (!pgd_access_permitted(orig, write)) 1344 1339 return 0; 1345 1340 1346 1341 refs = 0;