diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2010-07-22 18:53:23 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2010-07-22 18:53:23 -0400 |
commit | ca91e6c09d656c6deb1f2bc5d57186c718106aa5 (patch) | |
tree | a8d30759b6fac5616691b7a4a94222ab371d2bd6 /arch/powerpc | |
parent | b1623e7eb280f853f60338c7bb68bd3f3a970205 (diff) |
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>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/mm/hash_low_64.S | 9 | ||||
-rw-r--r-- | arch/powerpc/mm/hash_utils_64.c | 19 |
2 files changed, 11 insertions, 17 deletions
diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S index a719f53921a5..3079f6b44cf5 100644 --- a/arch/powerpc/mm/hash_low_64.S +++ b/arch/powerpc/mm/hash_low_64.S | |||
@@ -68,9 +68,6 @@ _GLOBAL(__hash_page_4K) | |||
68 | std r8,STK_PARM(r8)(r1) | 68 | std r8,STK_PARM(r8)(r1) |
69 | std r9,STK_PARM(r9)(r1) | 69 | std r9,STK_PARM(r9)(r1) |
70 | 70 | ||
71 | /* Add _PAGE_PRESENT to access */ | ||
72 | ori r4,r4,_PAGE_PRESENT | ||
73 | |||
74 | /* Save non-volatile registers. | 71 | /* Save non-volatile registers. |
75 | * r31 will hold "old PTE" | 72 | * r31 will hold "old PTE" |
76 | * r30 is "new PTE" | 73 | * r30 is "new PTE" |
@@ -347,9 +344,6 @@ _GLOBAL(__hash_page_4K) | |||
347 | std r8,STK_PARM(r8)(r1) | 344 | std r8,STK_PARM(r8)(r1) |
348 | std r9,STK_PARM(r9)(r1) | 345 | std r9,STK_PARM(r9)(r1) |
349 | 346 | ||
350 | /* Add _PAGE_PRESENT to access */ | ||
351 | ori r4,r4,_PAGE_PRESENT | ||
352 | |||
353 | /* Save non-volatile registers. | 347 | /* Save non-volatile registers. |
354 | * r31 will hold "old PTE" | 348 | * r31 will hold "old PTE" |
355 | * r30 is "new PTE" | 349 | * r30 is "new PTE" |
@@ -687,9 +681,6 @@ _GLOBAL(__hash_page_64K) | |||
687 | std r8,STK_PARM(r8)(r1) | 681 | std r8,STK_PARM(r8)(r1) |
688 | std r9,STK_PARM(r9)(r1) | 682 | std r9,STK_PARM(r9)(r1) |
689 | 683 | ||
690 | /* Add _PAGE_PRESENT to access */ | ||
691 | ori r4,r4,_PAGE_PRESENT | ||
692 | |||
693 | /* Save non-volatile registers. | 684 | /* Save non-volatile registers. |
694 | * r31 will hold "old PTE" | 685 | * r31 will hold "old PTE" |
695 | * r30 is "new PTE" | 686 | * r30 is "new PTE" |
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 98f262de5585..40847a9dd6db 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -955,6 +955,17 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
955 | return 1; | 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 | #ifdef CONFIG_HUGETLB_PAGE | 969 | #ifdef CONFIG_HUGETLB_PAGE |
959 | if (hugeshift) | 970 | if (hugeshift) |
960 | return __hash_page_huge(ea, access, vsid, ptep, trap, local, | 971 | return __hash_page_huge(ea, access, vsid, ptep, trap, local, |
@@ -967,14 +978,6 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
967 | DBG_LOW(" i-pte: %016lx %016lx\n", pte_val(*ptep), | 978 | DBG_LOW(" i-pte: %016lx %016lx\n", pte_val(*ptep), |
968 | pte_val(*(ptep + PTRS_PER_PTE))); | 979 | pte_val(*(ptep + PTRS_PER_PTE))); |
969 | #endif | 980 | #endif |
970 | /* Pre-check access permissions (will be re-checked atomically | ||
971 | * in __hash_page_XX but this pre-check is a fast path | ||
972 | */ | ||
973 | if (access & ~pte_val(*ptep)) { | ||
974 | DBG_LOW(" no access !\n"); | ||
975 | return 1; | ||
976 | } | ||
977 | |||
978 | /* Do actual hashing */ | 981 | /* Do actual hashing */ |
979 | #ifdef CONFIG_PPC_64K_PAGES | 982 | #ifdef CONFIG_PPC_64K_PAGES |
980 | /* If _PAGE_4K_PFN is set, make sure this is a 4k segment */ | 983 | /* If _PAGE_4K_PFN is set, make sure this is a 4k segment */ |