|
@@ -44,6 +44,16 @@
|
|
|
|
|
|
#define _PAGE_PTE 0x4000000000000000UL /* distinguishes PTEs from pointers */
|
|
#define _PAGE_PTE 0x4000000000000000UL /* distinguishes PTEs from pointers */
|
|
#define _PAGE_PRESENT 0x8000000000000000UL /* pte contains a translation */
|
|
#define _PAGE_PRESENT 0x8000000000000000UL /* pte contains a translation */
|
|
|
|
+/*
|
|
|
|
+ * We need to mark a pmd pte invalid while splitting. We can do that by clearing
|
|
|
|
+ * the _PAGE_PRESENT bit. But then that will be taken as a swap pte. In order to
|
|
|
|
+ * differentiate between two use a SW field when invalidating.
|
|
|
|
+ *
|
|
|
|
+ * We do that temporary invalidate for regular pte entry in ptep_set_access_flags
|
|
|
|
+ *
|
|
|
|
+ * This is used only when _PAGE_PRESENT is cleared.
|
|
|
|
+ */
|
|
|
|
+#define _PAGE_INVALID _RPAGE_SW0
|
|
|
|
|
|
/*
|
|
/*
|
|
* Top and bottom bits of RPN which can be used by hash
|
|
* 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)
|
|
|
|
|
|
static inline int pte_present(pte_t pte)
|
|
static inline int pte_present(pte_t pte)
|
|
{
|
|
{
|
|
- return !!(pte_raw(pte) & cpu_to_be64(_PAGE_PRESENT));
|
|
|
|
|
|
+ /*
|
|
|
|
+ * A pte is considerent present if _PAGE_PRESENT is set.
|
|
|
|
+ * We also need to consider the pte present which is marked
|
|
|
|
+ * invalid during ptep_set_access_flags. Hence we look for _PAGE_INVALID
|
|
|
|
+ * if we find _PAGE_PRESENT cleared.
|
|
|
|
+ */
|
|
|
|
+ return !!(pte_raw(pte) & cpu_to_be64(_PAGE_PRESENT | _PAGE_INVALID));
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_PPC_MEM_KEYS
|
|
#ifdef CONFIG_PPC_MEM_KEYS
|