]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ARM: 8578/1: mm: ensure pmd_present only checks the valid bit
authorWill Deacon <will.deacon@arm.com>
Tue, 7 Jun 2016 16:57:54 +0000 (17:57 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 27 Jul 2016 16:55:49 +0000 (09:55 -0700)
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@arm.com: comment update regarding pmd_mknotpresent patch]

Fixes: 8d9625070073 ("ARM: mm: Transparent huge page support for LPAE systems.")
Cc: Russell King <linux@armlinux.org.uk>
Cc: Steve Capper <Steve.Capper@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/arm/include/asm/pgtable-2level.h
arch/arm/include/asm/pgtable-3level.h
arch/arm/include/asm/pgtable.h

index 219ac88a954243b3e3acaebcebd9871ea49825e4..bed6c8fa54b504182471a259ba84f5d682983f07 100644 (file)
@@ -163,6 +163,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
 
 #define pmd_large(pmd)         (pmd_val(pmd) & 2)
 #define pmd_bad(pmd)           (pmd_val(pmd) & 2)
+#define pmd_present(pmd)       (pmd_val(pmd))
 
 #define copy_pmd(pmdpd,pmdps)          \
        do {                            \
index 06e0bc0f8b00b2c7f9fe9f6dac97c81b00b803bb..ab7ee9205ca454254d7fc6200a15972804254d0e 100644 (file)
@@ -212,6 +212,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
index 89dba131703b6e7181a3dd20a9cdf954c126acab..9a9701815b57df432870335dee8cc9f8765a7a1a 100644 (file)
@@ -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)
 {