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

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
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -80,7 +80,9 @@ static __always_inline __pure bool use_fxsr(void)

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
extern void fpstate_init_soft(struct swregs_state *soft);
#else
+19 −16
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@
#include <linux/hardirq.h>
#include <linux/pkeys.h>

#include "xstate.h"

#define CREATE_TRACE_POINTS
#include <asm/trace/fpu.h>

@@ -203,15 +205,6 @@ void fpu_sync_fpstate(struct fpu *fpu)
	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)
{
	if (!use_xsave())
@@ -238,23 +231,33 @@ static inline void fpstate_init_fstate(struct fregs_state *fp)
	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);
		return;
	}

	memset(state, 0, fpu_kernel_xstate_size);
	xstate_init_xcomp_bv(&state->xsave, xfeatures_mask_uabi());

	if (static_cpu_has(X86_FEATURE_XSAVES))
		fpstate_init_xstate(&state->xsave);
	if (static_cpu_has(X86_FEATURE_FXSR))
	if (cpu_feature_enabled(X86_FEATURE_FXSR))
		fpstate_init_fxstate(&state->fxsave);
	else
		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 */
int fpu_clone(struct task_struct *dst)
+3 −3
Original line number Diff line number Diff line
@@ -121,10 +121,10 @@ static void __init fpu__init_system_mxcsr(void)
static void __init fpu__init_system_generic(void)
{
	/*
	 * Set up the legacy init FPU context. (xstate init might overwrite this
	 * with a more modern format, if the CPU supports it.)
	 * Set up the legacy init FPU context. Will be updated when the
	 * CPU supports XSAVE[S].
	 */
	fpstate_init(&init_fpstate);
	fpstate_init_user(&init_fpstate);

	fpu__init_system_mxcsr();
}
+3 −5
Original line number Diff line number Diff line
@@ -15,10 +15,10 @@
#include <asm/fpu/internal.h>
#include <asm/fpu/signal.h>
#include <asm/fpu/regset.h>
#include <asm/fpu/xstate.h>

#include <asm/tlbflush.h>
#include <asm/cpufeature.h>

#include "xstate.h"

/*
 * Although we spell it out in here, the Processor Trace
@@ -389,9 +389,7 @@ static void __init setup_init_fpu_buf(void)
	setup_xstate_features();
	print_xstate_features();

	if (boot_cpu_has(X86_FEATURE_XSAVES))
		init_fpstate.xsave.header.xcomp_bv = XCOMP_BV_COMPACTED_FORMAT |
						     xfeatures_mask_all;
	xstate_init_xcomp_bv(&init_fpstate.xsave, xfeatures_mask_all);

	/*
	 * Init all the features state with header.xfeatures being 0x0
+18 −0
Original line number Diff line number Diff line
/* 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
Loading