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);
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();
}
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;
}
/*
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)
* 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
*/
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(¤t->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;
}
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();
}
#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 */
/*
* 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) {
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;
*/
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)) {
static unsigned int xstate_supervisor_only_offsets[XFEATURE_MAX] __ro_after_init =
{ [ 0 ... XFEATURE_MAX - 1] = -1};
-/*
- * The XSAVE area of kernel can be in standard or compacted format;
- * it is always in standard format for user mode. This is the user
- * mode standard format size used for signal and ptrace frames.
- */
-unsigned int fpu_user_xstate_size __ro_after_init;
-
/*
* Return whether the system supports a given xfeature.
*
if (!paranoid_xstate_size_valid(kernel_size))
return -EINVAL;
- fpu_kernel_xstate_size = kernel_size;
- fpu_user_xstate_size = user_size;
+ /* Keep it the same for now */
+ fpu_kernel_cfg.max_size = kernel_size;
+ fpu_kernel_cfg.default_size = kernel_size;
+ fpu_user_cfg.max_size = user_size;
+ fpu_user_cfg.default_size = user_size;
return 0;
}
* We enabled the XSAVE hardware, but something went wrong and
* we can not use it. Disable it.
*/
-static void __init fpu__init_disable_system_xstate(void)
+static void __init fpu__init_disable_system_xstate(unsigned int legacy_size)
{
xfeatures_mask_all = 0;
cr4_clear_bits(X86_CR4_OSXSAVE);
setup_clear_cpu_cap(X86_FEATURE_XSAVE);
+
+ /* Restore the legacy size.*/
+ fpu_kernel_cfg.max_size = legacy_size;
+ fpu_kernel_cfg.default_size = legacy_size;
+ fpu_user_cfg.max_size = legacy_size;
+ fpu_user_cfg.default_size = legacy_size;
+
fpstate_reset(¤t->thread.fpu);
}
* Enable and initialize the xsave feature.
* Called once per system bootup.
*/
-void __init fpu__init_system_xstate(void)
+void __init fpu__init_system_xstate(unsigned int legacy_size)
{
unsigned int eax, ebx, ecx, edx;
u64 xfeatures;
* Update info used for ptrace frames; use standard-format size and no
* supervisor xstates:
*/
- update_regset_xstate_info(fpu_user_xstate_size, xfeatures_mask_uabi());
+ update_regset_xstate_info(fpu_user_cfg.max_size,
+ xfeatures_mask_uabi());
fpu__init_prepare_fx_sw_frame();
setup_init_fpu_buf();
print_xstate_offset_size();
pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n",
xfeatures_mask_all,
- fpu_kernel_xstate_size,
+ fpu_kernel_cfg.max_size,
boot_cpu_has(X86_FEATURE_XSAVES) ? "compacted" : "standard");
return;
out_disable:
/* something went wrong, try to boot without any XSAVE support */
- fpu__init_disable_system_xstate();
+ fpu__init_disable_system_xstate(legacy_size);
}
/*
extern void fpu__init_cpu_xstate(void);
-extern void fpu__init_system_xstate(void);
+extern void fpu__init_system_xstate(unsigned int legacy_size);
extern void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr);