aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Hansen <dave.hansen@intel.com>2017-11-06 17:29:51 -0800
committerDave Hansen <dave.hansen@intel.com>2017-11-06 17:29:51 -0800
commitef4f9e8cd08df643cedbccf043489edfdf88bf71 (patch)
treeeb9f79aaf07b06955856c131e11ad231424f4537
parentcd3420e4b5c472df96be1d4822f7c39a851f0968 (diff)
downloadx86-kaiser-ef4f9e8cd08df643cedbccf043489edfdf88bf71.tar.gz
x86, kaiser: allow NX to be set in p4d/pgd
From: Dave Hansen <dave.hansen@linux.intel.com> 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 <dave.hansen@linux.intel.com> Cc: Moritz Lipp <moritz.lipp@iaik.tugraz.at> Cc: Daniel Gruss <daniel.gruss@iaik.tugraz.at> Cc: Michael Schwarz <michael.schwarz@iaik.tugraz.at> Cc: Richard Fellner <richard.fellner@student.tugraz.at> Cc: Andy Lutomirski <luto@kernel.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Kees Cook <keescook@google.com> Cc: Hugh Dickins <hughd@google.com> Cc: x86@kernel.org
-rw-r--r--arch/x86/include/asm/pgtable.h14
1 files changed, 12 insertions, 2 deletions
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 5ce5a19f6cf7a9..c149fdfcd1ed7a 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -845,7 +845,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 */
@@ -879,7 +884,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)