On Fri, 10 Nov 2017, Dave Hansen wrote: This should be folded into the previous patch. > b/arch/x86/include/asm/pgtable_64.h | 94 +++++++++++++++++++++++------------- > 1 file changed, 61 insertions(+), 33 deletions(-) > > diff -puN arch/x86/include/asm/pgtable_64.h~kaiser-set-pgd-careful-plus-NX arch/x86/include/asm/pgtable_64.h > --- a/arch/x86/include/asm/pgtable_64.h~kaiser-set-pgd-careful-plus-NX 2017-11-10 11:22:09.932244947 -0800 > +++ b/arch/x86/include/asm/pgtable_64.h 2017-11-10 11:22:09.935244947 -0800 > @@ -177,38 +177,76 @@ static inline p4d_t *native_get_normal_p > /* > * Page table pages are page-aligned. The lower half of the top > * level is used for userspace and the top half for the kernel. > - * This returns true for user pages that need to get copied into > - * both the user and kernel copies of the page tables, and false > - * for kernel pages that should only be in the kernel copy. > + * > + * Returns true for parts of the PGD that map userspace and > + * false for the parts that map the kernel. > */ > -static inline bool is_userspace_pgd(void *__ptr) > +static inline bool pgdp_maps_userspace(void *__ptr) > { > unsigned long ptr = (unsigned long)__ptr; > > return ((ptr % PAGE_SIZE) < (PAGE_SIZE / 2)); > } > > +/* > + * Does this PGD allow access via userspace? s/via/from/ > + */ > +static inline bool pgd_userspace_access(pgd_t pgd) > +{ > + return (pgd.pgd & _PAGE_USER); > +} > + > +/* > + * Returns the pgd_t that the kernel should use in its page tables. Should? Can the caller still decide to put something different there? I doubt that. > +static inline pgd_t kaiser_set_shadow_pgd(pgd_t *pgdp, pgd_t pgd) > +{ > +#ifdef CONFIG_KAISER > + if (pgd_userspace_access(pgd)) { > + if (pgdp_maps_userspace(pgdp)) { > + /* > + * The user/shadow page tables get the full > + * PGD, accessible to userspace: s/to/from/ > + */ > + native_get_shadow_pgd(pgdp)->pgd = pgd.pgd; > + /* > + * For the copy of the pgd that the kernel > + * uses, make it unusable to userspace. This > + * ensures if we get out to userspace with the > + * wrong CR3 value, userspace will crash > + * instead of running. > + */ > + pgd.pgd |= _PAGE_NX; > + } > + } else if (!pgd.pgd) { > + /* > + * We are clearing the PGD and can not check _PAGE_USER > + * in the zero'd PGD. Just the argument cannot be checked because it's clearing the entry. The pgd entry itself is not yet modified, so it could be checked. * We never do this on the > + * pre-populated kernel PGDs, except for pgd_bad(). > + */ > + if (pgdp_maps_userspace(pgdp)) { > + native_get_shadow_pgd(pgdp)->pgd = pgd.pgd; > + } else { > + /* > + * Uh, we are very confused. We have been > + * asked to clear a PGD that is in the kernel > + * part of the address space. We preallocated > + * all the KAISER PGDs, so this should never > + * happen. > + */ > + WARN_ON_ONCE(1); > + } > + } Thanks, tglx -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>