]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
x86/fpu: Move xstate size to fpu_*_cfg
authorThomas Gleixner <tglx@linutronix.de>
Thu, 14 Oct 2021 23:09:34 +0000 (01:09 +0200)
committerBorislav Petkov <bp@suse.de>
Thu, 21 Oct 2021 17:38:55 +0000 (19:38 +0200)
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: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20211014230739.296830097@linutronix.de
arch/x86/kernel/fpu/core.c
arch/x86/kernel/fpu/init.c
arch/x86/kernel/fpu/internal.h
arch/x86/kernel/fpu/regset.c
arch/x86/kernel/fpu/signal.c
arch/x86/kernel/fpu/xstate.c
arch/x86/kernel/fpu/xstate.h

index 3512bb241d955ebef7fdb59ff4a80fa78dc106c3..69abf3a2299d56a71c0b9936dae13619322b1795 100644 (file)
@@ -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;
 }
 
 /*
index c9293ade321d50a3593d0086b447a142bb6ddb75..58043ed08662506497b6c6d05801799feea38b1a 100644 (file)
@@ -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();
 }
index 5c4f71ff6ae9fe579933a678fa9cc56a20c0e189..e1d8a352f12d11ea0d5274de913a7e181c17dc72 100644 (file)
@@ -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 */
index f8c485ab73f592e2998416b7be48fedfd8cea077..437d7c930c0bdcabc1e5d86fea5d31acae42be7b 100644 (file)
@@ -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) {
index f9af1747be6e17b341eedaeb053ce49d0ae3102c..fab4403696630f543ef11229aeb4d1c3653b76aa 100644 (file)
@@ -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)) {
index c5582bd16f7a3ee8a88221818eb102ad650f844d..94f5e3739ae07b5d0a74cbcb0db6354f325acc5b 100644 (file)
@@ -77,13 +77,6 @@ static unsigned int xstate_comp_offsets[XFEATURE_MAX] __ro_after_init =
 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.
  *
@@ -716,8 +709,11 @@ static int __init init_xstate_size(void)
        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;
 }
@@ -726,11 +722,18 @@ static int __init init_xstate_size(void)
  * 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(&current->thread.fpu);
 }
 
@@ -738,7 +741,7 @@ static void __init fpu__init_disable_system_xstate(void)
  * 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;
@@ -810,7 +813,8 @@ void __init fpu__init_system_xstate(void)
         * 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();
@@ -830,13 +834,13 @@ void __init fpu__init_system_xstate(void)
        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);
 }
 
 /*
index 379dbfa4f52618668a234710b497b68da2e1b789..3d45eb04471b6c112175a01576996ab95219429b 100644 (file)
@@ -31,7 +31,7 @@ extern int copy_sigframe_from_user_to_xstate(struct fpstate *fpstate, const void
 
 
 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);