lkml.org 
[lkml]   [2021]   [Jun]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[tip: x86/fpu] x86/fpu: Move FXSAVE_LEAK quirk info __copy_kernel_to_fpregs()
    The following commit has been merged into the x86/fpu branch of tip:

    Commit-ID: 1d9bffab116fadfe1594f5fea2b50ab280d81d30
    Gitweb: https://git.kernel.org/tip/1d9bffab116fadfe1594f5fea2b50ab280d81d30
    Author: Thomas Gleixner <tglx@linutronix.de>
    AuthorDate: Wed, 23 Jun 2021 14:02:15 +02:00
    Committer: Borislav Petkov <bp@suse.de>
    CommitterDate: Wed, 23 Jun 2021 19:26:37 +02:00

    x86/fpu: Move FXSAVE_LEAK quirk info __copy_kernel_to_fpregs()

    copy_kernel_to_fpregs() restores all xfeatures but it is also the place
    where the AMD FXSAVE_LEAK bug is handled.

    That prevents fpregs_restore_userregs() to limit the restored features,
    which is required to untangle PKRU and XSTATE handling and also for the
    upcoming supervisor state management.

    Move the FXSAVE_LEAK quirk into __copy_kernel_to_fpregs() and deinline that
    function which has become rather fat.

    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Borislav Petkov <bp@suse.de>
    Reviewed-by: Borislav Petkov <bp@suse.de>
    Link: https://lkml.kernel.org/r/20210623121456.114271278@linutronix.de
    ---
    arch/x86/include/asm/fpu/internal.h | 25 +------------------------
    arch/x86/kernel/fpu/core.c | 27 +++++++++++++++++++++++++++
    2 files changed, 28 insertions(+), 24 deletions(-)

    diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h
    index f7688f6..63d9796 100644
    --- a/arch/x86/include/asm/fpu/internal.h
    +++ b/arch/x86/include/asm/fpu/internal.h
    @@ -379,33 +379,10 @@ static inline int os_xrstor_safe(struct xregs_state *xstate, u64 mask)
    return err;
    }

    -static inline void __restore_fpregs_from_fpstate(union fpregs_state *fpstate, u64 mask)
    -{
    - if (use_xsave()) {
    - os_xrstor(&fpstate->xsave, mask);
    - } else {
    - if (use_fxsr())
    - fxrstor(&fpstate->fxsave);
    - else
    - frstor(&fpstate->fsave);
    - }
    -}
    +extern void __restore_fpregs_from_fpstate(union fpregs_state *fpstate, u64 mask);

    static inline void restore_fpregs_from_fpstate(union fpregs_state *fpstate)
    {
    - /*
    - * AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception is
    - * pending. Clear the x87 state here by setting it to fixed values.
    - * "m" is a random variable that should be in L1.
    - */
    - if (unlikely(static_cpu_has_bug(X86_BUG_FXSAVE_LEAK))) {
    - asm volatile(
    - "fnclex\n\t"
    - "emms\n\t"
    - "fildl %P[addr]" /* set F?P to defined value */
    - : : [addr] "m" (fpstate));
    - }
    -
    __restore_fpregs_from_fpstate(fpstate, -1);
    }

    diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
    index 6babf18..afd0dee 100644
    --- a/arch/x86/kernel/fpu/core.c
    +++ b/arch/x86/kernel/fpu/core.c
    @@ -124,6 +124,33 @@ void save_fpregs_to_fpstate(struct fpu *fpu)
    }
    EXPORT_SYMBOL(save_fpregs_to_fpstate);

    +void __restore_fpregs_from_fpstate(union fpregs_state *fpstate, u64 mask)
    +{
    + /*
    + * AMD K7/K8 and later CPUs up to Zen don't save/restore
    + * FDP/FIP/FOP unless an exception is pending. Clear the x87 state
    + * here by setting it to fixed values. "m" is a random variable
    + * that should be in L1.
    + */
    + if (unlikely(static_cpu_has_bug(X86_BUG_FXSAVE_LEAK))) {
    + asm volatile(
    + "fnclex\n\t"
    + "emms\n\t"
    + "fildl %P[addr]" /* set F?P to defined value */
    + : : [addr] "m" (fpstate));
    + }
    +
    + if (use_xsave()) {
    + os_xrstor(&fpstate->xsave, mask);
    + } else {
    + if (use_fxsr())
    + fxrstor(&fpstate->fxsave);
    + else
    + frstor(&fpstate->fsave);
    + }
    +}
    +EXPORT_SYMBOL_GPL(__restore_fpregs_from_fpstate);
    +
    void kernel_fpu_begin_mask(unsigned int kfpu_mask)
    {
    preempt_disable();
    \
     
     \ /
      Last update: 2021-06-24 00:10    [W:2.754 / U:0.328 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site