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: Andy Lutomirski <l...@kernel.org> Cc: Borislav Petkov <b...@alien8.de> Cc: Brian Gerst <brge...@gmail.com> Cc: Daniel Gruss <daniel.gr...@iaik.tugraz.at> Cc: Denys Vlasenko <dvlas...@redhat.com> Cc: H. Peter Anvin <h...@zytor.com> Cc: Hugh Dickins <hu...@google.com> Cc: Josh Poimboeuf <jpoim...@redhat.com> Cc: Kees Cook <keesc...@google.com> Cc: Linus Torvalds <torva...@linux-foundation.org> Cc: Michael Schwarz <michael.schw...@iaik.tugraz.at> Cc: Moritz Lipp <moritz.l...@iaik.tugraz.at> Cc: Peter Zijlstra <pet...@infradead.org> Cc: Richard Fellner <richard.fell...@student.tugraz.at> Cc: Thomas Gleixner <t...@linutronix.de> Cc: linux...@kvack.org Link: http://lkml.kernel.org/r/20171123003448.c6ab3...@viggo.jf.intel.com Signed-off-by: Ingo Molnar <mi...@kernel.org> --- arch/x86/include/asm/pgtable.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index d3901124143f..9cceaf6c0405 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -846,7 +846,12 @@ static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address) 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 *pgd, unsigned long address) 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) -- 2.14.1