lkml.org 
[lkml]   [2021]   [Jul]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v7 09/26] x86/fpu/xstate: Update the XSTATE save function to support dynamic states
    Date
    Extend os_xsave() to receive a mask argument of which states to save, in
    preparation for dynamic user state handling.

    Update KVM to set a valid fpu->state_mask, so it can continue to share with
    the core code.

    Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
    Reviewed-by: Len Brown <len.brown@intel.com>
    Cc: x86@kernel.org
    Cc: linux-kernel@vger.kernel.org
    Cc: kvm@vger.kernel.org
    ---
    Changes from v5:
    * Adjusted the changelog and code for the new base code.

    Changes from v3:
    * Updated the changelog. (Borislav Petkov)
    * Made the code change more reviewable.

    Changes from v2:
    * Updated the changelog to clarify the KVM code changes.
    ---
    arch/x86/include/asm/fpu/internal.h | 3 +--
    arch/x86/kernel/fpu/core.c | 2 +-
    arch/x86/kernel/fpu/signal.c | 2 +-
    arch/x86/kvm/x86.c | 9 +++++++--
    4 files changed, 10 insertions(+), 6 deletions(-)

    diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h
    index d2fc19c0e457..263e349ff85a 100644
    --- a/arch/x86/include/asm/fpu/internal.h
    +++ b/arch/x86/include/asm/fpu/internal.h
    @@ -298,9 +298,8 @@ static inline void os_xrstor_booting(struct xregs_state *xstate)
    * Uses either XSAVE or XSAVEOPT or XSAVES depending on the CPU features
    * and command line options. The choice is permanent until the next reboot.
    */
    -static inline void os_xsave(struct xregs_state *xstate)
    +static inline void os_xsave(struct xregs_state *xstate, u64 mask)
    {
    - u64 mask = xfeatures_mask_all;
    u32 lmask = mask;
    u32 hmask = mask >> 32;
    int err;
    diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
    index 1f158e96c34f..ed127c4d182b 100644
    --- a/arch/x86/kernel/fpu/core.c
    +++ b/arch/x86/kernel/fpu/core.c
    @@ -99,7 +99,7 @@ EXPORT_SYMBOL(irq_fpu_usable);
    void save_fpregs_to_fpstate(struct fpu *fpu)
    {
    if (likely(use_xsave())) {
    - os_xsave(&fpu->state->xsave);
    + os_xsave(&fpu->state->xsave, fpu->state_mask);

    /*
    * AVX512 state is tracked here because its use is
    diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
    index 2f35aada2007..f70f84d53442 100644
    --- a/arch/x86/kernel/fpu/signal.c
    +++ b/arch/x86/kernel/fpu/signal.c
    @@ -365,7 +365,7 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx,
    * the right place in memory. It's ia32 mode. Shrug.
    */
    if (xfeatures_mask_supervisor())
    - os_xsave(&fpu->state->xsave);
    + os_xsave(&fpu->state->xsave, fpu->state_mask);
    set_thread_flag(TIF_NEED_FPU_LOAD);
    }
    __fpu_invalidate_fpregs_state(fpu);
    diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
    index c7c273899eb0..8c4ecc1628eb 100644
    --- a/arch/x86/kvm/x86.c
    +++ b/arch/x86/kvm/x86.c
    @@ -9888,11 +9888,16 @@ static void kvm_save_current_fpu(struct fpu *fpu)
    * KVM does not support dynamic user states yet. Assume the buffer
    * always has the minimum size.
    */
    - if (test_thread_flag(TIF_NEED_FPU_LOAD))
    + if (test_thread_flag(TIF_NEED_FPU_LOAD)) {
    memcpy(fpu->state, current->thread.fpu.state,
    get_xstate_config(XSTATE_MIN_SIZE));
    - else
    + } else {
    + struct fpu *src_fpu = &current->thread.fpu;
    +
    + if (fpu->state_mask != src_fpu->state_mask)
    + fpu->state_mask = src_fpu->state_mask;
    save_fpregs_to_fpstate(fpu);
    + }
    }

    /* Swap (qemu) user FPU context for the guest FPU context. */
    --
    2.17.1
    \
     
     \ /
      Last update: 2021-07-10 15:40    [W:22.506 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site