From: Dave Hansen <dave.han...@linux.intel.com>

The user portion of the kernel page tables use the NX bit to
poison them for userspace.  But, that trips the p4d/pgd_bad()
checks.  Make sure it does not do that.

Signed-off-by: Dave Hansen <dave.han...@linux.intel.com>
Cc: Moritz Lipp <moritz.l...@iaik.tugraz.at>
Cc: Daniel Gruss <daniel.gr...@iaik.tugraz.at>
Cc: Michael Schwarz <michael.schw...@iaik.tugraz.at>
Cc: Richard Fellner <richard.fell...@student.tugraz.at>
Cc: Andy Lutomirski <l...@kernel.org>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Kees Cook <keesc...@google.com>
Cc: Hugh Dickins <hu...@google.com>
Cc: x...@kernel.org
---

 b/arch/x86/include/asm/pgtable.h |   14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff -puN arch/x86/include/asm/pgtable.h~kaiser-p4d-allow-nx 
arch/x86/include/asm/pgtable.h
--- a/arch/x86/include/asm/pgtable.h~kaiser-p4d-allow-nx        2017-11-22 
15:45:47.382619743 -0800
+++ b/arch/x86/include/asm/pgtable.h    2017-11-22 15:45:47.386619743 -0800
@@ -846,7 +846,12 @@ static inline pud_t *pud_offset(p4d_t *p
 
 static inline int p4d_bad(p4d_t p4d)
 {
-       return (p4d_flags(p4d) & ~(_KERNPG_TABLE | _PAGE_USER)) != 0;
+       unsigned long ignore_flags = _KERNPG_TABLE | _PAGE_USER;
+
+       if (IS_ENABLED(CONFIG_KAISER))
+               ignore_flags |= _PAGE_NX;
+
+       return (p4d_flags(p4d) & ~ignore_flags) != 0;
 }
 #endif  /* CONFIG_PGTABLE_LEVELS > 3 */
 
@@ -880,7 +885,12 @@ static inline p4d_t *p4d_offset(pgd_t *p
 
 static inline int pgd_bad(pgd_t pgd)
 {
-       return (pgd_flags(pgd) & ~_PAGE_USER) != _KERNPG_TABLE;
+       unsigned long ignore_flags = _PAGE_USER;
+
+       if (IS_ENABLED(CONFIG_KAISER))
+               ignore_flags |= _PAGE_NX;
+
+       return (pgd_flags(pgd) & ~ignore_flags) != _KERNPG_TABLE;
 }
 
 static inline int pgd_none(pgd_t pgd)
_

Reply via email to