Skip to content

Commit 1c4de1f

Browse files
hansendcIngo Molnar
authored andcommitted
x86/mm/pti: Allow NX poison to be set in p4d/pgd
With PAGE_TABLE_ISOLATION the user portion of the kernel page tables is poisoned with the NX bit so if the entry code exits with the kernel page tables selected in CR3, userspace crashes. But doing so trips the p4d/pgd_bad() checks. Make sure it does not do that. Signed-off-by: Dave Hansen <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Borislav Petkov <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Boris Ostrovsky <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Brian Gerst <[email protected]> Cc: David Laight <[email protected]> Cc: Denys Vlasenko <[email protected]> Cc: Eduardo Valentin <[email protected]> Cc: Greg KH <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Josh Poimboeuf <[email protected]> Cc: Juergen Gross <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Will Deacon <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 61e9b36 commit 1c4de1f

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

arch/x86/include/asm/pgtable.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,12 @@ static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address)
846846

847847
static inline int p4d_bad(p4d_t p4d)
848848
{
849-
return (p4d_flags(p4d) & ~(_KERNPG_TABLE | _PAGE_USER)) != 0;
849+
unsigned long ignore_flags = _KERNPG_TABLE | _PAGE_USER;
850+
851+
if (IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION))
852+
ignore_flags |= _PAGE_NX;
853+
854+
return (p4d_flags(p4d) & ~ignore_flags) != 0;
850855
}
851856
#endif /* CONFIG_PGTABLE_LEVELS > 3 */
852857

@@ -880,7 +885,12 @@ static inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address)
880885

881886
static inline int pgd_bad(pgd_t pgd)
882887
{
883-
return (pgd_flags(pgd) & ~_PAGE_USER) != _KERNPG_TABLE;
888+
unsigned long ignore_flags = _PAGE_USER;
889+
890+
if (IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION))
891+
ignore_flags |= _PAGE_NX;
892+
893+
return (pgd_flags(pgd) & ~ignore_flags) != _KERNPG_TABLE;
884894
}
885895

886896
static inline int pgd_none(pgd_t pgd)

0 commit comments

Comments
 (0)