History

Merge tag 'x86-fpu-2021-11-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fpu updates from Thomas Gleixner: - Cleanup of extable fixup handling to be more robust, which in turn allows to make the FPU exception fixups more robust as well. - Change the return code for signal frame related failures from explicit error codes to a boolean fail/success as that's all what the calling code evaluates. - A large refactoring of the FPU code to prepare for adding AMX support: - Distangle the public header maze and remove especially the misnomed kitchen sink internal.h which is despite it's name included all over the place. - Add a proper abstraction for the register buffer storage (struct fpstate) which allows to dynamically size the buffer at runtime by flipping the pointer to the buffer container from the default container which is embedded in task_struct::tread::fpu to a dynamically allocated container with a larger register buffer. - Convert the code over to the new fpstate mechanism. - Consolidate the KVM FPU handling by moving the FPU related code into the FPU core which removes the number of exports and avoids adding even more export when AMX has to be supported in KVM. This also removes duplicated code which was of course unnecessary different and incomplete in the KVM copy. - Simplify the KVM FPU buffer handling by utilizing the new fpstate container and just switching the buffer pointer from the user space buffer to the KVM guest buffer when entering vcpu_run() and flipping it back when leaving the function. This cuts the memory requirements of a vCPU for FPU buffers in half and avoids pointless memory copy operations. This also solves the so far unresolved problem of adding AMX support because the current FPU buffer handling of KVM inflicted a circular dependency between adding AMX support to the core and to KVM. With the new scheme of switching fpstate AMX support can be added to the core code without affecting KVM. - Replace various variables with proper data structures so the extra information required for adding dynamically enabled FPU features (AMX) can be added in one place - Add AMX (Advanced Matrix eXtensions) support (finally): AMX is a large XSTATE component which is going to be available with Saphire Rapids XEON CPUs. The feature comes with an extra MSR (MSR_XFD) which allows to trap the (first) use of an AMX related instruction, which has two benefits: 1) It allows the kernel to control access to the feature 2) It allows the kernel to dynamically allocate the large register state buffer instead of burdening every task with the the extra 8K or larger state storage. It would have been great to gain this kind of control already with AVX512. The support comes with the following infrastructure components: 1) arch_prctl() to - read the supported features (equivalent to XGETBV(0)) - read the permitted features for a task - request permission for a dynamically enabled feature Permission is granted per process, inherited on fork() and cleared on exec(). The permission policy of the kernel is restricted to sigaltstack size validation, but the syscall obviously allows further restrictions via seccomp etc. 2) A stronger sigaltstack size validation for sys_sigaltstack(2) which takes granted permissions and the potentially resulting larger signal frame into account. This mechanism can also be used to enforce factual sigaltstack validation independent of dynamic features to help with finding potential victims of the 2K sigaltstack size constant which is broken since AVX512 support was added. 3) Exception handling for #NM traps to catch first use of a extended feature via a new cause MSR. If the exception was caused by the use of such a feature, the handler checks permission for that feature. If permission has not been granted, the handler sends a SIGILL like the #UD handler would do if the feature would have been disabled in XCR0. If permission has been granted, then a new fpstate which fits the larger buffer requirement is allocated. In the unlikely case that this allocation fails, the handler sends SIGSEGV to the task. That's not elegant, but unavoidable as the other discussed options of preallocation or full per task permissions come with their own set of horrors for kernel and/or userspace. So this is the lesser of the evils and SIGSEGV caused by unexpected memory allocation failures is not a fundamentally new concept either. When allocation succeeds, the fpstate properties are filled in to reflect the extended feature set and the resulting sizes, the fpu::fpstate pointer is updated accordingly and the trap is disarmed for this task permanently. 4) Enumeration and size calculations 5) Trap switching via MSR_XFD The XFD (eXtended Feature Disable) MSR is context switched with the same life time rules as the FPU register state itself. The mechanism is keyed off with a static key which is default disabled so !AMX equipped CPUs have zero overhead. On AMX enabled CPUs the overhead is limited by comparing the tasks XFD value with a per CPU shadow variable to avoid redundant MSR writes. In case of switching from a AMX using task to a non AMX using task or vice versa, the extra MSR write is obviously inevitable. All other places which need to be aware of the variable feature sets and resulting variable sizes are not affected at all because they retrieve the information (feature set, sizes) unconditonally from the fpstate properties. 6) Enable the new AMX states Note, this is relatively new code despite the fact that AMX support is in the works for more than a year now. The big refactoring of the FPU code, which allowed to do a proper integration has been started exactly 3 weeks ago. Refactoring of the existing FPU code and of the original AMX patches took a week and has been subject to extensive review and testing. The only fallout which has not been caught in review and testing right away was restricted to AMX enabled systems, which is completely irrelevant for anyone outside Intel and their early access program. There might be dragons lurking as usual, but so far the fine grained refactoring has held up and eventual yet undetected fallout is bisectable and should be easily addressable before the 5.16 release. Famous last words... Many thanks to Chang Bae and Dave Hansen for working hard on this and also to the various test teams at Intel who reserved extra capacity to follow the rapid development of this closely which provides the confidence level required to offer this rather large update for inclusion into 5.16-rc1 * tag 'x86-fpu-2021-11-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (110 commits) Documentation/x86: Add documentation for using dynamic XSTATE features x86/fpu: Include vmalloc.h for vzalloc() selftests/x86/amx: Add context switch test selftests/x86/amx: Add test cases for AMX state management x86/fpu/amx: Enable the AMX feature in 64-bit mode x86/fpu: Add XFD handling for dynamic states x86/fpu: Calculate the default sizes independently x86/fpu/amx: Define AMX state components and have it used for boot-time checks x86/fpu/xstate: Prepare XSAVE feature table for gaps in state component numbers x86/fpu/xstate: Add fpstate_realloc()/free() x86/fpu/xstate: Add XFD #NM handler x86/fpu: Update XFD state where required x86/fpu: Add sanity checks for XFD x86/fpu: Add XFD state to fpstate x86/msr-index: Add MSRs for XFD x86/cpufeatures: Add eXtended Feature Disabling (XFD) feature bit x86/fpu: Reset permission and fpstate on exec() x86/fpu: Prepare fpu_clone() for dynamically enabled features x86/fpu/signal: Prepare for variable sigframe length x86/signal: Use fpu::__state_user_size for sigalt stack validation ...

Linus Torvalds committed 5 years ago

Commit 8cb1ae12 parents 7d20dd3 d7a959067 files · +3458 −1575Browse files

Unified · Split

67 files
  1. Documentation/admin-guide/kernel-parameters.txt +9 −0
  2. Documentation/x86/index.rst +1 −0
  3. Documentation/x86/xstate.rst +65 −0
  4. arch/Kconfig +3 −0
  5. arch/x86/Kconfig +17 −0
  6. arch/x86/events/perf_event.h +1 −0
  7. arch/x86/ia32/ia32_signal.c +7 −8
  8. arch/x86/include/asm/asm.h +20 −30
  9. arch/x86/include/asm/cpufeatures.h +2 −0
  10. arch/x86/include/asm/extable.h +28 −16
  11. arch/x86/include/asm/extable_fixup_types.h +22 −0
  12. arch/x86/include/asm/fpu/api.h +56 −2
  13. arch/x86/include/asm/fpu/internal.h +0 −540
  14. arch/x86/include/asm/fpu/sched.h +68 −0
  15. arch/x86/include/asm/fpu/signal.h +12 −1
  16. arch/x86/include/asm/fpu/types.h +206 −8
  17. arch/x86/include/asm/fpu/xcr.h +0 −11
  18. arch/x86/include/asm/fpu/xstate.h +30 −60
  19. arch/x86/include/asm/kvm_host.h +2 −5
  20. arch/x86/include/asm/msr-index.h +2 −0
  21. arch/x86/include/asm/msr.h +2 −2
  22. arch/x86/include/asm/pkru.h +1 −1
  23. arch/x86/include/asm/processor.h +3 −6
  24. arch/x86/include/asm/proto.h +1 −1
  25. arch/x86/include/asm/segment.h +1 −1
  26. arch/x86/include/asm/trace/fpu.h +2 −2
  27. arch/x86/include/uapi/asm/prctl.h +4 −0
  28. arch/x86/kernel/cpu/bugs.c +1 −1
  29. arch/x86/kernel/cpu/common.c +1 −1
  30. arch/x86/kernel/cpu/cpuid-deps.c +2 −0
  31. arch/x86/kernel/cpu/mce/core.c +11 −29
  32. arch/x86/kernel/cpu/mce/internal.h +2 −12
  33. arch/x86/kernel/cpu/mce/severity.c +11 −11
  34. arch/x86/kernel/fpu/bugs.c +1 −1
  35. arch/x86/kernel/fpu/context.h +83 −0
  36. arch/x86/kernel/fpu/core.c +315 −77
  37. arch/x86/kernel/fpu/init.c +34 −42
  38. arch/x86/kernel/fpu/internal.h +28 −0
  39. arch/x86/kernel/fpu/legacy.h +115 −0
  40. arch/x86/kernel/fpu/regset.c +20 −16
  41. arch/x86/kernel/fpu/signal.c +145 −140
  42. arch/x86/kernel/fpu/xstate.c +712 −186
  43. arch/x86/kernel/fpu/xstate.h +278 −0
  44. arch/x86/kernel/process.c +23 −4
  45. arch/x86/kernel/process_32.c +2 −3
  46. arch/x86/kernel/process_64.c +2 −3
  47. arch/x86/kernel/ptrace.c +1 −1
  48. arch/x86/kernel/sev.c +1 −1
  49. arch/x86/kernel/signal.c +71 −12
  50. arch/x86/kernel/smpboot.c +1 −1
  51. arch/x86/kernel/traps.c +39 −1
  52. arch/x86/kvm/svm/sev.c +1 −1
  53. arch/x86/kvm/svm/svm.c +4 −3
  54. arch/x86/kvm/vmx/vmx.c +1 −1
  55. arch/x86/kvm/x86.c +31 −227
  56. arch/x86/lib/copy_mc_64.S +4 −4
  57. arch/x86/math-emu/fpu_aux.c +1 −1
  58. arch/x86/math-emu/fpu_entry.c +3 −3
  59. arch/x86/math-emu/fpu_system.h +1 −1
  60. arch/x86/mm/extable.c +56 −79
  61. arch/x86/net/bpf_jit_comp.c +2 −9
  62. arch/x86/power/cpu.c +1 −1
  63. include/linux/signal.h +6 −0
  64. kernel/signal.c +29 −6
  65. scripts/sorttable.c +2 −2
  66. tools/testing/selftests/x86/Makefile +1 −1
  67. tools/testing/selftests/x86/amx.c +851 −0
Documentation/admin-guide/kernel-parameters.txt+9−0
@@ -5497,6 +5497,15 @@ · 5496 unmodified lines
5497 stifb= [HW]5497 stifb= [HW]
5498 Format: bpp:<bpp1>[:<bpp2>[:<bpp3>...]]5498 Format: bpp:<bpp1>[:<bpp2>[:<bpp3>...]]
5499 5499
5500 strict_sas_size=
5501 [X86]
5502 Format: <bool>
5503 Enable or disable strict sigaltstack size checks
5504 against the required signal frame size which
5505 depends on the supported FPU features. This can
5506 be used to filter out binaries which have
5507 not yet been made aware of AT_MINSIGSTKSZ.
5508
5500 sunrpc.min_resvport=5509 sunrpc.min_resvport=
5501 sunrpc.max_resvport=5510 sunrpc.max_resvport=
5502 [NFS,SUNRPC]5511 [NFS,SUNRPC]
Documentation/x86/index.rst+1−0
@@ -37,3 +37,4 @@ x86-specific Documentation · 36 unmodified lines
37 sgx37 sgx
38 features38 features
39 elf_auxvec39 elf_auxvec
40 xstate
Documentation/x86/xstate.rst+65−0
@@ -0,0 +1,65 @@
1Using XSTATE features in user space applications
2================================================
3
4The x86 architecture supports floating-point extensions which are
5enumerated via CPUID. Applications consult CPUID and use XGETBV to
6evaluate which features have been enabled by the kernel XCR0.
7
8Up to AVX-512 and PKRU states, these features are automatically enabled by
9the kernel if available. Features like AMX TILE_DATA (XSTATE component 18)
10are enabled by XCR0 as well, but the first use of related instruction is
11trapped by the kernel because by default the required large XSTATE buffers
12are not allocated automatically.
13
14Using dynamically enabled XSTATE features in user space applications
15--------------------------------------------------------------------
16
17The kernel provides an arch_prctl(2) based mechanism for applications to
18request the usage of such features. The arch_prctl(2) options related to
19this are:
20
21-ARCH_GET_XCOMP_SUPP
22
23 arch_prctl(ARCH_GET_XCOMP_SUPP, &features);
24
25 ARCH_GET_XCOMP_SUPP stores the supported features in userspace storage of
26 type uint64_t. The second argument is a pointer to that storage.
27
28-ARCH_GET_XCOMP_PERM
29
30 arch_prctl(ARCH_GET_XCOMP_PERM, &features);
31
32 ARCH_GET_XCOMP_PERM stores the features for which the userspace process
33 has permission in userspace storage of type uint64_t. The second argument
34 is a pointer to that storage.
35
36-ARCH_REQ_XCOMP_PERM
37
38 arch_prctl(ARCH_REQ_XCOMP_PERM, feature_nr);
39
40 ARCH_REQ_XCOMP_PERM allows to request permission for a dynamically enabled
41 feature or a feature set. A feature set can be mapped to a facility, e.g.
42 AMX, and can require one or more XSTATE components to be enabled.
43
44 The feature argument is the number of the highest XSTATE component which
45 is required for a facility to work.
46
47When requesting permission for a feature, the kernel checks the
48availability. The kernel ensures that sigaltstacks in the process's tasks
49are large enough to accommodate the resulting large signal frame. It
50enforces this both during ARCH_REQ_XCOMP_SUPP and during any subsequent
51sigaltstack(2) calls. If an installed sigaltstack is smaller than the
52resulting sigframe size, ARCH_REQ_XCOMP_SUPP results in -ENOSUPP. Also,
53sigaltstack(2) results in -ENOMEM if the requested altstack is too small
54for the permitted features.
55
56Permission, when granted, is valid per process. Permissions are inherited
57on fork(2) and cleared on exec(3).
58
59The first use of an instruction related to a dynamically enabled feature is
60trapped by the kernel. The trap handler checks whether the process has
61permission to use the feature. If the process has no permission then the
62kernel sends SIGILL to the application. If the process has permission then
63the handler allocates a larger xstate buffer for the task so the large
64state can be context switched. In the unlikely cases that the allocation
65fails, the kernel sends SIGSEGV.
arch/Kconfig+3−0
@@ -1288,6 +1288,9 @@ config ARCH_HAS_ELFCORE_COMPAT · 1287 unmodified lines
1288config ARCH_HAS_PARANOID_L1D_FLUSH1288config ARCH_HAS_PARANOID_L1D_FLUSH
1289 bool1289 bool
1290 1290
1291config DYNAMIC_SIGFRAME
1292 bool
1293
1291source "kernel/gcov/Kconfig"1294source "kernel/gcov/Kconfig"
1292 1295
1293source "scripts/gcc-plugins/Kconfig"1296source "scripts/gcc-plugins/Kconfig"
arch/x86/Kconfig+17−0
@@ -125,6 +125,7 @@ config X86 · 124 unmodified lines
125 select CLOCKSOURCE_VALIDATE_LAST_CYCLE125 select CLOCKSOURCE_VALIDATE_LAST_CYCLE
126 select CLOCKSOURCE_WATCHDOG126 select CLOCKSOURCE_WATCHDOG
127 select DCACHE_WORD_ACCESS127 select DCACHE_WORD_ACCESS
128 select DYNAMIC_SIGFRAME
128 select EDAC_ATOMIC_SCRUB129 select EDAC_ATOMIC_SCRUB
129 select EDAC_SUPPORT130 select EDAC_SUPPORT
130 select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && X86_LOCAL_APIC)131 select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && X86_LOCAL_APIC)
@@ -2399,6 +2400,22 @@ config MODIFY_LDT_SYSCALL · 2268 unmodified lines
2399 2400
2400 Saying 'N' here may make sense for embedded or server kernels.2401 Saying 'N' here may make sense for embedded or server kernels.
2401 2402
2403config STRICT_SIGALTSTACK_SIZE
2404 bool "Enforce strict size checking for sigaltstack"
2405 depends on DYNAMIC_SIGFRAME
2406 help
2407 For historical reasons MINSIGSTKSZ is a constant which became
2408 already too small with AVX512 support. Add a mechanism to
2409 enforce strict checking of the sigaltstack size against the
2410 real size of the FPU frame. This option enables the check
2411 by default. It can also be controlled via the kernel command
2412 line option 'strict_sas_size' independent of this config
2413 switch. Enabling it might break existing applications which
2414 allocate a too small sigaltstack but 'work' because they
2415 never get a signal delivered.
2416
2417 Say 'N' unless you want to really enforce this check.
2418
2402source "kernel/livepatch/Kconfig"2419source "kernel/livepatch/Kconfig"
2403 2420
2404endmenu2421endmenu
arch/x86/events/perf_event.h+1−0
@@ -14,6 +14,7 @@ · 13 unmodified lines
14 14
15#include <linux/perf_event.h>15#include <linux/perf_event.h>
16 16
17#include <asm/fpu/xstate.h>
17#include <asm/intel_ds.h>18#include <asm/intel_ds.h>
18#include <asm/cpu.h>19#include <asm/cpu.h>
19 20
arch/x86/ia32/ia32_signal.c+7−8
@@ -24,7 +24,6 @@ · 23 unmodified lines
24#include <linux/syscalls.h>24#include <linux/syscalls.h>
25#include <asm/ucontext.h>25#include <asm/ucontext.h>
26#include <linux/uaccess.h>26#include <linux/uaccess.h>
27#include <asm/fpu/internal.h>
28#include <asm/fpu/signal.h>27#include <asm/fpu/signal.h>
29#include <asm/ptrace.h>28#include <asm/ptrace.h>
30#include <asm/ia32_unistd.h>29#include <asm/ia32_unistd.h>
@@ -57,8 +56,8 @@ static inline void reload_segments(struct sigcontext_32 *sc) · 26 unmodified lines
57/*56/*
58 * Do a signal return; undo the signal stack.57 * Do a signal return; undo the signal stack.
59 */58 */
60static int ia32_restore_sigcontext(struct pt_regs *regs,59static bool ia32_restore_sigcontext(struct pt_regs *regs,
61 struct sigcontext_32 __user *usc)60 struct sigcontext_32 __user *usc)
62{61{
63 struct sigcontext_32 sc;62 struct sigcontext_32 sc;
64 63
@@ -66,7 +65,7 @@ static int ia32_restore_sigcontext(struct pt_regs *regs, · 1 unmodified line
66 current->restart_block.fn = do_no_restart_syscall;65 current->restart_block.fn = do_no_restart_syscall;
67 66
68 if (unlikely(copy_from_user(&sc, usc, sizeof(sc))))67 if (unlikely(copy_from_user(&sc, usc, sizeof(sc))))
69 return -EFAULT;68 return false;
70 69
71 /* Get only the ia32 registers. */70 /* Get only the ia32 registers. */
72 regs->bx = sc.bx;71 regs->bx = sc.bx;
@@ -111,7 +110,7 @@ COMPAT_SYSCALL_DEFINE0(sigreturn) · 38 unmodified lines
111 110
112 set_current_blocked(&set);111 set_current_blocked(&set);
113 112
114 if (ia32_restore_sigcontext(regs, &frame->sc))113 if (!ia32_restore_sigcontext(regs, &frame->sc))
115 goto badframe;114 goto badframe;
116 return regs->ax;115 return regs->ax;
117 116
@@ -135,7 +134,7 @@ COMPAT_SYSCALL_DEFINE0(rt_sigreturn) · 17 unmodified lines
135 134
136 set_current_blocked(&set);135 set_current_blocked(&set);
137 136
138 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext))137 if (!ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext))
139 goto badframe;138 goto badframe;
140 139
141 if (compat_restore_altstack(&frame->uc.uc_stack))140 if (compat_restore_altstack(&frame->uc.uc_stack))
@@ -220,8 +219,8 @@ static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, · 78 unmodified lines
220 219
221 sp = fpu__alloc_mathframe(sp, 1, &fx_aligned, &math_size);220 sp = fpu__alloc_mathframe(sp, 1, &fx_aligned, &math_size);
222 *fpstate = (struct _fpstate_32 __user *) sp;221 *fpstate = (struct _fpstate_32 __user *) sp;
223 if (copy_fpstate_to_sigframe(*fpstate, (void __user *)fx_aligned,222 if (!copy_fpstate_to_sigframe(*fpstate, (void __user *)fx_aligned,
224 math_size) < 0)223 math_size))
225 return (void __user *) -1L;224 return (void __user *) -1L;
226 225
227 sp -= frame_size;226 sp -= frame_size;
arch/x86/include/asm/asm.h+20−30
@@ -122,28 +122,19 @@ · 121 unmodified lines
122 122
123#ifdef __KERNEL__123#ifdef __KERNEL__
124 124
125# include <asm/extable_fixup_types.h>
126
125/* Exception table entry */127/* Exception table entry */
126#ifdef __ASSEMBLY__128#ifdef __ASSEMBLY__
127# define _ASM_EXTABLE_HANDLE(from, to, handler) \129
130# define _ASM_EXTABLE_TYPE(from, to, type) \
128 .pushsection "__ex_table","a" ; \131 .pushsection "__ex_table","a" ; \
129 .balign 4 ; \132 .balign 4 ; \
130 .long (from) - . ; \133 .long (from) - . ; \
131 .long (to) - . ; \134 .long (to) - . ; \
132 .long (handler) - . ; \135 .long type ; \
133 .popsection136 .popsection
134 137
135# define _ASM_EXTABLE(from, to) \
136 _ASM_EXTABLE_HANDLE(from, to, ex_handler_default)
137
138# define _ASM_EXTABLE_UA(from, to) \
139 _ASM_EXTABLE_HANDLE(from, to, ex_handler_uaccess)
140
141# define _ASM_EXTABLE_CPY(from, to) \
142 _ASM_EXTABLE_HANDLE(from, to, ex_handler_copy)
143
144# define _ASM_EXTABLE_FAULT(from, to) \
145 _ASM_EXTABLE_HANDLE(from, to, ex_handler_fault)
146
147# ifdef CONFIG_KPROBES138# ifdef CONFIG_KPROBES
148# define _ASM_NOKPROBE(entry) \139# define _ASM_NOKPROBE(entry) \
149 .pushsection "_kprobe_blacklist","aw" ; \140 .pushsection "_kprobe_blacklist","aw" ; \
@@ -155,27 +146,15 @@ · 5 unmodified lines
155# endif146# endif
156 147
157#else /* ! __ASSEMBLY__ */148#else /* ! __ASSEMBLY__ */
158# define _EXPAND_EXTABLE_HANDLE(x) #x149
159# define _ASM_EXTABLE_HANDLE(from, to, handler) \150# define _ASM_EXTABLE_TYPE(from, to, type) \
160 " .pushsection \"__ex_table\",\"a\"\n" \151 " .pushsection \"__ex_table\",\"a\"\n" \
161 " .balign 4\n" \152 " .balign 4\n" \
162 " .long (" #from ") - .\n" \153 " .long (" #from ") - .\n" \
163 " .long (" #to ") - .\n" \154 " .long (" #to ") - .\n" \
164 " .long (" _EXPAND_EXTABLE_HANDLE(handler) ") - .\n" \155 " .long " __stringify(type) " \n" \
165 " .popsection\n"156 " .popsection\n"
166 157
167# define _ASM_EXTABLE(from, to) \
168 _ASM_EXTABLE_HANDLE(from, to, ex_handler_default)
169
170# define _ASM_EXTABLE_UA(from, to) \
171 _ASM_EXTABLE_HANDLE(from, to, ex_handler_uaccess)
172
173# define _ASM_EXTABLE_CPY(from, to) \
174 _ASM_EXTABLE_HANDLE(from, to, ex_handler_copy)
175
176# define _ASM_EXTABLE_FAULT(from, to) \
177 _ASM_EXTABLE_HANDLE(from, to, ex_handler_fault)
178
179/* For C file, we already have NOKPROBE_SYMBOL macro */158/* For C file, we already have NOKPROBE_SYMBOL macro */
180 159
181/*160/*
@@ -188,6 +167,17 @@ register unsigned long current_stack_pointer asm(_ASM_SP); · 6 unmodified lines
188#define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer)167#define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer)
189#endif /* __ASSEMBLY__ */168#endif /* __ASSEMBLY__ */
190 169
191#endif /* __KERNEL__ */170#define _ASM_EXTABLE(from, to) \
171 _ASM_EXTABLE_TYPE(from, to, EX_TYPE_DEFAULT)
192 172
173#define _ASM_EXTABLE_UA(from, to) \
174 _ASM_EXTABLE_TYPE(from, to, EX_TYPE_UACCESS)
175
176#define _ASM_EXTABLE_CPY(from, to) \
177 _ASM_EXTABLE_TYPE(from, to, EX_TYPE_COPY)
178
179#define _ASM_EXTABLE_FAULT(from, to) \
180 _ASM_EXTABLE_TYPE(from, to, EX_TYPE_FAULT)
181
182#endif /* __KERNEL__ */
193#endif /* _ASM_X86_ASM_H */183#endif /* _ASM_X86_ASM_H */
arch/x86/include/asm/cpufeatures.h+2−0
@@ -277,6 +277,7 @@ · 276 unmodified lines
277#define X86_FEATURE_XSAVEC (10*32+ 1) /* XSAVEC instruction */277#define X86_FEATURE_XSAVEC (10*32+ 1) /* XSAVEC instruction */
278#define X86_FEATURE_XGETBV1 (10*32+ 2) /* XGETBV with ECX = 1 instruction */278#define X86_FEATURE_XGETBV1 (10*32+ 2) /* XGETBV with ECX = 1 instruction */
279#define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS instructions */279#define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS instructions */
280#define X86_FEATURE_XFD (10*32+ 4) /* "" eXtended Feature Disabling */
280 281
281/*282/*
282 * Extended auxiliary flags: Linux defined - for features scattered in various283 * Extended auxiliary flags: Linux defined - for features scattered in various
@@ -298,6 +299,7 @@ · 15 unmodified lines
298/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */299/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
299#define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */300#define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */
300#define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */301#define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */
302#define X86_FEATURE_AMX_TILE (18*32+24) /* AMX tile Support */
301 303
302/* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 13 */304/* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 13 */
303#define X86_FEATURE_CLZERO (13*32+ 0) /* CLZERO instruction */305#define X86_FEATURE_CLZERO (13*32+ 0) /* CLZERO instruction */
arch/x86/include/asm/extable.h+28−16
@@ -1,12 +1,18 @@
1/* SPDX-License-Identifier: GPL-2.0 */1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _ASM_X86_EXTABLE_H2#ifndef _ASM_X86_EXTABLE_H
3#define _ASM_X86_EXTABLE_H3#define _ASM_X86_EXTABLE_H
4
5#include <asm/extable_fixup_types.h>
6
4/*7/*
5 * The exception table consists of triples of addresses relative to the8 * The exception table consists of two addresses relative to the
6 * exception table entry itself. The first address is of an instruction9 * exception table entry itself and a type selector field.
7 * that is allowed to fault, the second is the target at which the program10 *
8 * should continue. The third is a handler function to deal with the fault11 * The first address is of an instruction that is allowed to fault, the
9 * caused by the instruction in the first field.12 * second is the target at which the program should continue.
13 *
14 * The type entry is used by fixup_exception() to select the handler to
15 * deal with the fault caused by the instruction in the first field.
10 *16 *
11 * All the routines below use bits of fixup code that are out of line17 * All the routines below use bits of fixup code that are out of line
12 * with the main instruction path. This means when everything is well,18 * with the main instruction path. This means when everything is well,
@@ -15,7 +21,7 @@ · 2 unmodified lines
15 */21 */
16 22
17struct exception_table_entry {23struct exception_table_entry {
18 int insn, fixup, handler;24 int insn, fixup, type;
19};25};
20struct pt_regs;26struct pt_regs;
21 27
@@ -25,21 +31,27 @@ struct pt_regs; · 3 unmodified lines
25 do { \31 do { \
26 (a)->fixup = (b)->fixup + (delta); \32 (a)->fixup = (b)->fixup + (delta); \
27 (b)->fixup = (tmp).fixup - (delta); \33 (b)->fixup = (tmp).fixup - (delta); \
28 (a)->handler = (b)->handler + (delta); \34 (a)->type = (b)->type; \
29 (b)->handler = (tmp).handler - (delta); \35 (b)->type = (tmp).type; \
30 } while (0)36 } while (0)
31 37
32enum handler_type {
33 EX_HANDLER_NONE,
34 EX_HANDLER_FAULT,
35 EX_HANDLER_UACCESS,
36 EX_HANDLER_OTHER
37};
38
39extern int fixup_exception(struct pt_regs *regs, int trapnr,38extern int fixup_exception(struct pt_regs *regs, int trapnr,
40 unsigned long error_code, unsigned long fault_addr);39 unsigned long error_code, unsigned long fault_addr);
41extern int fixup_bug(struct pt_regs *regs, int trapnr);40extern int fixup_bug(struct pt_regs *regs, int trapnr);
42extern enum handler_type ex_get_fault_handler_type(unsigned long ip);41extern int ex_get_fixup_type(unsigned long ip);
43extern void early_fixup_exception(struct pt_regs *regs, int trapnr);42extern void early_fixup_exception(struct pt_regs *regs, int trapnr);
44 43
44#ifdef CONFIG_X86_MCE
45extern void ex_handler_msr_mce(struct pt_regs *regs, bool wrmsr);
46#else
47static inline void ex_handler_msr_mce(struct pt_regs *regs, bool wrmsr) { }
48#endif
49
50#if defined(CONFIG_BPF_JIT) && defined(CONFIG_X86_64)
51bool ex_handler_bpf(const struct exception_table_entry *x, struct pt_regs *regs);
52#else
53static inline bool ex_handler_bpf(const struct exception_table_entry *x,
54 struct pt_regs *regs) { return false; }
55#endif
56
45#endif57#endif
arch/x86/include/asm/extable_fixup_types.h+22−0
@@ -0,0 +1,22 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _ASM_X86_EXTABLE_FIXUP_TYPES_H
3#define _ASM_X86_EXTABLE_FIXUP_TYPES_H
4
5#define EX_TYPE_NONE 0
6#define EX_TYPE_DEFAULT 1
7#define EX_TYPE_FAULT 2
8#define EX_TYPE_UACCESS 3
9#define EX_TYPE_COPY 4
10#define EX_TYPE_CLEAR_FS 5
11#define EX_TYPE_FPU_RESTORE 6
12#define EX_TYPE_WRMSR 7
13#define EX_TYPE_RDMSR 8
14#define EX_TYPE_BPF 9
15
16#define EX_TYPE_WRMSR_IN_MCE 10
17#define EX_TYPE_RDMSR_IN_MCE 11
18
19#define EX_TYPE_DEFAULT_MCE_SAFE 12
20#define EX_TYPE_FAULT_MCE_SAFE 13
21
22#endif
arch/x86/include/asm/fpu/api.h+56−2
@@ -12,6 +12,8 @@ · 11 unmodified lines
12#define _ASM_X86_FPU_API_H12#define _ASM_X86_FPU_API_H
13#include <linux/bottom_half.h>13#include <linux/bottom_half.h>
14 14
15#include <asm/fpu/types.h>
16
15/*17/*
16 * Use kernel_fpu_begin/end() if you intend to use FPU in kernel context. It18 * Use kernel_fpu_begin/end() if you intend to use FPU in kernel context. It
17 * disables preemption so be careful if you intend to use it for long periods19 * disables preemption so be careful if you intend to use it for long periods
@@ -48,9 +50,9 @@ static inline void kernel_fpu_begin(void) · 30 unmodified lines
48}50}
49 51
50/*52/*
51 * Use fpregs_lock() while editing CPU's FPU registers or fpu->state.53 * Use fpregs_lock() while editing CPU's FPU registers or fpu->fpstate.
52 * A context switch will (and softirq might) save CPU's FPU registers to54 * A context switch will (and softirq might) save CPU's FPU registers to
53 * fpu->state and set TIF_NEED_FPU_LOAD leaving CPU's FPU registers in55 * fpu->fpstate.regs and set TIF_NEED_FPU_LOAD leaving CPU's FPU registers in
54 * a random state.56 * a random state.
55 *57 *
56 * local_bh_disable() protects against both preemption and soft interrupts58 * local_bh_disable() protects against both preemption and soft interrupts
@@ -108,4 +110,56 @@ extern int cpu_has_xfeatures(u64 xfeatures_mask, const char **feature_name); · 51 unmodified lines
108 110
109static inline void update_pasid(void) { }111static inline void update_pasid(void) { }
110 112
113/* Trap handling */
114extern int fpu__exception_code(struct fpu *fpu, int trap_nr);
115extern void fpu_sync_fpstate(struct fpu *fpu);
116extern void fpu_reset_from_exception_fixup(void);
117
118/* Boot, hotplug and resume */
119extern void fpu__init_cpu(void);
120extern void fpu__init_system(struct cpuinfo_x86 *c);
121extern void fpu__init_check_bugs(void);
122extern void fpu__resume_cpu(void);
123
124#ifdef CONFIG_MATH_EMULATION
125extern void fpstate_init_soft(struct swregs_state *soft);
126#else
127static inline void fpstate_init_soft(struct swregs_state *soft) {}
128#endif
129
130/* State tracking */
131DECLARE_PER_CPU(struct fpu *, fpu_fpregs_owner_ctx);
132
133/* Process cleanup */
134#ifdef CONFIG_X86_64
135extern void fpstate_free(struct fpu *fpu);
136#else
137static inline void fpstate_free(struct fpu *fpu) { }
138#endif
139
140/* fpstate-related functions which are exported to KVM */
141extern void fpstate_clear_xstate_component(struct fpstate *fps, unsigned int xfeature);
142
143/* KVM specific functions */
144extern bool fpu_alloc_guest_fpstate(struct fpu_guest *gfpu);
145extern void fpu_free_guest_fpstate(struct fpu_guest *gfpu);
146extern int fpu_swap_kvm_fpstate(struct fpu_guest *gfpu, bool enter_guest);
147
148extern void fpu_copy_guest_fpstate_to_uabi(struct fpu_guest *gfpu, void *buf, unsigned int size, u32 pkru);
149extern int fpu_copy_uabi_to_guest_fpstate(struct fpu_guest *gfpu, const void *buf, u64 xcr0, u32 *vpkru);
150
151static inline void fpstate_set_confidential(struct fpu_guest *gfpu)
152{
153 gfpu->fpstate->is_confidential = true;
154}
155
156static inline bool fpstate_is_confidential(struct fpu_guest *gfpu)
157{
158 return gfpu->fpstate->is_confidential;
159}
160
161/* prctl */
162struct task_struct;
163extern long fpu_xstate_prctl(struct task_struct *tsk, int option, unsigned long arg2);
164
111#endif /* _ASM_X86_FPU_API_H */165#endif /* _ASM_X86_FPU_API_H */
arch/x86/include/asm/fpu/internal.h+0−540
@@ -1,540 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 1994 Linus Torvalds
4 *
5 * Pentium III FXSR, SSE support
6 * General FPU state handling cleanups
7 * Gareth Hughes <gareth@valinux.com>, May 2000
8 * x86-64 work by Andi Kleen 2002
9 */
10
11#ifndef _ASM_X86_FPU_INTERNAL_H
12#define _ASM_X86_FPU_INTERNAL_H
13
14#include <linux/compat.h>
15#include <linux/sched.h>
16#include <linux/slab.h>
17#include <linux/mm.h>
18
19#include <asm/user.h>
20#include <asm/fpu/api.h>
21#include <asm/fpu/xstate.h>
22#include <asm/fpu/xcr.h>
23#include <asm/cpufeature.h>
24#include <asm/trace/fpu.h>
25
26/*
27 * High level FPU state handling functions:
28 */
29extern int fpu__restore_sig(void __user *buf, int ia32_frame);
30extern void fpu__drop(struct fpu *fpu);
31extern void fpu__clear_user_states(struct fpu *fpu);
32extern int fpu__exception_code(struct fpu *fpu, int trap_nr);
33
34extern void fpu_sync_fpstate(struct fpu *fpu);
35
36/* Clone and exit operations */
37extern int fpu_clone(struct task_struct *dst);
38extern void fpu_flush_thread(void);
39
40/*
41 * Boot time FPU initialization functions:
42 */
43extern void fpu__init_cpu(void);
44extern void fpu__init_system_xstate(void);
45extern void fpu__init_cpu_xstate(void);
46extern void fpu__init_system(struct cpuinfo_x86 *c);
47extern void fpu__init_check_bugs(void);
48extern void fpu__resume_cpu(void);
49
50/*
51 * Debugging facility:
52 */
53#ifdef CONFIG_X86_DEBUG_FPU
54# define WARN_ON_FPU(x) WARN_ON_ONCE(x)
55#else
56# define WARN_ON_FPU(x) ({ (void)(x); 0; })
57#endif
58
59/*
60 * FPU related CPU feature flag helper routines:
61 */
62static __always_inline __pure bool use_xsaveopt(void)
63{
64 return static_cpu_has(X86_FEATURE_XSAVEOPT);
65}
66
67static __always_inline __pure bool use_xsave(void)
68{
69 return static_cpu_has(X86_FEATURE_XSAVE);
70}
71
72static __always_inline __pure bool use_fxsr(void)
73{
74 return static_cpu_has(X86_FEATURE_FXSR);
75}
76
77/*
78 * fpstate handling functions:
79 */
80
81extern union fpregs_state init_fpstate;
82
83extern void fpstate_init(union fpregs_state *state);
84#ifdef CONFIG_MATH_EMULATION
85extern void fpstate_init_soft(struct swregs_state *soft);
86#else
87static inline void fpstate_init_soft(struct swregs_state *soft) {}
88#endif
89extern void save_fpregs_to_fpstate(struct fpu *fpu);
90
91/* Returns 0 or the negated trap number, which results in -EFAULT for #PF */
92#define user_insn(insn, output, input...) \
93({ \
94 int err; \
95 \
96 might_fault(); \
97 \
98 asm volatile(ASM_STAC "\n" \
99 "1: " #insn "\n" \
100 "2: " ASM_CLAC "\n" \
101 ".section .fixup,\"ax\"\n" \
102 "3: negl %%eax\n" \
103 " jmp 2b\n" \
104 ".previous\n" \
105 _ASM_EXTABLE_FAULT(1b, 3b) \
106 : [err] "=a" (err), output \
107 : "0"(0), input); \
108 err; \
109})
110
111#define kernel_insn_err(insn, output, input...) \
112({ \
113 int err; \
114 asm volatile("1:" #insn "\n\t" \
115 "2:\n" \
116 ".section .fixup,\"ax\"\n" \
117 "3: movl $-1,%[err]\n" \
118 " jmp 2b\n" \
119 ".previous\n" \
120 _ASM_EXTABLE(1b, 3b) \
121 : [err] "=r" (err), output \
122 : "0"(0), input); \
123 err; \
124})
125
126#define kernel_insn(insn, output, input...) \
127 asm volatile("1:" #insn "\n\t" \
128 "2:\n" \
129 _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_fprestore) \
130 : output : input)
131
132static inline int fnsave_to_user_sigframe(struct fregs_state __user *fx)
133{
134 return user_insn(fnsave %[fx]; fwait, [fx] "=m" (*fx), "m" (*fx));
135}
136
137static inline int fxsave_to_user_sigframe(struct fxregs_state __user *fx)
138{
139 if (IS_ENABLED(CONFIG_X86_32))
140 return user_insn(fxsave %[fx], [fx] "=m" (*fx), "m" (*fx));
141 else
142 return user_insn(fxsaveq %[fx], [fx] "=m" (*fx), "m" (*fx));
143
144}
145
146static inline void fxrstor(struct fxregs_state *fx)
147{
148 if (IS_ENABLED(CONFIG_X86_32))
149 kernel_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
150 else
151 kernel_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
152}
153
154static inline int fxrstor_safe(struct fxregs_state *fx)
155{
156 if (IS_ENABLED(CONFIG_X86_32))
157 return kernel_insn_err(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
158 else
159 return kernel_insn_err(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
160}
161
162static inline int fxrstor_from_user_sigframe(struct fxregs_state __user *fx)
163{
164 if (IS_ENABLED(CONFIG_X86_32))
165 return user_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
166 else
167 return user_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
168}
169
170static inline void frstor(struct fregs_state *fx)
171{
172 kernel_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
173}
174
175static inline int frstor_safe(struct fregs_state *fx)
176{
177 return kernel_insn_err(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
178}
179
180static inline int frstor_from_user_sigframe(struct fregs_state __user *fx)
181{
182 return user_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
183}
184
185static inline void fxsave(struct fxregs_state *fx)
186{
187 if (IS_ENABLED(CONFIG_X86_32))
188 asm volatile( "fxsave %[fx]" : [fx] "=m" (*fx));
189 else
190 asm volatile("fxsaveq %[fx]" : [fx] "=m" (*fx));
191}
192
193/* These macros all use (%edi)/(%rdi) as the single memory argument. */
194#define XSAVE ".byte " REX_PREFIX "0x0f,0xae,0x27"
195#define XSAVEOPT ".byte " REX_PREFIX "0x0f,0xae,0x37"
196#define XSAVES ".byte " REX_PREFIX "0x0f,0xc7,0x2f"
197#define XRSTOR ".byte " REX_PREFIX "0x0f,0xae,0x2f"
198#define XRSTORS ".byte " REX_PREFIX "0x0f,0xc7,0x1f"
199
200/*
201 * After this @err contains 0 on success or the negated trap number when
202 * the operation raises an exception. For faults this results in -EFAULT.
203 */
204#define XSTATE_OP(op, st, lmask, hmask, err) \
205 asm volatile("1:" op "\n\t" \
206 "xor %[err], %[err]\n" \
207 "2:\n\t" \
208 ".pushsection .fixup,\"ax\"\n\t" \
209 "3: negl %%eax\n\t" \
210 "jmp 2b\n\t" \
211 ".popsection\n\t" \
212 _ASM_EXTABLE_FAULT(1b, 3b) \
213 : [err] "=a" (err) \
214 : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \
215 : "memory")
216
217/*
218 * If XSAVES is enabled, it replaces XSAVEOPT because it supports a compact
219 * format and supervisor states in addition to modified optimization in
220 * XSAVEOPT.
221 *
222 * Otherwise, if XSAVEOPT is enabled, XSAVEOPT replaces XSAVE because XSAVEOPT
223 * supports modified optimization which is not supported by XSAVE.
224 *
225 * We use XSAVE as a fallback.
226 *
227 * The 661 label is defined in the ALTERNATIVE* macros as the address of the
228 * original instruction which gets replaced. We need to use it here as the
229 * address of the instruction where we might get an exception at.
230 */
231#define XSTATE_XSAVE(st, lmask, hmask, err) \
232 asm volatile(ALTERNATIVE_2(XSAVE, \
233 XSAVEOPT, X86_FEATURE_XSAVEOPT, \
234 XSAVES, X86_FEATURE_XSAVES) \
235 "\n" \
236 "xor %[err], %[err]\n" \
237 "3:\n" \
238 ".pushsection .fixup,\"ax\"\n" \
239 "4: movl $-2, %[err]\n" \
240 "jmp 3b\n" \
241 ".popsection\n" \
242 _ASM_EXTABLE(661b, 4b) \
243 : [err] "=r" (err) \
244 : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \
245 : "memory")
246
247/*
248 * Use XRSTORS to restore context if it is enabled. XRSTORS supports compact
249 * XSAVE area format.
250 */
251#define XSTATE_XRESTORE(st, lmask, hmask) \
252 asm volatile(ALTERNATIVE(XRSTOR, \
253 XRSTORS, X86_FEATURE_XSAVES) \
254 "\n" \
255 "3:\n" \
256 _ASM_EXTABLE_HANDLE(661b, 3b, ex_handler_fprestore)\
257 : \
258 : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \
259 : "memory")
260
261/*
262 * This function is called only during boot time when x86 caps are not set
263 * up and alternative can not be used yet.
264 */
265static inline void os_xrstor_booting(struct xregs_state *xstate)
266{
267 u64 mask = xfeatures_mask_fpstate();
268 u32 lmask = mask;
269 u32 hmask = mask >> 32;
270 int err;
271
272 WARN_ON(system_state != SYSTEM_BOOTING);
273
274 if (boot_cpu_has(X86_FEATURE_XSAVES))
275 XSTATE_OP(XRSTORS, xstate, lmask, hmask, err);
276 else
277 XSTATE_OP(XRSTOR, xstate, lmask, hmask, err);
278
279 /*
280 * We should never fault when copying from a kernel buffer, and the FPU
281 * state we set at boot time should be valid.
282 */
283 WARN_ON_FPU(err);
284}
285
286/*
287 * Save processor xstate to xsave area.
288 *
289 * Uses either XSAVE or XSAVEOPT or XSAVES depending on the CPU features
290 * and command line options. The choice is permanent until the next reboot.
291 */
292static inline void os_xsave(struct xregs_state *xstate)
293{
294 u64 mask = xfeatures_mask_all;
295 u32 lmask = mask;
296 u32 hmask = mask >> 32;
297 int err;
298
299 WARN_ON_FPU(!alternatives_patched);
300
301 XSTATE_XSAVE(xstate, lmask, hmask, err);
302
303 /* We should never fault when copying to a kernel buffer: */
304 WARN_ON_FPU(err);
305}
306
307/*
308 * Restore processor xstate from xsave area.
309 *
310 * Uses XRSTORS when XSAVES is used, XRSTOR otherwise.
311 */
312static inline void os_xrstor(struct xregs_state *xstate, u64 mask)
313{
314 u32 lmask = mask;
315 u32 hmask = mask >> 32;
316
317 XSTATE_XRESTORE(xstate, lmask, hmask);
318}
319
320/*
321 * Save xstate to user space xsave area.
322 *
323 * We don't use modified optimization because xrstor/xrstors might track
324 * a different application.
325 *
326 * We don't use compacted format xsave area for
327 * backward compatibility for old applications which don't understand
328 * compacted format of xsave area.
329 */
330static inline int xsave_to_user_sigframe(struct xregs_state __user *buf)
331{
332 /*
333 * Include the features which are not xsaved/rstored by the kernel
334 * internally, e.g. PKRU. That's user space ABI and also required
335 * to allow the signal handler to modify PKRU.
336 */
337 u64 mask = xfeatures_mask_uabi();
338 u32 lmask = mask;
339 u32 hmask = mask >> 32;
340 int err;
341
342 /*
343 * Clear the xsave header first, so that reserved fields are
344 * initialized to zero.
345 */
346 err = __clear_user(&buf->header, sizeof(buf->header));
347 if (unlikely(err))
348 return -EFAULT;
349
350 stac();
351 XSTATE_OP(XSAVE, buf, lmask, hmask, err);
352 clac();
353
354 return err;
355}
356
357/*
358 * Restore xstate from user space xsave area.
359 */
360static inline int xrstor_from_user_sigframe(struct xregs_state __user *buf, u64 mask)
361{
362 struct xregs_state *xstate = ((__force struct xregs_state *)buf);
363 u32 lmask = mask;
364 u32 hmask = mask >> 32;
365 int err;
366
367 stac();
368 XSTATE_OP(XRSTOR, xstate, lmask, hmask, err);
369 clac();
370
371 return err;
372}
373
374/*
375 * Restore xstate from kernel space xsave area, return an error code instead of
376 * an exception.
377 */
378static inline int os_xrstor_safe(struct xregs_state *xstate, u64 mask)
379{
380 u32 lmask = mask;
381 u32 hmask = mask >> 32;
382 int err;
383
384 if (cpu_feature_enabled(X86_FEATURE_XSAVES))
385 XSTATE_OP(XRSTORS, xstate, lmask, hmask, err);
386 else
387 XSTATE_OP(XRSTOR, xstate, lmask, hmask, err);
388
389 return err;
390}
391
392extern void __restore_fpregs_from_fpstate(union fpregs_state *fpstate, u64 mask);
393
394static inline void restore_fpregs_from_fpstate(union fpregs_state *fpstate)
395{
396 __restore_fpregs_from_fpstate(fpstate, xfeatures_mask_fpstate());
397}
398
399extern int copy_fpstate_to_sigframe(void __user *buf, void __user *fp, int size);
400
401/*
402 * FPU context switch related helper methods:
403 */
404
405DECLARE_PER_CPU(struct fpu *, fpu_fpregs_owner_ctx);
406
407/*
408 * The in-register FPU state for an FPU context on a CPU is assumed to be
409 * valid if the fpu->last_cpu matches the CPU, and the fpu_fpregs_owner_ctx
410 * matches the FPU.
411 *
412 * If the FPU register state is valid, the kernel can skip restoring the
413 * FPU state from memory.
414 *
415 * Any code that clobbers the FPU registers or updates the in-memory
416 * FPU state for a task MUST let the rest of the kernel know that the
417 * FPU registers are no longer valid for this task.
418 *
419 * Either one of these invalidation functions is enough. Invalidate
420 * a resource you control: CPU if using the CPU for something else
421 * (with preemption disabled), FPU for the current task, or a task that
422 * is prevented from running by the current task.
423 */
424static inline void __cpu_invalidate_fpregs_state(void)
425{
426 __this_cpu_write(fpu_fpregs_owner_ctx, NULL);
427}
428
429static inline void __fpu_invalidate_fpregs_state(struct fpu *fpu)
430{
431 fpu->last_cpu = -1;
432}
433
434static inline int fpregs_state_valid(struct fpu *fpu, unsigned int cpu)
435{
436 return fpu == this_cpu_read(fpu_fpregs_owner_ctx) && cpu == fpu->last_cpu;
437}
438
439/*
440 * These generally need preemption protection to work,
441 * do try to avoid using these on their own:
442 */
443static inline void fpregs_deactivate(struct fpu *fpu)
444{
445 this_cpu_write(fpu_fpregs_owner_ctx, NULL);
446 trace_x86_fpu_regs_deactivated(fpu);
447}
448
449static inline void fpregs_activate(struct fpu *fpu)
450{
451 this_cpu_write(fpu_fpregs_owner_ctx, fpu);
452 trace_x86_fpu_regs_activated(fpu);
453}
454
455/* Internal helper for switch_fpu_return() and signal frame setup */
456static inline void fpregs_restore_userregs(void)
457{
458 struct fpu *fpu = &current->thread.fpu;
459 int cpu = smp_processor_id();
460
461 if (WARN_ON_ONCE(current->flags & PF_KTHREAD))
462 return;
463
464 if (!fpregs_state_valid(fpu, cpu)) {
465 u64 mask;
466
467 /*
468 * This restores _all_ xstate which has not been
469 * established yet.
470 *
471 * If PKRU is enabled, then the PKRU value is already
472 * correct because it was either set in switch_to() or in
473 * flush_thread(). So it is excluded because it might be
474 * not up to date in current->thread.fpu.xsave state.
475 */
476 mask = xfeatures_mask_restore_user() |
477 xfeatures_mask_supervisor();
478 __restore_fpregs_from_fpstate(&fpu->state, mask);
479
480 fpregs_activate(fpu);
481 fpu->last_cpu = cpu;
482 }
483 clear_thread_flag(TIF_NEED_FPU_LOAD);
484}
485
486/*
487 * FPU state switching for scheduling.
488 *
489 * This is a two-stage process:
490 *
491 * - switch_fpu_prepare() saves the old state.
492 * This is done within the context of the old process.
493 *
494 * - switch_fpu_finish() sets TIF_NEED_FPU_LOAD; the floating point state
495 * will get loaded on return to userspace, or when the kernel needs it.
496 *
497 * If TIF_NEED_FPU_LOAD is cleared then the CPU's FPU registers
498 * are saved in the current thread's FPU register state.
499 *
500 * If TIF_NEED_FPU_LOAD is set then CPU's FPU registers may not
501 * hold current()'s FPU registers. It is required to load the
502 * registers before returning to userland or using the content
503 * otherwise.
504 *
505 * The FPU context is only stored/restored for a user task and
506 * PF_KTHREAD is used to distinguish between kernel and user threads.
507 */
508static inline void switch_fpu_prepare(struct fpu *old_fpu, int cpu)
509{
510 if (static_cpu_has(X86_FEATURE_FPU) && !(current->flags & PF_KTHREAD)) {
511 save_fpregs_to_fpstate(old_fpu);
512 /*
513 * The save operation preserved register state, so the
514 * fpu_fpregs_owner_ctx is still @old_fpu. Store the
515 * current CPU number in @old_fpu, so the next return
516 * to user space can avoid the FPU register restore
517 * when is returns on the same CPU and still owns the
518 * context.
519 */
520 old_fpu->last_cpu = cpu;
521
522 trace_x86_fpu_regs_deactivated(old_fpu);
523 }
524}
525
526/*
527 * Misc helper functions:
528 */
529
530/*
531 * Delay loading of the complete FPU state until the return to userland.
532 * PKRU is handled separately.
533 */
534static inline void switch_fpu_finish(struct fpu *new_fpu)
535{
536 if (cpu_feature_enabled(X86_FEATURE_FPU))
537 set_thread_flag(TIF_NEED_FPU_LOAD);
538}
539
540#endif /* _ASM_X86_FPU_INTERNAL_H */
arch/x86/include/asm/fpu/sched.h+68−0
@@ -0,0 +1,68 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _ASM_X86_FPU_SCHED_H
3#define _ASM_X86_FPU_SCHED_H
4
5#include <linux/sched.h>
6
7#include <asm/cpufeature.h>
8#include <asm/fpu/types.h>
9
10#include <asm/trace/fpu.h>
11
12extern void save_fpregs_to_fpstate(struct fpu *fpu);
13extern void fpu__drop(struct fpu *fpu);
14extern int fpu_clone(struct task_struct *dst, unsigned long clone_flags);
15extern void fpu_flush_thread(void);
16
17/*
18 * FPU state switching for scheduling.
19 *
20 * This is a two-stage process:
21 *
22 * - switch_fpu_prepare() saves the old state.
23 * This is done within the context of the old process.
24 *
25 * - switch_fpu_finish() sets TIF_NEED_FPU_LOAD; the floating point state
26 * will get loaded on return to userspace, or when the kernel needs it.
27 *
28 * If TIF_NEED_FPU_LOAD is cleared then the CPU's FPU registers
29 * are saved in the current thread's FPU register state.
30 *
31 * If TIF_NEED_FPU_LOAD is set then CPU's FPU registers may not
32 * hold current()'s FPU registers. It is required to load the
33 * registers before returning to userland or using the content
34 * otherwise.
35 *
36 * The FPU context is only stored/restored for a user task and
37 * PF_KTHREAD is used to distinguish between kernel and user threads.
38 */
39static inline void switch_fpu_prepare(struct fpu *old_fpu, int cpu)
40{
41 if (cpu_feature_enabled(X86_FEATURE_FPU) &&
42 !(current->flags & PF_KTHREAD)) {
43 save_fpregs_to_fpstate(old_fpu);
44 /*
45 * The save operation preserved register state, so the
46 * fpu_fpregs_owner_ctx is still @old_fpu. Store the
47 * current CPU number in @old_fpu, so the next return
48 * to user space can avoid the FPU register restore
49 * when is returns on the same CPU and still owns the
50 * context.
51 */
52 old_fpu->last_cpu = cpu;
53
54 trace_x86_fpu_regs_deactivated(old_fpu);
55 }
56}
57
58/*
59 * Delay loading of the complete FPU state until the return to userland.
60 * PKRU is handled separately.
61 */
62static inline void switch_fpu_finish(void)
63{
64 if (cpu_feature_enabled(X86_FEATURE_FPU))
65 set_thread_flag(TIF_NEED_FPU_LOAD);
66}
67
68#endif /* _ASM_X86_FPU_SCHED_H */
arch/x86/include/asm/fpu/signal.h+12−1
@@ -5,6 +5,11 @@ · 4 unmodified lines
5#ifndef _ASM_X86_FPU_SIGNAL_H5#ifndef _ASM_X86_FPU_SIGNAL_H
6#define _ASM_X86_FPU_SIGNAL_H6#define _ASM_X86_FPU_SIGNAL_H
7 7
8#include <linux/compat.h>
9#include <linux/user.h>
10
11#include <asm/fpu/types.h>
12
8#ifdef CONFIG_X86_6413#ifdef CONFIG_X86_64
9# include <uapi/asm/sigcontext.h>14# include <uapi/asm/sigcontext.h>
10# include <asm/user32.h>15# include <asm/user32.h>
@@ -31,6 +36,12 @@ fpu__alloc_mathframe(unsigned long sp, int ia32_frame, · 20 unmodified lines
31 36
32unsigned long fpu__get_fpstate_size(void);37unsigned long fpu__get_fpstate_size(void);
33 38
34extern void fpu__init_prepare_fx_sw_frame(void);39extern bool copy_fpstate_to_sigframe(void __user *buf, void __user *fp, int size);
40extern void fpu__clear_user_states(struct fpu *fpu);
41extern bool fpu__restore_sig(void __user *buf, int ia32_frame);
42
43extern void restore_fpregs_from_fpstate(struct fpstate *fpstate, u64 mask);
44
45extern bool copy_fpstate_to_sigframe(void __user *buf, void __user *fp, int size);
35 46
36#endif /* _ASM_X86_FPU_SIGNAL_H */47#endif /* _ASM_X86_FPU_SIGNAL_H */
arch/x86/include/asm/fpu/types.h+206−8
@@ -120,6 +120,9 @@ enum xfeature { · 119 unmodified lines
120 XFEATURE_RSRVD_COMP_13,120 XFEATURE_RSRVD_COMP_13,
121 XFEATURE_RSRVD_COMP_14,121 XFEATURE_RSRVD_COMP_14,
122 XFEATURE_LBR,122 XFEATURE_LBR,
123 XFEATURE_RSRVD_COMP_16,
124 XFEATURE_XTILE_CFG,
125 XFEATURE_XTILE_DATA,
123 126
124 XFEATURE_MAX,127 XFEATURE_MAX,
125};128};
@@ -136,12 +139,21 @@ enum xfeature { · 10 unmodified lines
136#define XFEATURE_MASK_PKRU (1 << XFEATURE_PKRU)139#define XFEATURE_MASK_PKRU (1 << XFEATURE_PKRU)
137#define XFEATURE_MASK_PASID (1 << XFEATURE_PASID)140#define XFEATURE_MASK_PASID (1 << XFEATURE_PASID)
138#define XFEATURE_MASK_LBR (1 << XFEATURE_LBR)141#define XFEATURE_MASK_LBR (1 << XFEATURE_LBR)
142#define XFEATURE_MASK_XTILE_CFG (1 << XFEATURE_XTILE_CFG)
143#define XFEATURE_MASK_XTILE_DATA (1 << XFEATURE_XTILE_DATA)
139 144
140#define XFEATURE_MASK_FPSSE (XFEATURE_MASK_FP | XFEATURE_MASK_SSE)145#define XFEATURE_MASK_FPSSE (XFEATURE_MASK_FP | XFEATURE_MASK_SSE)
141#define XFEATURE_MASK_AVX512 (XFEATURE_MASK_OPMASK \146#define XFEATURE_MASK_AVX512 (XFEATURE_MASK_OPMASK \
142 | XFEATURE_MASK_ZMM_Hi256 \147 | XFEATURE_MASK_ZMM_Hi256 \
143 | XFEATURE_MASK_Hi16_ZMM)148 | XFEATURE_MASK_Hi16_ZMM)
144 149
150#ifdef CONFIG_X86_64
151# define XFEATURE_MASK_XTILE (XFEATURE_MASK_XTILE_DATA \
152 | XFEATURE_MASK_XTILE_CFG)
153#else
154# define XFEATURE_MASK_XTILE (0)
155#endif
156
145#define FIRST_EXTENDED_XFEATURE XFEATURE_YMM157#define FIRST_EXTENDED_XFEATURE XFEATURE_YMM
146 158
147struct reg_128_bit {159struct reg_128_bit {
@@ -153,6 +165,9 @@ struct reg_256_bit { · 5 unmodified lines
153struct reg_512_bit {165struct reg_512_bit {
154 u8 regbytes[512/8];166 u8 regbytes[512/8];
155};167};
168struct reg_1024_byte {
169 u8 regbytes[1024];
170};
156 171
157/*172/*
158 * State component 2:173 * State component 2:
@@ -255,6 +270,23 @@ struct arch_lbr_state { · 96 unmodified lines
255 u64 ler_to;270 u64 ler_to;
256 u64 ler_info;271 u64 ler_info;
257 struct lbr_entry entries[];272 struct lbr_entry entries[];
273};
274
275/*
276 * State component 17: 64-byte tile configuration register.
277 */
278struct xtile_cfg {
279 u64 tcfg[8];
280} __packed;
281
282/*
283 * State component 18: 1KB tile data register.
284 * Each register represents 16 64-byte rows of the matrix
285 * data. But the number of registers depends on the actual
286 * implementation.
287 */
288struct xtile_data {
289 struct reg_1024_byte tmm;
258} __packed;290} __packed;
259 291
260/*292/*
@@ -309,6 +341,91 @@ union fpregs_state { · 48 unmodified lines
309 u8 __padding[PAGE_SIZE];341 u8 __padding[PAGE_SIZE];
310};342};
311 343
344struct fpstate {
345 /* @kernel_size: The size of the kernel register image */
346 unsigned int size;
347
348 /* @user_size: The size in non-compacted UABI format */
349 unsigned int user_size;
350
351 /* @xfeatures: xfeatures for which the storage is sized */
352 u64 xfeatures;
353
354 /* @user_xfeatures: xfeatures valid in UABI buffers */
355 u64 user_xfeatures;
356
357 /* @xfd: xfeatures disabled to trap userspace use. */
358 u64 xfd;
359
360 /* @is_valloc: Indicator for dynamically allocated state */
361 unsigned int is_valloc : 1;
362
363 /* @is_guest: Indicator for guest state (KVM) */
364 unsigned int is_guest : 1;
365
366 /*
367 * @is_confidential: Indicator for KVM confidential mode.
368 * The FPU registers are restored by the
369 * vmentry firmware from encrypted guest
370 * memory. On vmexit the FPU registers are
371 * saved by firmware to encrypted guest memory
372 * and the registers are scrubbed before
373 * returning to the host. So there is no
374 * content which is worth saving and restoring.
375 * The fpstate has to be there so that
376 * preemption and softirq FPU usage works
377 * without special casing.
378 */
379 unsigned int is_confidential : 1;
380
381 /* @in_use: State is in use */
382 unsigned int in_use : 1;
383
384 /* @regs: The register state union for all supported formats */
385 union fpregs_state regs;
386
387 /* @regs is dynamically sized! Don't add anything after @regs! */
388} __aligned(64);
389
390struct fpu_state_perm {
391 /*
392 * @__state_perm:
393 *
394 * This bitmap indicates the permission for state components, which
395 * are available to a thread group. The permission prctl() sets the
396 * enabled state bits in thread_group_leader()->thread.fpu.
397 *
398 * All run time operations use the per thread information in the
399 * currently active fpu.fpstate which contains the xfeature masks
400 * and sizes for kernel and user space.
401 *
402 * This master permission field is only to be used when
403 * task.fpu.fpstate based checks fail to validate whether the task
404 * is allowed to expand it's xfeatures set which requires to
405 * allocate a larger sized fpstate buffer.
406 *
407 * Do not access this field directly. Use the provided helper
408 * function. Unlocked access is possible for quick checks.
409 */
410 u64 __state_perm;
411
412 /*
413 * @__state_size:
414 *
415 * The size required for @__state_perm. Only valid to access
416 * with sighand locked.
417 */
418 unsigned int __state_size;
419
420 /*
421 * @__user_state_size:
422 *
423 * The size required for @__state_perm user part. Only valid to
424 * access with sighand locked.
425 */
426 unsigned int __user_state_size;
427};
428
312/*429/*
313 * Highest level per task FPU state data structure that430 * Highest level per task FPU state data structure that
314 * contains the FPU register state plus various FPU431 * contains the FPU register state plus various FPU
@@ -337,19 +454,100 @@ struct fpu { · 22 unmodified lines
337 unsigned long avx512_timestamp;454 unsigned long avx512_timestamp;
338 455
339 /*456 /*
340 * @state:457 * @fpstate:
458 *
459 * Pointer to the active struct fpstate. Initialized to
460 * point at @__fpstate below.
461 */
462 struct fpstate *fpstate;
463
464 /*
465 * @__task_fpstate:
466 *
467 * Pointer to an inactive struct fpstate. Initialized to NULL. Is
468 * used only for KVM support to swap out the regular task fpstate.
469 */
470 struct fpstate *__task_fpstate;
471
472 /*
473 * @perm:
474 *
475 * Permission related information
476 */
477 struct fpu_state_perm perm;
478
479 /*
480 * @__fpstate:
341 *481 *
342 * In-memory copy of all FPU registers that we save/restore482 * Initial in-memory storage for FPU registers which are saved in
343 * over context switches. If the task is using the FPU then483 * context switch and when the kernel uses the FPU. The registers
344 * the registers in the FPU are more recent than this state484 * are restored from this storage on return to user space if they
345 * copy. If the task context-switches away then they get485 * are not longer containing the tasks FPU register state.
346 * saved here and represent the FPU state.
347 */486 */
348 union fpregs_state state;487 struct fpstate __fpstate;
349 /*488 /*
350 * WARNING: 'state' is dynamically-sized. Do not put489 * WARNING: '__fpstate' is dynamically-sized. Do not put
351 * anything after it here.490 * anything after it here.
352 */491 */
353};492};
354 493
494/*
495 * Guest pseudo FPU container
496 */
497struct fpu_guest {
498 /*
499 * @fpstate: Pointer to the allocated guest fpstate
500 */
501 struct fpstate *fpstate;
502};
503
504/*
505 * FPU state configuration data. Initialized at boot time. Read only after init.
506 */
507struct fpu_state_config {
508 /*
509 * @max_size:
510 *
511 * The maximum size of the register state buffer. Includes all
512 * supported features except independent managed features.
513 */
514 unsigned int max_size;
515
516 /*
517 * @default_size:
518 *
519 * The default size of the register state buffer. Includes all
520 * supported features except independent managed features and
521 * features which have to be requested by user space before usage.
522 */
523 unsigned int default_size;
524
525 /*
526 * @max_features:
527 *
528 * The maximum supported features bitmap. Does not include
529 * independent managed features.
530 */
531 u64 max_features;
532
533 /*
534 * @default_features:
535 *
536 * The default supported features bitmap. Does not include
537 * independent managed features and features which have to
538 * be requested by user space before usage.
539 */
540 u64 default_features;
541 /*
542 * @legacy_features:
543 *
544 * Features which can be reported back to user space
545 * even without XSAVE support, i.e. legacy features FP + SSE
546 */
547 u64 legacy_features;
548};
549
550/* FPU state configuration information */
551extern struct fpu_state_config fpu_kernel_cfg, fpu_user_cfg;
552
355#endif /* _ASM_X86_FPU_H */553#endif /* _ASM_X86_FPU_H */
arch/x86/include/asm/fpu/xcr.h+0−11
@@ -2,17 +2,6 @@ · 1 unmodified line
2#ifndef _ASM_X86_FPU_XCR_H2#ifndef _ASM_X86_FPU_XCR_H
3#define _ASM_X86_FPU_XCR_H3#define _ASM_X86_FPU_XCR_H
4 4
5/*
6 * MXCSR and XCR definitions:
7 */
8
9static inline void ldmxcsr(u32 mxcsr)
10{
11 asm volatile("ldmxcsr %0" :: "m" (mxcsr));
12}
13
14extern unsigned int mxcsr_feature_mask;
15
16#define XCR_XFEATURE_ENABLED_MASK 0x000000005#define XCR_XFEATURE_ENABLED_MASK 0x00000000
17 6
18static inline u64 xgetbv(u32 index)7static inline u64 xgetbv(u32 index)
arch/x86/include/asm/fpu/xstate.h+30−60
@@ -14,6 +14,8 @@ · 13 unmodified lines
14 14
15#define XSTATE_CPUID 0x0000000d15#define XSTATE_CPUID 0x0000000d
16 16
17#define TILE_CPUID 0x0000001d
18
17#define FXSAVE_SIZE 51219#define FXSAVE_SIZE 512
18 20
19#define XSAVE_HDR_SIZE 6421#define XSAVE_HDR_SIZE 64
@@ -33,7 +35,8 @@ · 13 unmodified lines
33 XFEATURE_MASK_Hi16_ZMM | \35 XFEATURE_MASK_Hi16_ZMM | \
34 XFEATURE_MASK_PKRU | \36 XFEATURE_MASK_PKRU | \
35 XFEATURE_MASK_BNDREGS | \37 XFEATURE_MASK_BNDREGS | \
36 XFEATURE_MASK_BNDCSR)38 XFEATURE_MASK_BNDCSR | \
39 XFEATURE_MASK_XTILE)
37 40
38/*41/*
39 * Features which are restored when returning to user space.42 * Features which are restored when returning to user space.
@@ -43,6 +46,9 @@ · 3 unmodified lines
43#define XFEATURE_MASK_USER_RESTORE \46#define XFEATURE_MASK_USER_RESTORE \
44 (XFEATURE_MASK_USER_SUPPORTED & ~XFEATURE_MASK_PKRU)47 (XFEATURE_MASK_USER_SUPPORTED & ~XFEATURE_MASK_PKRU)
45 48
49/* Features which are dynamically enabled for a process on request */
50#define XFEATURE_MASK_USER_DYNAMIC XFEATURE_MASK_XTILE_DATA
51
46/* All currently supported supervisor features */52/* All currently supported supervisor features */
47#define XFEATURE_MASK_SUPERVISOR_SUPPORTED (XFEATURE_MASK_PASID)53#define XFEATURE_MASK_SUPERVISOR_SUPPORTED (XFEATURE_MASK_PASID)
48 54
@@ -78,78 +84,42 @@ · 29 unmodified lines
78 XFEATURE_MASK_INDEPENDENT | \84 XFEATURE_MASK_INDEPENDENT | \
79 XFEATURE_MASK_SUPERVISOR_UNSUPPORTED)85 XFEATURE_MASK_SUPERVISOR_UNSUPPORTED)
80 86
81#ifdef CONFIG_X86_64
82#define REX_PREFIX "0x48, "
83#else
84#define REX_PREFIX
85#endif
86
87extern u64 xfeatures_mask_all;
88
89static inline u64 xfeatures_mask_supervisor(void)
90{
91 return xfeatures_mask_all & XFEATURE_MASK_SUPERVISOR_SUPPORTED;
92}
93
94/*87/*
95 * The xfeatures which are enabled in XCR0 and expected to be in ptrace88 * The feature mask required to restore FPU state:
96 * buffers and signal frames.89 * - All user states which are not eagerly switched in switch_to()/exec()
90 * - The suporvisor states
97 */91 */
98static inline u64 xfeatures_mask_uabi(void)92#define XFEATURE_MASK_FPSTATE (XFEATURE_MASK_USER_RESTORE | \
99{93 XFEATURE_MASK_SUPERVISOR_SUPPORTED)
100 return xfeatures_mask_all & XFEATURE_MASK_USER_SUPPORTED;
101}
102
103/*
104 * The xfeatures which are restored by the kernel when returning to user
105 * mode. This is not necessarily the same as xfeatures_mask_uabi() as the
106 * kernel does not manage all XCR0 enabled features via xsave/xrstor as
107 * some of them have to be switched eagerly on context switch and exec().
108 */
109static inline u64 xfeatures_mask_restore_user(void)
110{
111 return xfeatures_mask_all & XFEATURE_MASK_USER_RESTORE;
112}
113
114/*
115 * Like xfeatures_mask_restore_user() but additionally restors the
116 * supported supervisor states.
117 */
118static inline u64 xfeatures_mask_fpstate(void)
119{
120 return xfeatures_mask_all & \
121 (XFEATURE_MASK_USER_RESTORE | XFEATURE_MASK_SUPERVISOR_SUPPORTED);
122}
123
124static inline u64 xfeatures_mask_independent(void)
125{
126 if (!boot_cpu_has(X86_FEATURE_ARCH_LBR))
127 return XFEATURE_MASK_INDEPENDENT & ~XFEATURE_MASK_LBR;
128
129 return XFEATURE_MASK_INDEPENDENT;
130}
131 94
132extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS];95extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS];
133 96
134extern void __init update_regset_xstate_info(unsigned int size,97extern void __init update_regset_xstate_info(unsigned int size,
135 u64 xstate_mask);98 u64 xstate_mask);
136 99
137void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr);
138int xfeature_size(int xfeature_nr);100int xfeature_size(int xfeature_nr);
139int copy_uabi_from_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf);
140int copy_sigframe_from_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf);
141 101
142void xsaves(struct xregs_state *xsave, u64 mask);102void xsaves(struct xregs_state *xsave, u64 mask);
143void xrstors(struct xregs_state *xsave, u64 mask);103void xrstors(struct xregs_state *xsave, u64 mask);
144 104
145enum xstate_copy_mode {105int xfd_enable_feature(u64 xfd_err);
146 XSTATE_COPY_FP,106
147 XSTATE_COPY_FX,107#ifdef CONFIG_X86_64
148 XSTATE_COPY_XSAVE,108DECLARE_STATIC_KEY_FALSE(__fpu_state_size_dynamic);
149};109#endif
110
111#ifdef CONFIG_X86_64
112DECLARE_STATIC_KEY_FALSE(__fpu_state_size_dynamic);
150 113
151struct membuf;114static __always_inline __pure bool fpu_state_size_dynamic(void)
152void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk,115{
153 enum xstate_copy_mode mode);116 return static_branch_unlikely(&__fpu_state_size_dynamic);
117}
118#else
119static __always_inline __pure bool fpu_state_size_dynamic(void)
120{
121 return false;
122}
123#endif
154 124
155#endif125#endif
arch/x86/include/asm/kvm_host.h+2−5
@@ -691,11 +691,10 @@ struct kvm_vcpu_arch { · 690 unmodified lines
691 *691 *
692 * Note that while the PKRU state lives inside the fpu registers,692 * Note that while the PKRU state lives inside the fpu registers,
693 * it is switched out separately at VMENTER and VMEXIT time. The693 * it is switched out separately at VMENTER and VMEXIT time. The
694 * "guest_fpu" state here contains the guest FPU context, with the694 * "guest_fpstate" state here contains the guest FPU context, with the
695 * host PRKU bits.695 * host PRKU bits.
696 */696 */
697 struct fpu *user_fpu;697 struct fpu_guest guest_fpu;
698 struct fpu *guest_fpu;
699 698
700 u64 xcr0;699 u64 xcr0;
701 u64 guest_supported_xcr0;700 u64 guest_supported_xcr0;
@@ -1686,8 +1685,6 @@ void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector); · 984 unmodified lines
1686int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index,1685int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index,
1687 int reason, bool has_error_code, u32 error_code);1686 int reason, bool has_error_code, u32 error_code);
1688 1687
1689void kvm_free_guest_fpu(struct kvm_vcpu *vcpu);
1690
1691void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0, unsigned long cr0);1688void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0, unsigned long cr0);
1692void kvm_post_set_cr4(struct kvm_vcpu *vcpu, unsigned long old_cr4, unsigned long cr4);1689void kvm_post_set_cr4(struct kvm_vcpu *vcpu, unsigned long old_cr4, unsigned long cr4);
1693int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0);1690int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0);
arch/x86/include/asm/msr-index.h+2−0
@@ -625,6 +625,8 @@ · 624 unmodified lines
625 625
626#define MSR_IA32_BNDCFGS_RSVD 0x00000ffc626#define MSR_IA32_BNDCFGS_RSVD 0x00000ffc
627 627
628#define MSR_IA32_XFD 0x000001c4
629#define MSR_IA32_XFD_ERR 0x000001c5
628#define MSR_IA32_XSS 0x00000da0630#define MSR_IA32_XSS 0x00000da0
629 631
630#define MSR_IA32_APICBASE 0x0000001b632#define MSR_IA32_APICBASE 0x0000001b
arch/x86/include/asm/msr.h+2−2
@@ -92,7 +92,7 @@ static __always_inline unsigned long long __rdmsr(unsigned int msr) · 91 unmodified lines
92 92
93 asm volatile("1: rdmsr\n"93 asm volatile("1: rdmsr\n"
94 "2:\n"94 "2:\n"
95 _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_rdmsr_unsafe)95 _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_RDMSR)
96 : EAX_EDX_RET(val, low, high) : "c" (msr));96 : EAX_EDX_RET(val, low, high) : "c" (msr));
97 97
98 return EAX_EDX_VAL(val, low, high);98 return EAX_EDX_VAL(val, low, high);
@@ -102,7 +102,7 @@ static __always_inline void __wrmsr(unsigned int msr, u32 low, u32 high) · 3 unmodified lines
102{102{
103 asm volatile("1: wrmsr\n"103 asm volatile("1: wrmsr\n"
104 "2:\n"104 "2:\n"
105 _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_wrmsr_unsafe)105 _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_WRMSR)
106 : : "c" (msr), "a"(low), "d" (high) : "memory");106 : : "c" (msr), "a"(low), "d" (high) : "memory");
107}107}
108 108
arch/x86/include/asm/pkru.h+1−1
@@ -2,7 +2,7 @@ · 1 unmodified line
2#ifndef _ASM_X86_PKRU_H2#ifndef _ASM_X86_PKRU_H
3#define _ASM_X86_PKRU_H3#define _ASM_X86_PKRU_H
4 4
5#include <asm/fpu/xstate.h>5#include <asm/cpufeature.h>
6 6
7#define PKRU_AD_BIT 0x17#define PKRU_AD_BIT 0x1
8#define PKRU_WD_BIT 0x28#define PKRU_WD_BIT 0x2
arch/x86/include/asm/processor.h+3−6
@@ -461,9 +461,6 @@ DECLARE_PER_CPU(struct irq_stack *, hardirq_stack_ptr); · 460 unmodified lines
461DECLARE_PER_CPU(struct irq_stack *, softirq_stack_ptr);461DECLARE_PER_CPU(struct irq_stack *, softirq_stack_ptr);
462#endif /* !X86_64 */462#endif /* !X86_64 */
463 463
464extern unsigned int fpu_kernel_xstate_size;
465extern unsigned int fpu_user_xstate_size;
466
467struct perf_event;464struct perf_event;
468 465
469struct thread_struct {466struct thread_struct {
@@ -537,12 +534,12 @@ struct thread_struct { · 67 unmodified lines
537 */534 */
538};535};
539 536
540/* Whitelist the FPU state from the task_struct for hardened usercopy. */537extern void fpu_thread_struct_whitelist(unsigned long *offset, unsigned long *size);
538
541static inline void arch_thread_struct_whitelist(unsigned long *offset,539static inline void arch_thread_struct_whitelist(unsigned long *offset,
542 unsigned long *size)540 unsigned long *size)
543{541{
544 *offset = offsetof(struct thread_struct, fpu.state);542 fpu_thread_struct_whitelist(offset, size);
545 *size = fpu_kernel_xstate_size;
546}543}
547 544
548static inline void545static inline void
arch/x86/include/asm/proto.h+1−1
@@ -40,6 +40,6 @@ void x86_report_nx(void); · 39 unmodified lines
40extern int reboot_force;40extern int reboot_force;
41 41
42long do_arch_prctl_common(struct task_struct *task, int option,42long do_arch_prctl_common(struct task_struct *task, int option,
43 unsigned long cpuid_enabled);43 unsigned long arg2);
44 44
45#endif /* _ASM_X86_PROTO_H */45#endif /* _ASM_X86_PROTO_H */
arch/x86/include/asm/segment.h+1−1
@@ -339,7 +339,7 @@ static inline void __loadsegment_fs(unsigned short value) · 338 unmodified lines
339 "1: movw %0, %%fs \n"339 "1: movw %0, %%fs \n"
340 "2: \n"340 "2: \n"
341 341
342 _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_clear_fs)342 _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_CLEAR_FS)
343 343
344 : : "rm" (value) : "memory");344 : : "rm" (value) : "memory");
345}345}
arch/x86/include/asm/trace/fpu.h+2−2
@@ -22,8 +22,8 @@ DECLARE_EVENT_CLASS(x86_fpu, · 21 unmodified lines
22 __entry->fpu = fpu;22 __entry->fpu = fpu;
23 __entry->load_fpu = test_thread_flag(TIF_NEED_FPU_LOAD);23 __entry->load_fpu = test_thread_flag(TIF_NEED_FPU_LOAD);
24 if (boot_cpu_has(X86_FEATURE_OSXSAVE)) {24 if (boot_cpu_has(X86_FEATURE_OSXSAVE)) {
25 __entry->xfeatures = fpu->state.xsave.header.xfeatures;25 __entry->xfeatures = fpu->fpstate->regs.xsave.header.xfeatures;
26 __entry->xcomp_bv = fpu->state.xsave.header.xcomp_bv;26 __entry->xcomp_bv = fpu->fpstate->regs.xsave.header.xcomp_bv;
27 }27 }
28 ),28 ),
29 TP_printk("x86/fpu: %p load: %d xfeatures: %llx xcomp_bv: %llx",29 TP_printk("x86/fpu: %p load: %d xfeatures: %llx xcomp_bv: %llx",
arch/x86/include/uapi/asm/prctl.h+4−0
@@ -10,6 +10,10 @@ · 9 unmodified lines
10#define ARCH_GET_CPUID 0x101110#define ARCH_GET_CPUID 0x1011
11#define ARCH_SET_CPUID 0x101211#define ARCH_SET_CPUID 0x1012
12 12
13#define ARCH_GET_XCOMP_SUPP 0x1021
14#define ARCH_GET_XCOMP_PERM 0x1022
15#define ARCH_REQ_XCOMP_PERM 0x1023
16
13#define ARCH_MAP_VDSO_X32 0x200117#define ARCH_MAP_VDSO_X32 0x2001
14#define ARCH_MAP_VDSO_32 0x200218#define ARCH_MAP_VDSO_32 0x2002
15#define ARCH_MAP_VDSO_64 0x200319#define ARCH_MAP_VDSO_64 0x2003
arch/x86/kernel/cpu/bugs.c+1−1
@@ -22,7 +22,7 @@ · 21 unmodified lines
22#include <asm/bugs.h>22#include <asm/bugs.h>
23#include <asm/processor.h>23#include <asm/processor.h>
24#include <asm/processor-flags.h>24#include <asm/processor-flags.h>
25#include <asm/fpu/internal.h>25#include <asm/fpu/api.h>
26#include <asm/msr.h>26#include <asm/msr.h>
27#include <asm/vmx.h>27#include <asm/vmx.h>
28#include <asm/paravirt.h>28#include <asm/paravirt.h>
arch/x86/kernel/cpu/common.c+1−1
@@ -42,7 +42,7 @@ · 41 unmodified lines
42#include <asm/setup.h>42#include <asm/setup.h>
43#include <asm/apic.h>43#include <asm/apic.h>
44#include <asm/desc.h>44#include <asm/desc.h>
45#include <asm/fpu/internal.h>45#include <asm/fpu/api.h>
46#include <asm/mtrr.h>46#include <asm/mtrr.h>
47#include <asm/hwcap2.h>47#include <asm/hwcap2.h>
48#include <linux/numa.h>48#include <linux/numa.h>
arch/x86/kernel/cpu/cpuid-deps.c+2−0
@@ -75,6 +75,8 @@ static const struct cpuid_dep cpuid_deps[] = { · 74 unmodified lines
75 { X86_FEATURE_SGX_LC, X86_FEATURE_SGX },75 { X86_FEATURE_SGX_LC, X86_FEATURE_SGX },
76 { X86_FEATURE_SGX1, X86_FEATURE_SGX },76 { X86_FEATURE_SGX1, X86_FEATURE_SGX },
77 { X86_FEATURE_SGX2, X86_FEATURE_SGX1 },77 { X86_FEATURE_SGX2, X86_FEATURE_SGX1 },
78 { X86_FEATURE_XFD, X86_FEATURE_XSAVES },
79 { X86_FEATURE_AMX_TILE, X86_FEATURE_XFD },
78 {}80 {}
79};81};
80 82
arch/x86/kernel/cpu/mce/core.c+11−29
@@ -373,13 +373,16 @@ static int msr_to_offset(u32 msr) · 372 unmodified lines
373 return -1;373 return -1;
374}374}
375 375
376__visible bool ex_handler_rdmsr_fault(const struct exception_table_entry *fixup,376void ex_handler_msr_mce(struct pt_regs *regs, bool wrmsr)
377 struct pt_regs *regs, int trapnr,
378 unsigned long error_code,
379 unsigned long fault_addr)
380{377{
381 pr_emerg("MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n",378 if (wrmsr) {
382 (unsigned int)regs->cx, regs->ip, (void *)regs->ip);379 pr_emerg("MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n",
380 (unsigned int)regs->cx, (unsigned int)regs->dx, (unsigned int)regs->ax,
381 regs->ip, (void *)regs->ip);
382 } else {
383 pr_emerg("MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n",
384 (unsigned int)regs->cx, regs->ip, (void *)regs->ip);
385 }
383 386
384 show_stack_regs(regs);387 show_stack_regs(regs);
385 388
@@ -387,8 +390,6 @@ __visible bool ex_handler_rdmsr_fault(const struct exception_table_entry *fixup, · 1 unmodified line
387 390
388 while (true)391 while (true)
389 cpu_relax();392 cpu_relax();
390
391 return true;
392}393}
393 394
394/* MSR access wrappers used for error injection */395/* MSR access wrappers used for error injection */
@@ -420,32 +421,13 @@ static noinstr u64 mce_rdmsrl(u32 msr) · 25 unmodified lines
420 */421 */
421 asm volatile("1: rdmsr\n"422 asm volatile("1: rdmsr\n"
422 "2:\n"423 "2:\n"
423 _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_rdmsr_fault)424 _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_RDMSR_IN_MCE)
424 : EAX_EDX_RET(val, low, high) : "c" (msr));425 : EAX_EDX_RET(val, low, high) : "c" (msr));
425 426
426 427
427 return EAX_EDX_VAL(val, low, high);428 return EAX_EDX_VAL(val, low, high);
428}429}
429 430
430__visible bool ex_handler_wrmsr_fault(const struct exception_table_entry *fixup,
431 struct pt_regs *regs, int trapnr,
432 unsigned long error_code,
433 unsigned long fault_addr)
434{
435 pr_emerg("MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n",
436 (unsigned int)regs->cx, (unsigned int)regs->dx, (unsigned int)regs->ax,
437 regs->ip, (void *)regs->ip);
438
439 show_stack_regs(regs);
440
441 panic("MCA architectural violation!\n");
442
443 while (true)
444 cpu_relax();
445
446 return true;
447}
448
449static noinstr void mce_wrmsrl(u32 msr, u64 v)431static noinstr void mce_wrmsrl(u32 msr, u64 v)
450{432{
451 u32 low, high;433 u32 low, high;
@@ -470,7 +452,7 @@ static noinstr void mce_wrmsrl(u32 msr, u64 v) · 18 unmodified lines
470 /* See comment in mce_rdmsrl() */452 /* See comment in mce_rdmsrl() */
471 asm volatile("1: wrmsr\n"453 asm volatile("1: wrmsr\n"
472 "2:\n"454 "2:\n"
473 _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_wrmsr_fault)455 _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_WRMSR_IN_MCE)
474 : : "c" (msr), "a"(low), "d" (high) : "memory");456 : : "c" (msr), "a"(low), "d" (high) : "memory");
475}457}
476 458
arch/x86/kernel/cpu/mce/internal.h+2−12
@@ -61,7 +61,7 @@ static inline void cmci_disable_bank(int bank) { } · 60 unmodified lines
61static inline void intel_init_cmci(void) { }61static inline void intel_init_cmci(void) { }
62static inline void intel_init_lmce(void) { }62static inline void intel_init_lmce(void) { }
63static inline void intel_clear_lmce(void) { }63static inline void intel_clear_lmce(void) { }
64static inline bool intel_filter_mce(struct mce *m) { return false; };64static inline bool intel_filter_mce(struct mce *m) { return false; }
65#endif65#endif
66 66
67void mce_timer_kick(unsigned long interval);67void mce_timer_kick(unsigned long interval);
@@ -183,17 +183,7 @@ extern bool filter_mce(struct mce *m); · 115 unmodified lines
183#ifdef CONFIG_X86_MCE_AMD183#ifdef CONFIG_X86_MCE_AMD
184extern bool amd_filter_mce(struct mce *m);184extern bool amd_filter_mce(struct mce *m);
185#else185#else
186static inline bool amd_filter_mce(struct mce *m) { return false; };186static inline bool amd_filter_mce(struct mce *m) { return false; }
187#endif187#endif
188 188
189__visible bool ex_handler_rdmsr_fault(const struct exception_table_entry *fixup,
190 struct pt_regs *regs, int trapnr,
191 unsigned long error_code,
192 unsigned long fault_addr);
193
194__visible bool ex_handler_wrmsr_fault(const struct exception_table_entry *fixup,
195 struct pt_regs *regs, int trapnr,
196 unsigned long error_code,
197 unsigned long fault_addr);
198
199#endif /* __X86_MCE_INTERNAL_H__ */189#endif /* __X86_MCE_INTERNAL_H__ */
arch/x86/kernel/cpu/mce/severity.c+11−11
@@ -265,25 +265,25 @@ static bool is_copy_from_user(struct pt_regs *regs) · 264 unmodified lines
265 */265 */
266static int error_context(struct mce *m, struct pt_regs *regs)266static int error_context(struct mce *m, struct pt_regs *regs)
267{267{
268 enum handler_type t;
269
270 if ((m->cs & 3) == 3)268 if ((m->cs & 3) == 3)
271 return IN_USER;269 return IN_USER;
272 if (!mc_recoverable(m->mcgstatus))270 if (!mc_recoverable(m->mcgstatus))
273 return IN_KERNEL;271 return IN_KERNEL;
274 272
275 t = ex_get_fault_handler_type(m->ip);273 switch (ex_get_fixup_type(m->ip)) {
276 if (t == EX_HANDLER_FAULT) {274 case EX_TYPE_UACCESS:
277 m->kflags |= MCE_IN_KERNEL_RECOV;275 case EX_TYPE_COPY:
278 return IN_KERNEL_RECOV;276 if (!regs || !is_copy_from_user(regs))
279 }277 return IN_KERNEL;
280 if (t == EX_HANDLER_UACCESS && regs && is_copy_from_user(regs)) {
281 m->kflags |= MCE_IN_KERNEL_RECOV;
282 m->kflags |= MCE_IN_KERNEL_COPYIN;278 m->kflags |= MCE_IN_KERNEL_COPYIN;
279 fallthrough;
280 case EX_TYPE_FAULT_MCE_SAFE:
281 case EX_TYPE_DEFAULT_MCE_SAFE:
282 m->kflags |= MCE_IN_KERNEL_RECOV;
283 return IN_KERNEL_RECOV;283 return IN_KERNEL_RECOV;
284 default:
285 return IN_KERNEL;
284 }286 }
285
286 return IN_KERNEL;
287}287}
288 288
289static int mce_severity_amd_smca(struct mce *m, enum context err_ctx)289static int mce_severity_amd_smca(struct mce *m, enum context err_ctx)
arch/x86/kernel/fpu/bugs.c+1−1
@@ -2,7 +2,7 @@ · 1 unmodified line
2/*2/*
3 * x86 FPU bug checks:3 * x86 FPU bug checks:
4 */4 */
5#include <asm/fpu/internal.h>5#include <asm/fpu/api.h>
6 6
7/*7/*
8 * Boot time CPU/FPU FDIV bug detection code:8 * Boot time CPU/FPU FDIV bug detection code:
arch/x86/kernel/fpu/context.h+83−0
@@ -0,0 +1,83 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __X86_KERNEL_FPU_CONTEXT_H
3#define __X86_KERNEL_FPU_CONTEXT_H
4
5#include <asm/fpu/xstate.h>
6#include <asm/trace/fpu.h>
7
8/* Functions related to FPU context tracking */
9
10/*
11 * The in-register FPU state for an FPU context on a CPU is assumed to be
12 * valid if the fpu->last_cpu matches the CPU, and the fpu_fpregs_owner_ctx
13 * matches the FPU.
14 *
15 * If the FPU register state is valid, the kernel can skip restoring the
16 * FPU state from memory.
17 *
18 * Any code that clobbers the FPU registers or updates the in-memory
19 * FPU state for a task MUST let the rest of the kernel know that the
20 * FPU registers are no longer valid for this task.
21 *
22 * Either one of these invalidation functions is enough. Invalidate
23 * a resource you control: CPU if using the CPU for something else
24 * (with preemption disabled), FPU for the current task, or a task that
25 * is prevented from running by the current task.
26 */
27static inline void __cpu_invalidate_fpregs_state(void)
28{
29 __this_cpu_write(fpu_fpregs_owner_ctx, NULL);
30}
31
32static inline void __fpu_invalidate_fpregs_state(struct fpu *fpu)
33{
34 fpu->last_cpu = -1;
35}
36
37static inline int fpregs_state_valid(struct fpu *fpu, unsigned int cpu)
38{
39 return fpu == this_cpu_read(fpu_fpregs_owner_ctx) && cpu == fpu->last_cpu;
40}
41
42static inline void fpregs_deactivate(struct fpu *fpu)
43{
44 __this_cpu_write(fpu_fpregs_owner_ctx, NULL);
45 trace_x86_fpu_regs_deactivated(fpu);
46}
47
48static inline void fpregs_activate(struct fpu *fpu)
49{
50 __this_cpu_write(fpu_fpregs_owner_ctx, fpu);
51 trace_x86_fpu_regs_activated(fpu);
52}
53
54/* Internal helper for switch_fpu_return() and signal frame setup */
55static inline void fpregs_restore_userregs(void)
56{
57 struct fpu *fpu = &current->thread.fpu;
58 int cpu = smp_processor_id();
59
60 if (WARN_ON_ONCE(current->flags & PF_KTHREAD))
61 return;
62
63 if (!fpregs_state_valid(fpu, cpu)) {
64 /*
65 * This restores _all_ xstate which has not been
66 * established yet.
67 *
68 * If PKRU is enabled, then the PKRU value is already
69 * correct because it was either set in switch_to() or in
70 * flush_thread(). So it is excluded because it might be
71 * not up to date in current->thread.fpu.xsave state.
72 *
73 * XFD state is handled in restore_fpregs_from_fpstate().
74 */
75 restore_fpregs_from_fpstate(fpu->fpstate, XFEATURE_MASK_FPSTATE);
76
77 fpregs_activate(fpu);
78 fpu->last_cpu = cpu;
79 }
80 clear_thread_flag(TIF_NEED_FPU_LOAD);
81}
82
83#endif
arch/x86/kernel/fpu/core.c+315−77
@@ -6,8 +6,9 @@ · 5 unmodified lines
6 * General FPU state handling cleanups6 * General FPU state handling cleanups
7 * Gareth Hughes <gareth@valinux.com>, May 20007 * Gareth Hughes <gareth@valinux.com>, May 2000
8 */8 */
9#include <asm/fpu/internal.h>9#include <asm/fpu/api.h>
10#include <asm/fpu/regset.h>10#include <asm/fpu/regset.h>
11#include <asm/fpu/sched.h>
11#include <asm/fpu/signal.h>12#include <asm/fpu/signal.h>
12#include <asm/fpu/types.h>13#include <asm/fpu/types.h>
13#include <asm/traps.h>14#include <asm/traps.h>
@@ -15,15 +16,30 @@ · 1 unmodified line
15 16
16#include <linux/hardirq.h>17#include <linux/hardirq.h>
17#include <linux/pkeys.h>18#include <linux/pkeys.h>
19#include <linux/vmalloc.h>
20
21#include "context.h"
22#include "internal.h"
23#include "legacy.h"
24#include "xstate.h"
18 25
19#define CREATE_TRACE_POINTS26#define CREATE_TRACE_POINTS
20#include <asm/trace/fpu.h>27#include <asm/trace/fpu.h>
21 28
29#ifdef CONFIG_X86_64
30DEFINE_STATIC_KEY_FALSE(__fpu_state_size_dynamic);
31DEFINE_PER_CPU(u64, xfd_state);
32#endif
33
34/* The FPU state configuration data for kernel and user space */
35struct fpu_state_config fpu_kernel_cfg __ro_after_init;
36struct fpu_state_config fpu_user_cfg __ro_after_init;
37
22/*38/*
23 * Represents the initial FPU state. It's mostly (but not completely) zeroes,39 * Represents the initial FPU state. It's mostly (but not completely) zeroes,
24 * depending on the FPU hardware format:40 * depending on the FPU hardware format:
25 */41 */
26union fpregs_state init_fpstate __ro_after_init;42struct fpstate init_fpstate __ro_after_init;
27 43
28/*44/*
29 * Track whether the kernel is using the FPU state45 * Track whether the kernel is using the FPU state
@@ -83,7 +99,7 @@ bool irq_fpu_usable(void) · 53 unmodified lines
83EXPORT_SYMBOL(irq_fpu_usable);99EXPORT_SYMBOL(irq_fpu_usable);
84 100
85/*101/*
86 * Save the FPU register state in fpu->state. The register state is102 * Save the FPU register state in fpu->fpstate->regs. The register state is
87 * preserved.103 * preserved.
88 *104 *
89 * Must be called with fpregs_lock() held.105 * Must be called with fpregs_lock() held.
@@ -99,19 +115,19 @@ EXPORT_SYMBOL(irq_fpu_usable); · 9 unmodified lines
99void save_fpregs_to_fpstate(struct fpu *fpu)115void save_fpregs_to_fpstate(struct fpu *fpu)
100{116{
101 if (likely(use_xsave())) {117 if (likely(use_xsave())) {
102 os_xsave(&fpu->state.xsave);118 os_xsave(fpu->fpstate);
103 119
104 /*120 /*
105 * AVX512 state is tracked here because its use is121 * AVX512 state is tracked here because its use is
106 * known to slow the max clock speed of the core.122 * known to slow the max clock speed of the core.
107 */123 */
108 if (fpu->state.xsave.header.xfeatures & XFEATURE_MASK_AVX512)124 if (fpu->fpstate->regs.xsave.header.xfeatures & XFEATURE_MASK_AVX512)
109 fpu->avx512_timestamp = jiffies;125 fpu->avx512_timestamp = jiffies;
110 return;126 return;
111 }127 }
112 128
113 if (likely(use_fxsr())) {129 if (likely(use_fxsr())) {
114 fxsave(&fpu->state.fxsave);130 fxsave(&fpu->fpstate->regs.fxsave);
115 return;131 return;
116 }132 }
117 133
@@ -119,12 +135,11 @@ void save_fpregs_to_fpstate(struct fpu *fpu) · 1 unmodified line
119 * Legacy FPU register saving, FNSAVE always clears FPU registers,135 * Legacy FPU register saving, FNSAVE always clears FPU registers,
120 * so we have to reload them from the memory state.136 * so we have to reload them from the memory state.
121 */137 */
122 asm volatile("fnsave %[fp]; fwait" : [fp] "=m" (fpu->state.fsave));138 asm volatile("fnsave %[fp]; fwait" : [fp] "=m" (fpu->fpstate->regs.fsave));
123 frstor(&fpu->state.fsave);139 frstor(&fpu->fpstate->regs.fsave);
124}140}
125EXPORT_SYMBOL(save_fpregs_to_fpstate);
126 141
127void __restore_fpregs_from_fpstate(union fpregs_state *fpstate, u64 mask)142void restore_fpregs_from_fpstate(struct fpstate *fpstate, u64 mask)
128{143{
129 /*144 /*
130 * AMD K7/K8 and later CPUs up to Zen don't save/restore145 * AMD K7/K8 and later CPUs up to Zen don't save/restore
@@ -141,15 +156,181 @@ void __restore_fpregs_from_fpstate(union fpregs_state *fpstate, u64 mask) · 10 unmodified lines
141 }156 }
142 157
143 if (use_xsave()) {158 if (use_xsave()) {
144 os_xrstor(&fpstate->xsave, mask);159 /*
160 * Dynamically enabled features are enabled in XCR0, but
161 * usage requires also that the corresponding bits in XFD
162 * are cleared. If the bits are set then using a related
163 * instruction will raise #NM. This allows to do the
164 * allocation of the larger FPU buffer lazy from #NM or if
165 * the task has no permission to kill it which would happen
166 * via #UD if the feature is disabled in XCR0.
167 *
168 * XFD state is following the same life time rules as
169 * XSTATE and to restore state correctly XFD has to be
170 * updated before XRSTORS otherwise the component would
171 * stay in or go into init state even if the bits are set
172 * in fpstate::regs::xsave::xfeatures.
173 */
174 xfd_update_state(fpstate);
175
176 /*
177 * Restoring state always needs to modify all features
178 * which are in @mask even if the current task cannot use
179 * extended features.
180 *
181 * So fpstate->xfeatures cannot be used here, because then
182 * a feature for which the task has no permission but was
183 * used by the previous task would not go into init state.
184 */
185 mask = fpu_kernel_cfg.max_features & mask;
186
187 os_xrstor(fpstate, mask);
145 } else {188 } else {
146 if (use_fxsr())189 if (use_fxsr())
147 fxrstor(&fpstate->fxsave);190 fxrstor(&fpstate->regs.fxsave);
148 else191 else
149 frstor(&fpstate->fsave);192 frstor(&fpstate->regs.fsave);
150 }193 }
151}194}
152EXPORT_SYMBOL_GPL(__restore_fpregs_from_fpstate);195
196void fpu_reset_from_exception_fixup(void)
197{
198 restore_fpregs_from_fpstate(&init_fpstate, XFEATURE_MASK_FPSTATE);
199}
200
201#if IS_ENABLED(CONFIG_KVM)
202static void __fpstate_reset(struct fpstate *fpstate);
203
204bool fpu_alloc_guest_fpstate(struct fpu_guest *gfpu)
205{
206 struct fpstate *fpstate;
207 unsigned int size;
208
209 size = fpu_user_cfg.default_size + ALIGN(offsetof(struct fpstate, regs), 64);
210 fpstate = vzalloc(size);
211 if (!fpstate)
212 return false;
213
214 __fpstate_reset(fpstate);
215 fpstate_init_user(fpstate);
216 fpstate->is_valloc = true;
217 fpstate->is_guest = true;
218
219 gfpu->fpstate = fpstate;
220 return true;
221}
222EXPORT_SYMBOL_GPL(fpu_alloc_guest_fpstate);
223
224void fpu_free_guest_fpstate(struct fpu_guest *gfpu)
225{
226 struct fpstate *fps = gfpu->fpstate;
227
228 if (!fps)
229 return;
230
231 if (WARN_ON_ONCE(!fps->is_valloc || !fps->is_guest || fps->in_use))
232 return;
233
234 gfpu->fpstate = NULL;
235 vfree(fps);
236}
237EXPORT_SYMBOL_GPL(fpu_free_guest_fpstate);
238
239int fpu_swap_kvm_fpstate(struct fpu_guest *guest_fpu, bool enter_guest)
240{
241 struct fpstate *guest_fps = guest_fpu->fpstate;
242 struct fpu *fpu = &current->thread.fpu;
243 struct fpstate *cur_fps = fpu->fpstate;
244
245 fpregs_lock();
246 if (!cur_fps->is_confidential && !test_thread_flag(TIF_NEED_FPU_LOAD))
247 save_fpregs_to_fpstate(fpu);
248
249 /* Swap fpstate */
250 if (enter_guest) {
251 fpu->__task_fpstate = cur_fps;
252 fpu->fpstate = guest_fps;
253 guest_fps->in_use = true;
254 } else {
255 guest_fps->in_use = false;
256 fpu->fpstate = fpu->__task_fpstate;
257 fpu->__task_fpstate = NULL;
258 }
259
260 cur_fps = fpu->fpstate;
261
262 if (!cur_fps->is_confidential) {
263 /* Includes XFD update */
264 restore_fpregs_from_fpstate(cur_fps, XFEATURE_MASK_FPSTATE);
265 } else {
266 /*
267 * XSTATE is restored by firmware from encrypted
268 * memory. Make sure XFD state is correct while
269 * running with guest fpstate
270 */
271 xfd_update_state(cur_fps);
272 }
273
274 fpregs_mark_activate();
275 fpregs_unlock();
276 return 0;
277}
278EXPORT_SYMBOL_GPL(fpu_swap_kvm_fpstate);
279
280void fpu_copy_guest_fpstate_to_uabi(struct fpu_guest *gfpu, void *buf,
281 unsigned int size, u32 pkru)
282{
283 struct fpstate *kstate = gfpu->fpstate;
284 union fpregs_state *ustate = buf;
285 struct membuf mb = { .p = buf, .left = size };
286
287 if (cpu_feature_enabled(X86_FEATURE_XSAVE)) {
288 __copy_xstate_to_uabi_buf(mb, kstate, pkru, XSTATE_COPY_XSAVE);
289 } else {
290 memcpy(&ustate->fxsave, &kstate->regs.fxsave,
291 sizeof(ustate->fxsave));
292 /* Make it restorable on a XSAVE enabled host */
293 ustate->xsave.header.xfeatures = XFEATURE_MASK_FPSSE;
294 }
295}
296EXPORT_SYMBOL_GPL(fpu_copy_guest_fpstate_to_uabi);
297
298int fpu_copy_uabi_to_guest_fpstate(struct fpu_guest *gfpu, const void *buf,
299 u64 xcr0, u32 *vpkru)
300{
301 struct fpstate *kstate = gfpu->fpstate;
302 const union fpregs_state *ustate = buf;
303 struct pkru_state *xpkru;
304 int ret;
305
306 if (!cpu_feature_enabled(X86_FEATURE_XSAVE)) {
307 if (ustate->xsave.header.xfeatures & ~XFEATURE_MASK_FPSSE)
308 return -EINVAL;
309 if (ustate->fxsave.mxcsr & ~mxcsr_feature_mask)
310 return -EINVAL;
311 memcpy(&kstate->regs.fxsave, &ustate->fxsave, sizeof(ustate->fxsave));
312 return 0;
313 }
314
315 if (ustate->xsave.header.xfeatures & ~xcr0)
316 return -EINVAL;
317
318 ret = copy_uabi_from_kernel_to_xstate(kstate, ustate);
319 if (ret)
320 return ret;
321
322 /* Retrieve PKRU if not in init state */
323 if (kstate->regs.xsave.header.xfeatures & XFEATURE_MASK_PKRU) {
324 xpkru = get_xsave_addr(&kstate->regs.xsave, XFEATURE_PKRU);
325 *vpkru = xpkru->pkru;
326 }
327
328 /* Ensure that XCOMP_BV is set up for XSAVES */
329 xstate_init_xcomp_bv(&kstate->regs.xsave, kstate->xfeatures);
330 return 0;
331}
332EXPORT_SYMBOL_GPL(fpu_copy_uabi_to_guest_fpstate);
333#endif /* CONFIG_KVM */
153 334
154void kernel_fpu_begin_mask(unsigned int kfpu_mask)335void kernel_fpu_begin_mask(unsigned int kfpu_mask)
155{336{
@@ -203,52 +384,88 @@ void fpu_sync_fpstate(struct fpu *fpu) · 47 unmodified lines
203 fpregs_unlock();384 fpregs_unlock();
204}385}
205 386
206static inline void fpstate_init_xstate(struct xregs_state *xsave)387static inline unsigned int init_fpstate_copy_size(void)
207{388{
208 /*389 if (!use_xsave())
209 * XRSTORS requires these bits set in xcomp_bv, or it will390 return fpu_kernel_cfg.default_size;
210 * trigger #GP:391
211 */392 /* XSAVE(S) just needs the legacy and the xstate header part */
212 xsave->header.xcomp_bv = XCOMP_BV_COMPACTED_FORMAT | xfeatures_mask_all;393 return sizeof(init_fpstate.regs.xsave);
213}394}
214 395
215static inline void fpstate_init_fxstate(struct fxregs_state *fx)396static inline void fpstate_init_fxstate(struct fpstate *fpstate)
216{397{
217 fx->cwd = 0x37f;398 fpstate->regs.fxsave.cwd = 0x37f;
218 fx->mxcsr = MXCSR_DEFAULT;399 fpstate->regs.fxsave.mxcsr = MXCSR_DEFAULT;
219}400}
220 401
221/*402/*
222 * Legacy x87 fpstate state init:403 * Legacy x87 fpstate state init:
223 */404 */
224static inline void fpstate_init_fstate(struct fregs_state *fp)405static inline void fpstate_init_fstate(struct fpstate *fpstate)
225{406{
226 fp->cwd = 0xffff037fu;407 fpstate->regs.fsave.cwd = 0xffff037fu;
227 fp->swd = 0xffff0000u;408 fpstate->regs.fsave.swd = 0xffff0000u;
228 fp->twd = 0xffffffffu;409 fpstate->regs.fsave.twd = 0xffffffffu;
229 fp->fos = 0xffff0000u;410 fpstate->regs.fsave.fos = 0xffff0000u;
230}411}
231 412
232void fpstate_init(union fpregs_state *state)413/*
414 * Used in two places:
415 * 1) Early boot to setup init_fpstate for non XSAVE systems
416 * 2) fpu_init_fpstate_user() which is invoked from KVM
417 */
418void fpstate_init_user(struct fpstate *fpstate)
233{419{
234 if (!static_cpu_has(X86_FEATURE_FPU)) {420 if (!cpu_feature_enabled(X86_FEATURE_FPU)) {
235 fpstate_init_soft(&state->soft);421 fpstate_init_soft(&fpstate->regs.soft);
236 return;422 return;
237 }423 }
238 424
239 memset(state, 0, fpu_kernel_xstate_size);425 xstate_init_xcomp_bv(&fpstate->regs.xsave, fpstate->xfeatures);
240 426
241 if (static_cpu_has(X86_FEATURE_XSAVES))427 if (cpu_feature_enabled(X86_FEATURE_FXSR))
242 fpstate_init_xstate(&state->xsave);428 fpstate_init_fxstate(fpstate);
243 if (static_cpu_has(X86_FEATURE_FXSR))
244 fpstate_init_fxstate(&state->fxsave);
245 else429 else
246 fpstate_init_fstate(&state->fsave);430 fpstate_init_fstate(fpstate);
431}
432
433static void __fpstate_reset(struct fpstate *fpstate)
434{
435 /* Initialize sizes and feature masks */
436 fpstate->size = fpu_kernel_cfg.default_size;
437 fpstate->user_size = fpu_user_cfg.default_size;
438 fpstate->xfeatures = fpu_kernel_cfg.default_features;
439 fpstate->user_xfeatures = fpu_user_cfg.default_features;
440 fpstate->xfd = init_fpstate.xfd;
441}
442
443void fpstate_reset(struct fpu *fpu)
444{
445 /* Set the fpstate pointer to the default fpstate */
446 fpu->fpstate = &fpu->__fpstate;
447 __fpstate_reset(fpu->fpstate);
448
449 /* Initialize the permission related info in fpu */
450 fpu->perm.__state_perm = fpu_kernel_cfg.default_features;
451 fpu->perm.__state_size = fpu_kernel_cfg.default_size;
452 fpu->perm.__user_state_size = fpu_user_cfg.default_size;
453}
454
455static inline void fpu_inherit_perms(struct fpu *dst_fpu)
456{
457 if (fpu_state_size_dynamic()) {
458 struct fpu *src_fpu = &current->group_leader->thread.fpu;
459
460 spin_lock_irq(&current->sighand->siglock);
461 /* Fork also inherits the permissions of the parent */
462 dst_fpu->perm = src_fpu->perm;
463 spin_unlock_irq(&current->sighand->siglock);
464 }
247}465}
248EXPORT_SYMBOL_GPL(fpstate_init);
249 466
250/* Clone current's FPU state on fork */467/* Clone current's FPU state on fork */
251int fpu_clone(struct task_struct *dst)468int fpu_clone(struct task_struct *dst, unsigned long clone_flags)
252{469{
253 struct fpu *src_fpu = &current->thread.fpu;470 struct fpu *src_fpu = &current->thread.fpu;
254 struct fpu *dst_fpu = &dst->thread.fpu;471 struct fpu *dst_fpu = &dst->thread.fpu;
@@ -256,36 +473,67 @@ int fpu_clone(struct task_struct *dst) · 1 unmodified line
256 /* The new task's FPU state cannot be valid in the hardware. */473 /* The new task's FPU state cannot be valid in the hardware. */
257 dst_fpu->last_cpu = -1;474 dst_fpu->last_cpu = -1;
258 475
476 fpstate_reset(dst_fpu);
477
259 if (!cpu_feature_enabled(X86_FEATURE_FPU))478 if (!cpu_feature_enabled(X86_FEATURE_FPU))
260 return 0;479 return 0;
261 480
262 /*481 /*
263 * Don't let 'init optimized' areas of the XSAVE area482 * Enforce reload for user space tasks and prevent kernel threads
264 * leak into the child task:483 * from trying to save the FPU registers on context switch.
484 */
485 set_tsk_thread_flag(dst, TIF_NEED_FPU_LOAD);
486
487 /*
488 * No FPU state inheritance for kernel threads and IO
489 * worker threads.
490 */
491 if (dst->flags & (PF_KTHREAD | PF_IO_WORKER)) {
492 /* Clear out the minimal state */
493 memcpy(&dst_fpu->fpstate->regs, &init_fpstate.regs,
494 init_fpstate_copy_size());
495 return 0;
496 }
497
498 /*
499 * If a new feature is added, ensure all dynamic features are
500 * caller-saved from here!
265 */501 */
266 memset(&dst_fpu->state.xsave, 0, fpu_kernel_xstate_size);502 BUILD_BUG_ON(XFEATURE_MASK_USER_DYNAMIC != XFEATURE_MASK_XTILE_DATA);
267 503
268 /*504 /*
269 * If the FPU registers are not owned by current just memcpy() the505 * Save the default portion of the current FPU state into the
270 * state. Otherwise save the FPU registers directly into the506 * clone. Assume all dynamic features to be defined as caller-
271 * child's FPU context, without any memory-to-memory copying.507 * saved, which enables skipping both the expansion of fpstate
508 * and the copying of any dynamic state.
509 *
510 * Do not use memcpy() when TIF_NEED_FPU_LOAD is set because
511 * copying is not valid when current uses non-default states.
272 */512 */
273 fpregs_lock();513 fpregs_lock();
274 if (test_thread_flag(TIF_NEED_FPU_LOAD))514 if (test_thread_flag(TIF_NEED_FPU_LOAD))
275 memcpy(&dst_fpu->state, &src_fpu->state, fpu_kernel_xstate_size);515 fpregs_restore_userregs();
276 516 save_fpregs_to_fpstate(dst_fpu);
277 else517 if (!(clone_flags & CLONE_THREAD))
278 save_fpregs_to_fpstate(dst_fpu);518 fpu_inherit_perms(dst_fpu);
279 fpregs_unlock();519 fpregs_unlock();
280 520
281 set_tsk_thread_flag(dst, TIF_NEED_FPU_LOAD);
282
283 trace_x86_fpu_copy_src(src_fpu);521 trace_x86_fpu_copy_src(src_fpu);
284 trace_x86_fpu_copy_dst(dst_fpu);522 trace_x86_fpu_copy_dst(dst_fpu);
285 523
286 return 0;524 return 0;
287}525}
288 526
527/*
528 * Whitelist the FPU register state embedded into task_struct for hardened
529 * usercopy.
530 */
531void fpu_thread_struct_whitelist(unsigned long *offset, unsigned long *size)
532{
533 *offset = offsetof(struct thread_struct, fpu.__fpstate.regs);
534 *size = fpu_kernel_cfg.default_size;
535}
536
289/*537/*
290 * Drops current FPU state: deactivates the fpregs and538 * Drops current FPU state: deactivates the fpregs and
291 * the fpstate. NOTE: it still leaves previous contents539 * the fpstate. NOTE: it still leaves previous contents
@@ -319,28 +567,19 @@ void fpu__drop(struct fpu *fpu) · 27 unmodified lines
319static inline void restore_fpregs_from_init_fpstate(u64 features_mask)567static inline void restore_fpregs_from_init_fpstate(u64 features_mask)
320{568{
321 if (use_xsave())569 if (use_xsave())
322 os_xrstor(&init_fpstate.xsave, features_mask);570 os_xrstor(&init_fpstate, features_mask);
323 else if (use_fxsr())571 else if (use_fxsr())
324 fxrstor(&init_fpstate.fxsave);572 fxrstor(&init_fpstate.regs.fxsave);
325 else573 else
326 frstor(&init_fpstate.fsave);574 frstor(&init_fpstate.regs.fsave);
327 575
328 pkru_write_default();576 pkru_write_default();
329}577}
330 578
331static inline unsigned int init_fpstate_copy_size(void)
332{
333 if (!use_xsave())
334 return fpu_kernel_xstate_size;
335
336 /* XSAVE(S) just needs the legacy and the xstate header part */
337 return sizeof(init_fpstate.xsave);
338}
339
340/*579/*
341 * Reset current->fpu memory state to the init values.580 * Reset current->fpu memory state to the init values.
342 */581 */
343static void fpu_reset_fpstate(void)582static void fpu_reset_fpregs(void)
344{583{
345 struct fpu *fpu = &current->thread.fpu;584 struct fpu *fpu = &current->thread.fpu;
346 585
@@ -359,7 +598,7 @@ static void fpu_reset_fpstate(void) · 12 unmodified lines
359 * user space as PKRU is eagerly written in switch_to() and598 * user space as PKRU is eagerly written in switch_to() and
360 * flush_thread().599 * flush_thread().
361 */600 */
362 memcpy(&fpu->state, &init_fpstate, init_fpstate_copy_size());601 memcpy(&fpu->fpstate->regs, &init_fpstate.regs, init_fpstate_copy_size());
363 set_thread_flag(TIF_NEED_FPU_LOAD);602 set_thread_flag(TIF_NEED_FPU_LOAD);
364 fpregs_unlock();603 fpregs_unlock();
365}604}
@@ -375,7 +614,7 @@ void fpu__clear_user_states(struct fpu *fpu) · 9 unmodified lines
375 614
376 fpregs_lock();615 fpregs_lock();
377 if (!cpu_feature_enabled(X86_FEATURE_FPU)) {616 if (!cpu_feature_enabled(X86_FEATURE_FPU)) {
378 fpu_reset_fpstate();617 fpu_reset_fpregs();
379 fpregs_unlock();618 fpregs_unlock();
380 return;619 return;
381 }620 }
@@ -385,12 +624,11 @@ void fpu__clear_user_states(struct fpu *fpu) · 3 unmodified lines
385 * corresponding registers.624 * corresponding registers.
386 */625 */
387 if (xfeatures_mask_supervisor() &&626 if (xfeatures_mask_supervisor() &&
388 !fpregs_state_valid(fpu, smp_processor_id())) {627 !fpregs_state_valid(fpu, smp_processor_id()))
389 os_xrstor(&fpu->state.xsave, xfeatures_mask_supervisor());628 os_xrstor_supervisor(fpu->fpstate);
390 }
391 629
392 /* Reset user states in registers. */630 /* Reset user states in registers. */
393 restore_fpregs_from_init_fpstate(xfeatures_mask_restore_user());631 restore_fpregs_from_init_fpstate(XFEATURE_MASK_USER_RESTORE);
394 632
395 /*633 /*
396 * Now all FPU registers have their desired values. Inform the FPU634 * Now all FPU registers have their desired values. Inform the FPU
@@ -405,7 +643,8 @@ void fpu__clear_user_states(struct fpu *fpu) · 8 unmodified lines
405 643
406void fpu_flush_thread(void)644void fpu_flush_thread(void)
407{645{
408 fpu_reset_fpstate();646 fpstate_reset(&current->thread.fpu);
647 fpu_reset_fpregs();
409}648}
410/*649/*
411 * Load FPU context before returning to userspace.650 * Load FPU context before returning to userspace.
@@ -445,7 +684,6 @@ void fpregs_mark_activate(void) · 33 unmodified lines
445 fpu->last_cpu = smp_processor_id();684 fpu->last_cpu = smp_processor_id();
446 clear_thread_flag(TIF_NEED_FPU_LOAD);685 clear_thread_flag(TIF_NEED_FPU_LOAD);
447}686}
448EXPORT_SYMBOL_GPL(fpregs_mark_activate);
449 687
450/*688/*
451 * x87 math exception handling:689 * x87 math exception handling:
@@ -468,11 +706,11 @@ int fpu__exception_code(struct fpu *fpu, int trap_nr) · 16 unmodified lines
468 * fully reproduce the context of the exception.706 * fully reproduce the context of the exception.
469 */707 */
470 if (boot_cpu_has(X86_FEATURE_FXSR)) {708 if (boot_cpu_has(X86_FEATURE_FXSR)) {
471 cwd = fpu->state.fxsave.cwd;709 cwd = fpu->fpstate->regs.fxsave.cwd;
472 swd = fpu->state.fxsave.swd;710 swd = fpu->fpstate->regs.fxsave.swd;
473 } else {711 } else {
474 cwd = (unsigned short)fpu->state.fsave.cwd;712 cwd = (unsigned short)fpu->fpstate->regs.fsave.cwd;
475 swd = (unsigned short)fpu->state.fsave.swd;713 swd = (unsigned short)fpu->fpstate->regs.fsave.swd;
476 }714 }
477 715
478 err = swd & ~cwd;716 err = swd & ~cwd;
@@ -486,7 +724,7 @@ int fpu__exception_code(struct fpu *fpu, int trap_nr) · 7 unmodified lines
486 unsigned short mxcsr = MXCSR_DEFAULT;724 unsigned short mxcsr = MXCSR_DEFAULT;
487 725
488 if (boot_cpu_has(X86_FEATURE_XMM))726 if (boot_cpu_has(X86_FEATURE_XMM))
489 mxcsr = fpu->state.fxsave.mxcsr;727 mxcsr = fpu->fpstate->regs.fxsave.mxcsr;
490 728
491 err = ~(mxcsr >> 7) & mxcsr;729 err = ~(mxcsr >> 7) & mxcsr;
492 }730 }
arch/x86/kernel/fpu/init.c+34−42
@@ -2,7 +2,7 @@ · 1 unmodified line
2/*2/*
3 * x86 FPU boot time init code:3 * x86 FPU boot time init code:
4 */4 */
5#include <asm/fpu/internal.h>5#include <asm/fpu/api.h>
6#include <asm/tlbflush.h>6#include <asm/tlbflush.h>
7#include <asm/setup.h>7#include <asm/setup.h>
8 8
@@ -10,6 +10,10 @@ · 1 unmodified line
10#include <linux/sched/task.h>10#include <linux/sched/task.h>
11#include <linux/init.h>11#include <linux/init.h>
12 12
13#include "internal.h"
14#include "legacy.h"
15#include "xstate.h"
16
13/*17/*
14 * Initialize the registers found in all CPUs, CR0 and CR4:18 * Initialize the registers found in all CPUs, CR0 and CR4:
15 */19 */
@@ -34,7 +38,7 @@ static void fpu__init_cpu_generic(void) · 18 unmodified lines
34 /* Flush out any pending x87 state: */38 /* Flush out any pending x87 state: */
35#ifdef CONFIG_MATH_EMULATION39#ifdef CONFIG_MATH_EMULATION
36 if (!boot_cpu_has(X86_FEATURE_FPU))40 if (!boot_cpu_has(X86_FEATURE_FPU))
37 fpstate_init_soft(&current->thread.fpu.state.soft);41 fpstate_init_soft(&current->thread.fpu.fpstate->regs.soft);
38 else42 else
39#endif43#endif
40 asm volatile ("fninit");44 asm volatile ("fninit");
@@ -121,23 +125,14 @@ static void __init fpu__init_system_mxcsr(void) · 80 unmodified lines
121static void __init fpu__init_system_generic(void)125static void __init fpu__init_system_generic(void)
122{126{
123 /*127 /*
124 * Set up the legacy init FPU context. (xstate init might overwrite this128 * Set up the legacy init FPU context. Will be updated when the
125 * with a more modern format, if the CPU supports it.)129 * CPU supports XSAVE[S].
126 */130 */
127 fpstate_init(&init_fpstate);131 fpstate_init_user(&init_fpstate);
128 132
129 fpu__init_system_mxcsr();133 fpu__init_system_mxcsr();
130}134}
131 135
132/*
133 * Size of the FPU context state. All tasks in the system use the
134 * same context size, regardless of what portion they use.
135 * This is inherent to the XSAVE architecture which puts all state
136 * components into a single, continuous memory block:
137 */
138unsigned int fpu_kernel_xstate_size __ro_after_init;
139EXPORT_SYMBOL_GPL(fpu_kernel_xstate_size);
140
141/* Get alignment of the TYPE. */136/* Get alignment of the TYPE. */
142#define TYPE_ALIGN(TYPE) offsetof(struct { char x; TYPE test; }, test)137#define TYPE_ALIGN(TYPE) offsetof(struct { char x; TYPE test; }, test)
143 138
@@ -162,13 +157,13 @@ static void __init fpu__init_task_struct_size(void) · 18 unmodified lines
162 * Subtract off the static size of the register state.157 * Subtract off the static size of the register state.
163 * It potentially has a bunch of padding.158 * It potentially has a bunch of padding.
164 */159 */
165 task_size -= sizeof(((struct task_struct *)0)->thread.fpu.state);160 task_size -= sizeof(current->thread.fpu.__fpstate.regs);
166 161
167 /*162 /*
168 * Add back the dynamically-calculated register state163 * Add back the dynamically-calculated register state
169 * size.164 * size.
170 */165 */
171 task_size += fpu_kernel_xstate_size;166 task_size += fpu_kernel_cfg.default_size;
172 167
173 /*168 /*
174 * We dynamically size 'struct fpu', so we require that169 * We dynamically size 'struct fpu', so we require that
@@ -177,7 +172,7 @@ static void __init fpu__init_task_struct_size(void) · 2 unmodified lines
177 * you hit a compile error here, check the structure to172 * you hit a compile error here, check the structure to
178 * see if something got added to the end.173 * see if something got added to the end.
179 */174 */
180 CHECK_MEMBER_AT_END_OF(struct fpu, state);175 CHECK_MEMBER_AT_END_OF(struct fpu, __fpstate);
181 CHECK_MEMBER_AT_END_OF(struct thread_struct, fpu);176 CHECK_MEMBER_AT_END_OF(struct thread_struct, fpu);
182 CHECK_MEMBER_AT_END_OF(struct task_struct, thread);177 CHECK_MEMBER_AT_END_OF(struct task_struct, thread);
183 178
@@ -192,37 +187,34 @@ static void __init fpu__init_task_struct_size(void) · 8 unmodified lines
192 */187 */
193static void __init fpu__init_system_xstate_size_legacy(void)188static void __init fpu__init_system_xstate_size_legacy(void)
194{189{
195 static int on_boot_cpu __initdata = 1;190 unsigned int size;
196
197 WARN_ON_FPU(!on_boot_cpu);
198 on_boot_cpu = 0;
199 191
200 /*192 /*
201 * Note that xstate sizes might be overwritten later during193 * Note that the size configuration might be overwritten later
202 * fpu__init_system_xstate().194 * during fpu__init_system_xstate().
203 */195 */
204 196 if (!cpu_feature_enabled(X86_FEATURE_FPU)) {
205 if (!boot_cpu_has(X86_FEATURE_FPU)) {197 size = sizeof(struct swregs_state);
206 fpu_kernel_xstate_size = sizeof(struct swregs_state);198 } else if (cpu_feature_enabled(X86_FEATURE_FXSR)) {
199 size = sizeof(struct fxregs_state);
200 fpu_user_cfg.legacy_features = XFEATURE_MASK_FPSSE;
207 } else {201 } else {
208 if (boot_cpu_has(X86_FEATURE_FXSR))202 size = sizeof(struct fregs_state);
209 fpu_kernel_xstate_size =203 fpu_user_cfg.legacy_features = XFEATURE_MASK_FP;
210 sizeof(struct fxregs_state);
211 else
212 fpu_kernel_xstate_size =
213 sizeof(struct fregs_state);
214 }204 }
215 205
216 fpu_user_xstate_size = fpu_kernel_xstate_size;206 fpu_kernel_cfg.max_size = size;
207 fpu_kernel_cfg.default_size = size;
208 fpu_user_cfg.max_size = size;
209 fpu_user_cfg.default_size = size;
210 fpstate_reset(&current->thread.fpu);
217}211}
218 212
219/* Legacy code to initialize eager fpu mode. */213static void __init fpu__init_init_fpstate(void)
220static void __init fpu__init_system_ctx_switch(void)
221{214{
222 static bool on_boot_cpu __initdata = 1;215 /* Bring init_fpstate size and features up to date */
223 216 init_fpstate.size = fpu_kernel_cfg.max_size;
224 WARN_ON_FPU(!on_boot_cpu);217 init_fpstate.xfeatures = fpu_kernel_cfg.max_features;
225 on_boot_cpu = 0;
226}218}
227 219
228/*220/*
@@ -231,6 +223,7 @@ static void __init fpu__init_system_ctx_switch(void) · 2 unmodified lines
231 */223 */
232void __init fpu__init_system(struct cpuinfo_x86 *c)224void __init fpu__init_system(struct cpuinfo_x86 *c)
233{225{
226 fpstate_reset(&current->thread.fpu);
234 fpu__init_system_early_generic(c);227 fpu__init_system_early_generic(c);
235 228
236 /*229 /*
@@ -241,8 +234,7 @@ void __init fpu__init_system(struct cpuinfo_x86 *c) · 4 unmodified lines
241 234
242 fpu__init_system_generic();235 fpu__init_system_generic();
243 fpu__init_system_xstate_size_legacy();236 fpu__init_system_xstate_size_legacy();
244 fpu__init_system_xstate();237 fpu__init_system_xstate(fpu_kernel_cfg.max_size);
245 fpu__init_task_struct_size();238 fpu__init_task_struct_size();
246 239 fpu__init_init_fpstate();
247 fpu__init_system_ctx_switch();
248}240}
arch/x86/kernel/fpu/internal.h+28−0
@@ -0,0 +1,28 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __X86_KERNEL_FPU_INTERNAL_H
3#define __X86_KERNEL_FPU_INTERNAL_H
4
5extern struct fpstate init_fpstate;
6
7/* CPU feature check wrappers */
8static __always_inline __pure bool use_xsave(void)
9{
10 return cpu_feature_enabled(X86_FEATURE_XSAVE);
11}
12
13static __always_inline __pure bool use_fxsr(void)
14{
15 return cpu_feature_enabled(X86_FEATURE_FXSR);
16}
17
18#ifdef CONFIG_X86_DEBUG_FPU
19# define WARN_ON_FPU(x) WARN_ON_ONCE(x)
20#else
21# define WARN_ON_FPU(x) ({ (void)(x); 0; })
22#endif
23
24/* Used in init.c */
25extern void fpstate_init_user(struct fpstate *fpstate);
26extern void fpstate_reset(struct fpu *fpu);
27
28#endif
arch/x86/kernel/fpu/legacy.h+115−0
@@ -0,0 +1,115 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __X86_KERNEL_FPU_LEGACY_H
3#define __X86_KERNEL_FPU_LEGACY_H
4
5#include <asm/fpu/types.h>
6
7extern unsigned int mxcsr_feature_mask;
8
9static inline void ldmxcsr(u32 mxcsr)
10{
11 asm volatile("ldmxcsr %0" :: "m" (mxcsr));
12}
13
14/*
15 * Returns 0 on success or the trap number when the operation raises an
16 * exception.
17 */
18#define user_insn(insn, output, input...) \
19({ \
20 int err; \
21 \
22 might_fault(); \
23 \
24 asm volatile(ASM_STAC "\n" \
25 "1: " #insn "\n" \
26 "2: " ASM_CLAC "\n" \
27 _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FAULT_MCE_SAFE) \
28 : [err] "=a" (err), output \
29 : "0"(0), input); \
30 err; \
31})
32
33#define kernel_insn_err(insn, output, input...) \
34({ \
35 int err; \
36 asm volatile("1:" #insn "\n\t" \
37 "2:\n" \
38 ".section .fixup,\"ax\"\n" \
39 "3: movl $-1,%[err]\n" \
40 " jmp 2b\n" \
41 ".previous\n" \
42 _ASM_EXTABLE(1b, 3b) \
43 : [err] "=r" (err), output \
44 : "0"(0), input); \
45 err; \
46})
47
48#define kernel_insn(insn, output, input...) \
49 asm volatile("1:" #insn "\n\t" \
50 "2:\n" \
51 _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FPU_RESTORE) \
52 : output : input)
53
54static inline int fnsave_to_user_sigframe(struct fregs_state __user *fx)
55{
56 return user_insn(fnsave %[fx]; fwait, [fx] "=m" (*fx), "m" (*fx));
57}
58
59static inline int fxsave_to_user_sigframe(struct fxregs_state __user *fx)
60{
61 if (IS_ENABLED(CONFIG_X86_32))
62 return user_insn(fxsave %[fx], [fx] "=m" (*fx), "m" (*fx));
63 else
64 return user_insn(fxsaveq %[fx], [fx] "=m" (*fx), "m" (*fx));
65
66}
67
68static inline void fxrstor(struct fxregs_state *fx)
69{
70 if (IS_ENABLED(CONFIG_X86_32))
71 kernel_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
72 else
73 kernel_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
74}
75
76static inline int fxrstor_safe(struct fxregs_state *fx)
77{
78 if (IS_ENABLED(CONFIG_X86_32))
79 return kernel_insn_err(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
80 else
81 return kernel_insn_err(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
82}
83
84static inline int fxrstor_from_user_sigframe(struct fxregs_state __user *fx)
85{
86 if (IS_ENABLED(CONFIG_X86_32))
87 return user_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
88 else
89 return user_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
90}
91
92static inline void frstor(struct fregs_state *fx)
93{
94 kernel_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
95}
96
97static inline int frstor_safe(struct fregs_state *fx)
98{
99 return kernel_insn_err(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
100}
101
102static inline int frstor_from_user_sigframe(struct fregs_state __user *fx)
103{
104 return user_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
105}
106
107static inline void fxsave(struct fxregs_state *fx)
108{
109 if (IS_ENABLED(CONFIG_X86_32))
110 asm volatile( "fxsave %[fx]" : [fx] "=m" (*fx));
111 else
112 asm volatile("fxsaveq %[fx]" : [fx] "=m" (*fx));
113}
114
115#endif
arch/x86/kernel/fpu/regset.c+20−16
@@ -5,10 +5,14 @@ · 4 unmodified lines
5#include <linux/sched/task_stack.h>5#include <linux/sched/task_stack.h>
6#include <linux/vmalloc.h>6#include <linux/vmalloc.h>
7 7
8#include <asm/fpu/internal.h>8#include <asm/fpu/api.h>
9#include <asm/fpu/signal.h>9#include <asm/fpu/signal.h>
10#include <asm/fpu/regset.h>10#include <asm/fpu/regset.h>
11#include <asm/fpu/xstate.h>11
12#include "context.h"
13#include "internal.h"
14#include "legacy.h"
15#include "xstate.h"
12 16
13/*17/*
14 * The xstateregs_active() routine is the same as the regset_fpregs_active() routine,18 * The xstateregs_active() routine is the same as the regset_fpregs_active() routine,
@@ -74,8 +78,8 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset, · 59 unmodified lines
74 sync_fpstate(fpu);78 sync_fpstate(fpu);
75 79
76 if (!use_xsave()) {80 if (!use_xsave()) {
77 return membuf_write(&to, &fpu->state.fxsave,81 return membuf_write(&to, &fpu->fpstate->regs.fxsave,
78 sizeof(fpu->state.fxsave));82 sizeof(fpu->fpstate->regs.fxsave));
79 }83 }
80 84
81 copy_xstate_to_uabi_buf(to, target, XSTATE_COPY_FX);85 copy_xstate_to_uabi_buf(to, target, XSTATE_COPY_FX);
@@ -110,15 +114,15 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset, · 28 unmodified lines
110 fpu_force_restore(fpu);114 fpu_force_restore(fpu);
111 115
112 /* Copy the state */116 /* Copy the state */
113 memcpy(&fpu->state.fxsave, &newstate, sizeof(newstate));117 memcpy(&fpu->fpstate->regs.fxsave, &newstate, sizeof(newstate));
114 118
115 /* Clear xmm8..15 */119 /* Clear xmm8..15 */
116 BUILD_BUG_ON(sizeof(fpu->state.fxsave.xmm_space) != 16 * 16);120 BUILD_BUG_ON(sizeof(fpu->__fpstate.regs.fxsave.xmm_space) != 16 * 16);
117 memset(&fpu->state.fxsave.xmm_space[8], 0, 8 * 16);121 memset(&fpu->fpstate->regs.fxsave.xmm_space[8], 0, 8 * 16);
118 122
119 /* Mark FP and SSE as in use when XSAVE is enabled */123 /* Mark FP and SSE as in use when XSAVE is enabled */
120 if (use_xsave())124 if (use_xsave())
121 fpu->state.xsave.header.xfeatures |= XFEATURE_MASK_FPSSE;125 fpu->fpstate->regs.xsave.header.xfeatures |= XFEATURE_MASK_FPSSE;
122 126
123 return 0;127 return 0;
124}128}
@@ -149,7 +153,7 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset, · 24 unmodified lines
149 /*153 /*
150 * A whole standard-format XSAVE buffer is needed:154 * A whole standard-format XSAVE buffer is needed:
151 */155 */
152 if (pos != 0 || count != fpu_user_xstate_size)156 if (pos != 0 || count != fpu_user_cfg.max_size)
153 return -EFAULT;157 return -EFAULT;
154 158
155 if (!kbuf) {159 if (!kbuf) {
@@ -164,7 +168,7 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset, · 8 unmodified lines
164 }168 }
165 169
166 fpu_force_restore(fpu);170 fpu_force_restore(fpu);
167 ret = copy_uabi_from_kernel_to_xstate(&fpu->state.xsave, kbuf ?: tmpbuf);171 ret = copy_uabi_from_kernel_to_xstate(fpu->fpstate, kbuf ?: tmpbuf);
168 172
169out:173out:
170 vfree(tmpbuf);174 vfree(tmpbuf);
@@ -283,7 +287,7 @@ static void __convert_from_fxsr(struct user_i387_ia32_struct *env, · 112 unmodified lines
283void287void
284convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk)288convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk)
285{289{
286 __convert_from_fxsr(env, tsk, &tsk->thread.fpu.state.fxsave);290 __convert_from_fxsr(env, tsk, &tsk->thread.fpu.fpstate->regs.fxsave);
287}291}
288 292
289void convert_to_fxsr(struct fxregs_state *fxsave,293void convert_to_fxsr(struct fxregs_state *fxsave,
@@ -326,7 +330,7 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset, · 36 unmodified lines
326 return fpregs_soft_get(target, regset, to);330 return fpregs_soft_get(target, regset, to);
327 331
328 if (!cpu_feature_enabled(X86_FEATURE_FXSR)) {332 if (!cpu_feature_enabled(X86_FEATURE_FXSR)) {
329 return membuf_write(&to, &fpu->state.fsave,333 return membuf_write(&to, &fpu->fpstate->regs.fsave,
330 sizeof(struct fregs_state));334 sizeof(struct fregs_state));
331 }335 }
332 336
@@ -337,7 +341,7 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset, · 4 unmodified lines
337 copy_xstate_to_uabi_buf(mb, target, XSTATE_COPY_FP);341 copy_xstate_to_uabi_buf(mb, target, XSTATE_COPY_FP);
338 fx = &fxsave;342 fx = &fxsave;
339 } else {343 } else {
340 fx = &fpu->state.fxsave;344 fx = &fpu->fpstate->regs.fxsave;
341 }345 }
342 346
343 __convert_from_fxsr(&env, target, fx);347 __convert_from_fxsr(&env, target, fx);
@@ -366,16 +370,16 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset, · 22 unmodified lines
366 fpu_force_restore(fpu);370 fpu_force_restore(fpu);
367 371
368 if (cpu_feature_enabled(X86_FEATURE_FXSR))372 if (cpu_feature_enabled(X86_FEATURE_FXSR))
369 convert_to_fxsr(&fpu->state.fxsave, &env);373 convert_to_fxsr(&fpu->fpstate->regs.fxsave, &env);
370 else374 else
371 memcpy(&fpu->state.fsave, &env, sizeof(env));375 memcpy(&fpu->fpstate->regs.fsave, &env, sizeof(env));
372 376
373 /*377 /*
374 * Update the header bit in the xsave header, indicating the378 * Update the header bit in the xsave header, indicating the
375 * presence of FP.379 * presence of FP.
376 */380 */
377 if (cpu_feature_enabled(X86_FEATURE_XSAVE))381 if (cpu_feature_enabled(X86_FEATURE_XSAVE))
378 fpu->state.xsave.header.xfeatures |= XFEATURE_MASK_FP;382 fpu->fpstate->regs.xsave.header.xfeatures |= XFEATURE_MASK_FP;
379 383
380 return 0;384 return 0;
381}385}
arch/x86/kernel/fpu/signal.c+145−140
@@ -7,23 +7,25 @@ · 6 unmodified lines
7#include <linux/cpu.h>7#include <linux/cpu.h>
8#include <linux/pagemap.h>8#include <linux/pagemap.h>
9 9
10#include <asm/fpu/internal.h>
11#include <asm/fpu/signal.h>10#include <asm/fpu/signal.h>
12#include <asm/fpu/regset.h>11#include <asm/fpu/regset.h>
13#include <asm/fpu/xstate.h>12#include <asm/fpu/xstate.h>
14 13
15#include <asm/sigframe.h>14#include <asm/sigframe.h>
15#include <asm/trapnr.h>
16#include <asm/trace/fpu.h>16#include <asm/trace/fpu.h>
17 17
18static struct _fpx_sw_bytes fx_sw_reserved __ro_after_init;18#include "context.h"
19static struct _fpx_sw_bytes fx_sw_reserved_ia32 __ro_after_init;19#include "internal.h"
20#include "legacy.h"
21#include "xstate.h"
20 22
21/*23/*
22 * Check for the presence of extended state information in the24 * Check for the presence of extended state information in the
23 * user fpstate pointer in the sigcontext.25 * user fpstate pointer in the sigcontext.
24 */26 */
25static inline int check_xstate_in_sigframe(struct fxregs_state __user *fxbuf,27static inline bool check_xstate_in_sigframe(struct fxregs_state __user *fxbuf,
26 struct _fpx_sw_bytes *fx_sw)28 struct _fpx_sw_bytes *fx_sw)
27{29{
28 int min_xstate_size = sizeof(struct fxregs_state) +30 int min_xstate_size = sizeof(struct fxregs_state) +
29 sizeof(struct xstate_header);31 sizeof(struct xstate_header);
@@ -31,12 +33,12 @@ static inline int check_xstate_in_sigframe(struct fxregs_state __user *fxbuf, · 1 unmodified line
31 unsigned int magic2;33 unsigned int magic2;
32 34
33 if (__copy_from_user(fx_sw, &fxbuf->sw_reserved[0], sizeof(*fx_sw)))35 if (__copy_from_user(fx_sw, &fxbuf->sw_reserved[0], sizeof(*fx_sw)))
34 return -EFAULT;36 return false;
35 37
36 /* Check for the first magic field and other error scenarios. */38 /* Check for the first magic field and other error scenarios. */
37 if (fx_sw->magic1 != FP_XSTATE_MAGIC1 ||39 if (fx_sw->magic1 != FP_XSTATE_MAGIC1 ||
38 fx_sw->xstate_size < min_xstate_size ||40 fx_sw->xstate_size < min_xstate_size ||
39 fx_sw->xstate_size > fpu_user_xstate_size ||41 fx_sw->xstate_size > current->thread.fpu.fpstate->user_size ||
40 fx_sw->xstate_size > fx_sw->extended_size)42 fx_sw->xstate_size > fx_sw->extended_size)
41 goto setfx;43 goto setfx;
42 44
@@ -47,10 +49,10 @@ static inline int check_xstate_in_sigframe(struct fxregs_state __user *fxbuf, · 4 unmodified lines
47 * in the memory layout.49 * in the memory layout.
48 */50 */
49 if (__get_user(magic2, (__u32 __user *)(fpstate + fx_sw->xstate_size)))51 if (__get_user(magic2, (__u32 __user *)(fpstate + fx_sw->xstate_size)))
50 return -EFAULT;52 return false;
51 53
52 if (likely(magic2 == FP_XSTATE_MAGIC2))54 if (likely(magic2 == FP_XSTATE_MAGIC2))
53 return 0;55 return true;
54setfx:56setfx:
55 trace_x86_fpu_xstate_check_failed(&current->thread.fpu);57 trace_x86_fpu_xstate_check_failed(&current->thread.fpu);
56 58
@@ -58,22 +60,22 @@ setfx: · 1 unmodified line
58 fx_sw->magic1 = 0;60 fx_sw->magic1 = 0;
59 fx_sw->xstate_size = sizeof(struct fxregs_state);61 fx_sw->xstate_size = sizeof(struct fxregs_state);
60 fx_sw->xfeatures = XFEATURE_MASK_FPSSE;62 fx_sw->xfeatures = XFEATURE_MASK_FPSSE;
61 return 0;63 return true;
62}64}
63 65
64/*66/*
65 * Signal frame handlers.67 * Signal frame handlers.
66 */68 */
67static inline int save_fsave_header(struct task_struct *tsk, void __user *buf)69static inline bool save_fsave_header(struct task_struct *tsk, void __user *buf)
68{70{
69 if (use_fxsr()) {71 if (use_fxsr()) {
70 struct xregs_state *xsave = &tsk->thread.fpu.state.xsave;72 struct xregs_state *xsave = &tsk->thread.fpu.fpstate->regs.xsave;
71 struct user_i387_ia32_struct env;73 struct user_i387_ia32_struct env;
72 struct _fpstate_32 __user *fp = buf;74 struct _fpstate_32 __user *fp = buf;
73 75
74 fpregs_lock();76 fpregs_lock();
75 if (!test_thread_flag(TIF_NEED_FPU_LOAD))77 if (!test_thread_flag(TIF_NEED_FPU_LOAD))
76 fxsave(&tsk->thread.fpu.state.fxsave);78 fxsave(&tsk->thread.fpu.fpstate->regs.fxsave);
77 fpregs_unlock();79 fpregs_unlock();
78 80
79 convert_from_fxsr(&env, tsk);81 convert_from_fxsr(&env, tsk);
@@ -81,33 +83,54 @@ static inline int save_fsave_header(struct task_struct *tsk, void __user *buf) · 1 unmodified line
81 if (__copy_to_user(buf, &env, sizeof(env)) ||83 if (__copy_to_user(buf, &env, sizeof(env)) ||
82 __put_user(xsave->i387.swd, &fp->status) ||84 __put_user(xsave->i387.swd, &fp->status) ||
83 __put_user(X86_FXSR_MAGIC, &fp->magic))85 __put_user(X86_FXSR_MAGIC, &fp->magic))
84 return -1;86 return false;
85 } else {87 } else {
86 struct fregs_state __user *fp = buf;88 struct fregs_state __user *fp = buf;
87 u32 swd;89 u32 swd;
90
88 if (__get_user(swd, &fp->swd) || __put_user(swd, &fp->status))91 if (__get_user(swd, &fp->swd) || __put_user(swd, &fp->status))
89 return -1;92 return false;
90 }93 }
91 94
92 return 0;95 return true;
96}
97
98/*
99 * Prepare the SW reserved portion of the fxsave memory layout, indicating
100 * the presence of the extended state information in the memory layout
101 * pointed to by the fpstate pointer in the sigcontext.
102 * This is saved when ever the FP and extended state context is
103 * saved on the user stack during the signal handler delivery to the user.
104 */
105static inline void save_sw_bytes(struct _fpx_sw_bytes *sw_bytes, bool ia32_frame,
106 struct fpstate *fpstate)
107{
108 sw_bytes->magic1 = FP_XSTATE_MAGIC1;
109 sw_bytes->extended_size = fpstate->user_size + FP_XSTATE_MAGIC2_SIZE;
110 sw_bytes->xfeatures = fpstate->user_xfeatures;
111 sw_bytes->xstate_size = fpstate->user_size;
112
113 if (ia32_frame)
114 sw_bytes->extended_size += sizeof(struct fregs_state);
93}115}
94 116
95static inline int save_xstate_epilog(void __user *buf, int ia32_frame)117static inline bool save_xstate_epilog(void __user *buf, int ia32_frame,
118 struct fpstate *fpstate)
96{119{
97 struct xregs_state __user *x = buf;120 struct xregs_state __user *x = buf;
98 struct _fpx_sw_bytes *sw_bytes;121 struct _fpx_sw_bytes sw_bytes;
99 u32 xfeatures;122 u32 xfeatures;
100 int err;123 int err;
101 124
102 /* Setup the bytes not touched by the [f]xsave and reserved for SW. */125 /* Setup the bytes not touched by the [f]xsave and reserved for SW. */
103 sw_bytes = ia32_frame ? &fx_sw_reserved_ia32 : &fx_sw_reserved;126 save_sw_bytes(&sw_bytes, ia32_frame, fpstate);
104 err = __copy_to_user(&x->i387.sw_reserved, sw_bytes, sizeof(*sw_bytes));127 err = __copy_to_user(&x->i387.sw_reserved, &sw_bytes, sizeof(sw_bytes));
105 128
106 if (!use_xsave())129 if (!use_xsave())
107 return err;130 return !err;
108 131
109 err |= __put_user(FP_XSTATE_MAGIC2,132 err |= __put_user(FP_XSTATE_MAGIC2,
110 (__u32 __user *)(buf + fpu_user_xstate_size));133 (__u32 __user *)(buf + fpstate->user_size));
111 134
112 /*135 /*
113 * Read the xfeatures which we copied (directly from the cpu or136 * Read the xfeatures which we copied (directly from the cpu or
@@ -130,23 +153,17 @@ static inline int save_xstate_epilog(void __user *buf, int ia32_frame) · 16 unmodified lines
130 153
131 err |= __put_user(xfeatures, (__u32 __user *)&x->header.xfeatures);154 err |= __put_user(xfeatures, (__u32 __user *)&x->header.xfeatures);
132 155
133 return err;156 return !err;
134}157}
135 158
136static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf)159static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf)
137{160{
138 int err;
139
140 if (use_xsave())161 if (use_xsave())
141 err = xsave_to_user_sigframe(buf);162 return xsave_to_user_sigframe(buf);
142 else if (use_fxsr())163 if (use_fxsr())
143 err = fxsave_to_user_sigframe((struct fxregs_state __user *) buf);164 return fxsave_to_user_sigframe((struct fxregs_state __user *) buf);
144 else165 else
145 err = fnsave_to_user_sigframe((struct fregs_state __user *) buf);166 return fnsave_to_user_sigframe((struct fregs_state __user *) buf);
146
147 if (unlikely(err) && __clear_user(buf, fpu_user_xstate_size))
148 err = -EFAULT;
149 return err;
150}167}
151 168
152/*169/*
@@ -159,10 +176,8 @@ static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf) · 6 unmodified lines
159 * buf == buf_fx for 64-bit frames and 32-bit fsave frame.176 * buf == buf_fx for 64-bit frames and 32-bit fsave frame.
160 * buf != buf_fx for 32-bit frames with fxstate.177 * buf != buf_fx for 32-bit frames with fxstate.
161 *178 *
162 * Try to save it directly to the user frame with disabled page fault handler.179 * Save it directly to the user frame with disabled page fault handler. If
163 * If this fails then do the slow path where the FPU state is first saved to180 * that faults, try to clear the frame which handles the page fault.
164 * task's fpu->state and then copy it to the user frame pointed to by the
165 * aligned pointer 'buf_fx'.
166 *181 *
167 * If this is a 32-bit frame with fxstate, put a fsave header before182 * If this is a 32-bit frame with fxstate, put a fsave header before
168 * the aligned state at 'buf_fx'.183 * the aligned state at 'buf_fx'.
@@ -170,10 +185,11 @@ static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf) · 1 unmodified line
170 * For [f]xsave state, update the SW reserved fields in the [f]xsave frame185 * For [f]xsave state, update the SW reserved fields in the [f]xsave frame
171 * indicating the absence/presence of the extended state to the user.186 * indicating the absence/presence of the extended state to the user.
172 */187 */
173int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)188bool copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)
174{189{
175 struct task_struct *tsk = current;190 struct task_struct *tsk = current;
176 int ia32_fxstate = (buf != buf_fx);191 struct fpstate *fpstate = tsk->thread.fpu.fpstate;
192 bool ia32_fxstate = (buf != buf_fx);
177 int ret;193 int ret;
178 194
179 ia32_fxstate &= (IS_ENABLED(CONFIG_X86_32) ||195 ia32_fxstate &= (IS_ENABLED(CONFIG_X86_32) ||
@@ -181,13 +197,25 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) · 1 unmodified line
181 197
182 if (!static_cpu_has(X86_FEATURE_FPU)) {198 if (!static_cpu_has(X86_FEATURE_FPU)) {
183 struct user_i387_ia32_struct fp;199 struct user_i387_ia32_struct fp;
200
184 fpregs_soft_get(current, NULL, (struct membuf){.p = &fp,201 fpregs_soft_get(current, NULL, (struct membuf){.p = &fp,
185 .left = sizeof(fp)});202 .left = sizeof(fp)});
186 return copy_to_user(buf, &fp, sizeof(fp)) ? -EFAULT : 0;203 return !copy_to_user(buf, &fp, sizeof(fp));
187 }204 }
188 205
189 if (!access_ok(buf, size))206 if (!access_ok(buf, size))
190 return -EACCES;207 return false;
208
209 if (use_xsave()) {
210 struct xregs_state __user *xbuf = buf_fx;
211
212 /*
213 * Clear the xsave header first, so that reserved fields are
214 * initialized to zero.
215 */
216 if (__clear_user(&xbuf->header, sizeof(xbuf->header)))
217 return false;
218 }
191retry:219retry:
192 /*220 /*
193 * Load the FPU registers if they are not valid for the current task.221 * Load the FPU registers if they are not valid for the current task.
@@ -205,26 +233,26 @@ retry: · 11 unmodified lines
205 fpregs_unlock();233 fpregs_unlock();
206 234
207 if (ret) {235 if (ret) {
208 if (!fault_in_pages_writeable(buf_fx, fpu_user_xstate_size))236 if (!__clear_user(buf_fx, fpstate->user_size))
209 goto retry;237 goto retry;
210 return -EFAULT;238 return false;
211 }239 }
212 240
213 /* Save the fsave header for the 32-bit frames. */241 /* Save the fsave header for the 32-bit frames. */
214 if ((ia32_fxstate || !use_fxsr()) && save_fsave_header(tsk, buf))242 if ((ia32_fxstate || !use_fxsr()) && !save_fsave_header(tsk, buf))
215 return -1;243 return false;
216 244
217 if (use_fxsr() && save_xstate_epilog(buf_fx, ia32_fxstate))245 if (use_fxsr() && !save_xstate_epilog(buf_fx, ia32_fxstate, fpstate))
218 return -1;246 return false;
219 247
220 return 0;248 return true;
221}249}
222 250
223static int __restore_fpregs_from_user(void __user *buf, u64 xrestore,251static int __restore_fpregs_from_user(void __user *buf, u64 ufeatures,
224 bool fx_only)252 u64 xrestore, bool fx_only)
225{253{
226 if (use_xsave()) {254 if (use_xsave()) {
227 u64 init_bv = xfeatures_mask_uabi() & ~xrestore;255 u64 init_bv = ufeatures & ~xrestore;
228 int ret;256 int ret;
229 257
230 if (likely(!fx_only))258 if (likely(!fx_only))
@@ -233,7 +261,7 @@ static int __restore_fpregs_from_user(void __user *buf, u64 xrestore, · 2 unmodified lines
233 ret = fxrstor_from_user_sigframe(buf);261 ret = fxrstor_from_user_sigframe(buf);
234 262
235 if (!ret && unlikely(init_bv))263 if (!ret && unlikely(init_bv))
236 os_xrstor(&init_fpstate.xsave, init_bv);264 os_xrstor(&init_fpstate, init_bv);
237 return ret;265 return ret;
238 } else if (use_fxsr()) {266 } else if (use_fxsr()) {
239 return fxrstor_from_user_sigframe(buf);267 return fxrstor_from_user_sigframe(buf);
@@ -246,16 +274,19 @@ static int __restore_fpregs_from_user(void __user *buf, u64 xrestore, · 6 unmodified lines
246 * Attempt to restore the FPU registers directly from user memory.274 * Attempt to restore the FPU registers directly from user memory.
247 * Pagefaults are handled and any errors returned are fatal.275 * Pagefaults are handled and any errors returned are fatal.
248 */276 */
249static int restore_fpregs_from_user(void __user *buf, u64 xrestore,277static bool restore_fpregs_from_user(void __user *buf, u64 xrestore,
250 bool fx_only, unsigned int size)278 bool fx_only, unsigned int size)
251{279{
252 struct fpu *fpu = &current->thread.fpu;280 struct fpu *fpu = &current->thread.fpu;
253 int ret;281 int ret;
254 282
255retry:283retry:
256 fpregs_lock();284 fpregs_lock();
285 /* Ensure that XFD is up to date */
286 xfd_update_state(fpu->fpstate);
257 pagefault_disable();287 pagefault_disable();
258 ret = __restore_fpregs_from_user(buf, xrestore, fx_only);288 ret = __restore_fpregs_from_user(buf, fpu->fpstate->user_xfeatures,
289 xrestore, fx_only);
259 pagefault_enable();290 pagefault_enable();
260 291
261 if (unlikely(ret)) {292 if (unlikely(ret)) {
@@ -275,13 +306,12 @@ retry: · 13 unmodified lines
275 fpregs_unlock();306 fpregs_unlock();
276 307
277 /* Try to handle #PF, but anything else is fatal. */308 /* Try to handle #PF, but anything else is fatal. */
278 if (ret != -EFAULT)309 if (ret != X86_TRAP_PF)
279 return -EINVAL;310 return false;
280 311
281 ret = fault_in_pages_readable(buf, size);312 if (!fault_in_pages_readable(buf, size))
282 if (!ret)
283 goto retry;313 goto retry;
284 return ret;314 return false;
285 }315 }
286 316
287 /*317 /*
@@ -294,45 +324,40 @@ retry: · 6 unmodified lines
294 * been restored from a user buffer directly.324 * been restored from a user buffer directly.
295 */325 */
296 if (test_thread_flag(TIF_NEED_FPU_LOAD) && xfeatures_mask_supervisor())326 if (test_thread_flag(TIF_NEED_FPU_LOAD) && xfeatures_mask_supervisor())
297 os_xrstor(&fpu->state.xsave, xfeatures_mask_supervisor());327 os_xrstor_supervisor(fpu->fpstate);
298 328
299 fpregs_mark_activate();329 fpregs_mark_activate();
300 fpregs_unlock();330 fpregs_unlock();
301 return 0;331 return true;
302}332}
303 333
304static int __fpu_restore_sig(void __user *buf, void __user *buf_fx,334static bool __fpu_restore_sig(void __user *buf, void __user *buf_fx,
305 bool ia32_fxstate)335 bool ia32_fxstate)
306{336{
307 int state_size = fpu_kernel_xstate_size;
308 struct task_struct *tsk = current;337 struct task_struct *tsk = current;
309 struct fpu *fpu = &tsk->thread.fpu;338 struct fpu *fpu = &tsk->thread.fpu;
310 struct user_i387_ia32_struct env;339 struct user_i387_ia32_struct env;
340 bool success, fx_only = false;
341 union fpregs_state *fpregs;
342 unsigned int state_size;
311 u64 user_xfeatures = 0;343 u64 user_xfeatures = 0;
312 bool fx_only = false;
313 int ret;
314 344
315 if (use_xsave()) {345 if (use_xsave()) {
316 struct _fpx_sw_bytes fx_sw_user;346 struct _fpx_sw_bytes fx_sw_user;
317 347
318 ret = check_xstate_in_sigframe(buf_fx, &fx_sw_user);348 if (!check_xstate_in_sigframe(buf_fx, &fx_sw_user))
319 if (unlikely(ret))349 return false;
320 return ret;
321 350
322 fx_only = !fx_sw_user.magic1;351 fx_only = !fx_sw_user.magic1;
323 state_size = fx_sw_user.xstate_size;352 state_size = fx_sw_user.xstate_size;
324 user_xfeatures = fx_sw_user.xfeatures;353 user_xfeatures = fx_sw_user.xfeatures;
325 } else {354 } else {
326 user_xfeatures = XFEATURE_MASK_FPSSE;355 user_xfeatures = XFEATURE_MASK_FPSSE;
356 state_size = fpu->fpstate->user_size;
327 }357 }
328 358
329 if (likely(!ia32_fxstate)) {359 if (likely(!ia32_fxstate)) {
330 /*360 /* Restore the FPU registers directly from user memory. */
331 * Attempt to restore the FPU registers directly from user
332 * memory. For that to succeed, the user access cannot cause page
333 * faults. If it does, fall back to the slow path below, going
334 * through the kernel buffer with the enabled pagefault handler.
335 */
336 return restore_fpregs_from_user(buf_fx, user_xfeatures, fx_only,361 return restore_fpregs_from_user(buf_fx, user_xfeatures, fx_only,
337 state_size);362 state_size);
338 }363 }
@@ -342,9 +367,8 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx, · 3 unmodified lines
342 * to be ignored for histerical raisins. The legacy state is folded367 * to be ignored for histerical raisins. The legacy state is folded
343 * in once the larger state has been copied.368 * in once the larger state has been copied.
344 */369 */
345 ret = __copy_from_user(&env, buf, sizeof(env));370 if (__copy_from_user(&env, buf, sizeof(env)))
346 if (ret)371 return false;
347 return ret;
348 372
349 /*373 /*
350 * By setting TIF_NEED_FPU_LOAD it is ensured that our xstate is374 * By setting TIF_NEED_FPU_LOAD it is ensured that our xstate is
@@ -363,38 +387,38 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx, · 12 unmodified lines
363 * the right place in memory. It's ia32 mode. Shrug.387 * the right place in memory. It's ia32 mode. Shrug.
364 */388 */
365 if (xfeatures_mask_supervisor())389 if (xfeatures_mask_supervisor())
366 os_xsave(&fpu->state.xsave);390 os_xsave(fpu->fpstate);
367 set_thread_flag(TIF_NEED_FPU_LOAD);391 set_thread_flag(TIF_NEED_FPU_LOAD);
368 }392 }
369 __fpu_invalidate_fpregs_state(fpu);393 __fpu_invalidate_fpregs_state(fpu);
370 __cpu_invalidate_fpregs_state();394 __cpu_invalidate_fpregs_state();
371 fpregs_unlock();395 fpregs_unlock();
372 396
397 fpregs = &fpu->fpstate->regs;
373 if (use_xsave() && !fx_only) {398 if (use_xsave() && !fx_only) {
374 ret = copy_sigframe_from_user_to_xstate(&fpu->state.xsave, buf_fx);399 if (copy_sigframe_from_user_to_xstate(fpu->fpstate, buf_fx))
375 if (ret)400 return false;
376 return ret;
377 } else {401 } else {
378 if (__copy_from_user(&fpu->state.fxsave, buf_fx,402 if (__copy_from_user(&fpregs->fxsave, buf_fx,
379 sizeof(fpu->state.fxsave)))403 sizeof(fpregs->fxsave)))
380 return -EFAULT;404 return false;
381 405
382 if (IS_ENABLED(CONFIG_X86_64)) {406 if (IS_ENABLED(CONFIG_X86_64)) {
383 /* Reject invalid MXCSR values. */407 /* Reject invalid MXCSR values. */
384 if (fpu->state.fxsave.mxcsr & ~mxcsr_feature_mask)408 if (fpregs->fxsave.mxcsr & ~mxcsr_feature_mask)
385 return -EINVAL;409 return false;
386 } else {410 } else {
387 /* Mask invalid bits out for historical reasons (broken hardware). */411 /* Mask invalid bits out for historical reasons (broken hardware). */
388 fpu->state.fxsave.mxcsr &= mxcsr_feature_mask;412 fpregs->fxsave.mxcsr &= mxcsr_feature_mask;
389 }413 }
390 414
391 /* Enforce XFEATURE_MASK_FPSSE when XSAVE is enabled */415 /* Enforce XFEATURE_MASK_FPSSE when XSAVE is enabled */
392 if (use_xsave())416 if (use_xsave())
393 fpu->state.xsave.header.xfeatures |= XFEATURE_MASK_FPSSE;417 fpregs->xsave.header.xfeatures |= XFEATURE_MASK_FPSSE;
394 }418 }
395 419
396 /* Fold the legacy FP storage */420 /* Fold the legacy FP storage */
397 convert_to_fxsr(&fpu->state.fxsave, &env);421 convert_to_fxsr(&fpregs->fxsave, &env);
398 422
399 fpregs_lock();423 fpregs_lock();
400 if (use_xsave()) {424 if (use_xsave()) {
@@ -409,40 +433,45 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx, · 8 unmodified lines
409 */433 */
410 u64 mask = user_xfeatures | xfeatures_mask_supervisor();434 u64 mask = user_xfeatures | xfeatures_mask_supervisor();
411 435
412 fpu->state.xsave.header.xfeatures &= mask;436 fpregs->xsave.header.xfeatures &= mask;
413 ret = os_xrstor_safe(&fpu->state.xsave, xfeatures_mask_all);437 success = !os_xrstor_safe(fpu->fpstate,
438 fpu_kernel_cfg.max_features);
414 } else {439 } else {
415 ret = fxrstor_safe(&fpu->state.fxsave);440 success = !fxrstor_safe(&fpregs->fxsave);
416 }441 }
417 442
418 if (likely(!ret))443 if (likely(success))
419 fpregs_mark_activate();444 fpregs_mark_activate();
420 445
421 fpregs_unlock();446 fpregs_unlock();
422 return ret;447 return success;
423}448}
424static inline int xstate_sigframe_size(void)449
450static inline unsigned int xstate_sigframe_size(struct fpstate *fpstate)
425{451{
426 return use_xsave() ? fpu_user_xstate_size + FP_XSTATE_MAGIC2_SIZE :452 unsigned int size = fpstate->user_size;
427 fpu_user_xstate_size;453
454 return use_xsave() ? size + FP_XSTATE_MAGIC2_SIZE : size;
428}455}
429 456
430/*457/*
431 * Restore FPU state from a sigframe:458 * Restore FPU state from a sigframe:
432 */459 */
433int fpu__restore_sig(void __user *buf, int ia32_frame)460bool fpu__restore_sig(void __user *buf, int ia32_frame)
434{461{
435 unsigned int size = xstate_sigframe_size();
436 struct fpu *fpu = &current->thread.fpu;462 struct fpu *fpu = &current->thread.fpu;
437 void __user *buf_fx = buf;463 void __user *buf_fx = buf;
438 bool ia32_fxstate = false;464 bool ia32_fxstate = false;
439 int ret;465 bool success = false;
466 unsigned int size;
440 467
441 if (unlikely(!buf)) {468 if (unlikely(!buf)) {
442 fpu__clear_user_states(fpu);469 fpu__clear_user_states(fpu);
443 return 0;470 return true;
444 }471 }
445 472
473 size = xstate_sigframe_size(fpu->fpstate);
474
446 ia32_frame &= (IS_ENABLED(CONFIG_X86_32) ||475 ia32_frame &= (IS_ENABLED(CONFIG_X86_32) ||
447 IS_ENABLED(CONFIG_IA32_EMULATION));476 IS_ENABLED(CONFIG_IA32_EMULATION));
448 477
@@ -456,30 +485,28 @@ int fpu__restore_sig(void __user *buf, int ia32_frame) · 7 unmodified lines
456 ia32_fxstate = true;485 ia32_fxstate = true;
457 }486 }
458 487
459 if (!access_ok(buf, size)) {488 if (!access_ok(buf, size))
460 ret = -EACCES;
461 goto out;489 goto out;
462 }
463 490
464 if (!IS_ENABLED(CONFIG_X86_64) && !cpu_feature_enabled(X86_FEATURE_FPU)) {491 if (!IS_ENABLED(CONFIG_X86_64) && !cpu_feature_enabled(X86_FEATURE_FPU)) {
465 ret = fpregs_soft_set(current, NULL, 0,492 success = !fpregs_soft_set(current, NULL, 0,
466 sizeof(struct user_i387_ia32_struct),493 sizeof(struct user_i387_ia32_struct),
467 NULL, buf);494 NULL, buf);
468 } else {495 } else {
469 ret = __fpu_restore_sig(buf, buf_fx, ia32_fxstate);496 success = __fpu_restore_sig(buf, buf_fx, ia32_fxstate);
470 }497 }
471 498
472out:499out:
473 if (unlikely(ret))500 if (unlikely(!success))
474 fpu__clear_user_states(fpu);501 fpu__clear_user_states(fpu);
475 return ret;502 return success;
476}503}
477 504
478unsigned long505unsigned long
479fpu__alloc_mathframe(unsigned long sp, int ia32_frame,506fpu__alloc_mathframe(unsigned long sp, int ia32_frame,
480 unsigned long *buf_fx, unsigned long *size)507 unsigned long *buf_fx, unsigned long *size)
481{508{
482 unsigned long frame_size = xstate_sigframe_size();509 unsigned long frame_size = xstate_sigframe_size(current->thread.fpu.fpstate);
483 510
484 *buf_fx = sp = round_down(sp - frame_size, 64);511 *buf_fx = sp = round_down(sp - frame_size, 64);
485 if (ia32_frame && use_fxsr()) {512 if (ia32_frame && use_fxsr()) {
@@ -492,9 +519,12 @@ fpu__alloc_mathframe(unsigned long sp, int ia32_frame, · 6 unmodified lines
492 return sp;519 return sp;
493}520}
494 521
495unsigned long fpu__get_fpstate_size(void)522unsigned long __init fpu__get_fpstate_size(void)
496{523{
497 unsigned long ret = xstate_sigframe_size();524 unsigned long ret = fpu_user_cfg.max_size;
525
526 if (use_xsave())
527 ret += FP_XSTATE_MAGIC2_SIZE;
498 528
499 /*529 /*
500 * This space is needed on (most) 32-bit kernels, or when a 32-bit530 * This space is needed on (most) 32-bit kernels, or when a 32-bit
@@ -510,28 +540,3 @@ unsigned long fpu__get_fpstate_size(void) · 9 unmodified lines
510 return ret;540 return ret;
511}541}
512 542
513/*
514 * Prepare the SW reserved portion of the fxsave memory layout, indicating
515 * the presence of the extended state information in the memory layout
516 * pointed by the fpstate pointer in the sigcontext.
517 * This will be saved when ever the FP and extended state context is
518 * saved on the user stack during the signal handler delivery to the user.
519 */
520void fpu__init_prepare_fx_sw_frame(void)
521{
522 int size = fpu_user_xstate_size + FP_XSTATE_MAGIC2_SIZE;
523
524 fx_sw_reserved.magic1 = FP_XSTATE_MAGIC1;
525 fx_sw_reserved.extended_size = size;
526 fx_sw_reserved.xfeatures = xfeatures_mask_uabi();
527 fx_sw_reserved.xstate_size = fpu_user_xstate_size;
528
529 if (IS_ENABLED(CONFIG_IA32_EMULATION) ||
530 IS_ENABLED(CONFIG_X86_32)) {
531 int fsave_header_size = sizeof(struct fregs_state);
532
533 fx_sw_reserved_ia32 = fx_sw_reserved;
534 fx_sw_reserved_ia32.extended_size = size + fsave_header_size;
535 }
536}
537
arch/x86/kernel/fpu/xstate.c+712−186
@@ -4,21 +4,33 @@ · 3 unmodified lines
4 *4 *
5 * Author: Suresh Siddha <suresh.b.siddha@intel.com>5 * Author: Suresh Siddha <suresh.b.siddha@intel.com>
6 */6 */
7#include <linux/bitops.h>
7#include <linux/compat.h>8#include <linux/compat.h>
8#include <linux/cpu.h>9#include <linux/cpu.h>
9#include <linux/mman.h>10#include <linux/mman.h>
11#include <linux/nospec.h>
10#include <linux/pkeys.h>12#include <linux/pkeys.h>
11#include <linux/seq_file.h>13#include <linux/seq_file.h>
12#include <linux/proc_fs.h>14#include <linux/proc_fs.h>
15#include <linux/vmalloc.h>
13 16
14#include <asm/fpu/api.h>17#include <asm/fpu/api.h>
15#include <asm/fpu/internal.h>
16#include <asm/fpu/signal.h>
17#include <asm/fpu/regset.h>18#include <asm/fpu/regset.h>
18#include <asm/fpu/xstate.h>19#include <asm/fpu/signal.h>
20#include <asm/fpu/xcr.h>
19 21
20#include <asm/tlbflush.h>22#include <asm/tlbflush.h>
21#include <asm/cpufeature.h>23#include <asm/prctl.h>
24#include <asm/elf.h>
25
26#include "context.h"
27#include "internal.h"
28#include "legacy.h"
29#include "xstate.h"
30
31#define for_each_extended_xfeature(bit, mask) \
32 (bit) = FIRST_EXTENDED_XFEATURE; \
33 for_each_set_bit_from(bit, (unsigned long *)&(mask), 8 * sizeof(mask))
22 34
23/*35/*
24 * Although we spell it out in here, the Processor Trace36 * Although we spell it out in here, the Processor Trace
@@ -39,29 +51,32 @@ static const char *xfeature_names[] = · 14 unmodified lines
39 "Protection Keys User registers",51 "Protection Keys User registers",
40 "PASID state",52 "PASID state",
41 "unknown xstate feature" ,53 "unknown xstate feature" ,
54 "unknown xstate feature" ,
55 "unknown xstate feature" ,
56 "unknown xstate feature" ,
57 "unknown xstate feature" ,
58 "unknown xstate feature" ,
59 "AMX Tile config" ,
60 "AMX Tile data" ,
61 "unknown xstate feature" ,
42};62};
43 63
44static short xsave_cpuid_features[] __initdata = {64static unsigned short xsave_cpuid_features[] __initdata = {
45 X86_FEATURE_FPU,65 [XFEATURE_FP] = X86_FEATURE_FPU,
46 X86_FEATURE_XMM,66 [XFEATURE_SSE] = X86_FEATURE_XMM,
47 X86_FEATURE_AVX,67 [XFEATURE_YMM] = X86_FEATURE_AVX,
48 X86_FEATURE_MPX,68 [XFEATURE_BNDREGS] = X86_FEATURE_MPX,
49 X86_FEATURE_MPX,69 [XFEATURE_BNDCSR] = X86_FEATURE_MPX,
50 X86_FEATURE_AVX512F,70 [XFEATURE_OPMASK] = X86_FEATURE_AVX512F,
51 X86_FEATURE_AVX512F,71 [XFEATURE_ZMM_Hi256] = X86_FEATURE_AVX512F,
52 X86_FEATURE_AVX512F,72 [XFEATURE_Hi16_ZMM] = X86_FEATURE_AVX512F,
53 X86_FEATURE_INTEL_PT,73 [XFEATURE_PT_UNIMPLEMENTED_SO_FAR] = X86_FEATURE_INTEL_PT,
54 X86_FEATURE_PKU,74 [XFEATURE_PKRU] = X86_FEATURE_PKU,
55 X86_FEATURE_ENQCMD,75 [XFEATURE_PASID] = X86_FEATURE_ENQCMD,
76 [XFEATURE_XTILE_CFG] = X86_FEATURE_AMX_TILE,
77 [XFEATURE_XTILE_DATA] = X86_FEATURE_AMX_TILE,
56};78};
57 79
58/*
59 * This represents the full set of bits that should ever be set in a kernel
60 * XSAVE buffer, both supervisor and user xstates.
61 */
62u64 xfeatures_mask_all __ro_after_init;
63EXPORT_SYMBOL_GPL(xfeatures_mask_all);
64
65static unsigned int xstate_offsets[XFEATURE_MAX] __ro_after_init =80static unsigned int xstate_offsets[XFEATURE_MAX] __ro_after_init =
66 { [ 0 ... XFEATURE_MAX - 1] = -1};81 { [ 0 ... XFEATURE_MAX - 1] = -1};
67static unsigned int xstate_sizes[XFEATURE_MAX] __ro_after_init =82static unsigned int xstate_sizes[XFEATURE_MAX] __ro_after_init =
@@ -71,13 +86,6 @@ static unsigned int xstate_comp_offsets[XFEATURE_MAX] __ro_after_init = · 3 unmodified lines
71static unsigned int xstate_supervisor_only_offsets[XFEATURE_MAX] __ro_after_init =86static unsigned int xstate_supervisor_only_offsets[XFEATURE_MAX] __ro_after_init =
72 { [ 0 ... XFEATURE_MAX - 1] = -1};87 { [ 0 ... XFEATURE_MAX - 1] = -1};
73 88
74/*
75 * The XSAVE area of kernel can be in standard or compacted format;
76 * it is always in standard format for user mode. This is the user
77 * mode standard format size used for signal and ptrace frames.
78 */
79unsigned int fpu_user_xstate_size __ro_after_init;
80
81/*89/*
82 * Return whether the system supports a given xfeature.90 * Return whether the system supports a given xfeature.
83 *91 *
@@ -85,7 +93,7 @@ unsigned int fpu_user_xstate_size __ro_after_init; · 1 unmodified line
85 */93 */
86int cpu_has_xfeatures(u64 xfeatures_needed, const char **feature_name)94int cpu_has_xfeatures(u64 xfeatures_needed, const char **feature_name)
87{95{
88 u64 xfeatures_missing = xfeatures_needed & ~xfeatures_mask_all;96 u64 xfeatures_missing = xfeatures_needed & ~fpu_kernel_cfg.max_features;
89 97
90 if (unlikely(feature_name)) {98 if (unlikely(feature_name)) {
91 long xfeature_idx, max_idx;99 long xfeature_idx, max_idx;
@@ -135,17 +143,26 @@ static bool xfeature_is_supervisor(int xfeature_nr) · 43 unmodified lines
135 */143 */
136void fpu__init_cpu_xstate(void)144void fpu__init_cpu_xstate(void)
137{145{
138 if (!boot_cpu_has(X86_FEATURE_XSAVE) || !xfeatures_mask_all)146 if (!boot_cpu_has(X86_FEATURE_XSAVE) || !fpu_kernel_cfg.max_features)
139 return;147 return;
140 148
141 cr4_set_bits(X86_CR4_OSXSAVE);149 cr4_set_bits(X86_CR4_OSXSAVE);
142 150
151 /*
152 * Must happen after CR4 setup and before xsetbv() to allow KVM
153 * lazy passthrough. Write independent of the dynamic state static
154 * key as that does not work on the boot CPU. This also ensures
155 * that any stale state is wiped out from XFD.
156 */
157 if (cpu_feature_enabled(X86_FEATURE_XFD))
158 wrmsrl(MSR_IA32_XFD, init_fpstate.xfd);
159
143 /*160 /*
144 * XCR_XFEATURE_ENABLED_MASK (aka. XCR0) sets user features161 * XCR_XFEATURE_ENABLED_MASK (aka. XCR0) sets user features
145 * managed by XSAVE{C, OPT, S} and XRSTOR{S}. Only XSAVE user162 * managed by XSAVE{C, OPT, S} and XRSTOR{S}. Only XSAVE user
146 * states can be set here.163 * states can be set here.
147 */164 */
148 xsetbv(XCR_XFEATURE_ENABLED_MASK, xfeatures_mask_uabi());165 xsetbv(XCR_XFEATURE_ENABLED_MASK, fpu_user_cfg.max_features);
149 166
150 /*167 /*
151 * MSR_IA32_XSS sets supervisor states managed by XSAVES.168 * MSR_IA32_XSS sets supervisor states managed by XSAVES.
@@ -158,7 +175,7 @@ void fpu__init_cpu_xstate(void) · 6 unmodified lines
158 175
159static bool xfeature_enabled(enum xfeature xfeature)176static bool xfeature_enabled(enum xfeature xfeature)
160{177{
161 return xfeatures_mask_all & BIT_ULL(xfeature);178 return fpu_kernel_cfg.max_features & BIT_ULL(xfeature);
162}179}
163 180
164/*181/*
@@ -184,10 +201,7 @@ static void __init setup_xstate_features(void) · 19 unmodified lines
184 xstate_sizes[XFEATURE_SSE] = sizeof_field(struct fxregs_state,201 xstate_sizes[XFEATURE_SSE] = sizeof_field(struct fxregs_state,
185 xmm_space);202 xmm_space);
186 203
187 for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {204 for_each_extended_xfeature(i, fpu_kernel_cfg.max_features) {
188 if (!xfeature_enabled(i))
189 continue;
190
191 cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);205 cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
192 206
193 xstate_sizes[i] = eax;207 xstate_sizes[i] = eax;
@@ -236,6 +250,8 @@ static void __init print_xstate_features(void) · 42 unmodified lines
236 print_xstate_feature(XFEATURE_MASK_Hi16_ZMM);250 print_xstate_feature(XFEATURE_MASK_Hi16_ZMM);
237 print_xstate_feature(XFEATURE_MASK_PKRU);251 print_xstate_feature(XFEATURE_MASK_PKRU);
238 print_xstate_feature(XFEATURE_MASK_PASID);252 print_xstate_feature(XFEATURE_MASK_PASID);
253 print_xstate_feature(XFEATURE_MASK_XTILE_CFG);
254 print_xstate_feature(XFEATURE_MASK_XTILE_DATA);
239}255}
240 256
241/*257/*
@@ -291,20 +307,15 @@ static void __init setup_xstate_comp_offsets(void) · 49 unmodified lines
291 xstate_comp_offsets[XFEATURE_SSE] = offsetof(struct fxregs_state,307 xstate_comp_offsets[XFEATURE_SSE] = offsetof(struct fxregs_state,
292 xmm_space);308 xmm_space);
293 309
294 if (!boot_cpu_has(X86_FEATURE_XSAVES)) {310 if (!cpu_feature_enabled(X86_FEATURE_XSAVES)) {
295 for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {311 for_each_extended_xfeature(i, fpu_kernel_cfg.max_features)
296 if (xfeature_enabled(i))312 xstate_comp_offsets[i] = xstate_offsets[i];
297 xstate_comp_offsets[i] = xstate_offsets[i];
298 }
299 return;313 return;
300 }314 }
301 315
302 next_offset = FXSAVE_SIZE + XSAVE_HDR_SIZE;316 next_offset = FXSAVE_SIZE + XSAVE_HDR_SIZE;
303 317
304 for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {318 for_each_extended_xfeature(i, fpu_kernel_cfg.max_features) {
305 if (!xfeature_enabled(i))
306 continue;
307
308 if (xfeature_is_aligned(i))319 if (xfeature_is_aligned(i))
309 next_offset = ALIGN(next_offset, 64);320 next_offset = ALIGN(next_offset, 64);
310 321
@@ -328,8 +339,8 @@ static void __init setup_supervisor_only_offsets(void) · 17 unmodified lines
328 339
329 next_offset = FXSAVE_SIZE + XSAVE_HDR_SIZE;340 next_offset = FXSAVE_SIZE + XSAVE_HDR_SIZE;
330 341
331 for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {342 for_each_extended_xfeature(i, fpu_kernel_cfg.max_features) {
332 if (!xfeature_enabled(i) || !xfeature_is_supervisor(i))343 if (!xfeature_is_supervisor(i))
333 continue;344 continue;
334 345
335 if (xfeature_is_aligned(i))346 if (xfeature_is_aligned(i))
@@ -347,14 +358,35 @@ static void __init print_xstate_offset_size(void) · 11 unmodified lines
347{358{
348 int i;359 int i;
349 360
350 for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {361 for_each_extended_xfeature(i, fpu_kernel_cfg.max_features) {
351 if (!xfeature_enabled(i))
352 continue;
353 pr_info("x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n",362 pr_info("x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n",
354 i, xstate_comp_offsets[i], i, xstate_sizes[i]);363 i, xstate_comp_offsets[i], i, xstate_sizes[i]);
355 }364 }
356}365}
357 366
367/*
368 * This function is called only during boot time when x86 caps are not set
369 * up and alternative can not be used yet.
370 */
371static __init void os_xrstor_booting(struct xregs_state *xstate)
372{
373 u64 mask = fpu_kernel_cfg.max_features & XFEATURE_MASK_FPSTATE;
374 u32 lmask = mask;
375 u32 hmask = mask >> 32;
376 int err;
377
378 if (cpu_feature_enabled(X86_FEATURE_XSAVES))
379 XSTATE_OP(XRSTORS, xstate, lmask, hmask, err);
380 else
381 XSTATE_OP(XRSTOR, xstate, lmask, hmask, err);
382
383 /*
384 * We should never fault when copying from a kernel buffer, and the FPU
385 * state we set at boot time should be valid.
386 */
387 WARN_ON_FPU(err);
388}
389
358/*390/*
359 * All supported features have either init state all zeros or are391 * All supported features have either init state all zeros or are
360 * handled in setup_init_fpu() individually. This is an explicit392 * handled in setup_init_fpu() individually. This is an explicit
@@ -372,36 +404,30 @@ static void __init print_xstate_offset_size(void) · 11 unmodified lines
372 XFEATURE_MASK_PKRU | \404 XFEATURE_MASK_PKRU | \
373 XFEATURE_MASK_BNDREGS | \405 XFEATURE_MASK_BNDREGS | \
374 XFEATURE_MASK_BNDCSR | \406 XFEATURE_MASK_BNDCSR | \
375 XFEATURE_MASK_PASID)407 XFEATURE_MASK_PASID | \
408 XFEATURE_MASK_XTILE)
376 409
377/*410/*
378 * setup the xstate image representing the init state411 * setup the xstate image representing the init state
379 */412 */
380static void __init setup_init_fpu_buf(void)413static void __init setup_init_fpu_buf(void)
381{414{
382 static int on_boot_cpu __initdata = 1;
383
384 BUILD_BUG_ON((XFEATURE_MASK_USER_SUPPORTED |415 BUILD_BUG_ON((XFEATURE_MASK_USER_SUPPORTED |
385 XFEATURE_MASK_SUPERVISOR_SUPPORTED) !=416 XFEATURE_MASK_SUPERVISOR_SUPPORTED) !=
386 XFEATURES_INIT_FPSTATE_HANDLED);417 XFEATURES_INIT_FPSTATE_HANDLED);
387 418
388 WARN_ON_FPU(!on_boot_cpu);
389 on_boot_cpu = 0;
390
391 if (!boot_cpu_has(X86_FEATURE_XSAVE))419 if (!boot_cpu_has(X86_FEATURE_XSAVE))
392 return;420 return;
393 421
394 setup_xstate_features();422 setup_xstate_features();
395 print_xstate_features();423 print_xstate_features();
396 424
397 if (boot_cpu_has(X86_FEATURE_XSAVES))425 xstate_init_xcomp_bv(&init_fpstate.regs.xsave, fpu_kernel_cfg.max_features);
398 init_fpstate.xsave.header.xcomp_bv = XCOMP_BV_COMPACTED_FORMAT |
399 xfeatures_mask_all;
400 426
401 /*427 /*
402 * Init all the features state with header.xfeatures being 0x0428 * Init all the features state with header.xfeatures being 0x0
403 */429 */
404 os_xrstor_booting(&init_fpstate.xsave);430 os_xrstor_booting(&init_fpstate.regs.xsave);
405 431
406 /*432 /*
407 * All components are now in init state. Read the state back so433 * All components are now in init state. Read the state back so
@@ -419,7 +445,7 @@ static void __init setup_init_fpu_buf(void) · 11 unmodified lines
419 * state is all zeroes or if not to add the necessary handling445 * state is all zeroes or if not to add the necessary handling
420 * here.446 * here.
421 */447 */
422 fxsave(&init_fpstate.fxsave);448 fxsave(&init_fpstate.regs.fxsave);
423}449}
424 450
425static int xfeature_uncompacted_offset(int xfeature_nr)451static int xfeature_uncompacted_offset(int xfeature_nr)
@@ -451,10 +477,11 @@ int xfeature_size(int xfeature_nr) · 25 unmodified lines
451}477}
452 478
453/* Validate an xstate header supplied by userspace (ptrace or sigreturn) */479/* Validate an xstate header supplied by userspace (ptrace or sigreturn) */
454static int validate_user_xstate_header(const struct xstate_header *hdr)480static int validate_user_xstate_header(const struct xstate_header *hdr,
481 struct fpstate *fpstate)
455{482{
456 /* No unknown or supervisor features may be set */483 /* No unknown or supervisor features may be set */
457 if (hdr->xfeatures & ~xfeatures_mask_uabi())484 if (hdr->xfeatures & ~fpstate->user_xfeatures)
458 return -EINVAL;485 return -EINVAL;
459 486
460 /* Userspace must use the uncompacted format */487 /* Userspace must use the uncompacted format */
@@ -474,7 +501,7 @@ static int validate_user_xstate_header(const struct xstate_header *hdr) · 13 unmodified lines
474 return 0;501 return 0;
475}502}
476 503
477static void __xstate_dump_leaves(void)504static void __init __xstate_dump_leaves(void)
478{505{
479 int i;506 int i;
480 u32 eax, ebx, ecx, edx;507 u32 eax, ebx, ecx, edx;
@@ -509,12 +536,73 @@ static void __xstate_dump_leaves(void) · 28 unmodified lines
509 } \536 } \
510} while (0)537} while (0)
511 538
539/**
540 * check_xtile_data_against_struct - Check tile data state size.
541 *
542 * Calculate the state size by multiplying the single tile size which is
543 * recorded in a C struct, and the number of tiles that the CPU informs.
544 * Compare the provided size with the calculation.
545 *
546 * @size: The tile data state size
547 *
548 * Returns: 0 on success, -EINVAL on mismatch.
549 */
550static int __init check_xtile_data_against_struct(int size)
551{
552 u32 max_palid, palid, state_size;
553 u32 eax, ebx, ecx, edx;
554 u16 max_tile;
555
556 /*
557 * Check the maximum palette id:
558 * eax: the highest numbered palette subleaf.
559 */
560 cpuid_count(TILE_CPUID, 0, &max_palid, &ebx, &ecx, &edx);
561
562 /*
563 * Cross-check each tile size and find the maximum number of
564 * supported tiles.
565 */
566 for (palid = 1, max_tile = 0; palid <= max_palid; palid++) {
567 u16 tile_size, max;
568
569 /*
570 * Check the tile size info:
571 * eax[31:16]: bytes per title
572 * ebx[31:16]: the max names (or max number of tiles)
573 */
574 cpuid_count(TILE_CPUID, palid, &eax, &ebx, &edx, &edx);
575 tile_size = eax >> 16;
576 max = ebx >> 16;
577
578 if (tile_size != sizeof(struct xtile_data)) {
579 pr_err("%s: struct is %zu bytes, cpu xtile %d bytes\n",
580 __stringify(XFEATURE_XTILE_DATA),
581 sizeof(struct xtile_data), tile_size);
582 __xstate_dump_leaves();
583 return -EINVAL;
584 }
585
586 if (max > max_tile)
587 max_tile = max;
588 }
589
590 state_size = sizeof(struct xtile_data) * max_tile;
591 if (size != state_size) {
592 pr_err("%s: calculated size is %u bytes, cpu state %d bytes\n",
593 __stringify(XFEATURE_XTILE_DATA), state_size, size);
594 __xstate_dump_leaves();
595 return -EINVAL;
596 }
597 return 0;
598}
599
512/*600/*
513 * We have a C struct for each 'xstate'. We need to ensure601 * We have a C struct for each 'xstate'. We need to ensure
514 * that our software representation matches what the CPU602 * that our software representation matches what the CPU
515 * tells us about the state's size.603 * tells us about the state's size.
516 */604 */
517static void check_xstate_against_struct(int nr)605static bool __init check_xstate_against_struct(int nr)
518{606{
519 /*607 /*
520 * Ask the CPU for the size of the state.608 * Ask the CPU for the size of the state.
@@ -532,6 +620,11 @@ static void check_xstate_against_struct(int nr) · 11 unmodified lines
532 XCHECK_SZ(sz, nr, XFEATURE_Hi16_ZMM, struct avx_512_hi16_state);620 XCHECK_SZ(sz, nr, XFEATURE_Hi16_ZMM, struct avx_512_hi16_state);
533 XCHECK_SZ(sz, nr, XFEATURE_PKRU, struct pkru_state);621 XCHECK_SZ(sz, nr, XFEATURE_PKRU, struct pkru_state);
534 XCHECK_SZ(sz, nr, XFEATURE_PASID, struct ia32_pasid_state);622 XCHECK_SZ(sz, nr, XFEATURE_PASID, struct ia32_pasid_state);
623 XCHECK_SZ(sz, nr, XFEATURE_XTILE_CFG, struct xtile_cfg);
624
625 /* The tile data size varies between implementations. */
626 if (nr == XFEATURE_XTILE_DATA)
627 check_xtile_data_against_struct(sz);
535 628
536 /*629 /*
537 * Make *SURE* to add any feature numbers in below if630 * Make *SURE* to add any feature numbers in below if
@@ -541,10 +634,39 @@ static void check_xstate_against_struct(int nr) · 3 unmodified lines
541 if ((nr < XFEATURE_YMM) ||634 if ((nr < XFEATURE_YMM) ||
542 (nr >= XFEATURE_MAX) ||635 (nr >= XFEATURE_MAX) ||
543 (nr == XFEATURE_PT_UNIMPLEMENTED_SO_FAR) ||636 (nr == XFEATURE_PT_UNIMPLEMENTED_SO_FAR) ||
544 ((nr >= XFEATURE_RSRVD_COMP_11) && (nr <= XFEATURE_LBR))) {637 ((nr >= XFEATURE_RSRVD_COMP_11) && (nr <= XFEATURE_RSRVD_COMP_16))) {
545 WARN_ONCE(1, "no structure for xstate: %d\n", nr);638 WARN_ONCE(1, "no structure for xstate: %d\n", nr);
546 XSTATE_WARN_ON(1);639 XSTATE_WARN_ON(1);
640 return false;
641 }
642 return true;
643}
644
645static unsigned int xstate_calculate_size(u64 xfeatures, bool compacted)
646{
647 unsigned int size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
648 int i;
649
650 for_each_extended_xfeature(i, xfeatures) {
651 /* Align from the end of the previous feature */
652 if (xfeature_is_aligned(i))
653 size = ALIGN(size, 64);
654 /*
655 * In compacted format the enabled features are packed,
656 * i.e. disabled features do not occupy space.
657 *
658 * In non-compacted format the offsets are fixed and
659 * disabled states still occupy space in the memory buffer.
660 */
661 if (!compacted)
662 size = xfeature_uncompacted_offset(i);
663 /*
664 * Add the feature size even for non-compacted format
665 * to make the end result correct
666 */
667 size += xfeature_size(i);
547 }668 }
669 return size;
548}670}
549 671
550/*672/*
@@ -556,44 +678,29 @@ static void check_xstate_against_struct(int nr) · 5 unmodified lines
556 * covered by these checks. Only the size of the buffer for task->fpu678 * covered by these checks. Only the size of the buffer for task->fpu
557 * is checked here.679 * is checked here.
558 */680 */
559static void do_extra_xstate_size_checks(void)681static bool __init paranoid_xstate_size_valid(unsigned int kernel_size)
560{682{
561 int paranoid_xstate_size = FXSAVE_SIZE + XSAVE_HDR_SIZE;683 bool compacted = cpu_feature_enabled(X86_FEATURE_XSAVES);
684 unsigned int size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
562 int i;685 int i;
563 686
564 for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {687 for_each_extended_xfeature(i, fpu_kernel_cfg.max_features) {
565 if (!xfeature_enabled(i))688 if (!check_xstate_against_struct(i))
566 continue;689 return false;
567
568 check_xstate_against_struct(i);
569 /*690 /*
570 * Supervisor state components can be managed only by691 * Supervisor state components can be managed only by
571 * XSAVES.692 * XSAVES.
572 */693 */
573 if (!cpu_feature_enabled(X86_FEATURE_XSAVES))694 if (!compacted && xfeature_is_supervisor(i)) {
574 XSTATE_WARN_ON(xfeature_is_supervisor(i));695 XSTATE_WARN_ON(1);
575 696 return false;
576 /* Align from the end of the previous feature */697 }
577 if (xfeature_is_aligned(i))
578 paranoid_xstate_size = ALIGN(paranoid_xstate_size, 64);
579 /*
580 * The offset of a given state in the non-compacted
581 * format is given to us in a CPUID leaf. We check
582 * them for being ordered (increasing offsets) in
583 * setup_xstate_features(). XSAVES uses compacted format.
584 */
585 if (!cpu_feature_enabled(X86_FEATURE_XSAVES))
586 paranoid_xstate_size = xfeature_uncompacted_offset(i);
587 /*
588 * The compacted-format offset always depends on where
589 * the previous state ended.
590 */
591 paranoid_xstate_size += xfeature_size(i);
592 }698 }
593 XSTATE_WARN_ON(paranoid_xstate_size != fpu_kernel_xstate_size);699 size = xstate_calculate_size(fpu_kernel_cfg.max_features, compacted);
700 XSTATE_WARN_ON(size != kernel_size);
701 return size == kernel_size;
594}702}
595 703
596
597/*704/*
598 * Get total size of enabled xstates in XCR0 | IA32_XSS.705 * Get total size of enabled xstates in XCR0 | IA32_XSS.
599 *706 *
@@ -644,7 +751,7 @@ static unsigned int __init get_xsaves_size_no_independent(void) · 44 unmodified lines
644 return size;751 return size;
645}752}
646 753
647static unsigned int __init get_xsave_size(void)754static unsigned int __init get_xsave_size_user(void)
648{755{
649 unsigned int eax, ebx, ecx, edx;756 unsigned int eax, ebx, ecx, edx;
650 /*757 /*
@@ -662,44 +769,54 @@ static unsigned int __init get_xsave_size(void) · 11 unmodified lines
662 * Will the runtime-enumerated 'xstate_size' fit in the init769 * Will the runtime-enumerated 'xstate_size' fit in the init
663 * task's statically-allocated buffer?770 * task's statically-allocated buffer?
664 */771 */
665static bool is_supported_xstate_size(unsigned int test_xstate_size)772static bool __init is_supported_xstate_size(unsigned int test_xstate_size)
666{773{
667 if (test_xstate_size <= sizeof(union fpregs_state))774 if (test_xstate_size <= sizeof(init_fpstate.regs))
668 return true;775 return true;
669 776
670 pr_warn("x86/fpu: xstate buffer too small (%zu < %d), disabling xsave\n",777 pr_warn("x86/fpu: xstate buffer too small (%zu < %d), disabling xsave\n",
671 sizeof(union fpregs_state), test_xstate_size);778 sizeof(init_fpstate.regs), test_xstate_size);
672 return false;779 return false;
673}780}
674 781
675static int __init init_xstate_size(void)782static int __init init_xstate_size(void)
676{783{
677 /* Recompute the context size for enabled features: */784 /* Recompute the context size for enabled features: */
678 unsigned int possible_xstate_size;785 unsigned int user_size, kernel_size, kernel_default_size;
679 unsigned int xsave_size;786 bool compacted = cpu_feature_enabled(X86_FEATURE_XSAVES);
680 787
681 xsave_size = get_xsave_size();788 /* Uncompacted user space size */
789 user_size = get_xsave_size_user();
682 790
683 if (boot_cpu_has(X86_FEATURE_XSAVES))791 /*
684 possible_xstate_size = get_xsaves_size_no_independent();792 * XSAVES kernel size includes supervisor states and
793 * uses compacted format when available.
794 *
795 * XSAVE does not support supervisor states so
796 * kernel and user size is identical.
797 */
798 if (compacted)
799 kernel_size = get_xsaves_size_no_independent();
685 else800 else
686 possible_xstate_size = xsave_size;801 kernel_size = user_size;
802
803 kernel_default_size =
804 xstate_calculate_size(fpu_kernel_cfg.default_features, compacted);
687 805
688 /* Ensure we have the space to store all enabled: */806 /* Ensure we have the space to store all default enabled features. */
689 if (!is_supported_xstate_size(possible_xstate_size))807 if (!is_supported_xstate_size(kernel_default_size))
690 return -EINVAL;808 return -EINVAL;
691 809
692 /*810 if (!paranoid_xstate_size_valid(kernel_size))
693 * The size is OK, we are definitely going to use xsave,811 return -EINVAL;
694 * make it known to the world that we need more space.812
695 */813 fpu_kernel_cfg.max_size = kernel_size;
696 fpu_kernel_xstate_size = possible_xstate_size;814 fpu_user_cfg.max_size = user_size;
697 do_extra_xstate_size_checks();815
816 fpu_kernel_cfg.default_size = kernel_default_size;
817 fpu_user_cfg.default_size =
818 xstate_calculate_size(fpu_user_cfg.default_features, false);
698 819
699 /*
700 * User space is always in standard format.
701 */
702 fpu_user_xstate_size = xsave_size;
703 return 0;820 return 0;
704}821}
705 822
@@ -707,28 +824,38 @@ static int __init init_xstate_size(void) · 1 unmodified line
707 * We enabled the XSAVE hardware, but something went wrong and824 * We enabled the XSAVE hardware, but something went wrong and
708 * we can not use it. Disable it.825 * we can not use it. Disable it.
709 */826 */
710static void fpu__init_disable_system_xstate(void)827static void __init fpu__init_disable_system_xstate(unsigned int legacy_size)
711{828{
712 xfeatures_mask_all = 0;829 fpu_kernel_cfg.max_features = 0;
713 cr4_clear_bits(X86_CR4_OSXSAVE);830 cr4_clear_bits(X86_CR4_OSXSAVE);
714 setup_clear_cpu_cap(X86_FEATURE_XSAVE);831 setup_clear_cpu_cap(X86_FEATURE_XSAVE);
832
833 /* Restore the legacy size.*/
834 fpu_kernel_cfg.max_size = legacy_size;
835 fpu_kernel_cfg.default_size = legacy_size;
836 fpu_user_cfg.max_size = legacy_size;
837 fpu_user_cfg.default_size = legacy_size;
838
839 /*
840 * Prevent enabling the static branch which enables writes to the
841 * XFD MSR.
842 */
843 init_fpstate.xfd = 0;
844
845 fpstate_reset(&current->thread.fpu);
715}846}
716 847
717/*848/*
718 * Enable and initialize the xsave feature.849 * Enable and initialize the xsave feature.
719 * Called once per system bootup.850 * Called once per system bootup.
720 */851 */
721void __init fpu__init_system_xstate(void)852void __init fpu__init_system_xstate(unsigned int legacy_size)
722{853{
723 unsigned int eax, ebx, ecx, edx;854 unsigned int eax, ebx, ecx, edx;
724 static int on_boot_cpu __initdata = 1;
725 u64 xfeatures;855 u64 xfeatures;
726 int err;856 int err;
727 int i;857 int i;
728 858
729 WARN_ON_FPU(!on_boot_cpu);
730 on_boot_cpu = 0;
731
732 if (!boot_cpu_has(X86_FEATURE_FPU)) {859 if (!boot_cpu_has(X86_FEATURE_FPU)) {
733 pr_info("x86/fpu: No FPU detected\n");860 pr_info("x86/fpu: No FPU detected\n");
734 return;861 return;
@@ -749,22 +876,22 @@ void __init fpu__init_system_xstate(void) · 14 unmodified lines
749 * Find user xstates supported by the processor.876 * Find user xstates supported by the processor.
750 */877 */
751 cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);878 cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);
752 xfeatures_mask_all = eax + ((u64)edx << 32);879 fpu_kernel_cfg.max_features = eax + ((u64)edx << 32);
753 880
754 /*881 /*
755 * Find supervisor xstates supported by the processor.882 * Find supervisor xstates supported by the processor.
756 */883 */
757 cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx);884 cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx);
758 xfeatures_mask_all |= ecx + ((u64)edx << 32);885 fpu_kernel_cfg.max_features |= ecx + ((u64)edx << 32);
759 886
760 if ((xfeatures_mask_uabi() & XFEATURE_MASK_FPSSE) != XFEATURE_MASK_FPSSE) {887 if ((fpu_kernel_cfg.max_features & XFEATURE_MASK_FPSSE) != XFEATURE_MASK_FPSSE) {
761 /*888 /*
762 * This indicates that something really unexpected happened889 * This indicates that something really unexpected happened
763 * with the enumeration. Disable XSAVE and try to continue890 * with the enumeration. Disable XSAVE and try to continue
764 * booting without it. This is too early to BUG().891 * booting without it. This is too early to BUG().
765 */892 */
766 pr_err("x86/fpu: FP/SSE not present amongst the CPU's xstate features: 0x%llx.\n",893 pr_err("x86/fpu: FP/SSE not present amongst the CPU's xstate features: 0x%llx.\n",
767 xfeatures_mask_all);894 fpu_kernel_cfg.max_features);
768 goto out_disable;895 goto out_disable;
769 }896 }
770 897
@@ -772,15 +899,39 @@ void __init fpu__init_system_xstate(void) · 1 unmodified line
772 * Clear XSAVE features that are disabled in the normal CPUID.899 * Clear XSAVE features that are disabled in the normal CPUID.
773 */900 */
774 for (i = 0; i < ARRAY_SIZE(xsave_cpuid_features); i++) {901 for (i = 0; i < ARRAY_SIZE(xsave_cpuid_features); i++) {
775 if (!boot_cpu_has(xsave_cpuid_features[i]))902 unsigned short cid = xsave_cpuid_features[i];
776 xfeatures_mask_all &= ~BIT_ULL(i);903
904 /* Careful: X86_FEATURE_FPU is 0! */
905 if ((i != XFEATURE_FP && !cid) || !boot_cpu_has(cid))
906 fpu_kernel_cfg.max_features &= ~BIT_ULL(i);
777 }907 }
778 908
779 xfeatures_mask_all &= XFEATURE_MASK_USER_SUPPORTED |909 if (!cpu_feature_enabled(X86_FEATURE_XFD))
910 fpu_kernel_cfg.max_features &= ~XFEATURE_MASK_USER_DYNAMIC;
911
912 fpu_kernel_cfg.max_features &= XFEATURE_MASK_USER_SUPPORTED |
780 XFEATURE_MASK_SUPERVISOR_SUPPORTED;913 XFEATURE_MASK_SUPERVISOR_SUPPORTED;
781 914
915 fpu_user_cfg.max_features = fpu_kernel_cfg.max_features;
916 fpu_user_cfg.max_features &= XFEATURE_MASK_USER_SUPPORTED;
917
918 /* Clean out dynamic features from default */
919 fpu_kernel_cfg.default_features = fpu_kernel_cfg.max_features;
920 fpu_kernel_cfg.default_features &= ~XFEATURE_MASK_USER_DYNAMIC;
921
922 fpu_user_cfg.default_features = fpu_user_cfg.max_features;
923 fpu_user_cfg.default_features &= ~XFEATURE_MASK_USER_DYNAMIC;
924
782 /* Store it for paranoia check at the end */925 /* Store it for paranoia check at the end */
783 xfeatures = xfeatures_mask_all;926 xfeatures = fpu_kernel_cfg.max_features;
927
928 /*
929 * Initialize the default XFD state in initfp_state and enable the
930 * dynamic sizing mechanism if dynamic states are available. The
931 * static key cannot be enabled here because this runs before
932 * jump_label_init(). This is delayed to an initcall.
933 */
934 init_fpstate.xfd = fpu_user_cfg.max_features & XFEATURE_MASK_USER_DYNAMIC;
784 935
785 /* Enable xstate instructions to be able to continue with initialization: */936 /* Enable xstate instructions to be able to continue with initialization: */
786 fpu__init_cpu_xstate();937 fpu__init_cpu_xstate();
@@ -788,13 +939,16 @@ void __init fpu__init_system_xstate(void) · 1 unmodified line
788 if (err)939 if (err)
789 goto out_disable;940 goto out_disable;
790 941
942 /* Reset the state for the current task */
943 fpstate_reset(&current->thread.fpu);
944
791 /*945 /*
792 * Update info used for ptrace frames; use standard-format size and no946 * Update info used for ptrace frames; use standard-format size and no
793 * supervisor xstates:947 * supervisor xstates:
794 */948 */
795 update_regset_xstate_info(fpu_user_xstate_size, xfeatures_mask_uabi());949 update_regset_xstate_info(fpu_user_cfg.max_size,
950 fpu_user_cfg.max_features);
796 951
797 fpu__init_prepare_fx_sw_frame();
798 setup_init_fpu_buf();952 setup_init_fpu_buf();
799 setup_xstate_comp_offsets();953 setup_xstate_comp_offsets();
800 setup_supervisor_only_offsets();954 setup_supervisor_only_offsets();
@@ -803,22 +957,22 @@ void __init fpu__init_system_xstate(void) · 2 unmodified lines
803 * Paranoia check whether something in the setup modified the957 * Paranoia check whether something in the setup modified the
804 * xfeatures mask.958 * xfeatures mask.
805 */959 */
806 if (xfeatures != xfeatures_mask_all) {960 if (xfeatures != fpu_kernel_cfg.max_features) {
807 pr_err("x86/fpu: xfeatures modified from 0x%016llx to 0x%016llx during init, disabling XSAVE\n",961 pr_err("x86/fpu: xfeatures modified from 0x%016llx to 0x%016llx during init, disabling XSAVE\n",
808 xfeatures, xfeatures_mask_all);962 xfeatures, fpu_kernel_cfg.max_features);
809 goto out_disable;963 goto out_disable;
810 }964 }
811 965
812 print_xstate_offset_size();966 print_xstate_offset_size();
813 pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n",967 pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n",
814 xfeatures_mask_all,968 fpu_kernel_cfg.max_features,
815 fpu_kernel_xstate_size,969 fpu_kernel_cfg.max_size,
816 boot_cpu_has(X86_FEATURE_XSAVES) ? "compacted" : "standard");970 boot_cpu_has(X86_FEATURE_XSAVES) ? "compacted" : "standard");
817 return;971 return;
818 972
819out_disable:973out_disable:
820 /* something went wrong, try to boot without any XSAVE support */974 /* something went wrong, try to boot without any XSAVE support */
821 fpu__init_disable_system_xstate();975 fpu__init_disable_system_xstate(legacy_size);
822}976}
823 977
824/*978/*
@@ -830,7 +984,7 @@ void fpu__resume_cpu(void) · 5 unmodified lines
830 * Restore XCR0 on xsave capable CPUs:984 * Restore XCR0 on xsave capable CPUs:
831 */985 */
832 if (cpu_feature_enabled(X86_FEATURE_XSAVE))986 if (cpu_feature_enabled(X86_FEATURE_XSAVE))
833 xsetbv(XCR_XFEATURE_ENABLED_MASK, xfeatures_mask_uabi());987 xsetbv(XCR_XFEATURE_ENABLED_MASK, fpu_user_cfg.max_features);
834 988
835 /*989 /*
836 * Restore IA32_XSS. The same CPUID bit enumerates support990 * Restore IA32_XSS. The same CPUID bit enumerates support
@@ -840,6 +994,9 @@ void fpu__resume_cpu(void) · 3 unmodified lines
840 wrmsrl(MSR_IA32_XSS, xfeatures_mask_supervisor() |994 wrmsrl(MSR_IA32_XSS, xfeatures_mask_supervisor() |
841 xfeatures_mask_independent());995 xfeatures_mask_independent());
842 }996 }
997
998 if (fpu_state_size_dynamic())
999 wrmsrl(MSR_IA32_XFD, current->thread.fpu.fpstate->xfd);
843}1000}
844 1001
845/*1002/*
@@ -886,7 +1043,7 @@ void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr) · 40 unmodified lines
886 * We should not ever be requesting features that we1043 * We should not ever be requesting features that we
887 * have not enabled.1044 * have not enabled.
888 */1045 */
889 WARN_ONCE(!(xfeatures_mask_all & BIT_ULL(xfeature_nr)),1046 WARN_ONCE(!(fpu_kernel_cfg.max_features & BIT_ULL(xfeature_nr)),
890 "get of unsupported state");1047 "get of unsupported state");
891 /*1048 /*
892 * This assumes the last 'xsave*' instruction to1049 * This assumes the last 'xsave*' instruction to
@@ -904,7 +1061,6 @@ void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr) · 11 unmodified lines
904 1061
905 return __raw_xsave_addr(xsave, xfeature_nr);1062 return __raw_xsave_addr(xsave, xfeature_nr);
906}1063}
907EXPORT_SYMBOL_GPL(get_xsave_addr);
908 1064
909#ifdef CONFIG_ARCH_HAS_PKEYS1065#ifdef CONFIG_ARCH_HAS_PKEYS
910 1066
@@ -961,9 +1117,10 @@ static void copy_feature(bool from_xstate, struct membuf *to, void *xstate, · 50 unmodified lines
961}1117}
962 1118
963/**1119/**
964 * copy_xstate_to_uabi_buf - Copy kernel saved xstate to a UABI buffer1120 * __copy_xstate_to_uabi_buf - Copy kernel saved xstate to a UABI buffer
965 * @to: membuf descriptor1121 * @to: membuf descriptor
966 * @tsk: The task from which to copy the saved xstate1122 * @fpstate: The fpstate buffer from which to copy
1123 * @pkru_val: The PKRU value to store in the PKRU component
967 * @copy_mode: The requested copy mode1124 * @copy_mode: The requested copy mode
968 *1125 *
969 * Converts from kernel XSAVE or XSAVES compacted format to UABI conforming1126 * Converts from kernel XSAVE or XSAVES compacted format to UABI conforming
@@ -972,14 +1129,15 @@ static void copy_feature(bool from_xstate, struct membuf *to, void *xstate, · 2 unmodified lines
972 *1129 *
973 * It supports partial copy but @to.pos always starts from zero.1130 * It supports partial copy but @to.pos always starts from zero.
974 */1131 */
975void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk,1132void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate,
976 enum xstate_copy_mode copy_mode)1133 u32 pkru_val, enum xstate_copy_mode copy_mode)
977{1134{
978 const unsigned int off_mxcsr = offsetof(struct fxregs_state, mxcsr);1135 const unsigned int off_mxcsr = offsetof(struct fxregs_state, mxcsr);
979 struct xregs_state *xsave = &tsk->thread.fpu.state.xsave;1136 struct xregs_state *xinit = &init_fpstate.regs.xsave;
980 struct xregs_state *xinit = &init_fpstate.xsave;1137 struct xregs_state *xsave = &fpstate->regs.xsave;
981 struct xstate_header header;1138 struct xstate_header header;
982 unsigned int zerofrom;1139 unsigned int zerofrom;
1140 u64 mask;
983 int i;1141 int i;
984 1142
985 memset(&header, 0, sizeof(header));1143 memset(&header, 0, sizeof(header));
@@ -996,7 +1154,7 @@ void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk, · 10 unmodified lines
996 break;1154 break;
997 1155
998 case XSTATE_COPY_XSAVE:1156 case XSTATE_COPY_XSAVE:
999 header.xfeatures &= xfeatures_mask_uabi();1157 header.xfeatures &= fpstate->user_xfeatures;
1000 break;1158 break;
1001 }1159 }
1002 1160
@@ -1033,17 +1191,15 @@ void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk, · 30 unmodified lines
1033 1191
1034 zerofrom = offsetof(struct xregs_state, extended_state_area);1192 zerofrom = offsetof(struct xregs_state, extended_state_area);
1035 1193
1036 for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {1194 /*
1037 /*1195 * The ptrace buffer is in non-compacted XSAVE format. In
1038 * The ptrace buffer is in non-compacted XSAVE format.1196 * non-compacted format disabled features still occupy state space,
1039 * In non-compacted format disabled features still occupy1197 * but there is no state to copy from in the compacted
1040 * state space, but there is no state to copy from in the1198 * init_fpstate. The gap tracking will zero these states.
1041 * compacted init_fpstate. The gap tracking will zero this1199 */
1042 * later.1200 mask = fpstate->user_xfeatures;
1043 */
1044 if (!(xfeatures_mask_uabi() & BIT_ULL(i)))
1045 continue;
1046 1201
1202 for_each_extended_xfeature(i, mask) {
1047 /*1203 /*
1048 * If there was a feature or alignment gap, zero the space1204 * If there was a feature or alignment gap, zero the space
1049 * in the destination buffer.1205 * in the destination buffer.
@@ -1055,10 +1211,9 @@ void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk, · 5 unmodified lines
1055 struct pkru_state pkru = {0};1211 struct pkru_state pkru = {0};
1056 /*1212 /*
1057 * PKRU is not necessarily up to date in the1213 * PKRU is not necessarily up to date in the
1058 * thread's XSAVE buffer. Fill this part from the1214 * XSAVE buffer. Use the provided value.
1059 * per-thread storage.
1060 */1215 */
1061 pkru.pkru = tsk->thread.pkru;1216 pkru.pkru = pkru_val;
1062 membuf_write(&to, &pkru, sizeof(pkru));1217 membuf_write(&to, &pkru, sizeof(pkru));
1063 } else {1218 } else {
1064 copy_feature(header.xfeatures & BIT_ULL(i), &to,1219 copy_feature(header.xfeatures & BIT_ULL(i), &to,
@@ -1078,6 +1233,25 @@ out: · 13 unmodified lines
1078 membuf_zero(&to, to.left);1233 membuf_zero(&to, to.left);
1079}1234}
1080 1235
1236/**
1237 * copy_xstate_to_uabi_buf - Copy kernel saved xstate to a UABI buffer
1238 * @to: membuf descriptor
1239 * @tsk: The task from which to copy the saved xstate
1240 * @copy_mode: The requested copy mode
1241 *
1242 * Converts from kernel XSAVE or XSAVES compacted format to UABI conforming
1243 * format, i.e. from the kernel internal hardware dependent storage format
1244 * to the requested @mode. UABI XSTATE is always uncompacted!
1245 *
1246 * It supports partial copy but @to.pos always starts from zero.
1247 */
1248void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk,
1249 enum xstate_copy_mode copy_mode)
1250{
1251 __copy_xstate_to_uabi_buf(to, tsk->thread.fpu.fpstate,
1252 tsk->thread.pkru, copy_mode);
1253}
1254
1081static int copy_from_buffer(void *dst, unsigned int offset, unsigned int size,1255static int copy_from_buffer(void *dst, unsigned int offset, unsigned int size,
1082 const void *kbuf, const void __user *ubuf)1256 const void *kbuf, const void __user *ubuf)
1083{1257{
@@ -1091,9 +1265,10 @@ static int copy_from_buffer(void *dst, unsigned int offset, unsigned int size, · 7 unmodified lines
1091}1265}
1092 1266
1093 1267
1094static int copy_uabi_to_xstate(struct xregs_state *xsave, const void *kbuf,1268static int copy_uabi_to_xstate(struct fpstate *fpstate, const void *kbuf,
1095 const void __user *ubuf)1269 const void __user *ubuf)
1096{1270{
1271 struct xregs_state *xsave = &fpstate->regs.xsave;
1097 unsigned int offset, size;1272 unsigned int offset, size;
1098 struct xstate_header hdr;1273 struct xstate_header hdr;
1099 u64 mask;1274 u64 mask;
@@ -1103,7 +1278,7 @@ static int copy_uabi_to_xstate(struct xregs_state *xsave, const void *kbuf, · 3 unmodified lines
1103 if (copy_from_buffer(&hdr, offset, sizeof(hdr), kbuf, ubuf))1278 if (copy_from_buffer(&hdr, offset, sizeof(hdr), kbuf, ubuf))
1104 return -EFAULT;1279 return -EFAULT;
1105 1280
1106 if (validate_user_xstate_header(&hdr))1281 if (validate_user_xstate_header(&hdr, fpstate))
1107 return -EINVAL;1282 return -EINVAL;
1108 1283
1109 /* Validate MXCSR when any of the related features is in use */1284 /* Validate MXCSR when any of the related features is in use */
@@ -1156,12 +1331,11 @@ static int copy_uabi_to_xstate(struct xregs_state *xsave, const void *kbuf, · 46 unmodified lines
1156 1331
1157/*1332/*
1158 * Convert from a ptrace standard-format kernel buffer to kernel XSAVE[S]1333 * Convert from a ptrace standard-format kernel buffer to kernel XSAVE[S]
1159 * format and copy to the target thread. This is called from1334 * format and copy to the target thread. Used by ptrace and KVM.
1160 * xstateregs_set().
1161 */1335 */
1162int copy_uabi_from_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf)1336int copy_uabi_from_kernel_to_xstate(struct fpstate *fpstate, const void *kbuf)
1163{1337{
1164 return copy_uabi_to_xstate(xsave, kbuf, NULL);1338 return copy_uabi_to_xstate(fpstate, kbuf, NULL);
1165}1339}
1166 1340
1167/*1341/*
@@ -1169,26 +1343,20 @@ int copy_uabi_from_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf) · 1 unmodified line
1169 * XSAVE[S] format and copy to the target thread. This is called from the1343 * XSAVE[S] format and copy to the target thread. This is called from the
1170 * sigreturn() and rt_sigreturn() system calls.1344 * sigreturn() and rt_sigreturn() system calls.
1171 */1345 */
1172int copy_sigframe_from_user_to_xstate(struct xregs_state *xsave,1346int copy_sigframe_from_user_to_xstate(struct fpstate *fpstate,
1173 const void __user *ubuf)1347 const void __user *ubuf)
1174{1348{
1175 return copy_uabi_to_xstate(xsave, NULL, ubuf);1349 return copy_uabi_to_xstate(fpstate, NULL, ubuf);
1176}1350}
1177 1351
1178static bool validate_xsaves_xrstors(u64 mask)1352static bool validate_independent_components(u64 mask)
1179{1353{
1180 u64 xchk;1354 u64 xchk;
1181 1355
1182 if (WARN_ON_FPU(!cpu_feature_enabled(X86_FEATURE_XSAVES)))1356 if (WARN_ON_FPU(!cpu_feature_enabled(X86_FEATURE_XSAVES)))
1183 return false;1357 return false;
1184 /*1358
1185 * Validate that this is either a task->fpstate related component1359 xchk = ~xfeatures_mask_independent();
1186 * subset or an independent one.
1187 */
1188 if (mask & xfeatures_mask_independent())
1189 xchk = ~xfeatures_mask_independent();
1190 else
1191 xchk = ~xfeatures_mask_all;
1192 1360
1193 if (WARN_ON_ONCE(!mask || mask & xchk))1361 if (WARN_ON_ONCE(!mask || mask & xchk))
1194 return false;1362 return false;
@@ -1206,14 +1374,13 @@ static bool validate_xsaves_xrstors(u64 mask) · 11 unmodified lines
1206 * buffer should be zeroed otherwise a consecutive XRSTORS from that buffer1374 * buffer should be zeroed otherwise a consecutive XRSTORS from that buffer
1207 * can #GP.1375 * can #GP.
1208 *1376 *
1209 * The feature mask must either be a subset of the independent features or1377 * The feature mask must be a subset of the independent features.
1210 * a subset of the task->fpstate related features.
1211 */1378 */
1212void xsaves(struct xregs_state *xstate, u64 mask)1379void xsaves(struct xregs_state *xstate, u64 mask)
1213{1380{
1214 int err;1381 int err;
1215 1382
1216 if (!validate_xsaves_xrstors(mask))1383 if (!validate_independent_components(mask))
1217 return;1384 return;
1218 1385
1219 XSTATE_OP(XSAVES, xstate, (u32)mask, (u32)(mask >> 32), err);1386 XSTATE_OP(XSAVES, xstate, (u32)mask, (u32)(mask >> 32), err);
@@ -1231,20 +1398,379 @@ void xsaves(struct xregs_state *xstate, u64 mask) · 11 unmodified lines
1231 * Proper usage is to restore the state which was saved with1398 * Proper usage is to restore the state which was saved with
1232 * xsaves() into @xstate.1399 * xsaves() into @xstate.
1233 *1400 *
1234 * The feature mask must either be a subset of the independent features or1401 * The feature mask must be a subset of the independent features.
1235 * a subset of the task->fpstate related features.
1236 */1402 */
1237void xrstors(struct xregs_state *xstate, u64 mask)1403void xrstors(struct xregs_state *xstate, u64 mask)
1238{1404{
1239 int err;1405 int err;
1240 1406
1241 if (!validate_xsaves_xrstors(mask))1407 if (!validate_independent_components(mask))
1242 return;1408 return;
1243 1409
1244 XSTATE_OP(XRSTORS, xstate, (u32)mask, (u32)(mask >> 32), err);1410 XSTATE_OP(XRSTORS, xstate, (u32)mask, (u32)(mask >> 32), err);
1245 WARN_ON_ONCE(err);1411 WARN_ON_ONCE(err);
1246}1412}
1247 1413
1414#if IS_ENABLED(CONFIG_KVM)
1415void fpstate_clear_xstate_component(struct fpstate *fps, unsigned int xfeature)
1416{
1417 void *addr = get_xsave_addr(&fps->regs.xsave, xfeature);
1418
1419 if (addr)
1420 memset(addr, 0, xstate_sizes[xfeature]);
1421}
1422EXPORT_SYMBOL_GPL(fpstate_clear_xstate_component);
1423#endif
1424
1425#ifdef CONFIG_X86_64
1426
1427#ifdef CONFIG_X86_DEBUG_FPU
1428/*
1429 * Ensure that a subsequent XSAVE* or XRSTOR* instruction with RFBM=@mask
1430 * can safely operate on the @fpstate buffer.
1431 */
1432static bool xstate_op_valid(struct fpstate *fpstate, u64 mask, bool rstor)
1433{
1434 u64 xfd = __this_cpu_read(xfd_state);
1435
1436 if (fpstate->xfd == xfd)
1437 return true;
1438
1439 /*
1440 * The XFD MSR does not match fpstate->xfd. That's invalid when
1441 * the passed in fpstate is current's fpstate.
1442 */
1443 if (fpstate->xfd == current->thread.fpu.fpstate->xfd)
1444 return false;
1445
1446 /*
1447 * XRSTOR(S) from init_fpstate are always correct as it will just
1448 * bring all components into init state and not read from the
1449 * buffer. XSAVE(S) raises #PF after init.
1450 */
1451 if (fpstate == &init_fpstate)
1452 return rstor;
1453
1454 /*
1455 * XSAVE(S): clone(), fpu_swap_kvm_fpu()
1456 * XRSTORS(S): fpu_swap_kvm_fpu()
1457 */
1458
1459 /*
1460 * No XSAVE/XRSTOR instructions (except XSAVE itself) touch
1461 * the buffer area for XFD-disabled state components.
1462 */
1463 mask &= ~xfd;
1464
1465 /*
1466 * Remove features which are valid in fpstate. They
1467 * have space allocated in fpstate.
1468 */
1469 mask &= ~fpstate->xfeatures;
1470
1471 /*
1472 * Any remaining state components in 'mask' might be written
1473 * by XSAVE/XRSTOR. Fail validation it found.
1474 */
1475 return !mask;
1476}
1477
1478void xfd_validate_state(struct fpstate *fpstate, u64 mask, bool rstor)
1479{
1480 WARN_ON_ONCE(!xstate_op_valid(fpstate, mask, rstor));
1481}
1482#endif /* CONFIG_X86_DEBUG_FPU */
1483
1484static int __init xfd_update_static_branch(void)
1485{
1486 /*
1487 * If init_fpstate.xfd has bits set then dynamic features are
1488 * available and the dynamic sizing must be enabled.
1489 */
1490 if (init_fpstate.xfd)
1491 static_branch_enable(&__fpu_state_size_dynamic);
1492 return 0;
1493}
1494arch_initcall(xfd_update_static_branch)
1495
1496void fpstate_free(struct fpu *fpu)
1497{
1498 if (fpu->fpstate && fpu->fpstate != &fpu->__fpstate)
1499 vfree(fpu->fpstate);
1500}
1501
1502/**
1503 * fpu_install_fpstate - Update the active fpstate in the FPU
1504 *
1505 * @fpu: A struct fpu * pointer
1506 * @newfps: A struct fpstate * pointer
1507 *
1508 * Returns: A null pointer if the last active fpstate is the embedded
1509 * one or the new fpstate is already installed;
1510 * otherwise, a pointer to the old fpstate which has to
1511 * be freed by the caller.
1512 */
1513static struct fpstate *fpu_install_fpstate(struct fpu *fpu,
1514 struct fpstate *newfps)
1515{
1516 struct fpstate *oldfps = fpu->fpstate;
1517
1518 if (fpu->fpstate == newfps)
1519 return NULL;
1520
1521 fpu->fpstate = newfps;
1522 return oldfps != &fpu->__fpstate ? oldfps : NULL;
1523}
1524
1525/**
1526 * fpstate_realloc - Reallocate struct fpstate for the requested new features
1527 *
1528 * @xfeatures: A bitmap of xstate features which extend the enabled features
1529 * of that task
1530 * @ksize: The required size for the kernel buffer
1531 * @usize: The required size for user space buffers
1532 *
1533 * Note vs. vmalloc(): If the task with a vzalloc()-allocated buffer
1534 * terminates quickly, vfree()-induced IPIs may be a concern, but tasks
1535 * with large states are likely to live longer.
1536 *
1537 * Returns: 0 on success, -ENOMEM on allocation error.
1538 */
1539static int fpstate_realloc(u64 xfeatures, unsigned int ksize,
1540 unsigned int usize)
1541{
1542 struct fpu *fpu = &current->thread.fpu;
1543 struct fpstate *curfps, *newfps = NULL;
1544 unsigned int fpsize;
1545
1546 curfps = fpu->fpstate;
1547 fpsize = ksize + ALIGN(offsetof(struct fpstate, regs), 64);
1548
1549 newfps = vzalloc(fpsize);
1550 if (!newfps)
1551 return -ENOMEM;
1552 newfps->size = ksize;
1553 newfps->user_size = usize;
1554 newfps->is_valloc = true;
1555
1556 fpregs_lock();
1557 /*
1558 * Ensure that the current state is in the registers before
1559 * swapping fpstate as that might invalidate it due to layout
1560 * changes.
1561 */
1562 if (test_thread_flag(TIF_NEED_FPU_LOAD))
1563 fpregs_restore_userregs();
1564
1565 newfps->xfeatures = curfps->xfeatures | xfeatures;
1566 newfps->user_xfeatures = curfps->user_xfeatures | xfeatures;
1567 newfps->xfd = curfps->xfd & ~xfeatures;
1568
1569 curfps = fpu_install_fpstate(fpu, newfps);
1570
1571 /* Do the final updates within the locked region */
1572 xstate_init_xcomp_bv(&newfps->regs.xsave, newfps->xfeatures);
1573 xfd_update_state(newfps);
1574
1575 fpregs_unlock();
1576
1577 vfree(curfps);
1578 return 0;
1579}
1580
1581static int validate_sigaltstack(unsigned int usize)
1582{
1583 struct task_struct *thread, *leader = current->group_leader;
1584 unsigned long framesize = get_sigframe_size();
1585
1586 lockdep_assert_held(&current->sighand->siglock);
1587
1588 /* get_sigframe_size() is based on fpu_user_cfg.max_size */
1589 framesize -= fpu_user_cfg.max_size;
1590 framesize += usize;
1591 for_each_thread(leader, thread) {
1592 if (thread->sas_ss_size && thread->sas_ss_size < framesize)
1593 return -ENOSPC;
1594 }
1595 return 0;
1596}
1597
1598static int __xstate_request_perm(u64 permitted, u64 requested)
1599{
1600 /*
1601 * This deliberately does not exclude !XSAVES as we still might
1602 * decide to optionally context switch XCR0 or talk the silicon
1603 * vendors into extending XFD for the pre AMX states, especially
1604 * AVX512.
1605 */
1606 bool compacted = cpu_feature_enabled(X86_FEATURE_XSAVES);
1607 struct fpu *fpu = &current->group_leader->thread.fpu;
1608 unsigned int ksize, usize;
1609 u64 mask;
1610 int ret;
1611
1612 /* Check whether fully enabled */
1613 if ((permitted & requested) == requested)
1614 return 0;
1615
1616 /* Calculate the resulting kernel state size */
1617 mask = permitted | requested;
1618 ksize = xstate_calculate_size(mask, compacted);
1619
1620 /* Calculate the resulting user state size */
1621 mask &= XFEATURE_MASK_USER_SUPPORTED;
1622 usize = xstate_calculate_size(mask, false);
1623
1624 ret = validate_sigaltstack(usize);
1625 if (ret)
1626 return ret;
1627
1628 /* Pairs with the READ_ONCE() in xstate_get_group_perm() */
1629 WRITE_ONCE(fpu->perm.__state_perm, requested);
1630 /* Protected by sighand lock */
1631 fpu->perm.__state_size = ksize;
1632 fpu->perm.__user_state_size = usize;
1633 return ret;
1634}
1635
1636/*
1637 * Permissions array to map facilities with more than one component
1638 */
1639static const u64 xstate_prctl_req[XFEATURE_MAX] = {
1640 [XFEATURE_XTILE_DATA] = XFEATURE_MASK_XTILE_DATA,
1641};
1642
1643static int xstate_request_perm(unsigned long idx)
1644{
1645 u64 permitted, requested;
1646 int ret;
1647
1648 if (idx >= XFEATURE_MAX)
1649 return -EINVAL;
1650
1651 /*
1652 * Look up the facility mask which can require more than
1653 * one xstate component.
1654 */
1655 idx = array_index_nospec(idx, ARRAY_SIZE(xstate_prctl_req));
1656 requested = xstate_prctl_req[idx];
1657 if (!requested)
1658 return -EOPNOTSUPP;
1659
1660 if ((fpu_user_cfg.max_features & requested) != requested)
1661 return -EOPNOTSUPP;
1662
1663 /* Lockless quick check */
1664 permitted = xstate_get_host_group_perm();
1665 if ((permitted & requested) == requested)
1666 return 0;
1667
1668 /* Protect against concurrent modifications */
1669 spin_lock_irq(&current->sighand->siglock);
1670 permitted = xstate_get_host_group_perm();
1671 ret = __xstate_request_perm(permitted, requested);
1672 spin_unlock_irq(&current->sighand->siglock);
1673 return ret;
1674}
1675
1676int xfd_enable_feature(u64 xfd_err)
1677{
1678 u64 xfd_event = xfd_err & XFEATURE_MASK_USER_DYNAMIC;
1679 unsigned int ksize, usize;
1680 struct fpu *fpu;
1681
1682 if (!xfd_event) {
1683 pr_err_once("XFD: Invalid xfd error: %016llx\n", xfd_err);
1684 return 0;
1685 }
1686
1687 /* Protect against concurrent modifications */
1688 spin_lock_irq(&current->sighand->siglock);
1689
1690 /* If not permitted let it die */
1691 if ((xstate_get_host_group_perm() & xfd_event) != xfd_event) {
1692 spin_unlock_irq(&current->sighand->siglock);
1693 return -EPERM;
1694 }
1695
1696 fpu = &current->group_leader->thread.fpu;
1697 ksize = fpu->perm.__state_size;
1698 usize = fpu->perm.__user_state_size;
1699 /*
1700 * The feature is permitted. State size is sufficient. Dropping
1701 * the lock is safe here even if more features are added from
1702 * another task, the retrieved buffer sizes are valid for the
1703 * currently requested feature(s).
1704 */
1705 spin_unlock_irq(&current->sighand->siglock);
1706
1707 /*
1708 * Try to allocate a new fpstate. If that fails there is no way
1709 * out.
1710 */
1711 if (fpstate_realloc(xfd_event, ksize, usize))
1712 return -EFAULT;
1713 return 0;
1714}
1715#else /* CONFIG_X86_64 */
1716static inline int xstate_request_perm(unsigned long idx)
1717{
1718 return -EPERM;
1719}
1720#endif /* !CONFIG_X86_64 */
1721
1722/**
1723 * fpu_xstate_prctl - xstate permission operations
1724 * @tsk: Redundant pointer to current
1725 * @option: A subfunction of arch_prctl()
1726 * @arg2: option argument
1727 * Return: 0 if successful; otherwise, an error code
1728 *
1729 * Option arguments:
1730 *
1731 * ARCH_GET_XCOMP_SUPP: Pointer to user space u64 to store the info
1732 * ARCH_GET_XCOMP_PERM: Pointer to user space u64 to store the info
1733 * ARCH_REQ_XCOMP_PERM: Facility number requested
1734 *
1735 * For facilities which require more than one XSTATE component, the request
1736 * must be the highest state component number related to that facility,
1737 * e.g. for AMX which requires XFEATURE_XTILE_CFG(17) and
1738 * XFEATURE_XTILE_DATA(18) this would be XFEATURE_XTILE_DATA(18).
1739 */
1740long fpu_xstate_prctl(struct task_struct *tsk, int option, unsigned long arg2)
1741{
1742 u64 __user *uptr = (u64 __user *)arg2;
1743 u64 permitted, supported;
1744 unsigned long idx = arg2;
1745
1746 if (tsk != current)
1747 return -EPERM;
1748
1749 switch (option) {
1750 case ARCH_GET_XCOMP_SUPP:
1751 supported = fpu_user_cfg.max_features | fpu_user_cfg.legacy_features;
1752 return put_user(supported, uptr);
1753
1754 case ARCH_GET_XCOMP_PERM:
1755 /*
1756 * Lockless snapshot as it can also change right after the
1757 * dropping the lock.
1758 */
1759 permitted = xstate_get_host_group_perm();
1760 permitted &= XFEATURE_MASK_USER_SUPPORTED;
1761 return put_user(permitted, uptr);
1762
1763 case ARCH_REQ_XCOMP_PERM:
1764 if (!IS_ENABLED(CONFIG_X86_64))
1765 return -EOPNOTSUPP;
1766
1767 return xstate_request_perm(idx);
1768
1769 default:
1770 return -EINVAL;
1771 }
1772}
1773
1248#ifdef CONFIG_PROC_PID_ARCH_STATUS1774#ifdef CONFIG_PROC_PID_ARCH_STATUS
1249/*1775/*
1250 * Report the amount of time elapsed in millisecond since last AVX5121776 * Report the amount of time elapsed in millisecond since last AVX512
arch/x86/kernel/fpu/xstate.h+278−0
@@ -0,0 +1,278 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __X86_KERNEL_FPU_XSTATE_H
3#define __X86_KERNEL_FPU_XSTATE_H
4
5#include <asm/cpufeature.h>
6#include <asm/fpu/xstate.h>
7
8#ifdef CONFIG_X86_64
9DECLARE_PER_CPU(u64, xfd_state);
10#endif
11
12static inline void xstate_init_xcomp_bv(struct xregs_state *xsave, u64 mask)
13{
14 /*
15 * XRSTORS requires these bits set in xcomp_bv, or it will
16 * trigger #GP:
17 */
18 if (cpu_feature_enabled(X86_FEATURE_XSAVES))
19 xsave->header.xcomp_bv = mask | XCOMP_BV_COMPACTED_FORMAT;
20}
21
22static inline u64 xstate_get_host_group_perm(void)
23{
24 /* Pairs with WRITE_ONCE() in xstate_request_perm() */
25 return READ_ONCE(current->group_leader->thread.fpu.perm.__state_perm);
26}
27
28enum xstate_copy_mode {
29 XSTATE_COPY_FP,
30 XSTATE_COPY_FX,
31 XSTATE_COPY_XSAVE,
32};
33
34struct membuf;
35extern void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate,
36 u32 pkru_val, enum xstate_copy_mode copy_mode);
37extern void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk,
38 enum xstate_copy_mode mode);
39extern int copy_uabi_from_kernel_to_xstate(struct fpstate *fpstate, const void *kbuf);
40extern int copy_sigframe_from_user_to_xstate(struct fpstate *fpstate, const void __user *ubuf);
41
42
43extern void fpu__init_cpu_xstate(void);
44extern void fpu__init_system_xstate(unsigned int legacy_size);
45
46extern void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr);
47
48static inline u64 xfeatures_mask_supervisor(void)
49{
50 return fpu_kernel_cfg.max_features & XFEATURE_MASK_SUPERVISOR_SUPPORTED;
51}
52
53static inline u64 xfeatures_mask_independent(void)
54{
55 if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR))
56 return XFEATURE_MASK_INDEPENDENT & ~XFEATURE_MASK_LBR;
57
58 return XFEATURE_MASK_INDEPENDENT;
59}
60
61/* XSAVE/XRSTOR wrapper functions */
62
63#ifdef CONFIG_X86_64
64#define REX_PREFIX "0x48, "
65#else
66#define REX_PREFIX
67#endif
68
69/* These macros all use (%edi)/(%rdi) as the single memory argument. */
70#define XSAVE ".byte " REX_PREFIX "0x0f,0xae,0x27"
71#define XSAVEOPT ".byte " REX_PREFIX "0x0f,0xae,0x37"
72#define XSAVES ".byte " REX_PREFIX "0x0f,0xc7,0x2f"
73#define XRSTOR ".byte " REX_PREFIX "0x0f,0xae,0x2f"
74#define XRSTORS ".byte " REX_PREFIX "0x0f,0xc7,0x1f"
75
76/*
77 * After this @err contains 0 on success or the trap number when the
78 * operation raises an exception.
79 */
80#define XSTATE_OP(op, st, lmask, hmask, err) \
81 asm volatile("1:" op "\n\t" \
82 "xor %[err], %[err]\n" \
83 "2:\n\t" \
84 _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FAULT_MCE_SAFE) \
85 : [err] "=a" (err) \
86 : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \
87 : "memory")
88
89/*
90 * If XSAVES is enabled, it replaces XSAVEOPT because it supports a compact
91 * format and supervisor states in addition to modified optimization in
92 * XSAVEOPT.
93 *
94 * Otherwise, if XSAVEOPT is enabled, XSAVEOPT replaces XSAVE because XSAVEOPT
95 * supports modified optimization which is not supported by XSAVE.
96 *
97 * We use XSAVE as a fallback.
98 *
99 * The 661 label is defined in the ALTERNATIVE* macros as the address of the
100 * original instruction which gets replaced. We need to use it here as the
101 * address of the instruction where we might get an exception at.
102 */
103#define XSTATE_XSAVE(st, lmask, hmask, err) \
104 asm volatile(ALTERNATIVE_2(XSAVE, \
105 XSAVEOPT, X86_FEATURE_XSAVEOPT, \
106 XSAVES, X86_FEATURE_XSAVES) \
107 "\n" \
108 "xor %[err], %[err]\n" \
109 "3:\n" \
110 ".pushsection .fixup,\"ax\"\n" \
111 "4: movl $-2, %[err]\n" \
112 "jmp 3b\n" \
113 ".popsection\n" \
114 _ASM_EXTABLE(661b, 4b) \
115 : [err] "=r" (err) \
116 : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \
117 : "memory")
118
119/*
120 * Use XRSTORS to restore context if it is enabled. XRSTORS supports compact
121 * XSAVE area format.
122 */
123#define XSTATE_XRESTORE(st, lmask, hmask) \
124 asm volatile(ALTERNATIVE(XRSTOR, \
125 XRSTORS, X86_FEATURE_XSAVES) \
126 "\n" \
127 "3:\n" \
128 _ASM_EXTABLE_TYPE(661b, 3b, EX_TYPE_FPU_RESTORE) \
129 : \
130 : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \
131 : "memory")
132
133#if defined(CONFIG_X86_64) && defined(CONFIG_X86_DEBUG_FPU)
134extern void xfd_validate_state(struct fpstate *fpstate, u64 mask, bool rstor);
135#else
136static inline void xfd_validate_state(struct fpstate *fpstate, u64 mask, bool rstor) { }
137#endif
138
139#ifdef CONFIG_X86_64
140static inline void xfd_update_state(struct fpstate *fpstate)
141{
142 if (fpu_state_size_dynamic()) {
143 u64 xfd = fpstate->xfd;
144
145 if (__this_cpu_read(xfd_state) != xfd) {
146 wrmsrl(MSR_IA32_XFD, xfd);
147 __this_cpu_write(xfd_state, xfd);
148 }
149 }
150}
151#else
152static inline void xfd_update_state(struct fpstate *fpstate) { }
153#endif
154
155/*
156 * Save processor xstate to xsave area.
157 *
158 * Uses either XSAVE or XSAVEOPT or XSAVES depending on the CPU features
159 * and command line options. The choice is permanent until the next reboot.
160 */
161static inline void os_xsave(struct fpstate *fpstate)
162{
163 u64 mask = fpstate->xfeatures;
164 u32 lmask = mask;
165 u32 hmask = mask >> 32;
166 int err;
167
168 WARN_ON_FPU(!alternatives_patched);
169 xfd_validate_state(fpstate, mask, false);
170
171 XSTATE_XSAVE(&fpstate->regs.xsave, lmask, hmask, err);
172
173 /* We should never fault when copying to a kernel buffer: */
174 WARN_ON_FPU(err);
175}
176
177/*
178 * Restore processor xstate from xsave area.
179 *
180 * Uses XRSTORS when XSAVES is used, XRSTOR otherwise.
181 */
182static inline void os_xrstor(struct fpstate *fpstate, u64 mask)
183{
184 u32 lmask = mask;
185 u32 hmask = mask >> 32;
186
187 xfd_validate_state(fpstate, mask, true);
188 XSTATE_XRESTORE(&fpstate->regs.xsave, lmask, hmask);
189}
190
191/* Restore of supervisor state. Does not require XFD */
192static inline void os_xrstor_supervisor(struct fpstate *fpstate)
193{
194 u64 mask = xfeatures_mask_supervisor();
195 u32 lmask = mask;
196 u32 hmask = mask >> 32;
197
198 XSTATE_XRESTORE(&fpstate->regs.xsave, lmask, hmask);
199}
200
201/*
202 * Save xstate to user space xsave area.
203 *
204 * We don't use modified optimization because xrstor/xrstors might track
205 * a different application.
206 *
207 * We don't use compacted format xsave area for backward compatibility for
208 * old applications which don't understand the compacted format of the
209 * xsave area.
210 *
211 * The caller has to zero buf::header before calling this because XSAVE*
212 * does not touch the reserved fields in the header.
213 */
214static inline int xsave_to_user_sigframe(struct xregs_state __user *buf)
215{
216 /*
217 * Include the features which are not xsaved/rstored by the kernel
218 * internally, e.g. PKRU. That's user space ABI and also required
219 * to allow the signal handler to modify PKRU.
220 */
221 struct fpstate *fpstate = current->thread.fpu.fpstate;
222 u64 mask = fpstate->user_xfeatures;
223 u32 lmask = mask;
224 u32 hmask = mask >> 32;
225 int err;
226
227 xfd_validate_state(fpstate, mask, false);
228
229 stac();
230 XSTATE_OP(XSAVE, buf, lmask, hmask, err);
231 clac();
232
233 return err;
234}
235
236/*
237 * Restore xstate from user space xsave area.
238 */
239static inline int xrstor_from_user_sigframe(struct xregs_state __user *buf, u64 mask)
240{
241 struct xregs_state *xstate = ((__force struct xregs_state *)buf);
242 u32 lmask = mask;
243 u32 hmask = mask >> 32;
244 int err;
245
246 xfd_validate_state(current->thread.fpu.fpstate, mask, true);
247
248 stac();
249 XSTATE_OP(XRSTOR, xstate, lmask, hmask, err);
250 clac();
251
252 return err;
253}
254
255/*
256 * Restore xstate from kernel space xsave area, return an error code instead of
257 * an exception.
258 */
259static inline int os_xrstor_safe(struct fpstate *fpstate, u64 mask)
260{
261 struct xregs_state *xstate = &fpstate->regs.xsave;
262 u32 lmask = mask;
263 u32 hmask = mask >> 32;
264 int err;
265
266 /* Ensure that XFD is up to date */
267 xfd_update_state(fpstate);
268
269 if (cpu_feature_enabled(X86_FEATURE_XSAVES))
270 XSTATE_OP(XRSTORS, xstate, lmask, hmask, err);
271 else
272 XSTATE_OP(XRSTOR, xstate, lmask, hmask, err);
273
274 return err;
275}
276
277
278#endif
arch/x86/kernel/process.c+23−4
@@ -30,7 +30,9 @@ · 29 unmodified lines
30#include <asm/apic.h>30#include <asm/apic.h>
31#include <linux/uaccess.h>31#include <linux/uaccess.h>
32#include <asm/mwait.h>32#include <asm/mwait.h>
33#include <asm/fpu/internal.h>33#include <asm/fpu/api.h>
34#include <asm/fpu/sched.h>
35#include <asm/fpu/xstate.h>
34#include <asm/debugreg.h>36#include <asm/debugreg.h>
35#include <asm/nmi.h>37#include <asm/nmi.h>
36#include <asm/tlbflush.h>38#include <asm/tlbflush.h>
@@ -88,8 +90,19 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) · 51 unmodified lines
88#ifdef CONFIG_VM8690#ifdef CONFIG_VM86
89 dst->thread.vm86 = NULL;91 dst->thread.vm86 = NULL;
90#endif92#endif
91 return fpu_clone(dst);93 /* Drop the copied pointer to current's fpstate */
94 dst->thread.fpu.fpstate = NULL;
95
96 return 0;
97}
98
99#ifdef CONFIG_X86_64
100void arch_release_task_struct(struct task_struct *tsk)
101{
102 if (fpu_state_size_dynamic())
103 fpstate_free(&tsk->thread.fpu);
92}104}
105#endif
93 106
94/*107/*
95 * Free thread data structures etc..108 * Free thread data structures etc..
@@ -155,6 +168,8 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg, · 59 unmodified lines
155 frame->flags = X86_EFLAGS_FIXED;168 frame->flags = X86_EFLAGS_FIXED;
156#endif169#endif
157 170
171 fpu_clone(p, clone_flags);
172
158 /* Kernel thread ? */173 /* Kernel thread ? */
159 if (unlikely(p->flags & PF_KTHREAD)) {174 if (unlikely(p->flags & PF_KTHREAD)) {
160 p->thread.pkru = pkru_get_init_value();175 p->thread.pkru = pkru_get_init_value();
@@ -962,13 +977,17 @@ unsigned long __get_wchan(struct task_struct *p) · 801 unmodified lines
962}977}
963 978
964long do_arch_prctl_common(struct task_struct *task, int option,979long do_arch_prctl_common(struct task_struct *task, int option,
965 unsigned long cpuid_enabled)980 unsigned long arg2)
966{981{
967 switch (option) {982 switch (option) {
968 case ARCH_GET_CPUID:983 case ARCH_GET_CPUID:
969 return get_cpuid_mode();984 return get_cpuid_mode();
970 case ARCH_SET_CPUID:985 case ARCH_SET_CPUID:
971 return set_cpuid_mode(task, cpuid_enabled);986 return set_cpuid_mode(task, arg2);
987 case ARCH_GET_XCOMP_SUPP:
988 case ARCH_GET_XCOMP_PERM:
989 case ARCH_REQ_XCOMP_PERM:
990 return fpu_xstate_prctl(task, option, arg2);
972 }991 }
973 992
974 return -EINVAL;993 return -EINVAL;
arch/x86/kernel/process_32.c+2−3
@@ -41,7 +41,7 @@ · 40 unmodified lines
41 41
42#include <asm/ldt.h>42#include <asm/ldt.h>
43#include <asm/processor.h>43#include <asm/processor.h>
44#include <asm/fpu/internal.h>44#include <asm/fpu/sched.h>
45#include <asm/desc.h>45#include <asm/desc.h>
46 46
47#include <linux/err.h>47#include <linux/err.h>
@@ -160,7 +160,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) · 112 unmodified lines
160 struct thread_struct *prev = &prev_p->thread,160 struct thread_struct *prev = &prev_p->thread,
161 *next = &next_p->thread;161 *next = &next_p->thread;
162 struct fpu *prev_fpu = &prev->fpu;162 struct fpu *prev_fpu = &prev->fpu;
163 struct fpu *next_fpu = &next->fpu;
164 int cpu = smp_processor_id();163 int cpu = smp_processor_id();
165 164
166 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */165 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
@@ -213,7 +212,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) · 46 unmodified lines
213 212
214 this_cpu_write(current_task, next_p);213 this_cpu_write(current_task, next_p);
215 214
216 switch_fpu_finish(next_fpu);215 switch_fpu_finish();
217 216
218 /* Load the Intel cache allocation PQR MSR. */217 /* Load the Intel cache allocation PQR MSR. */
219 resctrl_sched_in();218 resctrl_sched_in();
arch/x86/kernel/process_64.c+2−3
@@ -42,7 +42,7 @@ · 41 unmodified lines
42 42
43#include <asm/processor.h>43#include <asm/processor.h>
44#include <asm/pkru.h>44#include <asm/pkru.h>
45#include <asm/fpu/internal.h>45#include <asm/fpu/sched.h>
46#include <asm/mmu_context.h>46#include <asm/mmu_context.h>
47#include <asm/prctl.h>47#include <asm/prctl.h>
48#include <asm/desc.h>48#include <asm/desc.h>
@@ -559,7 +559,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) · 510 unmodified lines
559 struct thread_struct *prev = &prev_p->thread;559 struct thread_struct *prev = &prev_p->thread;
560 struct thread_struct *next = &next_p->thread;560 struct thread_struct *next = &next_p->thread;
561 struct fpu *prev_fpu = &prev->fpu;561 struct fpu *prev_fpu = &prev->fpu;
562 struct fpu *next_fpu = &next->fpu;
563 int cpu = smp_processor_id();562 int cpu = smp_processor_id();
564 563
565 WARN_ON_ONCE(IS_ENABLED(CONFIG_DEBUG_ENTRY) &&564 WARN_ON_ONCE(IS_ENABLED(CONFIG_DEBUG_ENTRY) &&
@@ -620,7 +619,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) · 54 unmodified lines
620 this_cpu_write(current_task, next_p);619 this_cpu_write(current_task, next_p);
621 this_cpu_write(cpu_current_top_of_stack, task_top_of_stack(next_p));620 this_cpu_write(cpu_current_top_of_stack, task_top_of_stack(next_p));
622 621
623 switch_fpu_finish(next_fpu);622 switch_fpu_finish();
624 623
625 /* Reload sp0. */624 /* Reload sp0. */
626 update_task_stack(next_p);625 update_task_stack(next_p);
arch/x86/kernel/ptrace.c+1−1
@@ -29,9 +29,9 @@ · 28 unmodified lines
29 29
30#include <linux/uaccess.h>30#include <linux/uaccess.h>
31#include <asm/processor.h>31#include <asm/processor.h>
32#include <asm/fpu/internal.h>
33#include <asm/fpu/signal.h>32#include <asm/fpu/signal.h>
34#include <asm/fpu/regset.h>33#include <asm/fpu/regset.h>
34#include <asm/fpu/xstate.h>
35#include <asm/debugreg.h>35#include <asm/debugreg.h>
36#include <asm/ldt.h>36#include <asm/ldt.h>
37#include <asm/desc.h>37#include <asm/desc.h>
arch/x86/kernel/sev.c+1−1
@@ -23,7 +23,7 @@ · 22 unmodified lines
23#include <asm/stacktrace.h>23#include <asm/stacktrace.h>
24#include <asm/sev.h>24#include <asm/sev.h>
25#include <asm/insn-eval.h>25#include <asm/insn-eval.h>
26#include <asm/fpu/internal.h>26#include <asm/fpu/xcr.h>
27#include <asm/processor.h>27#include <asm/processor.h>
28#include <asm/realmode.h>28#include <asm/realmode.h>
29#include <asm/traps.h>29#include <asm/traps.h>
arch/x86/kernel/signal.c+71−12
@@ -15,6 +15,7 @@ · 14 unmodified lines
15#include <linux/mm.h>15#include <linux/mm.h>
16#include <linux/smp.h>16#include <linux/smp.h>
17#include <linux/kernel.h>17#include <linux/kernel.h>
18#include <linux/kstrtox.h>
18#include <linux/errno.h>19#include <linux/errno.h>
19#include <linux/wait.h>20#include <linux/wait.h>
20#include <linux/tracehook.h>21#include <linux/tracehook.h>
@@ -30,8 +31,8 @@ · 9 unmodified lines
30 31
31#include <asm/processor.h>32#include <asm/processor.h>
32#include <asm/ucontext.h>33#include <asm/ucontext.h>
33#include <asm/fpu/internal.h>
34#include <asm/fpu/signal.h>34#include <asm/fpu/signal.h>
35#include <asm/fpu/xstate.h>
35#include <asm/vdso.h>36#include <asm/vdso.h>
36#include <asm/mce.h>37#include <asm/mce.h>
37#include <asm/sighandling.h>38#include <asm/sighandling.h>
@@ -41,6 +42,7 @@ · 3 unmodified lines
41#include <linux/compat.h>42#include <linux/compat.h>
42#include <asm/proto.h>43#include <asm/proto.h>
43#include <asm/ia32_unistd.h>44#include <asm/ia32_unistd.h>
45#include <asm/fpu/xstate.h>
44#endif /* CONFIG_X86_64 */46#endif /* CONFIG_X86_64 */
45 47
46#include <asm/syscall.h>48#include <asm/syscall.h>
@@ -79,9 +81,9 @@ static void force_valid_ss(struct pt_regs *regs) · 32 unmodified lines
79# define CONTEXT_COPY_SIZE sizeof(struct sigcontext)81# define CONTEXT_COPY_SIZE sizeof(struct sigcontext)
80#endif82#endif
81 83
82static int restore_sigcontext(struct pt_regs *regs,84static bool restore_sigcontext(struct pt_regs *regs,
83 struct sigcontext __user *usc,85 struct sigcontext __user *usc,
84 unsigned long uc_flags)86 unsigned long uc_flags)
85{87{
86 struct sigcontext sc;88 struct sigcontext sc;
87 89
@@ -89,7 +91,7 @@ static int restore_sigcontext(struct pt_regs *regs, · 1 unmodified line
89 current->restart_block.fn = do_no_restart_syscall;91 current->restart_block.fn = do_no_restart_syscall;
90 92
91 if (copy_from_user(&sc, usc, CONTEXT_COPY_SIZE))93 if (copy_from_user(&sc, usc, CONTEXT_COPY_SIZE))
92 return -EFAULT;94 return false;
93 95
94#ifdef CONFIG_X86_3296#ifdef CONFIG_X86_32
95 set_user_gs(regs, sc.gs);97 set_user_gs(regs, sc.gs);
@@ -244,7 +246,6 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, · 148 unmodified lines
244 unsigned long math_size = 0;246 unsigned long math_size = 0;
245 unsigned long sp = regs->sp;247 unsigned long sp = regs->sp;
246 unsigned long buf_fx = 0;248 unsigned long buf_fx = 0;
247 int ret;
248 249
249 /* redzone */250 /* redzone */
250 if (IS_ENABLED(CONFIG_X86_64))251 if (IS_ENABLED(CONFIG_X86_64))
@@ -292,8 +293,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, · 41 unmodified lines
292 }293 }
293 294
294 /* save i387 and extended state */295 /* save i387 and extended state */
295 ret = copy_fpstate_to_sigframe(*fpstate, (void __user *)buf_fx, math_size);296 if (!copy_fpstate_to_sigframe(*fpstate, (void __user *)buf_fx, math_size))
296 if (ret < 0)
297 return (void __user *)-1L;297 return (void __user *)-1L;
298 298
299 return (void __user *)sp;299 return (void __user *)sp;
@@ -643,7 +643,7 @@ SYSCALL_DEFINE0(sigreturn) · 343 unmodified lines
643 * x86_32 has no uc_flags bits relevant to restore_sigcontext.643 * x86_32 has no uc_flags bits relevant to restore_sigcontext.
644 * Save a few cycles by skipping the __get_user.644 * Save a few cycles by skipping the __get_user.
645 */645 */
646 if (restore_sigcontext(regs, &frame->sc, 0))646 if (!restore_sigcontext(regs, &frame->sc, 0))
647 goto badframe;647 goto badframe;
648 return regs->ax;648 return regs->ax;
649 649
@@ -671,7 +671,7 @@ SYSCALL_DEFINE0(rt_sigreturn) · 21 unmodified lines
671 671
672 set_current_blocked(&set);672 set_current_blocked(&set);
673 673
674 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags))674 if (!restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags))
675 goto badframe;675 goto badframe;
676 676
677 if (restore_altstack(&frame->uc.uc_stack))677 if (restore_altstack(&frame->uc.uc_stack))
@@ -721,12 +721,15 @@ badframe: · 43 unmodified lines
721 721
722/* max_frame_size tells userspace the worst case signal stack size. */722/* max_frame_size tells userspace the worst case signal stack size. */
723static unsigned long __ro_after_init max_frame_size;723static unsigned long __ro_after_init max_frame_size;
724static unsigned int __ro_after_init fpu_default_state_size;
724 725
725void __init init_sigframe_size(void)726void __init init_sigframe_size(void)
726{727{
728 fpu_default_state_size = fpu__get_fpstate_size();
729
727 max_frame_size = MAX_FRAME_SIGINFO_UCTXT_SIZE + MAX_FRAME_PADDING;730 max_frame_size = MAX_FRAME_SIGINFO_UCTXT_SIZE + MAX_FRAME_PADDING;
728 731
729 max_frame_size += fpu__get_fpstate_size() + MAX_XSAVE_PADDING;732 max_frame_size += fpu_default_state_size + MAX_XSAVE_PADDING;
730 733
731 /* Userspace expects an aligned size. */734 /* Userspace expects an aligned size. */
732 max_frame_size = round_up(max_frame_size, FRAME_ALIGNMENT);735 max_frame_size = round_up(max_frame_size, FRAME_ALIGNMENT);
@@ -910,6 +913,62 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where) · 177 unmodified lines
910 force_sig(SIGSEGV);913 force_sig(SIGSEGV);
911}914}
912 915
916#ifdef CONFIG_DYNAMIC_SIGFRAME
917#ifdef CONFIG_STRICT_SIGALTSTACK_SIZE
918static bool strict_sigaltstack_size __ro_after_init = true;
919#else
920static bool strict_sigaltstack_size __ro_after_init = false;
921#endif
922
923static int __init strict_sas_size(char *arg)
924{
925 return kstrtobool(arg, &strict_sigaltstack_size);
926}
927__setup("strict_sas_size", strict_sas_size);
928
929/*
930 * MINSIGSTKSZ is 2048 and can't be changed despite the fact that AVX512
931 * exceeds that size already. As such programs might never use the
932 * sigaltstack they just continued to work. While always checking against
933 * the real size would be correct, this might be considered a regression.
934 *
935 * Therefore avoid the sanity check, unless enforced by kernel
936 * configuration or command line option.
937 *
938 * When dynamic FPU features are supported, the check is also enforced when
939 * the task has permissions to use dynamic features. Tasks which have no
940 * permission are checked against the size of the non-dynamic feature set
941 * if strict checking is enabled. This avoids forcing all tasks on the
942 * system to allocate large sigaltstacks even if they are never going
943 * to use a dynamic feature. As this is serialized via sighand::siglock
944 * any permission request for a dynamic feature either happened already
945 * or will see the newly install sigaltstack size in the permission checks.
946 */
947bool sigaltstack_size_valid(size_t ss_size)
948{
949 unsigned long fsize = max_frame_size - fpu_default_state_size;
950 u64 mask;
951
952 lockdep_assert_held(&current->sighand->siglock);
953
954 if (!fpu_state_size_dynamic() && !strict_sigaltstack_size)
955 return true;
956
957 fsize += current->group_leader->thread.fpu.perm.__user_state_size;
958 if (likely(ss_size > fsize))
959 return true;
960
961 if (strict_sigaltstack_size)
962 return ss_size > fsize;
963
964 mask = current->group_leader->thread.fpu.perm.__state_perm;
965 if (mask & XFEATURE_MASK_USER_DYNAMIC)
966 return ss_size > fsize;
967
968 return true;
969}
970#endif /* CONFIG_DYNAMIC_SIGFRAME */
971
913#ifdef CONFIG_X86_X32_ABI972#ifdef CONFIG_X86_X32_ABI
914COMPAT_SYSCALL_DEFINE0(x32_rt_sigreturn)973COMPAT_SYSCALL_DEFINE0(x32_rt_sigreturn)
915{974{
@@ -929,7 +988,7 @@ COMPAT_SYSCALL_DEFINE0(x32_rt_sigreturn) · 13 unmodified lines
929 988
930 set_current_blocked(&set);989 set_current_blocked(&set);
931 990
932 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags))991 if (!restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags))
933 goto badframe;992 goto badframe;
934 993
935 if (compat_restore_altstack(&frame->uc.uc_stack))994 if (compat_restore_altstack(&frame->uc.uc_stack))
arch/x86/kernel/smpboot.c+1−1
@@ -70,7 +70,7 @@ · 69 unmodified lines
70#include <asm/mwait.h>70#include <asm/mwait.h>
71#include <asm/apic.h>71#include <asm/apic.h>
72#include <asm/io_apic.h>72#include <asm/io_apic.h>
73#include <asm/fpu/internal.h>73#include <asm/fpu/api.h>
74#include <asm/setup.h>74#include <asm/setup.h>
75#include <asm/uv/uv.h>75#include <asm/uv/uv.h>
76#include <linux/mc146818rtc.h>76#include <linux/mc146818rtc.h>
arch/x86/kernel/traps.c+39−1
@@ -48,7 +48,7 @@ · 47 unmodified lines
48#include <asm/ftrace.h>48#include <asm/ftrace.h>
49#include <asm/traps.h>49#include <asm/traps.h>
50#include <asm/desc.h>50#include <asm/desc.h>
51#include <asm/fpu/internal.h>51#include <asm/fpu/api.h>
52#include <asm/cpu.h>52#include <asm/cpu.h>
53#include <asm/cpu_entry_area.h>53#include <asm/cpu_entry_area.h>
54#include <asm/mce.h>54#include <asm/mce.h>
@@ -1108,10 +1108,48 @@ DEFINE_IDTENTRY(exc_spurious_interrupt_bug) · 1053 unmodified lines
1108 */1108 */
1109}1109}
1110 1110
1111static bool handle_xfd_event(struct pt_regs *regs)
1112{
1113 u64 xfd_err;
1114 int err;
1115
1116 if (!IS_ENABLED(CONFIG_X86_64) || !cpu_feature_enabled(X86_FEATURE_XFD))
1117 return false;
1118
1119 rdmsrl(MSR_IA32_XFD_ERR, xfd_err);
1120 if (!xfd_err)
1121 return false;
1122
1123 wrmsrl(MSR_IA32_XFD_ERR, 0);
1124
1125 /* Die if that happens in kernel space */
1126 if (WARN_ON(!user_mode(regs)))
1127 return false;
1128
1129 local_irq_enable();
1130
1131 err = xfd_enable_feature(xfd_err);
1132
1133 switch (err) {
1134 case -EPERM:
1135 force_sig_fault(SIGILL, ILL_ILLOPC, error_get_trap_addr(regs));
1136 break;
1137 case -EFAULT:
1138 force_sig(SIGSEGV);
1139 break;
1140 }
1141
1142 local_irq_disable();
1143 return true;
1144}
1145
1111DEFINE_IDTENTRY(exc_device_not_available)1146DEFINE_IDTENTRY(exc_device_not_available)
1112{1147{
1113 unsigned long cr0 = read_cr0();1148 unsigned long cr0 = read_cr0();
1114 1149
1150 if (handle_xfd_event(regs))
1151 return;
1152
1115#ifdef CONFIG_MATH_EMULATION1153#ifdef CONFIG_MATH_EMULATION
1116 if (!boot_cpu_has(X86_FEATURE_FPU) && (cr0 & X86_CR0_EM)) {1154 if (!boot_cpu_has(X86_FEATURE_FPU) && (cr0 & X86_CR0_EM)) {
1117 struct math_emu_info info = { };1155 struct math_emu_info info = { };
arch/x86/kvm/svm/sev.c+1−1
@@ -17,10 +17,10 @@ · 16 unmodified lines
17#include <linux/misc_cgroup.h>17#include <linux/misc_cgroup.h>
18#include <linux/processor.h>18#include <linux/processor.h>
19#include <linux/trace_events.h>19#include <linux/trace_events.h>
20#include <asm/fpu/internal.h>
21 20
22#include <asm/pkru.h>21#include <asm/pkru.h>
23#include <asm/trapnr.h>22#include <asm/trapnr.h>
23#include <asm/fpu/xcr.h>
24 24
25#include "x86.h"25#include "x86.h"
26#include "svm.h"26#include "svm.h"
arch/x86/kvm/svm/svm.c+4−3
@@ -36,6 +36,7 @@ · 35 unmodified lines
36#include <asm/spec-ctrl.h>36#include <asm/spec-ctrl.h>
37#include <asm/cpu_device_id.h>37#include <asm/cpu_device_id.h>
38#include <asm/traps.h>38#include <asm/traps.h>
39#include <asm/fpu/api.h>
39 40
40#include <asm/virtext.h>41#include <asm/virtext.h>
41#include "trace.h"42#include "trace.h"
@@ -1346,10 +1347,10 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu) · 1304 unmodified lines
1346 /*1347 /*
1347 * SEV-ES guests maintain an encrypted version of their FPU1348 * SEV-ES guests maintain an encrypted version of their FPU
1348 * state which is restored and saved on VMRUN and VMEXIT.1349 * state which is restored and saved on VMRUN and VMEXIT.
1349 * Free the fpu structure to prevent KVM from attempting to1350 * Mark vcpu->arch.guest_fpu->fpstate as scratch so it won't
1350 * access the FPU state.1351 * do xsave/xrstor on it.
1351 */1352 */
1352 kvm_free_guest_fpu(vcpu);1353 fpstate_set_confidential(&vcpu->arch.guest_fpu);
1353 }1354 }
1354 1355
1355 err = avic_init_vcpu(svm);1356 err = avic_init_vcpu(svm);
arch/x86/kvm/vmx/vmx.c+1−1
@@ -35,7 +35,7 @@ · 34 unmodified lines
35#include <asm/cpu_device_id.h>35#include <asm/cpu_device_id.h>
36#include <asm/debugreg.h>36#include <asm/debugreg.h>
37#include <asm/desc.h>37#include <asm/desc.h>
38#include <asm/fpu/internal.h>38#include <asm/fpu/api.h>
39#include <asm/idtentry.h>39#include <asm/idtentry.h>
40#include <asm/io.h>40#include <asm/io.h>
41#include <asm/irq_remapping.h>41#include <asm/irq_remapping.h>
arch/x86/kvm/x86.c+31−227
@@ -68,7 +68,9 @@ · 67 unmodified lines
68#include <asm/mce.h>68#include <asm/mce.h>
69#include <asm/pkru.h>69#include <asm/pkru.h>
70#include <linux/kernel_stat.h>70#include <linux/kernel_stat.h>
71#include <asm/fpu/internal.h> /* Ugh! */71#include <asm/fpu/api.h>
72#include <asm/fpu/xcr.h>
73#include <asm/fpu/xstate.h>
72#include <asm/pvclock.h>74#include <asm/pvclock.h>
73#include <asm/div64.h>75#include <asm/div64.h>
74#include <asm/irq_remapping.h>76#include <asm/irq_remapping.h>
@@ -293,8 +295,6 @@ u64 __read_mostly host_xcr0; · 218 unmodified lines
293u64 __read_mostly supported_xcr0;295u64 __read_mostly supported_xcr0;
294EXPORT_SYMBOL_GPL(supported_xcr0);296EXPORT_SYMBOL_GPL(supported_xcr0);
295 297
296static struct kmem_cache *x86_fpu_cache;
297
298static struct kmem_cache *x86_emulator_cache;298static struct kmem_cache *x86_emulator_cache;
299 299
300/*300/*
@@ -4700,144 +4700,27 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, · 4399 unmodified lines
4700 return 0;4700 return 0;
4701}4701}
4702 4702
4703#define XSTATE_COMPACTION_ENABLED (1ULL << 63)
4704
4705static void fill_xsave(u8 *dest, struct kvm_vcpu *vcpu)
4706{
4707 struct xregs_state *xsave = &vcpu->arch.guest_fpu->state.xsave;
4708 u64 xstate_bv = xsave->header.xfeatures;
4709 u64 valid;
4710
4711 /*
4712 * Copy legacy XSAVE area, to avoid complications with CPUID
4713 * leaves 0 and 1 in the loop below.
4714 */
4715 memcpy(dest, xsave, XSAVE_HDR_OFFSET);
4716
4717 /* Set XSTATE_BV */
4718 xstate_bv &= vcpu->arch.guest_supported_xcr0 | XFEATURE_MASK_FPSSE;
4719 *(u64 *)(dest + XSAVE_HDR_OFFSET) = xstate_bv;
4720
4721 /*
4722 * Copy each region from the possibly compacted offset to the
4723 * non-compacted offset.
4724 */
4725 valid = xstate_bv & ~XFEATURE_MASK_FPSSE;
4726 while (valid) {
4727 u32 size, offset, ecx, edx;
4728 u64 xfeature_mask = valid & -valid;
4729 int xfeature_nr = fls64(xfeature_mask) - 1;
4730 void *src;
4731
4732 cpuid_count(XSTATE_CPUID, xfeature_nr,
4733 &size, &offset, &ecx, &edx);
4734
4735 if (xfeature_nr == XFEATURE_PKRU) {
4736 memcpy(dest + offset, &vcpu->arch.pkru,
4737 sizeof(vcpu->arch.pkru));
4738 } else {
4739 src = get_xsave_addr(xsave, xfeature_nr);
4740 if (src)
4741 memcpy(dest + offset, src, size);
4742 }
4743
4744 valid -= xfeature_mask;
4745 }
4746}
4747
4748static void load_xsave(struct kvm_vcpu *vcpu, u8 *src)
4749{
4750 struct xregs_state *xsave = &vcpu->arch.guest_fpu->state.xsave;
4751 u64 xstate_bv = *(u64 *)(src + XSAVE_HDR_OFFSET);
4752 u64 valid;
4753
4754 /*
4755 * Copy legacy XSAVE area, to avoid complications with CPUID
4756 * leaves 0 and 1 in the loop below.
4757 */
4758 memcpy(xsave, src, XSAVE_HDR_OFFSET);
4759
4760 /* Set XSTATE_BV and possibly XCOMP_BV. */
4761 xsave->header.xfeatures = xstate_bv;
4762 if (boot_cpu_has(X86_FEATURE_XSAVES))
4763 xsave->header.xcomp_bv = host_xcr0 | XSTATE_COMPACTION_ENABLED;
4764
4765 /*
4766 * Copy each region from the non-compacted offset to the
4767 * possibly compacted offset.
4768 */
4769 valid = xstate_bv & ~XFEATURE_MASK_FPSSE;
4770 while (valid) {
4771 u32 size, offset, ecx, edx;
4772 u64 xfeature_mask = valid & -valid;
4773 int xfeature_nr = fls64(xfeature_mask) - 1;
4774
4775 cpuid_count(XSTATE_CPUID, xfeature_nr,
4776 &size, &offset, &ecx, &edx);
4777
4778 if (xfeature_nr == XFEATURE_PKRU) {
4779 memcpy(&vcpu->arch.pkru, src + offset,
4780 sizeof(vcpu->arch.pkru));
4781 } else {
4782 void *dest = get_xsave_addr(xsave, xfeature_nr);
4783
4784 if (dest)
4785 memcpy(dest, src + offset, size);
4786 }
4787
4788 valid -= xfeature_mask;
4789 }
4790}
4791
4792static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,4703static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
4793 struct kvm_xsave *guest_xsave)4704 struct kvm_xsave *guest_xsave)
4794{4705{
4795 if (!vcpu->arch.guest_fpu)4706 if (fpstate_is_confidential(&vcpu->arch.guest_fpu))
4796 return;4707 return;
4797 4708
4798 if (boot_cpu_has(X86_FEATURE_XSAVE)) {4709 fpu_copy_guest_fpstate_to_uabi(&vcpu->arch.guest_fpu,
4799 memset(guest_xsave, 0, sizeof(struct kvm_xsave));4710 guest_xsave->region,
4800 fill_xsave((u8 *) guest_xsave->region, vcpu);4711 sizeof(guest_xsave->region),
4801 } else {4712 vcpu->arch.pkru);
4802 memcpy(guest_xsave->region,
4803 &vcpu->arch.guest_fpu->state.fxsave,
4804 sizeof(struct fxregs_state));
4805 *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)] =
4806 XFEATURE_MASK_FPSSE;
4807 }
4808}4713}
4809 4714
4810#define XSAVE_MXCSR_OFFSET 24
4811
4812static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,4715static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
4813 struct kvm_xsave *guest_xsave)4716 struct kvm_xsave *guest_xsave)
4814{4717{
4815 u64 xstate_bv;4718 if (fpstate_is_confidential(&vcpu->arch.guest_fpu))
4816 u32 mxcsr;
4817
4818 if (!vcpu->arch.guest_fpu)
4819 return 0;4719 return 0;
4820 4720
4821 xstate_bv = *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)];4721 return fpu_copy_uabi_to_guest_fpstate(&vcpu->arch.guest_fpu,
4822 mxcsr = *(u32 *)&guest_xsave->region[XSAVE_MXCSR_OFFSET / sizeof(u32)];4722 guest_xsave->region,
4823 4723 supported_xcr0, &vcpu->arch.pkru);
4824 if (boot_cpu_has(X86_FEATURE_XSAVE)) {
4825 /*
4826 * Here we allow setting states that are not present in
4827 * CPUID leaf 0xD, index 0, EDX:EAX. This is for compatibility
4828 * with old userspace.
4829 */
4830 if (xstate_bv & ~supported_xcr0 || mxcsr & ~mxcsr_feature_mask)
4831 return -EINVAL;
4832 load_xsave(vcpu, (u8 *)guest_xsave->region);
4833 } else {
4834 if (xstate_bv & ~XFEATURE_MASK_FPSSE ||
4835 mxcsr & ~mxcsr_feature_mask)
4836 return -EINVAL;
4837 memcpy(&vcpu->arch.guest_fpu->state.fxsave,
4838 guest_xsave->region, sizeof(struct fxregs_state));
4839 }
4840 return 0;
4841}4724}
4842 4725
4843static void kvm_vcpu_ioctl_x86_get_xcrs(struct kvm_vcpu *vcpu,4726static void kvm_vcpu_ioctl_x86_get_xcrs(struct kvm_vcpu *vcpu,
@@ -8434,18 +8317,11 @@ int kvm_arch_init(void *opaque) · 3590 unmodified lines
8434 }8317 }
8435 8318
8436 r = -ENOMEM;8319 r = -ENOMEM;
8437 x86_fpu_cache = kmem_cache_create("x86_fpu", sizeof(struct fpu),
8438 __alignof__(struct fpu), SLAB_ACCOUNT,
8439 NULL);
8440 if (!x86_fpu_cache) {
8441 printk(KERN_ERR "kvm: failed to allocate cache for x86 fpu\n");
8442 goto out;
8443 }
8444 8320
8445 x86_emulator_cache = kvm_alloc_emulator_cache();8321 x86_emulator_cache = kvm_alloc_emulator_cache();
8446 if (!x86_emulator_cache) {8322 if (!x86_emulator_cache) {
8447 pr_err("kvm: failed to allocate cache for x86 emulator\n");8323 pr_err("kvm: failed to allocate cache for x86 emulator\n");
8448 goto out_free_x86_fpu_cache;8324 goto out;
8449 }8325 }
8450 8326
8451 user_return_msrs = alloc_percpu(struct kvm_user_return_msrs);8327 user_return_msrs = alloc_percpu(struct kvm_user_return_msrs);
@@ -8483,8 +8359,6 @@ out_free_percpu: · 31 unmodified lines
8483 free_percpu(user_return_msrs);8359 free_percpu(user_return_msrs);
8484out_free_x86_emulator_cache:8360out_free_x86_emulator_cache:
8485 kmem_cache_destroy(x86_emulator_cache);8361 kmem_cache_destroy(x86_emulator_cache);
8486out_free_x86_fpu_cache:
8487 kmem_cache_destroy(x86_fpu_cache);
8488out:8362out:
8489 return r;8363 return r;
8490}8364}
@@ -8511,7 +8385,6 @@ void kvm_arch_exit(void) · 20 unmodified lines
8511 kvm_mmu_module_exit();8385 kvm_mmu_module_exit();
8512 free_percpu(user_return_msrs);8386 free_percpu(user_return_msrs);
8513 kmem_cache_destroy(x86_emulator_cache);8387 kmem_cache_destroy(x86_emulator_cache);
8514 kmem_cache_destroy(x86_fpu_cache);
8515#ifdef CONFIG_KVM_XEN8388#ifdef CONFIG_KVM_XEN
8516 static_key_deferred_flush(&kvm_xen_enabled);8389 static_key_deferred_flush(&kvm_xen_enabled);
8517 WARN_ON(static_branch_unlikely(&kvm_xen_enabled.key));8390 WARN_ON(static_branch_unlikely(&kvm_xen_enabled.key));
@@ -9938,58 +9811,21 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) · 1420 unmodified lines
9938 return 0;9811 return 0;
9939}9812}
9940 9813
9941static void kvm_save_current_fpu(struct fpu *fpu)
9942{
9943 /*
9944 * If the target FPU state is not resident in the CPU registers, just
9945 * memcpy() from current, else save CPU state directly to the target.
9946 */
9947 if (test_thread_flag(TIF_NEED_FPU_LOAD))
9948 memcpy(&fpu->state, &current->thread.fpu.state,
9949 fpu_kernel_xstate_size);
9950 else
9951 save_fpregs_to_fpstate(fpu);
9952}
9953
9954/* Swap (qemu) user FPU context for the guest FPU context. */9814/* Swap (qemu) user FPU context for the guest FPU context. */
9955static void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)9815static void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
9956{9816{
9957 fpregs_lock();
9958
9959 kvm_save_current_fpu(vcpu->arch.user_fpu);
9960
9961 /*9817 /*
9962 * Guests with protected state can't have it set by the hypervisor,9818 * Exclude PKRU from restore as restored separately in
9963 * so skip trying to set it.9819 * kvm_x86_ops.run().
9964 */9820 */
9965 if (vcpu->arch.guest_fpu)9821 fpu_swap_kvm_fpstate(&vcpu->arch.guest_fpu, true);
9966 /* PKRU is separately restored in kvm_x86_ops.run. */
9967 __restore_fpregs_from_fpstate(&vcpu->arch.guest_fpu->state,
9968 ~XFEATURE_MASK_PKRU);
9969
9970 fpregs_mark_activate();
9971 fpregs_unlock();
9972
9973 trace_kvm_fpu(1);9822 trace_kvm_fpu(1);
9974}9823}
9975 9824
9976/* When vcpu_run ends, restore user space FPU context. */9825/* When vcpu_run ends, restore user space FPU context. */
9977static void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)9826static void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
9978{9827{
9979 fpregs_lock();9828 fpu_swap_kvm_fpstate(&vcpu->arch.guest_fpu, false);
9980
9981 /*
9982 * Guests with protected state can't have it read by the hypervisor,
9983 * so skip trying to save it.
9984 */
9985 if (vcpu->arch.guest_fpu)
9986 kvm_save_current_fpu(vcpu->arch.guest_fpu);
9987
9988 restore_fpregs_from_fpstate(&vcpu->arch.user_fpu->state);
9989
9990 fpregs_mark_activate();
9991 fpregs_unlock();
9992
9993 ++vcpu->stat.fpu_reload;9829 ++vcpu->stat.fpu_reload;
9994 trace_kvm_fpu(0);9830 trace_kvm_fpu(0);
9995}9831}
@@ -10570,12 +10406,12 @@ int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) · 574 unmodified lines
10570{10406{
10571 struct fxregs_state *fxsave;10407 struct fxregs_state *fxsave;
10572 10408
10573 if (!vcpu->arch.guest_fpu)10409 if (fpstate_is_confidential(&vcpu->arch.guest_fpu))
10574 return 0;10410 return 0;
10575 10411
10576 vcpu_load(vcpu);10412 vcpu_load(vcpu);
10577 10413
10578 fxsave = &vcpu->arch.guest_fpu->state.fxsave;10414 fxsave = &vcpu->arch.guest_fpu.fpstate->regs.fxsave;
10579 memcpy(fpu->fpr, fxsave->st_space, 128);10415 memcpy(fpu->fpr, fxsave->st_space, 128);
10580 fpu->fcw = fxsave->cwd;10416 fpu->fcw = fxsave->cwd;
10581 fpu->fsw = fxsave->swd;10417 fpu->fsw = fxsave->swd;
@@ -10593,12 +10429,12 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) · 11 unmodified lines
10593{10429{
10594 struct fxregs_state *fxsave;10430 struct fxregs_state *fxsave;
10595 10431
10596 if (!vcpu->arch.guest_fpu)10432 if (fpstate_is_confidential(&vcpu->arch.guest_fpu))
10597 return 0;10433 return 0;
10598 10434
10599 vcpu_load(vcpu);10435 vcpu_load(vcpu);
10600 10436
10601 fxsave = &vcpu->arch.guest_fpu->state.fxsave;10437 fxsave = &vcpu->arch.guest_fpu.fpstate->regs.fxsave;
10602 10438
10603 memcpy(fxsave->st_space, fpu->fpr, 128);10439 memcpy(fxsave->st_space, fpu->fpr, 128);
10604 fxsave->cwd = fpu->fcw;10440 fxsave->cwd = fpu->fcw;
@@ -10651,14 +10487,6 @@ static int sync_regs(struct kvm_vcpu *vcpu) · 46 unmodified lines
10651 10487
10652static void fx_init(struct kvm_vcpu *vcpu)10488static void fx_init(struct kvm_vcpu *vcpu)
10653{10489{
10654 if (!vcpu->arch.guest_fpu)
10655 return;
10656
10657 fpstate_init(&vcpu->arch.guest_fpu->state);
10658 if (boot_cpu_has(X86_FEATURE_XSAVES))
10659 vcpu->arch.guest_fpu->state.xsave.header.xcomp_bv =
10660 host_xcr0 | XSTATE_COMPACTION_ENABLED;
10661
10662 /*10490 /*
10663 * Ensure guest xcr0 is valid for loading10491 * Ensure guest xcr0 is valid for loading
10664 */10492 */
@@ -10667,15 +10495,6 @@ static void fx_init(struct kvm_vcpu *vcpu) · 2 unmodified lines
10667 vcpu->arch.cr0 |= X86_CR0_ET;10495 vcpu->arch.cr0 |= X86_CR0_ET;
10668}10496}
10669 10497
10670void kvm_free_guest_fpu(struct kvm_vcpu *vcpu)
10671{
10672 if (vcpu->arch.guest_fpu) {
10673 kmem_cache_free(x86_fpu_cache, vcpu->arch.guest_fpu);
10674 vcpu->arch.guest_fpu = NULL;
10675 }
10676}
10677EXPORT_SYMBOL_GPL(kvm_free_guest_fpu);
10678
10679int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)10498int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
10680{10499{
10681 if (kvm_check_tsc_unstable() && atomic_read(&kvm->online_vcpus) != 0)10500 if (kvm_check_tsc_unstable() && atomic_read(&kvm->online_vcpus) != 0)
@@ -10732,19 +10551,11 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) · 50 unmodified lines
10732 if (!alloc_emulate_ctxt(vcpu))10551 if (!alloc_emulate_ctxt(vcpu))
10733 goto free_wbinvd_dirty_mask;10552 goto free_wbinvd_dirty_mask;
10734 10553
10735 vcpu->arch.user_fpu = kmem_cache_zalloc(x86_fpu_cache,10554 if (!fpu_alloc_guest_fpstate(&vcpu->arch.guest_fpu)) {
10736 GFP_KERNEL_ACCOUNT);10555 pr_err("kvm: failed to allocate vcpu's fpu\n");
10737 if (!vcpu->arch.user_fpu) {
10738 pr_err("kvm: failed to allocate userspace's fpu\n");
10739 goto free_emulate_ctxt;10556 goto free_emulate_ctxt;
10740 }10557 }
10741 10558
10742 vcpu->arch.guest_fpu = kmem_cache_zalloc(x86_fpu_cache,
10743 GFP_KERNEL_ACCOUNT);
10744 if (!vcpu->arch.guest_fpu) {
10745 pr_err("kvm: failed to allocate vcpu's fpu\n");
10746 goto free_user_fpu;
10747 }
10748 fx_init(vcpu);10559 fx_init(vcpu);
10749 10560
10750 vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu);10561 vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu);
@@ -10777,9 +10588,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) · 26 unmodified lines
10777 return 0;10588 return 0;
10778 10589
10779free_guest_fpu:10590free_guest_fpu:
10780 kvm_free_guest_fpu(vcpu);10591 fpu_free_guest_fpstate(&vcpu->arch.guest_fpu);
10781free_user_fpu:
10782 kmem_cache_free(x86_fpu_cache, vcpu->arch.user_fpu);
10783free_emulate_ctxt:10592free_emulate_ctxt:
10784 kmem_cache_free(x86_emulator_cache, vcpu->arch.emulate_ctxt);10593 kmem_cache_free(x86_emulator_cache, vcpu->arch.emulate_ctxt);
10785free_wbinvd_dirty_mask:10594free_wbinvd_dirty_mask:
@@ -10828,8 +10637,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) · 42 unmodified lines
10828 10637
10829 kmem_cache_free(x86_emulator_cache, vcpu->arch.emulate_ctxt);10638 kmem_cache_free(x86_emulator_cache, vcpu->arch.emulate_ctxt);
10830 free_cpumask_var(vcpu->arch.wbinvd_dirty_mask);10639 free_cpumask_var(vcpu->arch.wbinvd_dirty_mask);
10831 kmem_cache_free(x86_fpu_cache, vcpu->arch.user_fpu);10640 fpu_free_guest_fpstate(&vcpu->arch.guest_fpu);
10832 kvm_free_guest_fpu(vcpu);
10833 10641
10834 kvm_hv_vcpu_uninit(vcpu);10642 kvm_hv_vcpu_uninit(vcpu);
10835 kvm_pmu_destroy(vcpu);10643 kvm_pmu_destroy(vcpu);
@@ -10881,8 +10689,8 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) · 45 unmodified lines
10881 kvm_async_pf_hash_reset(vcpu);10689 kvm_async_pf_hash_reset(vcpu);
10882 vcpu->arch.apf.halted = false;10690 vcpu->arch.apf.halted = false;
10883 10691
10884 if (vcpu->arch.guest_fpu && kvm_mpx_supported()) {10692 if (vcpu->arch.guest_fpu.fpstate && kvm_mpx_supported()) {
10885 void *mpx_state_buffer;10693 struct fpstate *fpstate = vcpu->arch.guest_fpu.fpstate;
10886 10694
10887 /*10695 /*
10888 * To avoid have the INIT path from kvm_apic_has_events() that be10696 * To avoid have the INIT path from kvm_apic_has_events() that be
@@ -10890,14 +10698,10 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) · 1 unmodified line
10890 */10698 */
10891 if (init_event)10699 if (init_event)
10892 kvm_put_guest_fpu(vcpu);10700 kvm_put_guest_fpu(vcpu);
10893 mpx_state_buffer = get_xsave_addr(&vcpu->arch.guest_fpu->state.xsave,10701
10894 XFEATURE_BNDREGS);10702 fpstate_clear_xstate_component(fpstate, XFEATURE_BNDREGS);
10895 if (mpx_state_buffer)10703 fpstate_clear_xstate_component(fpstate, XFEATURE_BNDCSR);
10896 memset(mpx_state_buffer, 0, sizeof(struct mpx_bndreg_state));10704
10897 mpx_state_buffer = get_xsave_addr(&vcpu->arch.guest_fpu->state.xsave,
10898 XFEATURE_BNDCSR);
10899 if (mpx_state_buffer)
10900 memset(mpx_state_buffer, 0, sizeof(struct mpx_bndcsr));
10901 if (init_event)10705 if (init_event)
10902 kvm_load_guest_fpu(vcpu);10706 kvm_load_guest_fpu(vcpu);
10903 }10707 }
arch/x86/lib/copy_mc_64.S+4−4
@@ -107,9 +107,9 @@ SYM_FUNC_END(copy_mc_fragile) · 106 unmodified lines
107 107
108 .previous108 .previous
109 109
110 _ASM_EXTABLE_FAULT(.L_read_leading_bytes, .E_leading_bytes)110 _ASM_EXTABLE_TYPE(.L_read_leading_bytes, .E_leading_bytes, EX_TYPE_DEFAULT_MCE_SAFE)
111 _ASM_EXTABLE_FAULT(.L_read_words, .E_read_words)111 _ASM_EXTABLE_TYPE(.L_read_words, .E_read_words, EX_TYPE_DEFAULT_MCE_SAFE)
112 _ASM_EXTABLE_FAULT(.L_read_trailing_bytes, .E_trailing_bytes)112 _ASM_EXTABLE_TYPE(.L_read_trailing_bytes, .E_trailing_bytes, EX_TYPE_DEFAULT_MCE_SAFE)
113 _ASM_EXTABLE(.L_write_leading_bytes, .E_leading_bytes)113 _ASM_EXTABLE(.L_write_leading_bytes, .E_leading_bytes)
114 _ASM_EXTABLE(.L_write_words, .E_write_words)114 _ASM_EXTABLE(.L_write_words, .E_write_words)
115 _ASM_EXTABLE(.L_write_trailing_bytes, .E_trailing_bytes)115 _ASM_EXTABLE(.L_write_trailing_bytes, .E_trailing_bytes)
@@ -149,5 +149,5 @@ SYM_FUNC_END(copy_mc_enhanced_fast_string) · 33 unmodified lines
149 149
150 .previous150 .previous
151 151
152 _ASM_EXTABLE_FAULT(.L_copy, .E_copy)152 _ASM_EXTABLE_TYPE(.L_copy, .E_copy, EX_TYPE_DEFAULT_MCE_SAFE)
153#endif /* !CONFIG_UML */153#endif /* !CONFIG_UML */
arch/x86/math-emu/fpu_aux.c+1−1
@@ -53,7 +53,7 @@ void fpstate_init_soft(struct swregs_state *soft) · 52 unmodified lines
53 53
54void finit(void)54void finit(void)
55{55{
56 fpstate_init_soft(&current->thread.fpu.state.soft);56 fpstate_init_soft(&current->thread.fpu.fpstate->regs.soft);
57}57}
58 58
59/*59/*
arch/x86/math-emu/fpu_entry.c+3−3
@@ -31,7 +31,7 @@ · 30 unmodified lines
31#include <linux/uaccess.h>31#include <linux/uaccess.h>
32#include <asm/traps.h>32#include <asm/traps.h>
33#include <asm/user.h>33#include <asm/user.h>
34#include <asm/fpu/internal.h>34#include <asm/fpu/api.h>
35 35
36#include "fpu_system.h"36#include "fpu_system.h"
37#include "fpu_emu.h"37#include "fpu_emu.h"
@@ -640,7 +640,7 @@ int fpregs_soft_set(struct task_struct *target, · 602 unmodified lines
640 unsigned int pos, unsigned int count,640 unsigned int pos, unsigned int count,
641 const void *kbuf, const void __user *ubuf)641 const void *kbuf, const void __user *ubuf)
642{642{
643 struct swregs_state *s387 = &target->thread.fpu.state.soft;643 struct swregs_state *s387 = &target->thread.fpu.fpstate->regs.soft;
644 void *space = s387->st_space;644 void *space = s387->st_space;
645 int ret;645 int ret;
646 int offset, other, i, tags, regnr, tag, newtop;646 int offset, other, i, tags, regnr, tag, newtop;
@@ -691,7 +691,7 @@ int fpregs_soft_get(struct task_struct *target, · 44 unmodified lines
691 const struct user_regset *regset,691 const struct user_regset *regset,
692 struct membuf to)692 struct membuf to)
693{693{
694 struct swregs_state *s387 = &target->thread.fpu.state.soft;694 struct swregs_state *s387 = &target->thread.fpu.fpstate->regs.soft;
695 const void *space = s387->st_space;695 const void *space = s387->st_space;
696 int offset = (S387->ftop & 7) * 10, other = 80 - offset;696 int offset = (S387->ftop & 7) * 10, other = 80 - offset;
697 697
arch/x86/math-emu/fpu_system.h+1−1
@@ -73,7 +73,7 @@ static inline bool seg_writable(struct desc_struct *d) · 72 unmodified lines
73 return (d->type & SEG_TYPE_EXECUTE_MASK) == SEG_TYPE_WRITABLE;73 return (d->type & SEG_TYPE_EXECUTE_MASK) == SEG_TYPE_WRITABLE;
74}74}
75 75
76#define I387 (&current->thread.fpu.state)76#define I387 (&current->thread.fpu.fpstate->regs)
77#define FPU_info (I387->soft.info)77#define FPU_info (I387->soft.info)
78 78
79#define FPU_CS (*(unsigned short *) &(FPU_info->regs->cs))79#define FPU_CS (*(unsigned short *) &(FPU_info->regs->cs))
arch/x86/mm/extable.c+56−79
@@ -4,46 +4,30 @@ · 3 unmodified lines
4#include <linux/sched/debug.h>4#include <linux/sched/debug.h>
5#include <xen/xen.h>5#include <xen/xen.h>
6 6
7#include <asm/fpu/internal.h>7#include <asm/fpu/api.h>
8#include <asm/sev.h>8#include <asm/sev.h>
9#include <asm/traps.h>9#include <asm/traps.h>
10#include <asm/kdebug.h>10#include <asm/kdebug.h>
11 11
12typedef bool (*ex_handler_t)(const struct exception_table_entry *,
13 struct pt_regs *, int, unsigned long,
14 unsigned long);
15
16static inline unsigned long12static inline unsigned long
17ex_fixup_addr(const struct exception_table_entry *x)13ex_fixup_addr(const struct exception_table_entry *x)
18{14{
19 return (unsigned long)&x->fixup + x->fixup;15 return (unsigned long)&x->fixup + x->fixup;
20}16}
21static inline ex_handler_t
22ex_fixup_handler(const struct exception_table_entry *x)
23{
24 return (ex_handler_t)((unsigned long)&x->handler + x->handler);
25}
26 17
27__visible bool ex_handler_default(const struct exception_table_entry *fixup,18static bool ex_handler_default(const struct exception_table_entry *fixup,
28 struct pt_regs *regs, int trapnr,19 struct pt_regs *regs)
29 unsigned long error_code,
30 unsigned long fault_addr)
31{20{
32 regs->ip = ex_fixup_addr(fixup);21 regs->ip = ex_fixup_addr(fixup);
33 return true;22 return true;
34}23}
35EXPORT_SYMBOL(ex_handler_default);
36 24
37__visible bool ex_handler_fault(const struct exception_table_entry *fixup,25static bool ex_handler_fault(const struct exception_table_entry *fixup,
38 struct pt_regs *regs, int trapnr,26 struct pt_regs *regs, int trapnr)
39 unsigned long error_code,
40 unsigned long fault_addr)
41{27{
42 regs->ip = ex_fixup_addr(fixup);
43 regs->ax = trapnr;28 regs->ax = trapnr;
44 return true;29 return ex_handler_default(fixup, regs);
45}30}
46EXPORT_SYMBOL_GPL(ex_handler_fault);
47 31
48/*32/*
49 * Handler for when we fail to restore a task's FPU state. We should never get33 * Handler for when we fail to restore a task's FPU state. We should never get
@@ -55,65 +39,47 @@ EXPORT_SYMBOL_GPL(ex_handler_fault); · 5 unmodified lines
55 * of vulnerability by restoring from the initial state (essentially, zeroing39 * of vulnerability by restoring from the initial state (essentially, zeroing
56 * out all the FPU registers) if we can't restore from the task's FPU state.40 * out all the FPU registers) if we can't restore from the task's FPU state.
57 */41 */
58__visible bool ex_handler_fprestore(const struct exception_table_entry *fixup,42static bool ex_handler_fprestore(const struct exception_table_entry *fixup,
59 struct pt_regs *regs, int trapnr,43 struct pt_regs *regs)
60 unsigned long error_code,
61 unsigned long fault_addr)
62{44{
63 regs->ip = ex_fixup_addr(fixup);45 regs->ip = ex_fixup_addr(fixup);
64 46
65 WARN_ONCE(1, "Bad FPU state detected at %pB, reinitializing FPU registers.",47 WARN_ONCE(1, "Bad FPU state detected at %pB, reinitializing FPU registers.",
66 (void *)instruction_pointer(regs));48 (void *)instruction_pointer(regs));
67 49
68 __restore_fpregs_from_fpstate(&init_fpstate, xfeatures_mask_fpstate());50 fpu_reset_from_exception_fixup();
69 return true;51 return true;
70}52}
71EXPORT_SYMBOL_GPL(ex_handler_fprestore);
72 53
73__visible bool ex_handler_uaccess(const struct exception_table_entry *fixup,54static bool ex_handler_uaccess(const struct exception_table_entry *fixup,
74 struct pt_regs *regs, int trapnr,55 struct pt_regs *regs, int trapnr)
75 unsigned long error_code,
76 unsigned long fault_addr)
77{56{
78 WARN_ONCE(trapnr == X86_TRAP_GP, "General protection fault in user access. Non-canonical address?");57 WARN_ONCE(trapnr == X86_TRAP_GP, "General protection fault in user access. Non-canonical address?");
79 regs->ip = ex_fixup_addr(fixup);58 return ex_handler_default(fixup, regs);
80 return true;
81}59}
82EXPORT_SYMBOL(ex_handler_uaccess);
83 60
84__visible bool ex_handler_copy(const struct exception_table_entry *fixup,61static bool ex_handler_copy(const struct exception_table_entry *fixup,
85 struct pt_regs *regs, int trapnr,62 struct pt_regs *regs, int trapnr)
86 unsigned long error_code,
87 unsigned long fault_addr)
88{63{
89 WARN_ONCE(trapnr == X86_TRAP_GP, "General protection fault in user access. Non-canonical address?");64 WARN_ONCE(trapnr == X86_TRAP_GP, "General protection fault in user access. Non-canonical address?");
90 regs->ip = ex_fixup_addr(fixup);65 return ex_handler_fault(fixup, regs, trapnr);
91 regs->ax = trapnr;
92 return true;
93}66}
94EXPORT_SYMBOL(ex_handler_copy);
95 67
96__visible bool ex_handler_rdmsr_unsafe(const struct exception_table_entry *fixup,68static bool ex_handler_rdmsr_unsafe(const struct exception_table_entry *fixup,
97 struct pt_regs *regs, int trapnr,69 struct pt_regs *regs)
98 unsigned long error_code,
99 unsigned long fault_addr)
100{70{
101 if (pr_warn_once("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n",71 if (pr_warn_once("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n",
102 (unsigned int)regs->cx, regs->ip, (void *)regs->ip))72 (unsigned int)regs->cx, regs->ip, (void *)regs->ip))
103 show_stack_regs(regs);73 show_stack_regs(regs);
104 74
105 /* Pretend that the read succeeded and returned 0. */75 /* Pretend that the read succeeded and returned 0. */
106 regs->ip = ex_fixup_addr(fixup);
107 regs->ax = 0;76 regs->ax = 0;
108 regs->dx = 0;77 regs->dx = 0;
109 return true;78 return ex_handler_default(fixup, regs);
110}79}
111EXPORT_SYMBOL(ex_handler_rdmsr_unsafe);
112 80
113__visible bool ex_handler_wrmsr_unsafe(const struct exception_table_entry *fixup,81static bool ex_handler_wrmsr_unsafe(const struct exception_table_entry *fixup,
114 struct pt_regs *regs, int trapnr,82 struct pt_regs *regs)
115 unsigned long error_code,
116 unsigned long fault_addr)
117{83{
118 if (pr_warn_once("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n",84 if (pr_warn_once("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n",
119 (unsigned int)regs->cx, (unsigned int)regs->dx,85 (unsigned int)regs->cx, (unsigned int)regs->dx,
@@ -121,45 +87,29 @@ __visible bool ex_handler_wrmsr_unsafe(const struct exception_table_entry *fixup · 1 unmodified line
121 show_stack_regs(regs);87 show_stack_regs(regs);
122 88
123 /* Pretend that the write succeeded. */89 /* Pretend that the write succeeded. */
124 regs->ip = ex_fixup_addr(fixup);90 return ex_handler_default(fixup, regs);
125 return true;
126}91}
127EXPORT_SYMBOL(ex_handler_wrmsr_unsafe);
128 92
129__visible bool ex_handler_clear_fs(const struct exception_table_entry *fixup,93static bool ex_handler_clear_fs(const struct exception_table_entry *fixup,
130 struct pt_regs *regs, int trapnr,94 struct pt_regs *regs)
131 unsigned long error_code,
132 unsigned long fault_addr)
133{95{
134 if (static_cpu_has(X86_BUG_NULL_SEG))96 if (static_cpu_has(X86_BUG_NULL_SEG))
135 asm volatile ("mov %0, %%fs" : : "rm" (__USER_DS));97 asm volatile ("mov %0, %%fs" : : "rm" (__USER_DS));
136 asm volatile ("mov %0, %%fs" : : "rm" (0));98 asm volatile ("mov %0, %%fs" : : "rm" (0));
137 return ex_handler_default(fixup, regs, trapnr, error_code, fault_addr);99 return ex_handler_default(fixup, regs);
138}100}
139EXPORT_SYMBOL(ex_handler_clear_fs);
140 101
141enum handler_type ex_get_fault_handler_type(unsigned long ip)102int ex_get_fixup_type(unsigned long ip)
142{103{
143 const struct exception_table_entry *e;104 const struct exception_table_entry *e = search_exception_tables(ip);
144 ex_handler_t handler;
145 105
146 e = search_exception_tables(ip);106 return e ? e->type : EX_TYPE_NONE;
147 if (!e)
148 return EX_HANDLER_NONE;
149 handler = ex_fixup_handler(e);
150 if (handler == ex_handler_fault)
151 return EX_HANDLER_FAULT;
152 else if (handler == ex_handler_uaccess || handler == ex_handler_copy)
153 return EX_HANDLER_UACCESS;
154 else
155 return EX_HANDLER_OTHER;
156}107}
157 108
158int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code,109int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code,
159 unsigned long fault_addr)110 unsigned long fault_addr)
160{111{
161 const struct exception_table_entry *e;112 const struct exception_table_entry *e;
162 ex_handler_t handler;
163 113
164#ifdef CONFIG_PNPBIOS114#ifdef CONFIG_PNPBIOS
165 if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {115 if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
@@ -179,8 +129,35 @@ int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code, · 13 unmodified lines
179 if (!e)129 if (!e)
180 return 0;130 return 0;
181 131
182 handler = ex_fixup_handler(e);132 switch (e->type) {
183 return handler(e, regs, trapnr, error_code, fault_addr);133 case EX_TYPE_DEFAULT:
134 case EX_TYPE_DEFAULT_MCE_SAFE:
135 return ex_handler_default(e, regs);
136 case EX_TYPE_FAULT:
137 case EX_TYPE_FAULT_MCE_SAFE:
138 return ex_handler_fault(e, regs, trapnr);
139 case EX_TYPE_UACCESS:
140 return ex_handler_uaccess(e, regs, trapnr);
141 case EX_TYPE_COPY:
142 return ex_handler_copy(e, regs, trapnr);
143 case EX_TYPE_CLEAR_FS:
144 return ex_handler_clear_fs(e, regs);
145 case EX_TYPE_FPU_RESTORE:
146 return ex_handler_fprestore(e, regs);
147 case EX_TYPE_RDMSR:
148 return ex_handler_rdmsr_unsafe(e, regs);
149 case EX_TYPE_WRMSR:
150 return ex_handler_wrmsr_unsafe(e, regs);
151 case EX_TYPE_BPF:
152 return ex_handler_bpf(e, regs);
153 case EX_TYPE_RDMSR_IN_MCE:
154 ex_handler_msr_mce(regs, false);
155 break;
156 case EX_TYPE_WRMSR_IN_MCE:
157 ex_handler_msr_mce(regs, true);
158 break;
159 }
160 BUG();
184}161}
185 162
186extern unsigned int early_recursion_flag;163extern unsigned int early_recursion_flag;
arch/x86/net/bpf_jit_comp.c+2−9
@@ -803,9 +803,7 @@ static int emit_atomic(u8 **pprog, u8 atomic_op, · 802 unmodified lines
803 return 0;803 return 0;
804}804}
805 805
806static bool ex_handler_bpf(const struct exception_table_entry *x,806bool ex_handler_bpf(const struct exception_table_entry *x, struct pt_regs *regs)
807 struct pt_regs *regs, int trapnr,
808 unsigned long error_code, unsigned long fault_addr)
809{807{
810 u32 reg = x->fixup >> 8;808 u32 reg = x->fixup >> 8;
811 809
@@ -1288,12 +1286,7 @@ st: if (is_imm8(insn->off)) · 476 unmodified lines
1288 }1286 }
1289 ex->insn = delta;1287 ex->insn = delta;
1290 1288
1291 delta = (u8 *)ex_handler_bpf - (u8 *)&ex->handler;1289 ex->type = EX_TYPE_BPF;
1292 if (!is_simm32(delta)) {
1293 pr_err("extable->handler doesn't fit into 32-bit\n");
1294 return -EFAULT;
1295 }
1296 ex->handler = delta;
1297 1290
1298 if (dst_reg > BPF_REG_9) {1291 if (dst_reg > BPF_REG_9) {
1299 pr_err("verifier error\n");1292 pr_err("verifier error\n");
arch/x86/power/cpu.c+1−1
@@ -20,7 +20,7 @@ · 19 unmodified lines
20#include <asm/page.h>20#include <asm/page.h>
21#include <asm/mce.h>21#include <asm/mce.h>
22#include <asm/suspend.h>22#include <asm/suspend.h>
23#include <asm/fpu/internal.h>23#include <asm/fpu/api.h>
24#include <asm/debugreg.h>24#include <asm/debugreg.h>
25#include <asm/cpu.h>25#include <asm/cpu.h>
26#include <asm/mmu_context.h>26#include <asm/mmu_context.h>
include/linux/signal.h+6−0
@@ -464,6 +464,12 @@ int __save_altstack(stack_t __user *, unsigned long); · 463 unmodified lines
464 unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \464 unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \
465} while (0);465} while (0);
466 466
467#ifdef CONFIG_DYNAMIC_SIGFRAME
468bool sigaltstack_size_valid(size_t ss_size);
469#else
470static inline bool sigaltstack_size_valid(size_t size) { return true; }
471#endif /* !CONFIG_DYNAMIC_SIGFRAME */
472
467#ifdef CONFIG_PROC_FS473#ifdef CONFIG_PROC_FS
468struct seq_file;474struct seq_file;
469extern void render_sigset_t(struct seq_file *, const char *, sigset_t *);475extern void render_sigset_t(struct seq_file *, const char *, sigset_t *);
kernel/signal.c+29−6
@@ -4138,11 +4138,29 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) · 4137 unmodified lines
4138 return 0;4138 return 0;
4139}4139}
4140 4140
4141#ifdef CONFIG_DYNAMIC_SIGFRAME
4142static inline void sigaltstack_lock(void)
4143 __acquires(&current->sighand->siglock)
4144{
4145 spin_lock_irq(&current->sighand->siglock);
4146}
4147
4148static inline void sigaltstack_unlock(void)
4149 __releases(&current->sighand->siglock)
4150{
4151 spin_unlock_irq(&current->sighand->siglock);
4152}
4153#else
4154static inline void sigaltstack_lock(void) { }
4155static inline void sigaltstack_unlock(void) { }
4156#endif
4157
4141static int4158static int
4142do_sigaltstack (const stack_t *ss, stack_t *oss, unsigned long sp,4159do_sigaltstack (const stack_t *ss, stack_t *oss, unsigned long sp,
4143 size_t min_ss_size)4160 size_t min_ss_size)
4144{4161{
4145 struct task_struct *t = current;4162 struct task_struct *t = current;
4163 int ret = 0;
4146 4164
4147 if (oss) {4165 if (oss) {
4148 memset(oss, 0, sizeof(stack_t));4166 memset(oss, 0, sizeof(stack_t));
@@ -4166,19 +4184,24 @@ do_sigaltstack (const stack_t *ss, stack_t *oss, unsigned long sp, · 17 unmodified lines
4166 ss_mode != 0))4184 ss_mode != 0))
4167 return -EINVAL;4185 return -EINVAL;
4168 4186
4187 sigaltstack_lock();
4169 if (ss_mode == SS_DISABLE) {4188 if (ss_mode == SS_DISABLE) {
4170 ss_size = 0;4189 ss_size = 0;
4171 ss_sp = NULL;4190 ss_sp = NULL;
4172 } else {4191 } else {
4173 if (unlikely(ss_size < min_ss_size))4192 if (unlikely(ss_size < min_ss_size))
4174 return -ENOMEM;4193 ret = -ENOMEM;
4194 if (!sigaltstack_size_valid(ss_size))
4195 ret = -ENOMEM;
4175 }4196 }
4176 4197 if (!ret) {
4177 t->sas_ss_sp = (unsigned long) ss_sp;4198 t->sas_ss_sp = (unsigned long) ss_sp;
4178 t->sas_ss_size = ss_size;4199 t->sas_ss_size = ss_size;
4179 t->sas_ss_flags = ss_flags;4200 t->sas_ss_flags = ss_flags;
4201 }
4202 sigaltstack_unlock();
4180 }4203 }
4181 return 0;4204 return ret;
4182}4205}
4183 4206
4184SYSCALL_DEFINE2(sigaltstack,const stack_t __user *,uss, stack_t __user *,uoss)4207SYSCALL_DEFINE2(sigaltstack,const stack_t __user *,uss, stack_t __user *,uoss)
scripts/sorttable.c+2−2
@@ -240,7 +240,7 @@ static void x86_sort_relative_table(char *extab_image, int image_size) · 239 unmodified lines
240 240
241 w(r(loc) + i, loc);241 w(r(loc) + i, loc);
242 w(r(loc + 1) + i + 4, loc + 1);242 w(r(loc + 1) + i + 4, loc + 1);
243 w(r(loc + 2) + i + 8, loc + 2);243 /* Don't touch the fixup type */
244 244
245 i += sizeof(uint32_t) * 3;245 i += sizeof(uint32_t) * 3;
246 }246 }
@@ -253,7 +253,7 @@ static void x86_sort_relative_table(char *extab_image, int image_size) · 6 unmodified lines
253 253
254 w(r(loc) - i, loc);254 w(r(loc) - i, loc);
255 w(r(loc + 1) - (i + 4), loc + 1);255 w(r(loc + 1) - (i + 4), loc + 1);
256 w(r(loc + 2) - (i + 8), loc + 2);256 /* Don't touch the fixup type */
257 257
258 i += sizeof(uint32_t) * 3;258 i += sizeof(uint32_t) * 3;
259 }259 }
tools/testing/selftests/x86/Makefile+1−1
@@ -18,7 +18,7 @@ TARGETS_C_32BIT_ONLY := entry_from_vm86 test_syscall_vdso unwind_vdso \ · 17 unmodified lines
18 test_FCMOV test_FCOMI test_FISTTP \18 test_FCMOV test_FCOMI test_FISTTP \
19 vdso_restorer19 vdso_restorer
20TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip syscall_numbering \20TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip syscall_numbering \
21 corrupt_xstate_header21 corrupt_xstate_header amx
22# Some selftests require 32bit support enabled also on 64bit systems22# Some selftests require 32bit support enabled also on 64bit systems
23TARGETS_C_32BIT_NEEDED := ldt_gdt ptrace_syscall23TARGETS_C_32BIT_NEEDED := ldt_gdt ptrace_syscall
24 24
tools/testing/selftests/x86/amx.c+851−0
@@ -0,0 +1,851 @@
1// SPDX-License-Identifier: GPL-2.0
2
3#define _GNU_SOURCE
4#include <err.h>
5#include <errno.h>
6#include <pthread.h>
7#include <setjmp.h>
8#include <stdio.h>
9#include <string.h>
10#include <stdbool.h>
11#include <unistd.h>
12#include <x86intrin.h>
13
14#include <sys/auxv.h>
15#include <sys/mman.h>
16#include <sys/shm.h>
17#include <sys/syscall.h>
18#include <sys/wait.h>
19
20#ifndef __x86_64__
21# error This test is 64-bit only
22#endif
23
24#define XSAVE_HDR_OFFSET 512
25#define XSAVE_HDR_SIZE 64
26
27struct xsave_buffer {
28 union {
29 struct {
30 char legacy[XSAVE_HDR_OFFSET];
31 char header[XSAVE_HDR_SIZE];
32 char extended[0];
33 };
34 char bytes[0];
35 };
36};
37
38static inline uint64_t xgetbv(uint32_t index)
39{
40 uint32_t eax, edx;
41
42 asm volatile("xgetbv;"
43 : "=a" (eax), "=d" (edx)
44 : "c" (index));
45 return eax + ((uint64_t)edx << 32);
46}
47
48static inline void cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
49{
50 asm volatile("cpuid;"
51 : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
52 : "0" (*eax), "2" (*ecx));
53}
54
55static inline void xsave(struct xsave_buffer *xbuf, uint64_t rfbm)
56{
57 uint32_t rfbm_lo = rfbm;
58 uint32_t rfbm_hi = rfbm >> 32;
59
60 asm volatile("xsave (%%rdi)"
61 : : "D" (xbuf), "a" (rfbm_lo), "d" (rfbm_hi)
62 : "memory");
63}
64
65static inline void xrstor(struct xsave_buffer *xbuf, uint64_t rfbm)
66{
67 uint32_t rfbm_lo = rfbm;
68 uint32_t rfbm_hi = rfbm >> 32;
69
70 asm volatile("xrstor (%%rdi)"
71 : : "D" (xbuf), "a" (rfbm_lo), "d" (rfbm_hi));
72}
73
74/* err() exits and will not return */
75#define fatal_error(msg, ...) err(1, "[FAIL]\t" msg, ##__VA_ARGS__)
76
77static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
78 int flags)
79{
80 struct sigaction sa;
81
82 memset(&sa, 0, sizeof(sa));
83 sa.sa_sigaction = handler;
84 sa.sa_flags = SA_SIGINFO | flags;
85 sigemptyset(&sa.sa_mask);
86 if (sigaction(sig, &sa, 0))
87 fatal_error("sigaction");
88}
89
90static void clearhandler(int sig)
91{
92 struct sigaction sa;
93
94 memset(&sa, 0, sizeof(sa));
95 sa.sa_handler = SIG_DFL;
96 sigemptyset(&sa.sa_mask);
97 if (sigaction(sig, &sa, 0))
98 fatal_error("sigaction");
99}
100
101#define XFEATURE_XTILECFG 17
102#define XFEATURE_XTILEDATA 18
103#define XFEATURE_MASK_XTILECFG (1 << XFEATURE_XTILECFG)
104#define XFEATURE_MASK_XTILEDATA (1 << XFEATURE_XTILEDATA)
105#define XFEATURE_MASK_XTILE (XFEATURE_MASK_XTILECFG | XFEATURE_MASK_XTILEDATA)
106
107#define CPUID_LEAF1_ECX_XSAVE_MASK (1 << 26)
108#define CPUID_LEAF1_ECX_OSXSAVE_MASK (1 << 27)
109static inline void check_cpuid_xsave(void)
110{
111 uint32_t eax, ebx, ecx, edx;
112
113 /*
114 * CPUID.1:ECX.XSAVE[bit 26] enumerates general
115 * support for the XSAVE feature set, including
116 * XGETBV.
117 */
118 eax = 1;
119 ecx = 0;
120 cpuid(&eax, &ebx, &ecx, &edx);
121 if (!(ecx & CPUID_LEAF1_ECX_XSAVE_MASK))
122 fatal_error("cpuid: no CPU xsave support");
123 if (!(ecx & CPUID_LEAF1_ECX_OSXSAVE_MASK))
124 fatal_error("cpuid: no OS xsave support");
125}
126
127static uint32_t xbuf_size;
128
129static struct {
130 uint32_t xbuf_offset;
131 uint32_t size;
132} xtiledata;
133
134#define CPUID_LEAF_XSTATE 0xd
135#define CPUID_SUBLEAF_XSTATE_USER 0x0
136#define TILE_CPUID 0x1d
137#define TILE_PALETTE_ID 0x1
138
139static void check_cpuid_xtiledata(void)
140{
141 uint32_t eax, ebx, ecx, edx;
142
143 eax = CPUID_LEAF_XSTATE;
144 ecx = CPUID_SUBLEAF_XSTATE_USER;
145 cpuid(&eax, &ebx, &ecx, &edx);
146
147 /*
148 * EBX enumerates the size (in bytes) required by the XSAVE
149 * instruction for an XSAVE area containing all the user state
150 * components corresponding to bits currently set in XCR0.
151 *
152 * Stash that off so it can be used to allocate buffers later.
153 */
154 xbuf_size = ebx;
155
156 eax = CPUID_LEAF_XSTATE;
157 ecx = XFEATURE_XTILEDATA;
158
159 cpuid(&eax, &ebx, &ecx, &edx);
160 /*
161 * eax: XTILEDATA state component size
162 * ebx: XTILEDATA state component offset in user buffer
163 */
164 if (!eax || !ebx)
165 fatal_error("xstate cpuid: invalid tile data size/offset: %d/%d",
166 eax, ebx);
167
168 xtiledata.size = eax;
169 xtiledata.xbuf_offset = ebx;
170}
171
172/* The helpers for managing XSAVE buffer and tile states: */
173
174struct xsave_buffer *alloc_xbuf(void)
175{
176 struct xsave_buffer *xbuf;
177
178 /* XSAVE buffer should be 64B-aligned. */
179 xbuf = aligned_alloc(64, xbuf_size);
180 if (!xbuf)
181 fatal_error("aligned_alloc()");
182 return xbuf;
183}
184
185static inline void clear_xstate_header(struct xsave_buffer *buffer)
186{
187 memset(&buffer->header, 0, sizeof(buffer->header));
188}
189
190static inline uint64_t get_xstatebv(struct xsave_buffer *buffer)
191{
192 /* XSTATE_BV is at the beginning of the header: */
193 return *(uint64_t *)&buffer->header;
194}
195
196static inline void set_xstatebv(struct xsave_buffer *buffer, uint64_t bv)
197{
198 /* XSTATE_BV is at the beginning of the header: */
199 *(uint64_t *)(&buffer->header) = bv;
200}
201
202static void set_rand_tiledata(struct xsave_buffer *xbuf)
203{
204 int *ptr = (int *)&xbuf->bytes[xtiledata.xbuf_offset];
205 int data;
206 int i;
207
208 /*
209 * Ensure that 'data' is never 0. This ensures that
210 * the registers are never in their initial configuration
211 * and thus never tracked as being in the init state.
212 */
213 data = rand() | 1;
214
215 for (i = 0; i < xtiledata.size / sizeof(int); i++, ptr++)
216 *ptr = data;
217}
218
219struct xsave_buffer *stashed_xsave;
220
221static void init_stashed_xsave(void)
222{
223 stashed_xsave = alloc_xbuf();
224 if (!stashed_xsave)
225 fatal_error("failed to allocate stashed_xsave\n");
226 clear_xstate_header(stashed_xsave);
227}
228
229static void free_stashed_xsave(void)
230{
231 free(stashed_xsave);
232}
233
234/* See 'struct _fpx_sw_bytes' at sigcontext.h */
235#define SW_BYTES_OFFSET 464
236/* N.B. The struct's field name varies so read from the offset. */
237#define SW_BYTES_BV_OFFSET (SW_BYTES_OFFSET + 8)
238
239static inline struct _fpx_sw_bytes *get_fpx_sw_bytes(void *buffer)
240{
241 return (struct _fpx_sw_bytes *)(buffer + SW_BYTES_OFFSET);
242}
243
244static inline uint64_t get_fpx_sw_bytes_features(void *buffer)
245{
246 return *(uint64_t *)(buffer + SW_BYTES_BV_OFFSET);
247}
248
249/* Work around printf() being unsafe in signals: */
250#define SIGNAL_BUF_LEN 1000
251char signal_message_buffer[SIGNAL_BUF_LEN];
252void sig_print(char *msg)
253{
254 int left = SIGNAL_BUF_LEN - strlen(signal_message_buffer) - 1;
255
256 strncat(signal_message_buffer, msg, left);
257}
258
259static volatile bool noperm_signaled;
260static int noperm_errs;
261/*
262 * Signal handler for when AMX is used but
263 * permission has not been obtained.
264 */
265static void handle_noperm(int sig, siginfo_t *si, void *ctx_void)
266{
267 ucontext_t *ctx = (ucontext_t *)ctx_void;
268 void *xbuf = ctx->uc_mcontext.fpregs;
269 struct _fpx_sw_bytes *sw_bytes;
270 uint64_t features;
271
272 /* Reset the signal message buffer: */
273 signal_message_buffer[0] = '\0';
274 sig_print("\tAt SIGILL handler,\n");
275
276 if (si->si_code != ILL_ILLOPC) {
277 noperm_errs++;
278 sig_print("[FAIL]\tInvalid signal code.\n");
279 } else {
280 sig_print("[OK]\tValid signal code (ILL_ILLOPC).\n");
281 }
282
283 sw_bytes = get_fpx_sw_bytes(xbuf);
284 /*
285 * Without permission, the signal XSAVE buffer should not
286 * have room for AMX register state (aka. xtiledata).
287 * Check that the size does not overlap with where xtiledata
288 * will reside.
289 *
290 * This also implies that no state components *PAST*
291 * XTILEDATA (features >=19) can be present in the buffer.
292 */
293 if (sw_bytes->xstate_size <= xtiledata.xbuf_offset) {
294 sig_print("[OK]\tValid xstate size\n");
295 } else {
296 noperm_errs++;
297 sig_print("[FAIL]\tInvalid xstate size\n");
298 }
299
300 features = get_fpx_sw_bytes_features(xbuf);
301 /*
302 * Without permission, the XTILEDATA feature
303 * bit should not be set.
304 */
305 if ((features & XFEATURE_MASK_XTILEDATA) == 0) {
306 sig_print("[OK]\tValid xstate mask\n");
307 } else {
308 noperm_errs++;
309 sig_print("[FAIL]\tInvalid xstate mask\n");
310 }
311
312 noperm_signaled = true;
313 ctx->uc_mcontext.gregs[REG_RIP] += 3; /* Skip the faulting XRSTOR */
314}
315
316/* Return true if XRSTOR is successful; otherwise, false. */
317static inline bool xrstor_safe(struct xsave_buffer *xbuf, uint64_t mask)
318{
319 noperm_signaled = false;
320 xrstor(xbuf, mask);
321
322 /* Print any messages produced by the signal code: */
323 printf("%s", signal_message_buffer);
324 /*
325 * Reset the buffer to make sure any future printing
326 * only outputs new messages:
327 */
328 signal_message_buffer[0] = '\0';
329
330 if (noperm_errs)
331 fatal_error("saw %d errors in noperm signal handler\n", noperm_errs);
332
333 return !noperm_signaled;
334}
335
336/*
337 * Use XRSTOR to populate the XTILEDATA registers with
338 * random data.
339 *
340 * Return true if successful; otherwise, false.
341 */
342static inline bool load_rand_tiledata(struct xsave_buffer *xbuf)
343{
344 clear_xstate_header(xbuf);
345 set_xstatebv(xbuf, XFEATURE_MASK_XTILEDATA);
346 set_rand_tiledata(xbuf);
347 return xrstor_safe(xbuf, XFEATURE_MASK_XTILEDATA);
348}
349
350/* Return XTILEDATA to its initial configuration. */
351static inline void init_xtiledata(void)
352{
353 clear_xstate_header(stashed_xsave);
354 xrstor_safe(stashed_xsave, XFEATURE_MASK_XTILEDATA);
355}
356
357enum expected_result { FAIL_EXPECTED, SUCCESS_EXPECTED };
358
359/* arch_prctl() and sigaltstack() test */
360
361#define ARCH_GET_XCOMP_PERM 0x1022
362#define ARCH_REQ_XCOMP_PERM 0x1023
363
364static void req_xtiledata_perm(void)
365{
366 syscall(SYS_arch_prctl, ARCH_REQ_XCOMP_PERM, XFEATURE_XTILEDATA);
367}
368
369static void validate_req_xcomp_perm(enum expected_result exp)
370{
371 unsigned long bitmask;
372 long rc;
373
374 rc = syscall(SYS_arch_prctl, ARCH_REQ_XCOMP_PERM, XFEATURE_XTILEDATA);
375 if (exp == FAIL_EXPECTED) {
376 if (rc) {
377 printf("[OK]\tARCH_REQ_XCOMP_PERM saw expected failure..\n");
378 return;
379 }
380
381 fatal_error("ARCH_REQ_XCOMP_PERM saw unexpected success.\n");
382 } else if (rc) {
383 fatal_error("ARCH_REQ_XCOMP_PERM saw unexpected failure.\n");
384 }
385
386 rc = syscall(SYS_arch_prctl, ARCH_GET_XCOMP_PERM, &bitmask);
387 if (rc) {
388 fatal_error("prctl(ARCH_GET_XCOMP_PERM) error: %ld", rc);
389 } else if (bitmask & XFEATURE_MASK_XTILE) {
390 printf("\tARCH_REQ_XCOMP_PERM is successful.\n");
391 }
392}
393
394static void validate_xcomp_perm(enum expected_result exp)
395{
396 bool load_success = load_rand_tiledata(stashed_xsave);
397
398 if (exp == FAIL_EXPECTED) {
399 if (load_success) {
400 noperm_errs++;
401 printf("[FAIL]\tLoad tiledata succeeded.\n");
402 } else {
403 printf("[OK]\tLoad tiledata failed.\n");
404 }
405 } else if (exp == SUCCESS_EXPECTED) {
406 if (load_success) {
407 printf("[OK]\tLoad tiledata succeeded.\n");
408 } else {
409 noperm_errs++;
410 printf("[FAIL]\tLoad tiledata failed.\n");
411 }
412 }
413}
414
415#ifndef AT_MINSIGSTKSZ
416# define AT_MINSIGSTKSZ 51
417#endif
418
419static void *alloc_altstack(unsigned int size)
420{
421 void *altstack;
422
423 altstack = mmap(NULL, size, PROT_READ | PROT_WRITE,
424 MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
425
426 if (altstack == MAP_FAILED)
427 fatal_error("mmap() for altstack");
428
429 return altstack;
430}
431
432static void setup_altstack(void *addr, unsigned long size, enum expected_result exp)
433{
434 stack_t ss;
435 int rc;
436
437 memset(&ss, 0, sizeof(ss));
438 ss.ss_size = size;
439 ss.ss_sp = addr;
440
441 rc = sigaltstack(&ss, NULL);
442
443 if (exp == FAIL_EXPECTED) {
444 if (rc) {
445 printf("[OK]\tsigaltstack() failed.\n");
446 } else {
447 fatal_error("sigaltstack() succeeded unexpectedly.\n");
448 }
449 } else if (rc) {
450 fatal_error("sigaltstack()");
451 }
452}
453
454static void test_dynamic_sigaltstack(void)
455{
456 unsigned int small_size, enough_size;
457 unsigned long minsigstksz;
458 void *altstack;
459
460 minsigstksz = getauxval(AT_MINSIGSTKSZ);
461 printf("\tAT_MINSIGSTKSZ = %lu\n", minsigstksz);
462 /*
463 * getauxval() itself can return 0 for failure or
464 * success. But, in this case, AT_MINSIGSTKSZ
465 * will always return a >=0 value if implemented.
466 * Just check for 0.
467 */
468 if (minsigstksz == 0) {
469 printf("no support for AT_MINSIGSTKSZ, skipping sigaltstack tests\n");
470 return;
471 }
472
473 enough_size = minsigstksz * 2;
474
475 altstack = alloc_altstack(enough_size);
476 printf("\tAllocate memory for altstack (%u bytes).\n", enough_size);
477
478 /*
479 * Try setup_altstack() with a size which can not fit
480 * XTILEDATA. ARCH_REQ_XCOMP_PERM should fail.
481 */
482 small_size = minsigstksz - xtiledata.size;
483 printf("\tAfter sigaltstack() with small size (%u bytes).\n", small_size);
484 setup_altstack(altstack, small_size, SUCCESS_EXPECTED);
485 validate_req_xcomp_perm(FAIL_EXPECTED);
486
487 /*
488 * Try setup_altstack() with a size derived from
489 * AT_MINSIGSTKSZ. It should be more than large enough
490 * and thus ARCH_REQ_XCOMP_PERM should succeed.
491 */
492 printf("\tAfter sigaltstack() with enough size (%u bytes).\n", enough_size);
493 setup_altstack(altstack, enough_size, SUCCESS_EXPECTED);
494 validate_req_xcomp_perm(SUCCESS_EXPECTED);
495
496 /*
497 * Try to coerce setup_altstack() to again accept a
498 * too-small altstack. This ensures that big-enough
499 * sigaltstacks can not shrink to a too-small value
500 * once XTILEDATA permission is established.
501 */
502 printf("\tThen, sigaltstack() with small size (%u bytes).\n", small_size);
503 setup_altstack(altstack, small_size, FAIL_EXPECTED);
504}
505
506static void test_dynamic_state(void)
507{
508 pid_t parent, child, grandchild;
509
510 parent = fork();
511 if (parent < 0) {
512 /* fork() failed */
513 fatal_error("fork");
514 } else if (parent > 0) {
515 int status;
516 /* fork() succeeded. Now in the parent. */
517
518 wait(&status);
519 if (!WIFEXITED(status) || WEXITSTATUS(status))
520 fatal_error("arch_prctl test parent exit");
521 return;
522 }
523 /* fork() succeeded. Now in the child . */
524
525 printf("[RUN]\tCheck ARCH_REQ_XCOMP_PERM around process fork() and sigaltack() test.\n");
526
527 printf("\tFork a child.\n");
528 child = fork();
529 if (child < 0) {
530 fatal_error("fork");
531 } else if (child > 0) {
532 int status;
533
534 wait(&status);
535 if (!WIFEXITED(status) || WEXITSTATUS(status))
536 fatal_error("arch_prctl test child exit");
537 _exit(0);
538 }
539
540 /*
541 * The permission request should fail without an
542 * XTILEDATA-compatible signal stack
543 */
544 printf("\tTest XCOMP_PERM at child.\n");
545 validate_xcomp_perm(FAIL_EXPECTED);
546
547 /*
548 * Set up an XTILEDATA-compatible signal stack and
549 * also obtain permission to populate XTILEDATA.
550 */
551 printf("\tTest dynamic sigaltstack at child:\n");
552 test_dynamic_sigaltstack();
553
554 /* Ensure that XTILEDATA can be populated. */
555 printf("\tTest XCOMP_PERM again at child.\n");
556 validate_xcomp_perm(SUCCESS_EXPECTED);
557
558 printf("\tFork a grandchild.\n");
559 grandchild = fork();
560 if (grandchild < 0) {
561 /* fork() failed */
562 fatal_error("fork");
563 } else if (!grandchild) {
564 /* fork() succeeded. Now in the (grand)child. */
565 printf("\tTest XCOMP_PERM at grandchild.\n");
566
567 /*
568 * Ensure that the grandchild inherited
569 * permission and a compatible sigaltstack:
570 */
571 validate_xcomp_perm(SUCCESS_EXPECTED);
572 } else {
573 int status;
574 /* fork() succeeded. Now in the parent. */
575
576 wait(&status);
577 if (!WIFEXITED(status) || WEXITSTATUS(status))
578 fatal_error("fork test grandchild");
579 }
580
581 _exit(0);
582}
583
584/*
585 * Save current register state and compare it to @xbuf1.'
586 *
587 * Returns false if @xbuf1 matches the registers.
588 * Returns true if @xbuf1 differs from the registers.
589 */
590static inline bool __validate_tiledata_regs(struct xsave_buffer *xbuf1)
591{
592 struct xsave_buffer *xbuf2;
593 int ret;
594
595 xbuf2 = alloc_xbuf();
596 if (!xbuf2)
597 fatal_error("failed to allocate XSAVE buffer\n");
598
599 xsave(xbuf2, XFEATURE_MASK_XTILEDATA);
600 ret = memcmp(&xbuf1->bytes[xtiledata.xbuf_offset],
601 &xbuf2->bytes[xtiledata.xbuf_offset],
602 xtiledata.size);
603
604 free(xbuf2);
605
606 if (ret == 0)
607 return false;
608 return true;
609}
610
611static inline void validate_tiledata_regs_same(struct xsave_buffer *xbuf)
612{
613 int ret = __validate_tiledata_regs(xbuf);
614
615 if (ret != 0)
616 fatal_error("TILEDATA registers changed");
617}
618
619static inline void validate_tiledata_regs_changed(struct xsave_buffer *xbuf)
620{
621 int ret = __validate_tiledata_regs(xbuf);
622
623 if (ret == 0)
624 fatal_error("TILEDATA registers did not change");
625}
626
627/* tiledata inheritance test */
628
629static void test_fork(void)
630{
631 pid_t child, grandchild;
632
633 child = fork();
634 if (child < 0) {
635 /* fork() failed */
636 fatal_error("fork");
637 } else if (child > 0) {
638 /* fork() succeeded. Now in the parent. */
639 int status;
640
641 wait(&status);
642 if (!WIFEXITED(status) || WEXITSTATUS(status))
643 fatal_error("fork test child");
644 return;
645 }
646 /* fork() succeeded. Now in the child. */
647 printf("[RUN]\tCheck tile data inheritance.\n\tBefore fork(), load tiledata\n");
648
649 load_rand_tiledata(stashed_xsave);
650
651 grandchild = fork();
652 if (grandchild < 0) {
653 /* fork() failed */
654 fatal_error("fork");
655 } else if (grandchild > 0) {
656 /* fork() succeeded. Still in the first child. */
657 int status;
658
659 wait(&status);
660 if (!WIFEXITED(status) || WEXITSTATUS(status))
661 fatal_error("fork test grand child");
662 _exit(0);
663 }
664 /* fork() succeeded. Now in the (grand)child. */
665
666 /*
667 * TILEDATA registers are not preserved across fork().
668 * Ensure that their value has changed:
669 */
670 validate_tiledata_regs_changed(stashed_xsave);
671
672 _exit(0);
673}
674
675/* Context switching test */
676
677static struct _ctxtswtest_cfg {
678 unsigned int iterations;
679 unsigned int num_threads;
680} ctxtswtest_config;
681
682struct futex_info {
683 pthread_t thread;
684 int nr;
685 pthread_mutex_t mutex;
686 struct futex_info *next;
687};
688
689static void *check_tiledata(void *info)
690{
691 struct futex_info *finfo = (struct futex_info *)info;
692 struct xsave_buffer *xbuf;
693 int i;
694
695 xbuf = alloc_xbuf();
696 if (!xbuf)
697 fatal_error("unable to allocate XSAVE buffer");
698
699 /*
700 * Load random data into 'xbuf' and then restore
701 * it to the tile registers themselves.
702 */
703 load_rand_tiledata(xbuf);
704 for (i = 0; i < ctxtswtest_config.iterations; i++) {
705 pthread_mutex_lock(&finfo->mutex);
706
707 /*
708 * Ensure the register values have not
709 * diverged from those recorded in 'xbuf'.
710 */
711 validate_tiledata_regs_same(xbuf);
712
713 /* Load new, random values into xbuf and registers */
714 load_rand_tiledata(xbuf);
715
716 /*
717 * The last thread's last unlock will be for
718 * thread 0's mutex. However, thread 0 will
719 * have already exited the loop and the mutex
720 * will already be unlocked.
721 *
722 * Because this is not an ERRORCHECK mutex,
723 * that inconsistency will be silently ignored.
724 */
725 pthread_mutex_unlock(&finfo->next->mutex);
726 }
727
728 free(xbuf);
729 /*
730 * Return this thread's finfo, which is
731 * a unique value for this thread.
732 */
733 return finfo;
734}
735
736static int create_threads(int num, struct futex_info *finfo)
737{
738 int i;
739
740 for (i = 0; i < num; i++) {
741 int next_nr;
742
743 finfo[i].nr = i;
744 /*
745 * Thread 'i' will wait on this mutex to
746 * be unlocked. Lock it immediately after
747 * initialization:
748 */
749 pthread_mutex_init(&finfo[i].mutex, NULL);
750 pthread_mutex_lock(&finfo[i].mutex);
751
752 next_nr = (i + 1) % num;
753 finfo[i].next = &finfo[next_nr];
754
755 if (pthread_create(&finfo[i].thread, NULL, check_tiledata, &finfo[i]))
756 fatal_error("pthread_create()");
757 }
758 return 0;
759}
760
761static void affinitize_cpu0(void)
762{
763 cpu_set_t cpuset;
764
765 CPU_ZERO(&cpuset);
766 CPU_SET(0, &cpuset);
767
768 if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0)
769 fatal_error("sched_setaffinity to CPU 0");
770}
771
772static void test_context_switch(void)
773{
774 struct futex_info *finfo;
775 int i;
776
777 /* Affinitize to one CPU to force context switches */
778 affinitize_cpu0();
779
780 req_xtiledata_perm();
781
782 printf("[RUN]\tCheck tiledata context switches, %d iterations, %d threads.\n",
783 ctxtswtest_config.iterations,
784 ctxtswtest_config.num_threads);
785
786
787 finfo = malloc(sizeof(*finfo) * ctxtswtest_config.num_threads);
788 if (!finfo)
789 fatal_error("malloc()");
790
791 create_threads(ctxtswtest_config.num_threads, finfo);
792
793 /*
794 * This thread wakes up thread 0
795 * Thread 0 will wake up 1
796 * Thread 1 will wake up 2
797 * ...
798 * the last thread will wake up 0
799 *
800 * ... this will repeat for the configured
801 * number of iterations.
802 */
803 pthread_mutex_unlock(&finfo[0].mutex);
804
805 /* Wait for all the threads to finish: */
806 for (i = 0; i < ctxtswtest_config.num_threads; i++) {
807 void *thread_retval;
808 int rc;
809
810 rc = pthread_join(finfo[i].thread, &thread_retval);
811
812 if (rc)
813 fatal_error("pthread_join() failed for thread %d err: %d\n",
814 i, rc);
815
816 if (thread_retval != &finfo[i])
817 fatal_error("unexpected thread retval for thread %d: %p\n",
818 i, thread_retval);
819
820 }
821
822 printf("[OK]\tNo incorrect case was found.\n");
823
824 free(finfo);
825}
826
827int main(void)
828{
829 /* Check hardware availability at first */
830 check_cpuid_xsave();
831 check_cpuid_xtiledata();
832
833 init_stashed_xsave();
834 sethandler(SIGILL, handle_noperm, 0);
835
836 test_dynamic_state();
837
838 /* Request permission for the following tests */
839 req_xtiledata_perm();
840
841 test_fork();
842
843 ctxtswtest_config.iterations = 10;
844 ctxtswtest_config.num_threads = 5;
845 test_context_switch();
846
847 clearhandler(SIGILL);
848 free_stashed_xsave();
849
850 return 0;
851}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t