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

powerpc/mm: Move around testing of _PAGE_PRESENT in hash code

Instead of adding _PAGE_PRESENT to the access permission mask
in each low level routine independently, we add it once from
hash_page().

We also move the preliminary access check (the racy one before
the PTE is locked) up so it applies to the huge page case. This
duplicates code in __hash_page_huge() which we'll remove in a
subsequent patch to fix a race in there.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

+11 -17
-9
arch/powerpc/mm/hash_low_64.S
··· 68 68 std r8,STK_PARM(r8)(r1) 69 69 std r9,STK_PARM(r9)(r1) 70 70 71 - /* Add _PAGE_PRESENT to access */ 72 - ori r4,r4,_PAGE_PRESENT 73 - 74 71 /* Save non-volatile registers. 75 72 * r31 will hold "old PTE" 76 73 * r30 is "new PTE" ··· 343 346 std r6,STK_PARM(r6)(r1) 344 347 std r8,STK_PARM(r8)(r1) 345 348 std r9,STK_PARM(r9)(r1) 346 - 347 - /* Add _PAGE_PRESENT to access */ 348 - ori r4,r4,_PAGE_PRESENT 349 349 350 350 /* Save non-volatile registers. 351 351 * r31 will hold "old PTE" ··· 680 686 std r6,STK_PARM(r6)(r1) 681 687 std r8,STK_PARM(r8)(r1) 682 688 std r9,STK_PARM(r9)(r1) 683 - 684 - /* Add _PAGE_PRESENT to access */ 685 - ori r4,r4,_PAGE_PRESENT 686 689 687 690 /* Save non-volatile registers. 688 691 * r31 will hold "old PTE"
+11 -8
arch/powerpc/mm/hash_utils_64.c
··· 955 955 return 1; 956 956 } 957 957 958 + /* Add _PAGE_PRESENT to the required access perm */ 959 + access |= _PAGE_PRESENT; 960 + 961 + /* Pre-check access permissions (will be re-checked atomically 962 + * in __hash_page_XX but this pre-check is a fast path 963 + */ 964 + if (access & ~pte_val(*ptep)) { 965 + DBG_LOW(" no access !\n"); 966 + return 1; 967 + } 968 + 958 969 #ifdef CONFIG_HUGETLB_PAGE 959 970 if (hugeshift) 960 971 return __hash_page_huge(ea, access, vsid, ptep, trap, local, ··· 978 967 DBG_LOW(" i-pte: %016lx %016lx\n", pte_val(*ptep), 979 968 pte_val(*(ptep + PTRS_PER_PTE))); 980 969 #endif 981 - /* Pre-check access permissions (will be re-checked atomically 982 - * in __hash_page_XX but this pre-check is a fast path 983 - */ 984 - if (access & ~pte_val(*ptep)) { 985 - DBG_LOW(" no access !\n"); 986 - return 1; 987 - } 988 - 989 970 /* Do actual hashing */ 990 971 #ifdef CONFIG_PPC_64K_PAGES 991 972 /* If _PAGE_4K_PFN is set, make sure this is a 4k segment */