summaryrefslogtreecommitdiff
path: root/arch/x86/include/asm/fpu
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2021-10-13 17:55:27 +0300
committerBorislav Petkov <bp@suse.de>2021-10-20 23:26:24 +0300
commit87d0e5be0fac322f4415128def9f16a71a267a40 (patch)
tree5d7e073a11499c4c65dab2e15e503a5123464e2e /arch/x86/include/asm/fpu
parentbf5d00470787067ff27593c6a097b5eb6e01168e (diff)
downloadlinux-87d0e5be0fac322f4415128def9f16a71a267a40.tar.xz
x86/fpu: Provide struct fpstate
New xfeatures will not longer be automatically stored in the regular XSAVE buffer in thread_struct::fpu. The kernel will provide the default sized buffer for storing the regular features up to AVX512 in thread_struct::fpu and if a task requests to use one of the new features then the register storage has to be extended. The state will be accessed via a pointer in thread_struct::fpu which defaults to the builtin storage and can be switched when extended storage is required. To avoid conditionals all over the code, create a new container for the register storage which will gain other information, e.g. size, feature masks etc., later. For now it just contains the register storage, which gives it exactly the same layout as the exiting fpu::state. Stick fpu::state and the new fpu::__fpstate into an anonymous union and initialize the pointer. Add build time checks to validate that both are at the same place and have the same size. This allows step by step conversion of all users. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Borislav Petkov <bp@suse.de> Link: https://lkml.kernel.org/r/20211013145322.234458659@linutronix.de
Diffstat (limited to 'arch/x86/include/asm/fpu')
-rw-r--r--arch/x86/include/asm/fpu/types.h20
1 files changed, 19 insertions, 1 deletions
diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h
index f5a38a5f3ae1..3bb6277efbb5 100644
--- a/arch/x86/include/asm/fpu/types.h
+++ b/arch/x86/include/asm/fpu/types.h
@@ -309,6 +309,13 @@ union fpregs_state {
u8 __padding[PAGE_SIZE];
};
+struct fpstate {
+ /* @regs: The register state union for all supported formats */
+ union fpregs_state regs;
+
+ /* @regs is dynamically sized! Don't add anything after @regs! */
+} __aligned(64);
+
/*
* Highest level per task FPU state data structure that
* contains the FPU register state plus various FPU
@@ -337,6 +344,14 @@ struct fpu {
unsigned long avx512_timestamp;
/*
+ * @fpstate:
+ *
+ * Pointer to the active struct fpstate. Initialized to
+ * point at @__fpstate below.
+ */
+ struct fpstate *fpstate;
+
+ /*
* @state:
*
* In-memory copy of all FPU registers that we save/restore
@@ -345,7 +360,10 @@ struct fpu {
* copy. If the task context-switches away then they get
* saved here and represent the FPU state.
*/
- union fpregs_state state;
+ union {
+ struct fpstate __fpstate;
+ union fpregs_state state;
+ };
/*
* WARNING: 'state' is dynamically-sized. Do not put
* anything after it here.