Commit 2bd264bc authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Borislav Petkov
Browse files

x86/fpu: Move xstate size to fpu_*_cfg



Use the new kernel and user space config storage to store and retrieve the
XSTATE buffer sizes. The default and the maximum size are the same for now,
but will change when support for dynamically enabled features is added.

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20211014230739.296830097@linutronix.de
parent cd9ae761
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -298,7 +298,7 @@ void fpu_sync_fpstate(struct fpu *fpu)
static inline unsigned int init_fpstate_copy_size(void)
{
	if (!use_xsave())
		return fpu_kernel_xstate_size;
		return fpu_kernel_cfg.default_size;

	/* XSAVE(S) just needs the legacy and the xstate header part */
	return sizeof(init_fpstate.regs.xsave);
@@ -347,8 +347,8 @@ void fpstate_reset(struct fpu *fpu)
	fpu->fpstate = &fpu->__fpstate;

	/* Initialize sizes and feature masks */
	fpu->fpstate->size		= fpu_kernel_xstate_size;
	fpu->fpstate->user_size		= fpu_user_xstate_size;
	fpu->fpstate->size		= fpu_kernel_cfg.default_size;
	fpu->fpstate->user_size		= fpu_user_cfg.default_size;
	fpu->fpstate->xfeatures		= xfeatures_mask_all;
	fpu->fpstate->user_xfeatures	= xfeatures_mask_uabi();
}
@@ -420,7 +420,7 @@ int fpu_clone(struct task_struct *dst)
void fpu_thread_struct_whitelist(unsigned long *offset, unsigned long *size)
{
	*offset = offsetof(struct thread_struct, fpu.__fpstate.regs);
	*size = fpu_kernel_xstate_size;
	*size = fpu_kernel_cfg.default_size;
}

/*
+14 −17
Original line number Diff line number Diff line
@@ -133,14 +133,6 @@ static void __init fpu__init_system_generic(void)
	fpu__init_system_mxcsr();
}

/*
 * Size of the FPU context state. All tasks in the system use the
 * same context size, regardless of what portion they use.
 * This is inherent to the XSAVE architecture which puts all state
 * components into a single, continuous memory block:
 */
unsigned int fpu_kernel_xstate_size __ro_after_init;

/* Get alignment of the TYPE. */
#define TYPE_ALIGN(TYPE) offsetof(struct { char x; TYPE test; }, test)

@@ -171,7 +163,7 @@ static void __init fpu__init_task_struct_size(void)
	 * Add back the dynamically-calculated register state
	 * size.
	 */
	task_size += fpu_kernel_xstate_size;
	task_size += fpu_kernel_cfg.default_size;

	/*
	 * We dynamically size 'struct fpu', so we require that
@@ -195,25 +187,30 @@ static void __init fpu__init_task_struct_size(void)
 */
static void __init fpu__init_system_xstate_size_legacy(void)
{
	unsigned int size;

	/*
	 * Note that xstate sizes might be overwritten later during
	 * fpu__init_system_xstate().
	 * Note that the size configuration might be overwritten later
	 * during fpu__init_system_xstate().
	 */
	if (!cpu_feature_enabled(X86_FEATURE_FPU))
		fpu_kernel_xstate_size = sizeof(struct swregs_state);
		size = sizeof(struct swregs_state);
	else if (cpu_feature_enabled(X86_FEATURE_FXSR))
		fpu_kernel_xstate_size = sizeof(struct fxregs_state);
		size = sizeof(struct fxregs_state);
	else
		fpu_kernel_xstate_size = sizeof(struct fregs_state);
		size = sizeof(struct fregs_state);

	fpu_user_xstate_size = fpu_kernel_xstate_size;
	fpu_kernel_cfg.max_size = size;
	fpu_kernel_cfg.default_size = size;
	fpu_user_cfg.max_size = size;
	fpu_user_cfg.default_size = size;
	fpstate_reset(&current->thread.fpu);
}

static void __init fpu__init_init_fpstate(void)
{
	/* Bring init_fpstate size and features up to date */
	init_fpstate.size		= fpu_kernel_xstate_size;
	init_fpstate.size		= fpu_kernel_cfg.max_size;
	init_fpstate.xfeatures		= xfeatures_mask_all;
}

@@ -234,7 +231,7 @@ void __init fpu__init_system(struct cpuinfo_x86 *c)

	fpu__init_system_generic();
	fpu__init_system_xstate_size_legacy();
	fpu__init_system_xstate();
	fpu__init_system_xstate(fpu_kernel_cfg.max_size);
	fpu__init_task_struct_size();
	fpu__init_init_fpstate();
}
+0 −2
Original line number Diff line number Diff line
@@ -2,8 +2,6 @@
#ifndef __X86_KERNEL_FPU_INTERNAL_H
#define __X86_KERNEL_FPU_INTERNAL_H

extern unsigned int fpu_kernel_xstate_size;
extern unsigned int fpu_user_xstate_size;
extern struct fpstate init_fpstate;

/* CPU feature check wrappers */
+1 −1
Original line number Diff line number Diff line
@@ -153,7 +153,7 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset,
	/*
	 * A whole standard-format XSAVE buffer is needed:
	 */
	if (pos != 0 || count != fpu_user_xstate_size)
	if (pos != 0 || count != fpu_user_cfg.max_size)
		return -EFAULT;

	if (!kbuf) {
+3 −3
Original line number Diff line number Diff line
@@ -503,7 +503,7 @@ fpu__alloc_mathframe(unsigned long sp, int ia32_frame,

unsigned long __init fpu__get_fpstate_size(void)
{
	unsigned long ret = fpu_user_xstate_size;
	unsigned long ret = fpu_user_cfg.max_size;

	if (use_xsave())
		ret += FP_XSTATE_MAGIC2_SIZE;
@@ -531,12 +531,12 @@ unsigned long __init fpu__get_fpstate_size(void)
 */
void __init fpu__init_prepare_fx_sw_frame(void)
{
	int size = fpu_user_xstate_size + FP_XSTATE_MAGIC2_SIZE;
	int size = fpu_user_cfg.default_size + FP_XSTATE_MAGIC2_SIZE;

	fx_sw_reserved.magic1 = FP_XSTATE_MAGIC1;
	fx_sw_reserved.extended_size = size;
	fx_sw_reserved.xfeatures = xfeatures_mask_uabi();
	fx_sw_reserved.xstate_size = fpu_user_xstate_size;
	fx_sw_reserved.xstate_size = fpu_user_cfg.default_size;

	if (IS_ENABLED(CONFIG_IA32_EMULATION) ||
	    IS_ENABLED(CONFIG_X86_32)) {
Loading