[PATCH 3.12 63/88] ARM: 8578/1: mm: ensure pmd_present only checks the valid bit

From: Jiri Slaby
Date: Thu Jul 14 2016 - 04:24:55 EST


From: Will Deacon <will.deacon@xxxxxxx>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 624531886987f0f1b5d01fb598034d039198e090 upstream.

In a subsequent patch, pmd_mknotpresent will clear the valid bit of the
pmd entry, resulting in a not-present entry from the hardware's
perspective. Unfortunately, pmd_present simply checks for a non-zero pmd
value and will therefore continue to return true even after a
pmd_mknotpresent operation. Since pmd_mknotpresent is only used for
managing huge entries, this is only an issue for the 3-level case.

This patch fixes the 3-level pmd_present implementation to take into
account the valid bit. For bisectability, the change is made before the
fix to pmd_mknotpresent.

[catalin.marinas@xxxxxxx: comment update regarding pmd_mknotpresent patch]

Fixes: 8d9625070073 ("ARM: mm: Transparent huge page support for LPAE systems.")
Cc: Russell King <linux@xxxxxxxxxxxxxxx>
Cc: Steve Capper <Steve.Capper@xxxxxxx>
Signed-off-by: Will Deacon <will.deacon@xxxxxxx>
Signed-off-by: Catalin Marinas <catalin.marinas@xxxxxxx>
Signed-off-by: Russell King <rmk+kernel@xxxxxxxxxxxxxxxx>
Signed-off-by: Jiri Slaby <jslaby@xxxxxxx>
---
arch/arm/include/asm/pgtable-2level.h | 1 +
arch/arm/include/asm/pgtable-3level.h | 1 +
arch/arm/include/asm/pgtable.h | 1 -
3 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
index c98c9c89b95c..3f1b3a4150b6 100644
--- a/arch/arm/include/asm/pgtable-2level.h
+++ b/arch/arm/include/asm/pgtable-2level.h
@@ -162,6 +162,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
}

#define pmd_bad(pmd) (pmd_val(pmd) & 2)
+#define pmd_present(pmd) (pmd_val(pmd))

#define copy_pmd(pmdpd,pmdps) \
do { \
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index 6a171d0afc12..8afa39f81477 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -209,6 +209,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
: !!(pmd_val(pmd) & (val)))
#define pmd_isclear(pmd, val) (!(pmd_val(pmd) & (val)))

+#define pmd_present(pmd) (pmd_isset((pmd), L_PMD_SECT_VALID))
#define pmd_young(pmd) (pmd_isset((pmd), PMD_SECT_AF))

#define __HAVE_ARCH_PMD_WRITE
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index a348bfd34f66..5bdf9864fb00 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -182,7 +182,6 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)

#define pmd_none(pmd) (!pmd_val(pmd))
-#define pmd_present(pmd) (pmd_val(pmd))

static inline pte_t *pmd_page_vaddr(pmd_t pmd)
{
--
2.9.1