From: Dave Hansen <[email protected]> We protect user portion of the kernel page tables with the NX bit to cripple it. But, that trips the p4d/pgd_bad() checks. Make sure it does not do that.
Signed-off-by: Dave Hansen <[email protected]> Cc: Moritz Lipp <[email protected]> Cc: Daniel Gruss <[email protected]> Cc: Michael Schwarz <[email protected]> Cc: Richard Fellner <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Kees Cook <[email protected]> Cc: Hugh Dickins <[email protected]> Cc: [email protected] --- 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-08 10:45:31.308681390 -0800 +++ b/arch/x86/include/asm/pgtable.h 2017-11-08 10:45:31.312681390 -0800 @@ -845,7 +845,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 */ @@ -879,7 +884,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) _

