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>
This commit is contained in:
Родитель
b1623e7eb2
Коммит
ca91e6c09d
|
@ -68,9 +68,6 @@ _GLOBAL(__hash_page_4K)
|
||||||
std r8,STK_PARM(r8)(r1)
|
std r8,STK_PARM(r8)(r1)
|
||||||
std r9,STK_PARM(r9)(r1)
|
std r9,STK_PARM(r9)(r1)
|
||||||
|
|
||||||
/* Add _PAGE_PRESENT to access */
|
|
||||||
ori r4,r4,_PAGE_PRESENT
|
|
||||||
|
|
||||||
/* Save non-volatile registers.
|
/* Save non-volatile registers.
|
||||||
* r31 will hold "old PTE"
|
* r31 will hold "old PTE"
|
||||||
* r30 is "new PTE"
|
* r30 is "new PTE"
|
||||||
|
@ -347,9 +344,6 @@ _GLOBAL(__hash_page_4K)
|
||||||
std r8,STK_PARM(r8)(r1)
|
std r8,STK_PARM(r8)(r1)
|
||||||
std r9,STK_PARM(r9)(r1)
|
std r9,STK_PARM(r9)(r1)
|
||||||
|
|
||||||
/* Add _PAGE_PRESENT to access */
|
|
||||||
ori r4,r4,_PAGE_PRESENT
|
|
||||||
|
|
||||||
/* Save non-volatile registers.
|
/* Save non-volatile registers.
|
||||||
* r31 will hold "old PTE"
|
* r31 will hold "old PTE"
|
||||||
* r30 is "new PTE"
|
* r30 is "new PTE"
|
||||||
|
@ -687,9 +681,6 @@ _GLOBAL(__hash_page_64K)
|
||||||
std r8,STK_PARM(r8)(r1)
|
std r8,STK_PARM(r8)(r1)
|
||||||
std r9,STK_PARM(r9)(r1)
|
std r9,STK_PARM(r9)(r1)
|
||||||
|
|
||||||
/* Add _PAGE_PRESENT to access */
|
|
||||||
ori r4,r4,_PAGE_PRESENT
|
|
||||||
|
|
||||||
/* Save non-volatile registers.
|
/* Save non-volatile registers.
|
||||||
* r31 will hold "old PTE"
|
* r31 will hold "old PTE"
|
||||||
* r30 is "new PTE"
|
* r30 is "new PTE"
|
||||||
|
|
|
@ -955,6 +955,17 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add _PAGE_PRESENT to the required access perm */
|
||||||
|
access |= _PAGE_PRESENT;
|
||||||
|
|
||||||
|
/* Pre-check access permissions (will be re-checked atomically
|
||||||
|
* in __hash_page_XX but this pre-check is a fast path
|
||||||
|
*/
|
||||||
|
if (access & ~pte_val(*ptep)) {
|
||||||
|
DBG_LOW(" no access !\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HUGETLB_PAGE
|
#ifdef CONFIG_HUGETLB_PAGE
|
||||||
if (hugeshift)
|
if (hugeshift)
|
||||||
return __hash_page_huge(ea, access, vsid, ptep, trap, local,
|
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)
|
||||||
DBG_LOW(" i-pte: %016lx %016lx\n", pte_val(*ptep),
|
DBG_LOW(" i-pte: %016lx %016lx\n", pte_val(*ptep),
|
||||||
pte_val(*(ptep + PTRS_PER_PTE)));
|
pte_val(*(ptep + PTRS_PER_PTE)));
|
||||||
#endif
|
#endif
|
||||||
/* Pre-check access permissions (will be re-checked atomically
|
|
||||||
* in __hash_page_XX but this pre-check is a fast path
|
|
||||||
*/
|
|
||||||
if (access & ~pte_val(*ptep)) {
|
|
||||||
DBG_LOW(" no access !\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do actual hashing */
|
/* Do actual hashing */
|
||||||
#ifdef CONFIG_PPC_64K_PAGES
|
#ifdef CONFIG_PPC_64K_PAGES
|
||||||
/* If _PAGE_4K_PFN is set, make sure this is a 4k segment */
|
/* If _PAGE_4K_PFN is set, make sure this is a 4k segment */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче