lkml.org 
[lkml]   [2021]   [Jun]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[RFC][PATCH 4/8] x86/fpu: remove PKRU from FPU user state clearing
    From
    Date

    From: Dave Hansen <dave.hansen@linux.intel.com>

    The signal code has a few points where it initializes user FPU state.
    Remove PKRU from the set of features which are initialized in the FPU
    code. Use write_pkru() to explicitly initialize PKRU instead of using
    the fpstate/XSAVE infrastructure.

    Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: x86@kernel.org
    Cc: Andy Lutomirski <luto@kernel.org>
    ---

    b/arch/x86/kernel/fpu/core.c | 8 +++++---
    b/arch/x86/kernel/fpu/signal.c | 5 ++++-
    b/arch/x86/kernel/signal.c | 1 +
    3 files changed, 10 insertions(+), 4 deletions(-)

    diff -puN arch/x86/kernel/fpu/core.c~no-pkru-in-fpu__clear_user_states arch/x86/kernel/fpu/core.c
    --- a/arch/x86/kernel/fpu/core.c~no-pkru-in-fpu__clear_user_states 2021-06-22 14:49:10.026051754 -0700
    +++ b/arch/x86/kernel/fpu/core.c 2021-06-22 14:49:10.039051754 -0700
    @@ -209,7 +209,8 @@ static inline void fpstate_init_xstate(s
    * XRSTORS requires these bits set in xcomp_bv, or it will
    * trigger #GP:
    */
    - xsave->header.xcomp_bv = XCOMP_BV_COMPACTED_FORMAT | xfeatures_mask_all;
    + xsave->header.xcomp_bv = XCOMP_BV_COMPACTED_FORMAT |
    + xfeatures_mask_fpstate();
    }

    static inline void fpstate_init_fxstate(struct fxregs_state *fx)
    @@ -389,8 +390,9 @@ void fpu__clear_user_states(struct fpu *
    os_xrstor(&fpu->state.xsave, xfeatures_mask_supervisor());
    }

    - /* Reset user states in registers. */
    - load_fpregs_from_init_fpstate(xfeatures_mask_restore_user());
    + /* Reset user registers maintained in fpstate. */
    + load_fpregs_from_init_fpstate(xfeatures_mask_fpstate() &
    + xfeatures_mask_restore_user());

    /*
    * Now all FPU registers have their desired values. Inform the FPU
    diff -puN arch/x86/kernel/fpu/signal.c~no-pkru-in-fpu__clear_user_states arch/x86/kernel/fpu/signal.c
    --- a/arch/x86/kernel/fpu/signal.c~no-pkru-in-fpu__clear_user_states 2021-06-22 14:49:10.031051754 -0700
    +++ b/arch/x86/kernel/fpu/signal.c 2021-06-22 14:49:10.040051754 -0700
    @@ -437,6 +437,7 @@ int fpu__restore_sig(void __user *buf, i
    int ret;

    if (unlikely(!buf)) {
    + write_pkru(pkru_get_init_value());
    fpu__clear_user_states(&current->thread.fpu);
    return 0;
    }
    @@ -468,8 +469,10 @@ int fpu__restore_sig(void __user *buf, i
    ret = __fpu_restore_sig(buf, buf_fx, ia32_fxstate);

    out:
    - if (unlikely(ret))
    + if (unlikely(ret)) {
    + write_pkru(pkru_get_init_value());
    fpu__clear_user_states(&current->thread.fpu);
    + }

    return ret;
    }
    diff -puN arch/x86/kernel/signal.c~no-pkru-in-fpu__clear_user_states arch/x86/kernel/signal.c
    --- a/arch/x86/kernel/signal.c~no-pkru-in-fpu__clear_user_states 2021-06-22 14:49:10.033051754 -0700
    +++ b/arch/x86/kernel/signal.c 2021-06-22 14:49:10.043051754 -0700
    @@ -835,6 +835,7 @@ handle_signal(struct ksignal *ksig, stru
    /*
    * Ensure the signal handler starts with the new fpu state.
    */
    + write_pkru(pkru_get_init_value());
    fpu__clear_user_states(fpu);
    }
    signal_setup_done(failed, ksig, stepping);
    _
    \
     
     \ /
      Last update: 2021-06-23 00:26    [W:2.627 / U:0.228 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site