aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.ibm.com>2018-08-22 13:16:04 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2018-08-22 22:16:01 -0400
commitbd0dbb73e01306a1060e56f81e5fe287be936477 (patch)
treec9fca4a21b66504708a415be3f63b5a4d03573a6
parent810e9f86f36f59f1d6f6710220c49afe0c705f38 (diff)
powerpc/mm/books3s: Add new pte bit to mark pte temporarily invalid.
When splitting a huge pmd pte, we need to mark the pmd entry invalid. We can do that by clearing _PAGE_PRESENT bit. But then that will be taken as a swap pte. In order to differentiate between the two use a software pte bit when invalidating. For regular pte, due to bd5050e38aec ("powerpc/mm/radix: Change pte relax sequence to handle nest MMU hang") we need to mark the pte entry invalid when relaxing access permission. Instead of marking pte_none which can result in different page table walk routines possibly skipping this pte entry, invalidate it but still keep it marked present. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--arch/powerpc/include/asm/book3s/64/pgtable.h18
1 files changed, 17 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index 676118743a06..13a688fc8cd0 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -44,6 +44,16 @@
44 44
45#define _PAGE_PTE 0x4000000000000000UL /* distinguishes PTEs from pointers */ 45#define _PAGE_PTE 0x4000000000000000UL /* distinguishes PTEs from pointers */
46#define _PAGE_PRESENT 0x8000000000000000UL /* pte contains a translation */ 46#define _PAGE_PRESENT 0x8000000000000000UL /* pte contains a translation */
47/*
48 * We need to mark a pmd pte invalid while splitting. We can do that by clearing
49 * the _PAGE_PRESENT bit. But then that will be taken as a swap pte. In order to
50 * differentiate between two use a SW field when invalidating.
51 *
52 * We do that temporary invalidate for regular pte entry in ptep_set_access_flags
53 *
54 * This is used only when _PAGE_PRESENT is cleared.
55 */
56#define _PAGE_INVALID _RPAGE_SW0
47 57
48/* 58/*
49 * Top and bottom bits of RPN which can be used by hash 59 * Top and bottom bits of RPN which can be used by hash
@@ -568,7 +578,13 @@ static inline pte_t pte_clear_savedwrite(pte_t pte)
568 578
569static inline int pte_present(pte_t pte) 579static inline int pte_present(pte_t pte)
570{ 580{
571 return !!(pte_raw(pte) & cpu_to_be64(_PAGE_PRESENT)); 581 /*
582 * A pte is considerent present if _PAGE_PRESENT is set.
583 * We also need to consider the pte present which is marked
584 * invalid during ptep_set_access_flags. Hence we look for _PAGE_INVALID
585 * if we find _PAGE_PRESENT cleared.
586 */
587 return !!(pte_raw(pte) & cpu_to_be64(_PAGE_PRESENT | _PAGE_INVALID));
572} 588}
573 589
574#ifdef CONFIG_PPC_MEM_KEYS 590#ifdef CONFIG_PPC_MEM_KEYS