aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/include
diff options
context:
space:
mode:
authorDave Hansen <dave.hansen@linux.intel.com>2015-09-02 19:31:25 -0400
committerIngo Molnar <mingo@kernel.org>2015-09-14 06:07:56 -0400
commit4109ca066b6b899ac7549bf3aac94b178ac95891 (patch)
tree973dcc892511f4f22d8ad3d27c718e9a5eae107d /arch/x86/include
parent0a265375028b241a9173b7c569dd2368ba97fcd4 (diff)
x86/fpu: Remove XSTATE_RESERVE
The original purpose of XSTATE_RESERVE was to carve out space to store all of the possible extended state components that get saved with the XSAVE instruction(s). However, we are now almost entirely dynamically allocating the buffers we use for XSAVE by placing them at the end of the task_struct and them sizing them at boot. The one exception for that is the init_task. The maximum extended state component size that we have today is on systems with space for AVX-512 and Memory Protection Keys: 2696 bytes. We have reserved a PAGE_SIZE buffer in the init_task via fpregs_state->__padding. This check ensures that even if the component sizes or layout were changed (which we do not expect), that we will still not overflow the init_task's buffer. In the case that we detect we might overflow the buffer, we completely disable XSAVE support in the kernel and try to boot as if we had 'legacy x87 FPU' support in place. This is a crippled state without any of the XSAVE-enabled features (MPX, AVX, etc...). But, it at least let us boot safely. Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: Fenghua Yu <fenghua.yu@intel.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Tim Chen <tim.c.chen@linux.intel.com> Cc: dave@sr71.net Cc: linux-kernel@vger.kernel.org Link: http://lkml.kernel.org/r/20150902233125.D948D475@viggo.jf.intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/include')
-rw-r--r--arch/x86/include/asm/fpu/types.h15
1 files changed, 7 insertions, 8 deletions
diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h
index c49c5173158e..6aaafe07338d 100644
--- a/arch/x86/include/asm/fpu/types.h
+++ b/arch/x86/include/asm/fpu/types.h
@@ -159,22 +159,19 @@ struct xstate_header {
159 u64 reserved[6]; 159 u64 reserved[6];
160} __attribute__((packed)); 160} __attribute__((packed));
161 161
162/* New processor state extensions should be added here: */
163#define XSTATE_RESERVE (sizeof(struct ymmh_struct) + \
164 sizeof(struct lwp_struct) + \
165 sizeof(struct mpx_struct) )
166/* 162/*
167 * This is our most modern FPU state format, as saved by the XSAVE 163 * This is our most modern FPU state format, as saved by the XSAVE
168 * and restored by the XRSTOR instructions. 164 * and restored by the XRSTOR instructions.
169 * 165 *
170 * It consists of a legacy fxregs portion, an xstate header and 166 * It consists of a legacy fxregs portion, an xstate header and
171 * subsequent fixed size areas as defined by the xstate header. 167 * subsequent areas as defined by the xstate header. Not all CPUs
172 * Not all CPUs support all the extensions. 168 * support all the extensions, so the size of the extended area
169 * can vary quite a bit between CPUs.
173 */ 170 */
174struct xregs_state { 171struct xregs_state {
175 struct fxregs_state i387; 172 struct fxregs_state i387;
176 struct xstate_header header; 173 struct xstate_header header;
177 u8 __reserved[XSTATE_RESERVE]; 174 u8 extended_state_area[0];
178} __attribute__ ((packed, aligned (64))); 175} __attribute__ ((packed, aligned (64)));
179 176
180/* 177/*
@@ -182,7 +179,9 @@ struct xregs_state {
182 * put together, so that we can pick the right one runtime. 179 * put together, so that we can pick the right one runtime.
183 * 180 *
184 * The size of the structure is determined by the largest 181 * The size of the structure is determined by the largest
185 * member - which is the xsave area: 182 * member - which is the xsave area. The padding is there
183 * to ensure that statically-allocated task_structs (just
184 * the init_task today) have enough space.
186 */ 185 */
187union fpregs_state { 186union fpregs_state {
188 struct fregs_state fsave; 187 struct fregs_state fsave;