Commit 126fe040 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Borislav Petkov

x86/fpu: Cleanup xstate xcomp_bv initialization

No point in having this duplicated all over the place with needlessly
different defines.

Provide a proper initialization function which initializes user buffers
properly and make KVM use it.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20211015011538.897664678@linutronix.de
parent 509e7a30
...@@ -80,7 +80,9 @@ static __always_inline __pure bool use_fxsr(void) ...@@ -80,7 +80,9 @@ static __always_inline __pure bool use_fxsr(void)
extern union fpregs_state init_fpstate; extern union fpregs_state init_fpstate;
extern void fpstate_init(union fpregs_state *state); extern void fpstate_init_user(union fpregs_state *state);
extern void fpu_init_fpstate_user(struct fpu *fpu);
#ifdef CONFIG_MATH_EMULATION #ifdef CONFIG_MATH_EMULATION
extern void fpstate_init_soft(struct swregs_state *soft); extern void fpstate_init_soft(struct swregs_state *soft);
#else #else
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include <linux/hardirq.h> #include <linux/hardirq.h>
#include <linux/pkeys.h> #include <linux/pkeys.h>
#include "xstate.h"
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include <asm/trace/fpu.h> #include <asm/trace/fpu.h>
...@@ -203,15 +205,6 @@ void fpu_sync_fpstate(struct fpu *fpu) ...@@ -203,15 +205,6 @@ void fpu_sync_fpstate(struct fpu *fpu)
fpregs_unlock(); fpregs_unlock();
} }
static inline void fpstate_init_xstate(struct xregs_state *xsave)
{
/*
* XRSTORS requires these bits set in xcomp_bv, or it will
* trigger #GP:
*/
xsave->header.xcomp_bv = XCOMP_BV_COMPACTED_FORMAT | xfeatures_mask_all;
}
static inline unsigned int init_fpstate_copy_size(void) static inline unsigned int init_fpstate_copy_size(void)
{ {
if (!use_xsave()) if (!use_xsave())
...@@ -238,23 +231,33 @@ static inline void fpstate_init_fstate(struct fregs_state *fp) ...@@ -238,23 +231,33 @@ static inline void fpstate_init_fstate(struct fregs_state *fp)
fp->fos = 0xffff0000u; fp->fos = 0xffff0000u;
} }
void fpstate_init(union fpregs_state *state) /*
* Used in two places:
* 1) Early boot to setup init_fpstate for non XSAVE systems
* 2) fpu_init_fpstate_user() which is invoked from KVM
*/
void fpstate_init_user(union fpregs_state *state)
{ {
if (!static_cpu_has(X86_FEATURE_FPU)) { if (!cpu_feature_enabled(X86_FEATURE_FPU)) {
fpstate_init_soft(&state->soft); fpstate_init_soft(&state->soft);
return; return;
} }
memset(state, 0, fpu_kernel_xstate_size); xstate_init_xcomp_bv(&state->xsave, xfeatures_mask_uabi());
if (static_cpu_has(X86_FEATURE_XSAVES)) if (cpu_feature_enabled(X86_FEATURE_FXSR))
fpstate_init_xstate(&state->xsave);
if (static_cpu_has(X86_FEATURE_FXSR))
fpstate_init_fxstate(&state->fxsave); fpstate_init_fxstate(&state->fxsave);
else else
fpstate_init_fstate(&state->fsave); fpstate_init_fstate(&state->fsave);
} }
EXPORT_SYMBOL_GPL(fpstate_init);
#if IS_ENABLED(CONFIG_KVM)
void fpu_init_fpstate_user(struct fpu *fpu)
{
fpstate_init_user(&fpu->state);
}
EXPORT_SYMBOL_GPL(fpu_init_fpstate_user);
#endif
/* Clone current's FPU state on fork */ /* Clone current's FPU state on fork */
int fpu_clone(struct task_struct *dst) int fpu_clone(struct task_struct *dst)
......
...@@ -121,10 +121,10 @@ static void __init fpu__init_system_mxcsr(void) ...@@ -121,10 +121,10 @@ static void __init fpu__init_system_mxcsr(void)
static void __init fpu__init_system_generic(void) static void __init fpu__init_system_generic(void)
{ {
/* /*
* Set up the legacy init FPU context. (xstate init might overwrite this * Set up the legacy init FPU context. Will be updated when the
* with a more modern format, if the CPU supports it.) * CPU supports XSAVE[S].
*/ */
fpstate_init(&init_fpstate); fpstate_init_user(&init_fpstate);
fpu__init_system_mxcsr(); fpu__init_system_mxcsr();
} }
......
...@@ -15,10 +15,10 @@ ...@@ -15,10 +15,10 @@
#include <asm/fpu/internal.h> #include <asm/fpu/internal.h>
#include <asm/fpu/signal.h> #include <asm/fpu/signal.h>
#include <asm/fpu/regset.h> #include <asm/fpu/regset.h>
#include <asm/fpu/xstate.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <asm/cpufeature.h>
#include "xstate.h"
/* /*
* Although we spell it out in here, the Processor Trace * Although we spell it out in here, the Processor Trace
...@@ -389,9 +389,7 @@ static void __init setup_init_fpu_buf(void) ...@@ -389,9 +389,7 @@ static void __init setup_init_fpu_buf(void)
setup_xstate_features(); setup_xstate_features();
print_xstate_features(); print_xstate_features();
if (boot_cpu_has(X86_FEATURE_XSAVES)) xstate_init_xcomp_bv(&init_fpstate.xsave, xfeatures_mask_all);
init_fpstate.xsave.header.xcomp_bv = XCOMP_BV_COMPACTED_FORMAT |
xfeatures_mask_all;
/* /*
* Init all the features state with header.xfeatures being 0x0 * Init all the features state with header.xfeatures being 0x0
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __X86_KERNEL_FPU_XSTATE_H
#define __X86_KERNEL_FPU_XSTATE_H
#include <asm/cpufeature.h>
#include <asm/fpu/xstate.h>
static inline void xstate_init_xcomp_bv(struct xregs_state *xsave, u64 mask)
{
/*
* XRSTORS requires these bits set in xcomp_bv, or it will
* trigger #GP:
*/
if (cpu_feature_enabled(X86_FEATURE_XSAVES))
xsave->header.xcomp_bv = mask | XCOMP_BV_COMPACTED_FORMAT;
}
#endif
...@@ -10626,14 +10626,6 @@ static int sync_regs(struct kvm_vcpu *vcpu) ...@@ -10626,14 +10626,6 @@ static int sync_regs(struct kvm_vcpu *vcpu)
static void fx_init(struct kvm_vcpu *vcpu) static void fx_init(struct kvm_vcpu *vcpu)
{ {
if (!vcpu->arch.guest_fpu)
return;
fpstate_init(&vcpu->arch.guest_fpu->state);
if (boot_cpu_has(X86_FEATURE_XSAVES))
vcpu->arch.guest_fpu->state.xsave.header.xcomp_bv =
host_xcr0 | XSTATE_COMPACTION_ENABLED;
/* /*
* Ensure guest xcr0 is valid for loading * Ensure guest xcr0 is valid for loading
*/ */
...@@ -10720,6 +10712,9 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) ...@@ -10720,6 +10712,9 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
pr_err("kvm: failed to allocate vcpu's fpu\n"); pr_err("kvm: failed to allocate vcpu's fpu\n");
goto free_user_fpu; goto free_user_fpu;
} }
fpu_init_fpstate_user(vcpu->arch.user_fpu);
fpu_init_fpstate_user(vcpu->arch.guest_fpu);
fx_init(vcpu); fx_init(vcpu);
vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu); vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment