lkml.org 
[lkml]   [2017]   [Nov]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH 09/30] x86, kaiser: only populate shadow page tables for userspace
    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

    \
     
     \ /
      Last update: 2017-11-20 21:12    [W:4.090 / U:0.808 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site