All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 14/15] x86, fpu: check to ensure increasing-offset xstate offsets
  2015-08-31 22:20 [PATCH 00/15] [v3] " Dave Hansen
@ 2015-08-31 22:20 ` Dave Hansen
  0 siblings, 0 replies; 35+ messages in thread
From: Dave Hansen @ 2015-08-31 22:20 UTC (permalink / raw)
  To: dave; +Cc: dave.hansen, mingo, x86, bp, fenghua.yu, tim.c.chen, linux-kernel


From: Dave Hansen <dave.hansen@linux.intel.com>

The xstate CPUID leaves enumerate where each state component is
inside the XSAVE buffer, along with the size of the entire
buffer.  Our new XSAVE sanity-checking code extrapolates an
expected _total_ buffer size by looking at the last component
that it encounters.

That method requires that the highest-numbered component also
be the one with the highest offset.  This is a pretty safe
assumption, but let's add some code to ensure it stays true.

To make this check work correctly, we also need to ensure we
only consider the offsets from enabled features because the
offset register (ebx) will return 0 on unsupported features.

This also means that we will preserve the -1's that we
initialized xstate_offsets/sizes[] with.  That will help
find bugs.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Borislav Petkov <bp@alien8.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
---

 b/arch/x86/kernel/fpu/xstate.c |   35 ++++++++++++++++++++++++-----------
 1 file changed, 24 insertions(+), 11 deletions(-)

diff -puN arch/x86/kernel/fpu/xstate.c~x86-fpu-increasing-offset-assumption arch/x86/kernel/fpu/xstate.c
--- a/arch/x86/kernel/fpu/xstate.c~x86-fpu-increasing-offset-assumption	2015-08-31 15:17:37.174009326 -0700
+++ b/arch/x86/kernel/fpu/xstate.c	2015-08-31 15:17:37.177009463 -0700
@@ -185,18 +185,41 @@ void fpu__init_cpu_xstate(void)
 }
 
 /*
+ * Note that in the future we will likely need a pair of
+ * functions here: one for user xstates and the other for
+ * system xstates.  For now, they are the same.
+ */
+static int xfeature_enabled(enum xfeature xfeature)
+{
+	return !!(xfeatures_mask & (1UL << xfeature));
+}
+
+/*
  * Record the offsets and sizes of various xstates contained
  * in the XSAVE state memory layout.
  */
 static void __init setup_xstate_features(void)
 {
 	u32 eax, ebx, ecx, edx, i;
+	/* start at the beginnning of the "extended state" */
+	unsigned int last_good_offset = offsetof(struct xregs_state,
+						 extended_state_area);
 
 	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
-		cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
+		if (!xfeature_enabled(i))
+			continue;
 
+		cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
 		xstate_offsets[i] = ebx;
 		xstate_sizes[i] = eax;
+		/*
+		 * In our xstate size checks, we assume that the
+		 * highest-numbered xstate feature has the
+		 * highest offset in the buffer.  Ensure it does.
+		 */
+		WARN_ONCE(last_good_offset > xstate_offsets[i],
+			"x86/fpu: misordered xstate at %d\n", last_good_offset);
+		last_good_offset = xstate_offsets[i];
 
 		printk(KERN_INFO "x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n", i, ebx, i, eax);
 	}
@@ -226,16 +249,6 @@ static void __init print_xstate_features
 }
 
 /*
- * Note that in the future we will likely need a pair of
- * functions here: one for user xstates and the other for
- * system xstates.  For now, they are the same.
- */
-static int xfeature_enabled(enum xfeature xfeature)
-{
-	return !!(xfeatures_mask & (1UL << xfeature));
-}
-
-/*
  * This function sets up offsets and sizes of all extended states in
  * xsave area. This supports both standard format and compacted format
  * of the xsave aread.
_

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks
@ 2015-09-02 23:31 Dave Hansen
  2015-09-02 23:31 ` [PATCH 02/15] x86, fpu: move XSAVE-disabling code to a helper Dave Hansen
                   ` (15 more replies)
  0 siblings, 16 replies; 35+ messages in thread
From: Dave Hansen @ 2015-09-02 23:31 UTC (permalink / raw)
  To: dave; +Cc: mingo, x86, bp, fenghua.yu, tim.c.chen, linux-kernel

Changes in v4:
 * Fix up a few compile errors/warnings

Changes in v3:
 * rework XSTATE_* macros using Ingo's suggested naming
 * change state size printk to be in decimal
 * add some more sanity-checking to detect and work around
   an undersized 'xregs_state'
 * remove "nr_" from some of the names used.

Changes in v2:
 * remove references to Processor Trace XSAVE state
   (will defer to another patch set)
 * Remove some cruft from last patch
 * move last_good_offset fix in to the patch that
   introduced it

These patches make some updates to the x86 XSAVE code.

They have been build and boot tested including on hardware
and/or simulators with AVX-512 and MPX.  It boots in all
of the tested configurations without hitting any of the
new warnings in this code.  I even added the Memory
Protecion Keys (the xfeature after MPX) patches on top of
this and everything works fine.

There are basically 5 things going on here:
 * removal of the LWP (lightweight profiling) code
 * naming and type cleanups
 * removal of xfeatures_nr variable
 * addition of AVX-512 C structures
 * new sanity checks of XSAVE buffer sizing

Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Borislav Petkov <bp@alien8.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-kernel@vger.kernel.org

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 02/15] x86, fpu: move XSAVE-disabling code to a helper
  2015-09-02 23:31 [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Dave Hansen
@ 2015-09-02 23:31 ` Dave Hansen
  2015-09-14 12:19   ` [tip:x86/fpu] x86/fpu: Move " tip-bot for Dave Hansen
  2015-09-02 23:31 ` [PATCH 01/15] x86, fpu: print xfeature buffer size in decimal Dave Hansen
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Dave Hansen @ 2015-09-02 23:31 UTC (permalink / raw)
  To: dave; +Cc: dave.hansen, mingo, x86, bp, fenghua.yu, tim.c.chen, linux-kernel


From: Dave Hansen <dave.hansen@linux.intel.com>

When we want to _completely_ disable XSAVE support as far as
the kernel is concerned, we have a big set of feature flags
to clear.  We currently only do this in cases where the user
asks for it to be disabled, but we are about to expand the
places where we do it to handle errors too.

Move the code in to xstate.c, and put it in the xstate.h
header.  We will use it in the next patch too.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Borislav Petkov <bp@alien8.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
---

 b/arch/x86/include/asm/fpu/xstate.h |    1 +
 b/arch/x86/kernel/fpu/init.c        |   12 +-----------
 b/arch/x86/kernel/fpu/xstate.c      |   19 +++++++++++++++++++
 3 files changed, 21 insertions(+), 11 deletions(-)

diff -puN arch/x86/include/asm/fpu/xstate.h~clear-all-xsave-cpu-caps arch/x86/include/asm/fpu/xstate.h
--- a/arch/x86/include/asm/fpu/xstate.h~clear-all-xsave-cpu-caps	2015-09-02 15:52:47.582783889 -0700
+++ b/arch/x86/include/asm/fpu/xstate.h	2015-09-02 16:26:19.739216233 -0700
@@ -40,6 +40,7 @@ extern u64 xstate_fx_sw_bytes[USER_XSTAT
 
 extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask);
 
+void fpu__xstate_clear_all_cpu_caps(void);
 void *get_xsave_addr(struct xregs_state *xsave, int xstate);
 const void *get_xsave_field_ptr(int xstate_field);
 
diff -puN arch/x86/kernel/fpu/init.c~clear-all-xsave-cpu-caps arch/x86/kernel/fpu/init.c
--- a/arch/x86/kernel/fpu/init.c~clear-all-xsave-cpu-caps	2015-09-02 15:52:47.583783934 -0700
+++ b/arch/x86/kernel/fpu/init.c	2015-09-02 16:26:19.739216233 -0700
@@ -354,17 +354,7 @@ static int __init x86_noxsave_setup(char
 	if (strlen(s))
 		return 0;
 
-	setup_clear_cpu_cap(X86_FEATURE_XSAVE);
-	setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
-	setup_clear_cpu_cap(X86_FEATURE_XSAVEC);
-	setup_clear_cpu_cap(X86_FEATURE_XSAVES);
-	setup_clear_cpu_cap(X86_FEATURE_AVX);
-	setup_clear_cpu_cap(X86_FEATURE_AVX2);
-	setup_clear_cpu_cap(X86_FEATURE_AVX512F);
-	setup_clear_cpu_cap(X86_FEATURE_AVX512PF);
-	setup_clear_cpu_cap(X86_FEATURE_AVX512ER);
-	setup_clear_cpu_cap(X86_FEATURE_AVX512CD);
-	setup_clear_cpu_cap(X86_FEATURE_MPX);
+	fpu__xstate_clear_all_cpu_caps();
 
 	return 1;
 }
diff -puN arch/x86/kernel/fpu/xstate.c~clear-all-xsave-cpu-caps arch/x86/kernel/fpu/xstate.c
--- a/arch/x86/kernel/fpu/xstate.c~clear-all-xsave-cpu-caps	2015-09-02 15:52:47.585784026 -0700
+++ b/arch/x86/kernel/fpu/xstate.c	2015-09-02 16:26:25.775490411 -0700
@@ -39,6 +39,25 @@ static unsigned int xstate_comp_offsets[
 static unsigned int xfeatures_nr;
 
 /*
+ * Clear all of the X86_FEATURE_* bits that are unavailable
+ * when the CPU has no XSAVE support.
+ */
+void fpu__xstate_clear_all_cpu_caps(void)
+{
+	setup_clear_cpu_cap(X86_FEATURE_XSAVE);
+	setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
+	setup_clear_cpu_cap(X86_FEATURE_XSAVEC);
+	setup_clear_cpu_cap(X86_FEATURE_XSAVES);
+	setup_clear_cpu_cap(X86_FEATURE_AVX);
+	setup_clear_cpu_cap(X86_FEATURE_AVX2);
+	setup_clear_cpu_cap(X86_FEATURE_AVX512F);
+	setup_clear_cpu_cap(X86_FEATURE_AVX512PF);
+	setup_clear_cpu_cap(X86_FEATURE_AVX512ER);
+	setup_clear_cpu_cap(X86_FEATURE_AVX512CD);
+	setup_clear_cpu_cap(X86_FEATURE_MPX);
+}
+
+/*
  * Return whether the system supports a given xfeature.
  *
  * Also return the name of the (most advanced) feature that the caller requested:
_

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 01/15] x86, fpu: print xfeature buffer size in decimal
  2015-09-02 23:31 [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Dave Hansen
  2015-09-02 23:31 ` [PATCH 02/15] x86, fpu: move XSAVE-disabling code to a helper Dave Hansen
@ 2015-09-02 23:31 ` Dave Hansen
  2015-09-14 12:19   ` [tip:x86/fpu] x86/fpu: Print " tip-bot for Dave Hansen
  2015-09-02 23:31 ` [PATCH 04/15] x86, fpu: kill LWP support Dave Hansen
                   ` (13 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Dave Hansen @ 2015-09-02 23:31 UTC (permalink / raw)
  To: dave; +Cc: dave.hansen, mingo, x86, bp, fenghua.yu, tim.c.chen, linux-kernel


From: Dave Hansen <dave.hansen@linux.intel.com>

This is utterly a personal taste thing, but I find it way easier
to read structure sizes in decimal than in hex.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Borislav Petkov <bp@alien8.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
---

 b/arch/x86/kernel/fpu/xstate.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff -puN arch/x86/kernel/fpu/xstate.c~print-decimal arch/x86/kernel/fpu/xstate.c
--- a/arch/x86/kernel/fpu/xstate.c~print-decimal	2015-09-02 15:52:46.798748157 -0700
+++ b/arch/x86/kernel/fpu/xstate.c	2015-09-02 16:26:28.032592932 -0700
@@ -187,7 +187,7 @@ static void __init setup_xstate_features
 		xstate_offsets[leaf] = ebx;
 		xstate_sizes[leaf] = eax;
 
-		printk(KERN_INFO "x86/fpu: xstate_offset[%d]: %04x, xstate_sizes[%d]: %04x\n", leaf, ebx, leaf, eax);
+		printk(KERN_INFO "x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n", leaf, ebx, leaf, eax);
 	}
 }
 
@@ -357,7 +357,7 @@ void __init fpu__init_system_xstate(void
 	setup_init_fpu_buf();
 	setup_xstate_comp();
 
-	pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is 0x%x bytes, using '%s' format.\n",
+	pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n",
 		xfeatures_mask,
 		xstate_size,
 		cpu_has_xsaves ? "compacted" : "standard");
_

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 04/15] x86, fpu: kill LWP support
  2015-09-02 23:31 [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Dave Hansen
  2015-09-02 23:31 ` [PATCH 02/15] x86, fpu: move XSAVE-disabling code to a helper Dave Hansen
  2015-09-02 23:31 ` [PATCH 01/15] x86, fpu: print xfeature buffer size in decimal Dave Hansen
@ 2015-09-02 23:31 ` Dave Hansen
  2015-09-14 12:20   ` [tip:x86/fpu] x86/fpu: Remove partial LWP support definitions tip-bot for Dave Hansen
  2015-09-02 23:31 ` [PATCH 03/15] x86, fpu: remove XSTATE_RESERVE Dave Hansen
                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Dave Hansen @ 2015-09-02 23:31 UTC (permalink / raw)
  To: dave; +Cc: dave.hansen, mingo, x86, bp, fenghua.yu, tim.c.chen, linux-kernel


From: Dave Hansen <dave.hansen@linux.intel.com>

LightWeight Profiling was evidently an AMD profiling feature that
we never got around to implementing.  Remove the references to it.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Borislav Petkov <bp@alien8.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
---

 b/arch/x86/include/asm/fpu/types.h |    5 -----
 1 file changed, 5 deletions(-)

diff -puN arch/x86/include/asm/fpu/types.h~axe-lwp arch/x86/include/asm/fpu/types.h
--- a/arch/x86/include/asm/fpu/types.h~axe-lwp	2015-09-02 15:52:49.170856263 -0700
+++ b/arch/x86/include/asm/fpu/types.h	2015-09-02 16:26:19.738216188 -0700
@@ -132,11 +132,6 @@ struct ymmh_struct {
 	u8				ymmh_space[256];
 };
 
-/* We don't support LWP yet: */
-struct lwp_struct {
-	u8				reserved[128];
-};
-
 /* Intel MPX support: */
 struct bndreg {
 	u64				lower_bound;
_

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 03/15] x86, fpu: remove XSTATE_RESERVE
  2015-09-02 23:31 [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Dave Hansen
                   ` (2 preceding siblings ...)
  2015-09-02 23:31 ` [PATCH 04/15] x86, fpu: kill LWP support Dave Hansen
@ 2015-09-02 23:31 ` Dave Hansen
  2015-09-14 12:20   ` [tip:x86/fpu] x86/fpu: Remove XSTATE_RESERVE tip-bot for Dave Hansen
  2015-09-02 23:31 ` [PATCH 05/15] x86, fpu: XSAVE macro renames Dave Hansen
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Dave Hansen @ 2015-09-02 23:31 UTC (permalink / raw)
  To: dave; +Cc: dave.hansen, mingo, x86, bp, fenghua.yu, tim.c.chen, linux-kernel


From: Dave Hansen <dave.hansen@linux.intel.com>

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: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Borislav Petkov <bp@alien8.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
---

 b/arch/x86/include/asm/fpu/types.h |   15 ++++-----
 b/arch/x86/kernel/fpu/xstate.c     |   60 ++++++++++++++++++++++++++++++++-----
 2 files changed, 59 insertions(+), 16 deletions(-)

diff -puN arch/x86/include/asm/fpu/types.h~remove-xstate_reserve arch/x86/include/asm/fpu/types.h
--- a/arch/x86/include/asm/fpu/types.h~remove-xstate_reserve	2015-09-02 15:52:48.449823403 -0700
+++ b/arch/x86/include/asm/fpu/types.h	2015-09-02 16:26:23.562389888 -0700
@@ -159,22 +159,19 @@ struct xstate_header {
 	u64				reserved[6];
 } __attribute__((packed));
 
-/* New processor state extensions should be added here: */
-#define XSTATE_RESERVE			(sizeof(struct ymmh_struct) + \
-					 sizeof(struct lwp_struct)  + \
-					 sizeof(struct mpx_struct)  )
 /*
  * This is our most modern FPU state format, as saved by the XSAVE
  * and restored by the XRSTOR instructions.
  *
  * It consists of a legacy fxregs portion, an xstate header and
- * subsequent fixed size areas as defined by the xstate header.
- * Not all CPUs support all the extensions.
+ * subsequent areas as defined by the xstate header.  Not all CPUs
+ * support all the extensions, so the size of the extended area
+ * can vary quite a bit between CPUs.
  */
 struct xregs_state {
 	struct fxregs_state		i387;
 	struct xstate_header		header;
-	u8				__reserved[XSTATE_RESERVE];
+	u8				extended_state_area[0];
 } __attribute__ ((packed, aligned (64)));
 
 /*
@@ -182,7 +179,9 @@ struct xregs_state {
  * put together, so that we can pick the right one runtime.
  *
  * The size of the structure is determined by the largest
- * member - which is the xsave area:
+ * member - which is the xsave area.  The padding is there
+ * to ensure that statically-allocated task_structs (just
+ * the init_task today) have enough space.
  */
 union fpregs_state {
 	struct fregs_state		fsave;
diff -puN arch/x86/kernel/fpu/xstate.c~remove-xstate_reserve arch/x86/kernel/fpu/xstate.c
--- a/arch/x86/kernel/fpu/xstate.c~remove-xstate_reserve	2015-09-02 15:52:48.451823494 -0700
+++ b/arch/x86/kernel/fpu/xstate.c	2015-09-02 16:26:19.740216279 -0700
@@ -312,24 +312,64 @@ static void __init setup_init_fpu_buf(vo
 /*
  * Calculate total size of enabled xstates in XCR0/xfeatures_mask.
  */
-static void __init init_xstate_size(void)
+static unsigned int __init calculate_xstate_size(void)
 {
 	unsigned int eax, ebx, ecx, edx;
+	unsigned int calculated_xstate_size;
 	int i;
 
 	if (!cpu_has_xsaves) {
 		cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);
-		xstate_size = ebx;
-		return;
+		calculated_xstate_size = ebx;
+		return calculated_xstate_size;
 	}
 
-	xstate_size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
+	calculated_xstate_size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
 	for (i = 2; i < 64; i++) {
 		if (test_bit(i, (unsigned long *)&xfeatures_mask)) {
 			cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
-			xstate_size += eax;
+			calculated_xstate_size += eax;
 		}
 	}
+	return calculated_xstate_size;
+}
+
+/*
+ * Will the runtime-enumerated 'xstate_size' fit in the init
+ * task's statically-allocated buffer?
+ */
+static bool is_supported_xstate_size(unsigned int test_xstate_size)
+{
+	if (test_xstate_size <= sizeof(union fpregs_state))
+		return true;
+
+	pr_warn("x86/fpu: xstate buffer too small (%zu < %d), disabling xsave\n",
+			sizeof(union fpregs_state), test_xstate_size);
+	return false;
+}
+
+static int init_xstate_size(void)
+{
+	/* Recompute the context size for enabled features: */
+	unsigned int possible_xstate_size = calculate_xstate_size();
+
+	/* Ensure we have the space to store all enabled: */
+	if (!is_supported_xstate_size(possible_xstate_size))
+		return -EINVAL;
+
+	/*
+	 * The size is OK, we are definitely going to use xsave,
+	 * make it known to the world that we need more space.
+	 */
+	xstate_size = possible_xstate_size;
+	return 0;
+}
+
+void fpu__init_disable_system_xstate(void)
+{
+	xfeatures_mask = 0;
+	cr4_clear_bits(X86_CR4_OSXSAVE);
+	fpu__xstate_clear_all_cpu_caps();
 }
 
 /*
@@ -340,6 +380,7 @@ void __init fpu__init_system_xstate(void
 {
 	unsigned int eax, ebx, ecx, edx;
 	static int on_boot_cpu = 1;
+	int err;
 
 	WARN_ON_FPU(!on_boot_cpu);
 	on_boot_cpu = 0;
@@ -367,9 +408,12 @@ void __init fpu__init_system_xstate(void
 
 	/* Enable xstate instructions to be able to continue with initialization: */
 	fpu__init_cpu_xstate();
-
-	/* Recompute the context size for enabled features: */
-	init_xstate_size();
+	err = init_xstate_size();
+	if (err) {
+		/* something went wrong, boot without any XSAVE support */
+		fpu__init_disable_system_xstate();
+		return;
+	}
 
 	update_regset_xstate_info(xstate_size, xfeatures_mask);
 	fpu__init_prepare_fx_sw_frame();
_

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 05/15] x86, fpu: XSAVE macro renames
  2015-09-02 23:31 [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Dave Hansen
                   ` (3 preceding siblings ...)
  2015-09-02 23:31 ` [PATCH 03/15] x86, fpu: remove XSTATE_RESERVE Dave Hansen
@ 2015-09-02 23:31 ` Dave Hansen
  2015-09-14 12:21   ` [tip:x86/fpu] x86/fpu: Rename XSAVE macros tip-bot for Dave Hansen
  2015-09-02 23:31 ` [PATCH 06/15] x86, fpu: rename XFEATURES_NR_MAX Dave Hansen
                   ` (10 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Dave Hansen @ 2015-09-02 23:31 UTC (permalink / raw)
  To: dave; +Cc: dave.hansen, mingo, x86, bp, fenghua.yu, tim.c.chen, linux-kernel


From: Dave Hansen <dave.hansen@linux.intel.com>

There are two concepts that have some confusing naming:
 1. Extended State Component numbers (currently called
    XFEATURE_BIT_*)
 2. Extended State Component masks (currently called XSTATE_*)

The numbers are (currently) from 0-9.  State component 3 is the
bounds registers for MPX, for instance.

But when we want to enable "state component 3", we go set a bit
in XCR0.  The bit we set is 1<<3.  We can check to see if a
state component feature is enabled by looking at its bit.

The current 'xfeature_bit's are at best xfeature bit _numbers_.
Calling them bits is at best inconsistent with ending the enum
list with 'XFEATURES_NR_MAX'.

This patch renames the enum to be 'xfeature'.  These also
happen to be what the Intel documentation calls a "state
component".

We also want to differentiate these from the "XSTATE_*" macros.
The "XSTATE_*" macros are a mask, and we rename them to match.

These macros are reasonably widely used so this patch is a
wee bit big, but this really is just a rename.

The only non-mechanical part of this is the

	s/XSTATE_EXTEND_MASK/XFEATURE_MASK_EXTEND/

We need a better name for it, but that's another patch.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Borislav Petkov <bp@alien8.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
---

 b/arch/x86/crypto/camellia_aesni_avx2_glue.c |    3 +
 b/arch/x86/crypto/camellia_aesni_avx_glue.c  |    3 +
 b/arch/x86/crypto/cast5_avx_glue.c           |    3 +
 b/arch/x86/crypto/cast6_avx_glue.c           |    3 +
 b/arch/x86/crypto/serpent_avx2_glue.c        |    3 +
 b/arch/x86/crypto/serpent_avx_glue.c         |    3 +
 b/arch/x86/crypto/sha1_ssse3_glue.c          |    2 -
 b/arch/x86/crypto/sha256_ssse3_glue.c        |    2 -
 b/arch/x86/crypto/sha512_ssse3_glue.c        |    2 -
 b/arch/x86/crypto/twofish_avx_glue.c         |    2 -
 b/arch/x86/include/asm/fpu/types.h           |   44 +++++++++++++++------------
 b/arch/x86/include/asm/fpu/xstate.h          |   14 +++++---
 b/arch/x86/kernel/fpu/init.c                 |    6 +--
 b/arch/x86/kernel/fpu/regset.c               |    4 +-
 b/arch/x86/kernel/fpu/signal.c               |    6 +--
 b/arch/x86/kernel/fpu/xstate.c               |   36 ++++++++++++----------
 b/arch/x86/kernel/traps.c                    |    2 -
 b/arch/x86/kvm/cpuid.c                       |    4 +-
 b/arch/x86/kvm/x86.c                         |   27 ++++++++--------
 b/arch/x86/kvm/x86.h                         |    6 +--
 b/arch/x86/mm/mpx.c                          |    6 +--
 21 files changed, 101 insertions(+), 80 deletions(-)

diff -puN arch/x86/crypto/camellia_aesni_avx2_glue.c~x86-fpu-rename-xfeature_bit arch/x86/crypto/camellia_aesni_avx2_glue.c
--- a/arch/x86/crypto/camellia_aesni_avx2_glue.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.768883518 -0700
+++ b/arch/x86/crypto/camellia_aesni_avx2_glue.c	2015-09-02 15:52:49.805885204 -0700
@@ -567,7 +567,8 @@ static int __init camellia_aesni_init(vo
 		return -ENODEV;
 	}
 
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+				&feature_name)) {
 		pr_info("CPU feature '%s' is not supported.\n", feature_name);
 		return -ENODEV;
 	}
diff -puN arch/x86/crypto/camellia_aesni_avx_glue.c~x86-fpu-rename-xfeature_bit arch/x86/crypto/camellia_aesni_avx_glue.c
--- a/arch/x86/crypto/camellia_aesni_avx_glue.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.769883563 -0700
+++ b/arch/x86/crypto/camellia_aesni_avx_glue.c	2015-09-02 15:52:49.805885204 -0700
@@ -554,7 +554,8 @@ static int __init camellia_aesni_init(vo
 {
 	const char *feature_name;
 
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+				&feature_name)) {
 		pr_info("CPU feature '%s' is not supported.\n", feature_name);
 		return -ENODEV;
 	}
diff -puN arch/x86/crypto/cast5_avx_glue.c~x86-fpu-rename-xfeature_bit arch/x86/crypto/cast5_avx_glue.c
--- a/arch/x86/crypto/cast5_avx_glue.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.771883654 -0700
+++ b/arch/x86/crypto/cast5_avx_glue.c	2015-09-02 15:52:49.806885250 -0700
@@ -469,7 +469,8 @@ static int __init cast5_init(void)
 {
 	const char *feature_name;
 
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+				&feature_name)) {
 		pr_info("CPU feature '%s' is not supported.\n", feature_name);
 		return -ENODEV;
 	}
diff -puN arch/x86/crypto/cast6_avx_glue.c~x86-fpu-rename-xfeature_bit arch/x86/crypto/cast6_avx_glue.c
--- a/arch/x86/crypto/cast6_avx_glue.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.773883745 -0700
+++ b/arch/x86/crypto/cast6_avx_glue.c	2015-09-02 15:52:49.806885250 -0700
@@ -591,7 +591,8 @@ static int __init cast6_init(void)
 {
 	const char *feature_name;
 
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+				&feature_name)) {
 		pr_info("CPU feature '%s' is not supported.\n", feature_name);
 		return -ENODEV;
 	}
diff -puN arch/x86/crypto/serpent_avx2_glue.c~x86-fpu-rename-xfeature_bit arch/x86/crypto/serpent_avx2_glue.c
--- a/arch/x86/crypto/serpent_avx2_glue.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.774883791 -0700
+++ b/arch/x86/crypto/serpent_avx2_glue.c	2015-09-02 15:52:49.807885295 -0700
@@ -542,7 +542,8 @@ static int __init init(void)
 		pr_info("AVX2 instructions are not detected.\n");
 		return -ENODEV;
 	}
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+				&feature_name)) {
 		pr_info("CPU feature '%s' is not supported.\n", feature_name);
 		return -ENODEV;
 	}
diff -puN arch/x86/crypto/serpent_avx_glue.c~x86-fpu-rename-xfeature_bit arch/x86/crypto/serpent_avx_glue.c
--- a/arch/x86/crypto/serpent_avx_glue.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.776883882 -0700
+++ b/arch/x86/crypto/serpent_avx_glue.c	2015-09-02 15:52:49.807885295 -0700
@@ -597,7 +597,8 @@ static int __init serpent_init(void)
 {
 	const char *feature_name;
 
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+				&feature_name)) {
 		pr_info("CPU feature '%s' is not supported.\n", feature_name);
 		return -ENODEV;
 	}
diff -puN arch/x86/crypto/sha1_ssse3_glue.c~x86-fpu-rename-xfeature_bit arch/x86/crypto/sha1_ssse3_glue.c
--- a/arch/x86/crypto/sha1_ssse3_glue.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.778883973 -0700
+++ b/arch/x86/crypto/sha1_ssse3_glue.c	2015-09-02 15:52:49.807885295 -0700
@@ -121,7 +121,7 @@ static struct shash_alg alg = {
 #ifdef CONFIG_AS_AVX
 static bool __init avx_usable(void)
 {
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, NULL)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
 		if (cpu_has_avx)
 			pr_info("AVX detected but unusable.\n");
 		return false;
diff -puN arch/x86/crypto/sha256_ssse3_glue.c~x86-fpu-rename-xfeature_bit arch/x86/crypto/sha256_ssse3_glue.c
--- a/arch/x86/crypto/sha256_ssse3_glue.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.779884019 -0700
+++ b/arch/x86/crypto/sha256_ssse3_glue.c	2015-09-02 15:52:49.808885341 -0700
@@ -130,7 +130,7 @@ static struct shash_alg algs[] = { {
 #ifdef CONFIG_AS_AVX
 static bool __init avx_usable(void)
 {
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, NULL)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
 		if (cpu_has_avx)
 			pr_info("AVX detected but unusable.\n");
 		return false;
diff -puN arch/x86/crypto/sha512_ssse3_glue.c~x86-fpu-rename-xfeature_bit arch/x86/crypto/sha512_ssse3_glue.c
--- a/arch/x86/crypto/sha512_ssse3_glue.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.781884110 -0700
+++ b/arch/x86/crypto/sha512_ssse3_glue.c	2015-09-02 15:52:49.808885341 -0700
@@ -129,7 +129,7 @@ static struct shash_alg algs[] = { {
 #ifdef CONFIG_AS_AVX
 static bool __init avx_usable(void)
 {
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, NULL)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
 		if (cpu_has_avx)
 			pr_info("AVX detected but unusable.\n");
 		return false;
diff -puN arch/x86/crypto/twofish_avx_glue.c~x86-fpu-rename-xfeature_bit arch/x86/crypto/twofish_avx_glue.c
--- a/arch/x86/crypto/twofish_avx_glue.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.783884201 -0700
+++ b/arch/x86/crypto/twofish_avx_glue.c	2015-09-02 15:52:49.808885341 -0700
@@ -558,7 +558,7 @@ static int __init twofish_init(void)
 {
 	const char *feature_name;
 
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
 		pr_info("CPU feature '%s' is not supported.\n", feature_name);
 		return -ENODEV;
 	}
diff -puN arch/x86/include/asm/fpu/types.h~x86-fpu-rename-xfeature_bit arch/x86/include/asm/fpu/types.h
--- a/arch/x86/include/asm/fpu/types.h~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.784884247 -0700
+++ b/arch/x86/include/asm/fpu/types.h	2015-09-02 16:25:46.638712748 -0700
@@ -95,30 +95,36 @@ struct swregs_state {
 /*
  * List of XSAVE features Linux knows about:
  */
-enum xfeature_bit {
-	XSTATE_BIT_FP,
-	XSTATE_BIT_SSE,
-	XSTATE_BIT_YMM,
-	XSTATE_BIT_BNDREGS,
-	XSTATE_BIT_BNDCSR,
-	XSTATE_BIT_OPMASK,
-	XSTATE_BIT_ZMM_Hi256,
-	XSTATE_BIT_Hi16_ZMM,
+enum xfeature {
+	XFEATURE_FP,
+	XFEATURE_SSE,
+	/*
+	 * Values above here are "legacy states".
+	 * Those below are "extended states".
+	 */
+	XFEATURE_YMM,
+	XFEATURE_BNDREGS,
+	XFEATURE_BNDCSR,
+	XFEATURE_OPMASK,
+	XFEATURE_ZMM_Hi256,
+	XFEATURE_Hi16_ZMM,
 
 	XFEATURES_NR_MAX,
 };
 
-#define XSTATE_FP		(1 << XSTATE_BIT_FP)
-#define XSTATE_SSE		(1 << XSTATE_BIT_SSE)
-#define XSTATE_YMM		(1 << XSTATE_BIT_YMM)
-#define XSTATE_BNDREGS		(1 << XSTATE_BIT_BNDREGS)
-#define XSTATE_BNDCSR		(1 << XSTATE_BIT_BNDCSR)
-#define XSTATE_OPMASK		(1 << XSTATE_BIT_OPMASK)
-#define XSTATE_ZMM_Hi256	(1 << XSTATE_BIT_ZMM_Hi256)
-#define XSTATE_Hi16_ZMM		(1 << XSTATE_BIT_Hi16_ZMM)
+#define XFEATURE_MASK_FP		(1 << XFEATURE_FP)
+#define XFEATURE_MASK_SSE		(1 << XFEATURE_SSE)
+#define XFEATURE_MASK_YMM		(1 << XFEATURE_YMM)
+#define XFEATURE_MASK_BNDREGS		(1 << XFEATURE_BNDREGS)
+#define XFEATURE_MASK_BNDCSR		(1 << XFEATURE_BNDCSR)
+#define XFEATURE_MASK_OPMASK		(1 << XFEATURE_OPMASK)
+#define XFEATURE_MASK_ZMM_Hi256		(1 << XFEATURE_ZMM_Hi256)
+#define XFEATURE_MASK_Hi16_ZMM		(1 << XFEATURE_Hi16_ZMM)
 
-#define XSTATE_FPSSE		(XSTATE_FP | XSTATE_SSE)
-#define XSTATE_AVX512		(XSTATE_OPMASK | XSTATE_ZMM_Hi256 | XSTATE_Hi16_ZMM)
+#define XFEATURE_MASK_FPSSE		(XFEATURE_MASK_FP | XFEATURE_MASK_SSE)
+#define XFEATURE_MASK_AVX512		(XFEATURE_MASK_OPMASK \
+					 | XFEATURE_MASK_ZMM_Hi256 \
+					 | XFEATURE_MASK_Hi16_ZMM)
 
 /*
  * There are 16x 256-bit AVX registers named YMM0-YMM15.
diff -puN arch/x86/include/asm/fpu/xstate.h~x86-fpu-rename-xfeature_bit arch/x86/include/asm/fpu/xstate.h
--- a/arch/x86/include/asm/fpu/xstate.h~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.786884338 -0700
+++ b/arch/x86/include/asm/fpu/xstate.h	2015-09-02 16:26:07.201646755 -0700
@@ -6,7 +6,7 @@
 #include <linux/uaccess.h>
 
 /* Bit 63 of XCR0 is reserved for future expansion */
-#define XSTATE_EXTEND_MASK	(~(XSTATE_FPSSE | (1ULL << 63)))
+#define XFEATURE_MASK_EXTEND	(~(XFEATURE_MASK_FPSSE | (1ULL << 63)))
 
 #define XSTATE_CPUID		0x0000000d
 
@@ -19,14 +19,18 @@
 #define XSAVE_YMM_OFFSET    (XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET)
 
 /* Supported features which support lazy state saving */
-#define XSTATE_LAZY	(XSTATE_FP | XSTATE_SSE | XSTATE_YMM		      \
-			| XSTATE_OPMASK | XSTATE_ZMM_Hi256 | XSTATE_Hi16_ZMM)
+#define XFEATURE_MASK_LAZY	(XFEATURE_MASK_FP | \
+				 XFEATURE_MASK_SSE | \
+				 XFEATURE_MASK_YMM | \
+				 XFEATURE_MASK_OPMASK |	\
+				 XFEATURE_MASK_ZMM_Hi256 | \
+				 XFEATURE_MASK_Hi16_ZMM)
 
 /* Supported features which require eager state saving */
-#define XSTATE_EAGER	(XSTATE_BNDREGS | XSTATE_BNDCSR)
+#define XFEATURE_MASK_EAGER	(XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR)
 
 /* All currently supported features */
-#define XCNTXT_MASK	(XSTATE_LAZY | XSTATE_EAGER)
+#define XCNTXT_MASK	(XFEATURE_MASK_LAZY | XFEATURE_MASK_EAGER)
 
 #ifdef CONFIG_X86_64
 #define REX_PREFIX	"0x48, "
diff -puN arch/x86/kernel/fpu/init.c~x86-fpu-rename-xfeature_bit arch/x86/kernel/fpu/init.c
--- a/arch/x86/kernel/fpu/init.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.788884429 -0700
+++ b/arch/x86/kernel/fpu/init.c	2015-09-02 15:52:49.809885386 -0700
@@ -290,11 +290,11 @@ static void __init fpu__init_system_ctx_
 	if (cpu_has_xsaveopt && eagerfpu != DISABLE)
 		eagerfpu = ENABLE;
 
-	if (xfeatures_mask & XSTATE_EAGER) {
+	if (xfeatures_mask & XFEATURE_MASK_EAGER) {
 		if (eagerfpu == DISABLE) {
 			pr_err("x86/fpu: eagerfpu switching disabled, disabling the following xstate features: 0x%llx.\n",
-			       xfeatures_mask & XSTATE_EAGER);
-			xfeatures_mask &= ~XSTATE_EAGER;
+			       xfeatures_mask & XFEATURE_MASK_EAGER);
+			xfeatures_mask &= ~XFEATURE_MASK_EAGER;
 		} else {
 			eagerfpu = ENABLE;
 		}
diff -puN arch/x86/kernel/fpu/regset.c~x86-fpu-rename-xfeature_bit arch/x86/kernel/fpu/regset.c
--- a/arch/x86/kernel/fpu/regset.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.789884475 -0700
+++ b/arch/x86/kernel/fpu/regset.c	2015-09-02 15:52:49.810885432 -0700
@@ -66,7 +66,7 @@ int xfpregs_set(struct task_struct *targ
 	 * presence of FP and SSE state.
 	 */
 	if (cpu_has_xsave)
-		fpu->state.xsave.header.xfeatures |= XSTATE_FPSSE;
+		fpu->state.xsave.header.xfeatures |= XFEATURE_MASK_FPSSE;
 
 	return ret;
 }
@@ -326,7 +326,7 @@ int fpregs_set(struct task_struct *targe
 	 * presence of FP.
 	 */
 	if (cpu_has_xsave)
-		fpu->state.xsave.header.xfeatures |= XSTATE_FP;
+		fpu->state.xsave.header.xfeatures |= XFEATURE_MASK_FP;
 	return ret;
 }
 
diff -puN arch/x86/kernel/fpu/signal.c~x86-fpu-rename-xfeature_bit arch/x86/kernel/fpu/signal.c
--- a/arch/x86/kernel/fpu/signal.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.791884566 -0700
+++ b/arch/x86/kernel/fpu/signal.c	2015-09-02 15:52:49.810885432 -0700
@@ -107,7 +107,7 @@ static inline int save_xstate_epilog(voi
 	 * header as well as change any contents in the memory layout.
 	 * xrestore as part of sigreturn will capture all the changes.
 	 */
-	xfeatures |= XSTATE_FPSSE;
+	xfeatures |= XFEATURE_MASK_FPSSE;
 
 	err |= __put_user(xfeatures, (__u32 *)&x->header.xfeatures);
 
@@ -207,7 +207,7 @@ sanitize_restored_xstate(struct task_str
 		 * layout and not enabled by the OS.
 		 */
 		if (fx_only)
-			header->xfeatures = XSTATE_FPSSE;
+			header->xfeatures = XFEATURE_MASK_FPSSE;
 		else
 			header->xfeatures &= (xfeatures_mask & xfeatures);
 	}
@@ -230,7 +230,7 @@ static inline int copy_user_to_fpregs_ze
 {
 	if (use_xsave()) {
 		if ((unsigned long)buf % 64 || fx_only) {
-			u64 init_bv = xfeatures_mask & ~XSTATE_FPSSE;
+			u64 init_bv = xfeatures_mask & ~XFEATURE_MASK_FPSSE;
 			copy_kernel_to_xregs(&init_fpstate.xsave, init_bv);
 			return copy_user_to_fxregs(buf);
 		} else {
diff -puN arch/x86/kernel/fpu/xstate.c~x86-fpu-rename-xfeature_bit arch/x86/kernel/fpu/xstate.c
--- a/arch/x86/kernel/fpu/xstate.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.792884612 -0700
+++ b/arch/x86/kernel/fpu/xstate.c	2015-09-02 16:25:46.638712748 -0700
@@ -72,7 +72,7 @@ int cpu_has_xfeatures(u64 xfeatures_need
 		/*
 		 * So we use FLS here to be able to print the most advanced
 		 * feature that was requested but is missing. So if a driver
-		 * asks about "XSTATE_SSE | XSTATE_YMM" we'll print the
+		 * asks about "XFEATURE_MASK_SSE | XFEATURE_MASK_YMM" we'll print the
 		 * missing AVX feature - this is the most informative message
 		 * to users:
 		 */
@@ -131,7 +131,7 @@ void fpstate_sanitize_xstate(struct fpu
 	/*
 	 * FP is in init state
 	 */
-	if (!(xfeatures & XSTATE_FP)) {
+	if (!(xfeatures & XFEATURE_MASK_FP)) {
 		fx->cwd = 0x37f;
 		fx->swd = 0;
 		fx->twd = 0;
@@ -144,7 +144,7 @@ void fpstate_sanitize_xstate(struct fpu
 	/*
 	 * SSE is in init state
 	 */
-	if (!(xfeatures & XSTATE_SSE))
+	if (!(xfeatures & XFEATURE_MASK_SSE))
 		memset(&fx->xmm_space[0], 0, 256);
 
 	/*
@@ -223,14 +223,14 @@ static void __init print_xstate_feature(
  */
 static void __init print_xstate_features(void)
 {
-	print_xstate_feature(XSTATE_FP);
-	print_xstate_feature(XSTATE_SSE);
-	print_xstate_feature(XSTATE_YMM);
-	print_xstate_feature(XSTATE_BNDREGS);
-	print_xstate_feature(XSTATE_BNDCSR);
-	print_xstate_feature(XSTATE_OPMASK);
-	print_xstate_feature(XSTATE_ZMM_Hi256);
-	print_xstate_feature(XSTATE_Hi16_ZMM);
+	print_xstate_feature(XFEATURE_MASK_FP);
+	print_xstate_feature(XFEATURE_MASK_SSE);
+	print_xstate_feature(XFEATURE_MASK_YMM);
+	print_xstate_feature(XFEATURE_MASK_BNDREGS);
+	print_xstate_feature(XFEATURE_MASK_BNDCSR);
+	print_xstate_feature(XFEATURE_MASK_OPMASK);
+	print_xstate_feature(XFEATURE_MASK_ZMM_Hi256);
+	print_xstate_feature(XFEATURE_MASK_Hi16_ZMM);
 }
 
 /*
@@ -365,7 +365,11 @@ static int init_xstate_size(void)
 	return 0;
 }
 
-void fpu__init_disable_system_xstate(void)
+/*
+ * We enabled the XSAVE hardware, but something went wrong and
+ * we can not use it.  Disable it.
+ */
+static void fpu__init_disable_system_xstate(void)
 {
 	xfeatures_mask = 0;
 	cr4_clear_bits(X86_CR4_OSXSAVE);
@@ -398,7 +402,7 @@ void __init fpu__init_system_xstate(void
 	cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);
 	xfeatures_mask = eax + ((u64)edx << 32);
 
-	if ((xfeatures_mask & XSTATE_FPSSE) != XSTATE_FPSSE) {
+	if ((xfeatures_mask & XFEATURE_MASK_FPSSE) != XFEATURE_MASK_FPSSE) {
 		pr_err("x86/fpu: FP/SSE not present amongst the CPU's xstate features: 0x%llx.\n", xfeatures_mask);
 		BUG();
 	}
@@ -451,7 +455,7 @@ void fpu__resume_cpu(void)
  * Inputs:
  *	xstate: the thread's storage area for all FPU data
  *	xstate_feature: state which is defined in xsave.h (e.g.
- *	XSTATE_FP, XSTATE_SSE, etc...)
+ *	XFEATURE_MASK_FP, XFEATURE_MASK_SSE, etc...)
  * Output:
  *	address of the state in the xsave area, or NULL if the
  *	field is not present in the xsave buffer.
@@ -502,8 +506,8 @@ EXPORT_SYMBOL_GPL(get_xsave_addr);
  * Note that this only works on the current task.
  *
  * Inputs:
- *	@xsave_state: state which is defined in xsave.h (e.g. XSTATE_FP,
- *	XSTATE_SSE, etc...)
+ *	@xsave_state: state which is defined in xsave.h (e.g. XFEATURE_MASK_FP,
+ *	XFEATURE_MASK_SSE, etc...)
  * Output:
  *	address of the state in the xsave area or NULL if the state
  *	is not present or is in its 'init state'.
diff -puN arch/x86/kernel/traps.c~x86-fpu-rename-xfeature_bit arch/x86/kernel/traps.c
--- a/arch/x86/kernel/traps.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.794884703 -0700
+++ b/arch/x86/kernel/traps.c	2015-09-02 16:24:49.864133927 -0700
@@ -395,7 +395,7 @@ dotraplinkage void do_bounds(struct pt_r
 	 * which is all zeros which indicates MPX was not
 	 * responsible for the exception.
 	 */
-	bndcsr = get_xsave_field_ptr(XSTATE_BNDCSR);
+	bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR);
 	if (!bndcsr)
 		goto exit_trap;
 
diff -puN arch/x86/kvm/cpuid.c~x86-fpu-rename-xfeature_bit arch/x86/kvm/cpuid.c
--- a/arch/x86/kvm/cpuid.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.796884794 -0700
+++ b/arch/x86/kvm/cpuid.c	2015-09-02 15:52:49.811885477 -0700
@@ -30,7 +30,7 @@ static u32 xstate_required_size(u64 xsta
 	int feature_bit = 0;
 	u32 ret = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET;
 
-	xstate_bv &= XSTATE_EXTEND_MASK;
+	xstate_bv &= XFEATURE_MASK_EXTEND;
 	while (xstate_bv) {
 		if (xstate_bv & 0x1) {
 		        u32 eax, ebx, ecx, edx, offset;
@@ -51,7 +51,7 @@ u64 kvm_supported_xcr0(void)
 	u64 xcr0 = KVM_SUPPORTED_XCR0 & host_xcr0;
 
 	if (!kvm_x86_ops->mpx_supported())
-		xcr0 &= ~(XSTATE_BNDREGS | XSTATE_BNDCSR);
+		xcr0 &= ~(XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR);
 
 	return xcr0;
 }
diff -puN arch/x86/kvm/x86.c~x86-fpu-rename-xfeature_bit arch/x86/kvm/x86.c
--- a/arch/x86/kvm/x86.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.798884885 -0700
+++ b/arch/x86/kvm/x86.c	2015-09-02 15:52:49.814885614 -0700
@@ -662,9 +662,9 @@ static int __kvm_set_xcr(struct kvm_vcpu
 	/* Only support XCR_XFEATURE_ENABLED_MASK(xcr0) now  */
 	if (index != XCR_XFEATURE_ENABLED_MASK)
 		return 1;
-	if (!(xcr0 & XSTATE_FP))
+	if (!(xcr0 & XFEATURE_MASK_FP))
 		return 1;
-	if ((xcr0 & XSTATE_YMM) && !(xcr0 & XSTATE_SSE))
+	if ((xcr0 & XFEATURE_MASK_YMM) && !(xcr0 & XFEATURE_MASK_SSE))
 		return 1;
 
 	/*
@@ -672,23 +672,24 @@ static int __kvm_set_xcr(struct kvm_vcpu
 	 * saving.  However, xcr0 bit 0 is always set, even if the
 	 * emulated CPU does not support XSAVE (see fx_init).
 	 */
-	valid_bits = vcpu->arch.guest_supported_xcr0 | XSTATE_FP;
+	valid_bits = vcpu->arch.guest_supported_xcr0 | XFEATURE_MASK_FP;
 	if (xcr0 & ~valid_bits)
 		return 1;
 
-	if ((!(xcr0 & XSTATE_BNDREGS)) != (!(xcr0 & XSTATE_BNDCSR)))
+	if ((!(xcr0 & XFEATURE_MASK_BNDREGS)) !=
+	    (!(xcr0 & XFEATURE_MASK_BNDCSR)))
 		return 1;
 
-	if (xcr0 & XSTATE_AVX512) {
-		if (!(xcr0 & XSTATE_YMM))
+	if (xcr0 & XFEATURE_MASK_AVX512) {
+		if (!(xcr0 & XFEATURE_MASK_YMM))
 			return 1;
-		if ((xcr0 & XSTATE_AVX512) != XSTATE_AVX512)
+		if ((xcr0 & XFEATURE_MASK_AVX512) != XFEATURE_MASK_AVX512)
 			return 1;
 	}
 	kvm_put_guest_xcr0(vcpu);
 	vcpu->arch.xcr0 = xcr0;
 
-	if ((xcr0 ^ old_xcr0) & XSTATE_EXTEND_MASK)
+	if ((xcr0 ^ old_xcr0) & XFEATURE_MASK_EXTEND)
 		kvm_update_cpuid(vcpu);
 	return 0;
 }
@@ -2918,7 +2919,7 @@ static void fill_xsave(u8 *dest, struct
 	 * Copy each region from the possibly compacted offset to the
 	 * non-compacted offset.
 	 */
-	valid = xstate_bv & ~XSTATE_FPSSE;
+	valid = xstate_bv & ~XFEATURE_MASK_FPSSE;
 	while (valid) {
 		u64 feature = valid & -valid;
 		int index = fls64(feature) - 1;
@@ -2956,7 +2957,7 @@ static void load_xsave(struct kvm_vcpu *
 	 * Copy each region from the non-compacted offset to the
 	 * possibly compacted offset.
 	 */
-	valid = xstate_bv & ~XSTATE_FPSSE;
+	valid = xstate_bv & ~XFEATURE_MASK_FPSSE;
 	while (valid) {
 		u64 feature = valid & -valid;
 		int index = fls64(feature) - 1;
@@ -2984,7 +2985,7 @@ static void kvm_vcpu_ioctl_x86_get_xsave
 			&vcpu->arch.guest_fpu.state.fxsave,
 			sizeof(struct fxregs_state));
 		*(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)] =
-			XSTATE_FPSSE;
+			XFEATURE_MASK_FPSSE;
 	}
 }
 
@@ -3004,7 +3005,7 @@ static int kvm_vcpu_ioctl_x86_set_xsave(
 			return -EINVAL;
 		load_xsave(vcpu, (u8 *)guest_xsave->region);
 	} else {
-		if (xstate_bv & ~XSTATE_FPSSE)
+		if (xstate_bv & ~XFEATURE_MASK_FPSSE)
 			return -EINVAL;
 		memcpy(&vcpu->arch.guest_fpu.state.fxsave,
 			guest_xsave->region, sizeof(struct fxregs_state));
@@ -7011,7 +7012,7 @@ static void fx_init(struct kvm_vcpu *vcp
 	/*
 	 * Ensure guest xcr0 is valid for loading
 	 */
-	vcpu->arch.xcr0 = XSTATE_FP;
+	vcpu->arch.xcr0 = XFEATURE_MASK_FP;
 
 	vcpu->arch.cr0 |= X86_CR0_ET;
 }
diff -puN arch/x86/kvm/x86.h~x86-fpu-rename-xfeature_bit arch/x86/kvm/x86.h
--- a/arch/x86/kvm/x86.h~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.800884976 -0700
+++ b/arch/x86/kvm/x86.h	2015-09-02 15:52:49.814885614 -0700
@@ -180,9 +180,9 @@ int kvm_mtrr_get_msr(struct kvm_vcpu *vc
 bool kvm_mtrr_check_gfn_range_consistency(struct kvm_vcpu *vcpu, gfn_t gfn,
 					  int page_num);
 
-#define KVM_SUPPORTED_XCR0     (XSTATE_FP | XSTATE_SSE | XSTATE_YMM \
-				| XSTATE_BNDREGS | XSTATE_BNDCSR \
-				| XSTATE_AVX512)
+#define KVM_SUPPORTED_XCR0     (XFEATURE_MASK_FP | XFEATURE_MASK_SSE \
+				| XFEATURE_MASK_YMM | XFEATURE_MASK_BNDREGS \
+				| XFEATURE_MASK_BNDCSR | XFEATURE_MASK_AVX512)
 extern u64 host_xcr0;
 
 extern u64 kvm_supported_xcr0(void);
diff -puN arch/x86/mm/mpx.c~x86-fpu-rename-xfeature_bit arch/x86/mm/mpx.c
--- a/arch/x86/mm/mpx.c~x86-fpu-rename-xfeature_bit	2015-09-02 15:52:49.802885067 -0700
+++ b/arch/x86/mm/mpx.c	2015-09-02 16:24:49.865133973 -0700
@@ -295,7 +295,7 @@ siginfo_t *mpx_generate_siginfo(struct p
 		goto err_out;
 	}
 	/* get bndregs field from current task's xsave area */
-	bndregs = get_xsave_field_ptr(XSTATE_BNDREGS);
+	bndregs = get_xsave_field_ptr(XFEATURE_MASK_BNDREGS);
 	if (!bndregs) {
 		err = -EINVAL;
 		goto err_out;
@@ -352,7 +352,7 @@ static __user void *mpx_get_bounds_dir(v
 	 * The bounds directory pointer is stored in a register
 	 * only accessible if we first do an xsave.
 	 */
-	bndcsr = get_xsave_field_ptr(XSTATE_BNDCSR);
+	bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR);
 	if (!bndcsr)
 		return MPX_INVALID_BOUNDS_DIR;
 
@@ -529,7 +529,7 @@ static int do_mpx_bt_fault(void)
 	const struct bndcsr *bndcsr;
 	struct mm_struct *mm = current->mm;
 
-	bndcsr = get_xsave_field_ptr(XSTATE_BNDCSR);
+	bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR);
 	if (!bndcsr)
 		return -EINVAL;
 	/*
_

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 06/15] x86, fpu: rename XFEATURES_NR_MAX
  2015-09-02 23:31 [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Dave Hansen
                   ` (4 preceding siblings ...)
  2015-09-02 23:31 ` [PATCH 05/15] x86, fpu: XSAVE macro renames Dave Hansen
@ 2015-09-02 23:31 ` Dave Hansen
  2015-09-14 12:21   ` [tip:x86/fpu] x86/fpu: Rename XFEATURES_NR_MAX tip-bot for Dave Hansen
  2015-09-02 23:31 ` [PATCH 08/15] x86, fpu: remove xfeature_nr Dave Hansen
                   ` (9 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Dave Hansen @ 2015-09-02 23:31 UTC (permalink / raw)
  To: dave; +Cc: dave.hansen, mingo, x86, bp, fenghua.yu, tim.c.chen, linux-kernel


From: Dave Hansen <dave.hansen@linux.intel.com>

This is a logcal followon to the last patch.  It makes the
XFEATURE_MAX naming consistent with the other enum values.
This is what Ingo suggested.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Borislav Petkov <bp@alien8.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
---

 b/arch/x86/include/asm/fpu/types.h |    2 +-
 b/arch/x86/kernel/fpu/xstate.c     |    4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff -puN arch/x86/include/asm/fpu/types.h~rename-XFEATURES_NR_MAX arch/x86/include/asm/fpu/types.h
--- a/arch/x86/include/asm/fpu/types.h~rename-XFEATURES_NR_MAX	2015-09-02 15:52:52.792021293 -0700
+++ b/arch/x86/include/asm/fpu/types.h	2015-09-02 16:25:42.343517651 -0700
@@ -109,7 +109,7 @@ enum xfeature {
 	XFEATURE_ZMM_Hi256,
 	XFEATURE_Hi16_ZMM,
 
-	XFEATURES_NR_MAX,
+	XFEATURE_MAX,
 };
 
 #define XFEATURE_MASK_FP		(1 << XFEATURE_FP)
diff -puN arch/x86/kernel/fpu/xstate.c~rename-XFEATURES_NR_MAX arch/x86/kernel/fpu/xstate.c
--- a/arch/x86/kernel/fpu/xstate.c~rename-XFEATURES_NR_MAX	2015-09-02 15:52:52.794021384 -0700
+++ b/arch/x86/kernel/fpu/xstate.c	2015-09-02 16:25:42.343517651 -0700
@@ -31,8 +31,8 @@ static const char *xfeature_names[] =
  */
 u64 xfeatures_mask __read_mostly;
 
-static unsigned int xstate_offsets[XFEATURES_NR_MAX] = { [ 0 ... XFEATURES_NR_MAX - 1] = -1};
-static unsigned int xstate_sizes[XFEATURES_NR_MAX]   = { [ 0 ... XFEATURES_NR_MAX - 1] = -1};
+static unsigned int xstate_offsets[XFEATURE_MAX] = { [ 0 ... XFEATURE_MAX - 1] = -1};
+static unsigned int xstate_sizes[XFEATURE_MAX]   = { [ 0 ... XFEATURE_MAX - 1] = -1};
 static unsigned int xstate_comp_offsets[sizeof(xfeatures_mask)*8];
 
 /* The number of supported xfeatures in xfeatures_mask: */
_

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 08/15] x86, fpu: remove xfeature_nr
  2015-09-02 23:31 [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Dave Hansen
                   ` (5 preceding siblings ...)
  2015-09-02 23:31 ` [PATCH 06/15] x86, fpu: rename XFEATURES_NR_MAX Dave Hansen
@ 2015-09-02 23:31 ` Dave Hansen
  2015-09-14 12:22   ` [tip:x86/fpu] x86/fpu: Remove 'xfeature_nr' tip-bot for Dave Hansen
  2015-09-02 23:31 ` [PATCH 07/15] x86, fpu: rework XSTATE_* macros to remove magic '2' Dave Hansen
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Dave Hansen @ 2015-09-02 23:31 UTC (permalink / raw)
  To: dave; +Cc: dave.hansen, mingo, x86, bp, fenghua.yu, tim.c.chen, linux-kernel


From: Dave Hansen <dave.hansen@linux.intel.com>

xfeature_nr ended up being initialized too late for me to
use it in the "xsave size sanity check" patch which is
later in the series.  I tried to move around its initialization
but realized that it was just as easy to get rid of it.

We only have 9 XFEATURES.  Instead of dynamically calculating
and storing the last feature, just use the compile-time max:
XFEATURES_NR_MAX.  Note that even with 'xfeatures_nr' we can
had "holes" in the xfeatures_mask that we had to deal with.

We also change a 'leaf' variable to be a plain 'i'.  Although
it is used to grab a cpuid leaf in this one loop, all of the
other loops just use an 'i' and I find it much more obvious
to keep the naming consistent across all the similar loops.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Borislav Petkov <bp@alien8.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
---

 b/arch/x86/kernel/fpu/xstate.c |   24 ++++++++----------------
 1 file changed, 8 insertions(+), 16 deletions(-)

diff -puN arch/x86/kernel/fpu/xstate.c~kill-xfeatures_nr arch/x86/kernel/fpu/xstate.c
--- a/arch/x86/kernel/fpu/xstate.c~kill-xfeatures_nr	2015-09-02 15:52:54.230086831 -0700
+++ b/arch/x86/kernel/fpu/xstate.c	2015-09-02 16:24:52.380248215 -0700
@@ -35,9 +35,6 @@ static unsigned int xstate_offsets[XFEAT
 static unsigned int xstate_sizes[XFEATURE_MAX]   = { [ 0 ... XFEATURE_MAX - 1] = -1};
 static unsigned int xstate_comp_offsets[sizeof(xfeatures_mask)*8];
 
-/* The number of supported xfeatures in xfeatures_mask: */
-static unsigned int xfeatures_nr;
-
 /*
  * Clear all of the X86_FEATURE_* bits that are unavailable
  * when the CPU has no XSAVE support.
@@ -190,23 +187,18 @@ void fpu__init_cpu_xstate(void)
 /*
  * Record the offsets and sizes of various xstates contained
  * in the XSAVE state memory layout.
- *
- * ( Note that certain features might be non-present, for them
- *   we'll have 0 offset and 0 size. )
  */
 static void __init setup_xstate_features(void)
 {
-	u32 eax, ebx, ecx, edx, leaf;
-
-	xfeatures_nr = fls64(xfeatures_mask);
+	u32 eax, ebx, ecx, edx, i;
 
-	for (leaf = FIRST_EXTENDED_XFEATURE; leaf < xfeatures_nr; leaf++) {
-		cpuid_count(XSTATE_CPUID, leaf, &eax, &ebx, &ecx, &edx);
+	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
+		cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
 
-		xstate_offsets[leaf] = ebx;
-		xstate_sizes[leaf] = eax;
+		xstate_offsets[i] = ebx;
+		xstate_sizes[i] = eax;
 
-		printk(KERN_INFO "x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n", leaf, ebx, leaf, eax);
+		printk(KERN_INFO "x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n", i, ebx, i, eax);
 	}
 }
 
@@ -252,7 +244,7 @@ static void __init setup_xstate_comp(voi
 	xstate_comp_offsets[1] = offsetof(struct fxregs_state, xmm_space);
 
 	if (!cpu_has_xsaves) {
-		for (i = FIRST_EXTENDED_XFEATURE; i < xfeatures_nr; i++) {
+		for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
 			if (test_bit(i, (unsigned long *)&xfeatures_mask)) {
 				xstate_comp_offsets[i] = xstate_offsets[i];
 				xstate_comp_sizes[i] = xstate_sizes[i];
@@ -264,7 +256,7 @@ static void __init setup_xstate_comp(voi
 	xstate_comp_offsets[FIRST_EXTENDED_XFEATURE] =
 	  	FXSAVE_SIZE + XSAVE_HDR_SIZE;
 
-	for (i = FIRST_EXTENDED_XFEATURE; i < xfeatures_nr; i++) {
+	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
 		if (test_bit(i, (unsigned long *)&xfeatures_mask))
 			xstate_comp_sizes[i] = xstate_sizes[i];
 		else
_

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 07/15] x86, fpu: rework XSTATE_* macros to remove magic '2'
  2015-09-02 23:31 [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Dave Hansen
                   ` (6 preceding siblings ...)
  2015-09-02 23:31 ` [PATCH 08/15] x86, fpu: remove xfeature_nr Dave Hansen
@ 2015-09-02 23:31 ` Dave Hansen
  2015-09-14 12:21   ` [tip:x86/fpu] x86/fpu: Rework " tip-bot for Dave Hansen
  2015-09-02 23:31 ` [PATCH 10/15] x86, fpu: rework MPX 'xstate' types Dave Hansen
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Dave Hansen @ 2015-09-02 23:31 UTC (permalink / raw)
  To: dave; +Cc: dave.hansen, mingo, x86, bp, fenghua.yu, tim.c.chen, linux-kernel


From: Dave Hansen <dave.hansen@linux.intel.com>

The 'xstate.c' code has a bunch of references to '2'.  This
is because we have a lot more work to do for the "extended"
xstates than the "legacy" ones and state component 2 is the
first "extended" state.

This patch replaces all of the instances of '2' with
FIRST_EXTENDED_XFEATURE, which clearly explains what is
going on.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Borislav Petkov <bp@alien8.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
---

 b/arch/x86/include/asm/fpu/types.h |    2 ++
 b/arch/x86/kernel/fpu/xstate.c     |   13 +++++++------
 2 files changed, 9 insertions(+), 6 deletions(-)

diff -puN arch/x86/include/asm/fpu/types.h~remove-hard-coded-values arch/x86/include/asm/fpu/types.h
--- a/arch/x86/include/asm/fpu/types.h~remove-hard-coded-values	2015-09-02 15:52:53.495053333 -0700
+++ b/arch/x86/include/asm/fpu/types.h	2015-09-02 16:24:49.864133927 -0700
@@ -126,6 +126,8 @@ enum xfeature {
 					 | XFEATURE_MASK_ZMM_Hi256 \
 					 | XFEATURE_MASK_Hi16_ZMM)
 
+#define FIRST_EXTENDED_XFEATURE	XFEATURE_YMM
+
 /*
  * There are 16x 256-bit AVX registers named YMM0-YMM15.
  * The low 128 bits are aliased to the 16 SSE registers (XMM0-XMM15)
diff -puN arch/x86/kernel/fpu/xstate.c~remove-hard-coded-values arch/x86/kernel/fpu/xstate.c
--- a/arch/x86/kernel/fpu/xstate.c~remove-hard-coded-values	2015-09-02 15:52:53.496053379 -0700
+++ b/arch/x86/kernel/fpu/xstate.c	2015-09-02 16:25:38.017321147 -0700
@@ -200,7 +200,7 @@ static void __init setup_xstate_features
 
 	xfeatures_nr = fls64(xfeatures_mask);
 
-	for (leaf = 2; leaf < xfeatures_nr; leaf++) {
+	for (leaf = FIRST_EXTENDED_XFEATURE; leaf < xfeatures_nr; leaf++) {
 		cpuid_count(XSTATE_CPUID, leaf, &eax, &ebx, &ecx, &edx);
 
 		xstate_offsets[leaf] = ebx;
@@ -252,7 +252,7 @@ static void __init setup_xstate_comp(voi
 	xstate_comp_offsets[1] = offsetof(struct fxregs_state, xmm_space);
 
 	if (!cpu_has_xsaves) {
-		for (i = 2; i < xfeatures_nr; i++) {
+		for (i = FIRST_EXTENDED_XFEATURE; i < xfeatures_nr; i++) {
 			if (test_bit(i, (unsigned long *)&xfeatures_mask)) {
 				xstate_comp_offsets[i] = xstate_offsets[i];
 				xstate_comp_sizes[i] = xstate_sizes[i];
@@ -261,15 +261,16 @@ static void __init setup_xstate_comp(voi
 		return;
 	}
 
-	xstate_comp_offsets[2] = FXSAVE_SIZE + XSAVE_HDR_SIZE;
+	xstate_comp_offsets[FIRST_EXTENDED_XFEATURE] =
+		FXSAVE_SIZE + XSAVE_HDR_SIZE;
 
-	for (i = 2; i < xfeatures_nr; i++) {
+	for (i = FIRST_EXTENDED_XFEATURE; i < xfeatures_nr; i++) {
 		if (test_bit(i, (unsigned long *)&xfeatures_mask))
 			xstate_comp_sizes[i] = xstate_sizes[i];
 		else
 			xstate_comp_sizes[i] = 0;
 
-		if (i > 2)
+		if (i > FIRST_EXTENDED_XFEATURE)
 			xstate_comp_offsets[i] = xstate_comp_offsets[i-1]
 					+ xstate_comp_sizes[i-1];
 
@@ -325,7 +326,7 @@ static unsigned int __init calculate_xst
 	}
 
 	calculated_xstate_size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
-	for (i = 2; i < 64; i++) {
+	for (i = FIRST_EXTENDED_XFEATURE; i < 64; i++) {
 		if (test_bit(i, (unsigned long *)&xfeatures_mask)) {
 			cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
 			calculated_xstate_size += eax;
_

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 11/15] x86, fpu: rework YMM definition
  2015-09-02 23:31 [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Dave Hansen
                   ` (10 preceding siblings ...)
  2015-09-02 23:31 ` [PATCH 09/15] x86, fpu: add helper xfeature_enabled() instead of test_bit() Dave Hansen
@ 2015-09-02 23:31 ` Dave Hansen
  2015-09-14 12:23   ` [tip:x86/fpu] x86/fpu: Rework " tip-bot for Dave Hansen
  2015-09-02 23:31 ` [PATCH 13/15] x86, fpu: correct and check XSAVE xstate size calculations Dave Hansen
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Dave Hansen @ 2015-09-02 23:31 UTC (permalink / raw)
  To: dave; +Cc: dave.hansen, mingo, x86, bp, fenghua.yu, tim.c.chen, linux-kernel


From: Dave Hansen <dave.hansen@linux.intel.com>

We are about to rework all of the "extended state" definitions.
This makes the 'ymm' naming consistent with the AVX-512 types
we will introduce later.

We also add a convenience type: "reg_128_bit" so that we do
not have to spell out our arithmetic.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Borislav Petkov <bp@alien8.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
---

 b/arch/x86/include/asm/fpu/types.h |   16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff -puN arch/x86/include/asm/fpu/types.h~x86-fpu-rework-ymm-types arch/x86/include/asm/fpu/types.h
--- a/arch/x86/include/asm/fpu/types.h~x86-fpu-rework-ymm-types	2015-09-02 16:23:51.041462059 -0700
+++ b/arch/x86/include/asm/fpu/types.h	2015-09-02 16:24:20.692808898 -0700
@@ -128,17 +128,23 @@ enum xfeature {
 
 #define FIRST_EXTENDED_XFEATURE	XFEATURE_YMM
 
+struct reg_128_bit {
+	u8      regbytes[128/8];
+};
+
 /*
+ * State component 2:
+ *
  * There are 16x 256-bit AVX registers named YMM0-YMM15.
  * The low 128 bits are aliased to the 16 SSE registers (XMM0-XMM15)
- * and are stored in 'struct fxregs_state::xmm_space[]'.
+ * and are stored in 'struct fxregs_state::xmm_space[]' in the
+ * "legacy" area.
  *
- * The high 128 bits are stored here:
- *    16x 128 bits == 256 bytes.
+ * The high 128 bits are stored here.
  */
 struct ymmh_struct {
-	u8				ymmh_space[256];
-};
+	struct reg_128_bit              hi_ymm[16];
+} __packed;
 
 /* Intel MPX support: */
 
_

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 12/15] x86, fpu: add C structures for AVX-512 state components
  2015-09-02 23:31 [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Dave Hansen
                   ` (8 preceding siblings ...)
  2015-09-02 23:31 ` [PATCH 10/15] x86, fpu: rework MPX 'xstate' types Dave Hansen
@ 2015-09-02 23:31 ` Dave Hansen
  2015-09-14 12:23   ` [tip:x86/fpu] x86/fpu: Add " tip-bot for Dave Hansen
  2015-09-02 23:31 ` [PATCH 09/15] x86, fpu: add helper xfeature_enabled() instead of test_bit() Dave Hansen
                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Dave Hansen @ 2015-09-02 23:31 UTC (permalink / raw)
  To: dave; +Cc: dave.hansen, mingo, x86, bp, fenghua.yu, tim.c.chen, linux-kernel


From: Dave Hansen <dave.hansen@linux.intel.com>

AVX-512 has 3 separate state components:
1. opmask registers
2. zmm upper half of registers 0-15
3. new zmm registers (16-31)

This patch adds C structures for the three components along with
a few comments mostly lifted from the SDM to explain what they
do.  This will allow us to check our structures against what the
hardware tells us about the sizes of the components.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Borislav Petkov <bp@alien8.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
---

 b/arch/x86/include/asm/fpu/types.h |   33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff -puN arch/x86/include/asm/fpu/types.h~avx-512-structs arch/x86/include/asm/fpu/types.h
--- a/arch/x86/include/asm/fpu/types.h~avx-512-structs	2015-09-02 16:23:51.379477412 -0700
+++ b/arch/x86/include/asm/fpu/types.h	2015-09-02 16:24:16.569621612 -0700
@@ -131,6 +131,12 @@ enum xfeature {
 struct reg_128_bit {
 	u8      regbytes[128/8];
 };
+struct reg_256_bit {
+	u8	regbytes[256/8];
+};
+struct reg_512_bit {
+	u8	regbytes[512/8];
+};
 
 /*
  * State component 2:
@@ -179,6 +185,33 @@ struct mpx_bndcsr_state {
 	};
 } __packed;
 
+/* AVX-512 Components: */
+
+/*
+ * State component 5 is used for the 8 64-bit opmask registers
+ * k0-k7 (opmask state).
+ */
+struct avx_512_opmask_state {
+	u64				opmask_reg[8];
+} __packed;
+
+/*
+ * State component 6 is used for the upper 256 bits of the
+ * registers ZMM0-ZMM15. These 16 256-bit values are denoted
+ * ZMM0_H-ZMM15_H (ZMM_Hi256 state).
+ */
+struct avx_512_zmm_uppers_state {
+	struct reg_256_bit		zmm_upper[16];
+} __packed;
+
+/*
+ * State component 7 is used for the 16 512-bit registers
+ * ZMM16-ZMM31 (Hi16_ZMM state).
+ */
+struct avx_512_hi16_state {
+	struct reg_512_bit		hi16_zmm[16];
+} __packed;
+
 struct xstate_header {
 	u64				xfeatures;
 	u64				xcomp_bv;
_

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 10/15] x86, fpu: rework MPX 'xstate' types
  2015-09-02 23:31 [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Dave Hansen
                   ` (7 preceding siblings ...)
  2015-09-02 23:31 ` [PATCH 07/15] x86, fpu: rework XSTATE_* macros to remove magic '2' Dave Hansen
@ 2015-09-02 23:31 ` Dave Hansen
  2015-09-14 12:22   ` [tip:x86/fpu] x86/fpu/mpx: Rework " tip-bot for Dave Hansen
  2015-09-02 23:31 ` [PATCH 12/15] x86, fpu: add C structures for AVX-512 state components Dave Hansen
                   ` (6 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Dave Hansen @ 2015-09-02 23:31 UTC (permalink / raw)
  To: dave; +Cc: dave.hansen, mingo, x86, bp, fenghua.yu, tim.c.chen, linux-kernel


From: Dave Hansen <dave.hansen@linux.intel.com>

MPX includes two separate "extended state components".  There is
no real need to have an 'mpx_struct' because we never really
manage the states together.

We also separate out the actual data in 'mpx_bndcsr_state' from
the padding.  We will shortly be checking the state sizes against
our structures and need them to match.  For consistency, we also
ensure to prefix these types with 'mpx_'.

Lastly, we add some comments to mirror some of the descriptions
in the Intel documents (SDM) of the various state components.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Borislav Petkov <bp@alien8.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
---

 b/arch/x86/include/asm/fpu/types.h |   29 +++++++++++++++++++++++------
 b/arch/x86/include/asm/trace/mpx.h |    7 ++++---
 b/arch/x86/kernel/traps.c          |    2 +-
 b/arch/x86/mm/mpx.c                |    9 +++++----
 4 files changed, 33 insertions(+), 14 deletions(-)

diff -puN arch/x86/include/asm/fpu/types.h~x86-fpu-rework-mpx-types arch/x86/include/asm/fpu/types.h
--- a/arch/x86/include/asm/fpu/types.h~x86-fpu-rework-mpx-types	2015-09-02 15:52:55.416140884 -0700
+++ b/arch/x86/include/asm/fpu/types.h	2015-09-02 16:24:41.457752090 -0700
@@ -141,20 +141,37 @@ struct ymmh_struct {
 };
 
 /* Intel MPX support: */
-struct bndreg {
+
+struct mpx_bndreg {
 	u64				lower_bound;
 	u64				upper_bound;
 } __packed;
+/*
+ * State component 3 is used for the 4 128-bit bounds registers
+ */
+struct mpx_bndreg_state {
+	struct mpx_bndreg		bndreg[4];
+} __packed;
 
-struct bndcsr {
+/*
+ * State component 4 is used for the 64-bit user-mode MPX
+ * configuration register BNDCFGU and the 64-bit MPX status
+ * register BNDSTATUS.  We call the pair "BNDCSR".
+ */
+struct mpx_bndcsr {
 	u64				bndcfgu;
 	u64				bndstatus;
 } __packed;
 
-struct mpx_struct {
-	struct bndreg			bndreg[4];
-	struct bndcsr			bndcsr;
-};
+/*
+ * The BNDCSR state is padded out to be 64-bytes in size.
+ */
+struct mpx_bndcsr_state {
+	union {
+		struct mpx_bndcsr		bndcsr;
+		u8				pad_to_64_bytes[64];
+	};
+} __packed;
 
 struct xstate_header {
 	u64				xfeatures;
diff -puN arch/x86/include/asm/trace/mpx.h~x86-fpu-rework-mpx-types arch/x86/include/asm/trace/mpx.h
--- a/arch/x86/include/asm/trace/mpx.h~x86-fpu-rework-mpx-types	2015-09-02 15:52:55.417140929 -0700
+++ b/arch/x86/include/asm/trace/mpx.h	2015-09-02 15:52:55.424141248 -0700
@@ -11,7 +11,7 @@
 TRACE_EVENT(mpx_bounds_register_exception,
 
 	TP_PROTO(void *addr_referenced,
-		 const struct bndreg *bndreg),
+		 const struct mpx_bndreg *bndreg),
 	TP_ARGS(addr_referenced, bndreg),
 
 	TP_STRUCT__entry(
@@ -44,7 +44,7 @@ TRACE_EVENT(mpx_bounds_register_exceptio
 
 TRACE_EVENT(bounds_exception_mpx,
 
-	TP_PROTO(const struct bndcsr *bndcsr),
+	TP_PROTO(const struct mpx_bndcsr *bndcsr),
 	TP_ARGS(bndcsr),
 
 	TP_STRUCT__entry(
@@ -116,7 +116,8 @@ TRACE_EVENT(mpx_new_bounds_table,
 /*
  * This gets used outside of MPX-specific code, so we need a stub.
  */
-static inline void trace_bounds_exception_mpx(const struct bndcsr *bndcsr)
+static inline
+void trace_bounds_exception_mpx(const struct mpx_bndcsr *bndcsr)
 {
 }
 
diff -puN arch/x86/kernel/traps.c~x86-fpu-rework-mpx-types arch/x86/kernel/traps.c
--- a/arch/x86/kernel/traps.c~x86-fpu-rework-mpx-types	2015-09-02 15:52:55.419141021 -0700
+++ b/arch/x86/kernel/traps.c	2015-09-02 15:52:55.425141294 -0700
@@ -372,7 +372,7 @@ dotraplinkage void do_double_fault(struc
 dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
 {
 	enum ctx_state prev_state;
-	const struct bndcsr *bndcsr;
+	const struct mpx_bndcsr *bndcsr;
 	siginfo_t *info;
 
 	prev_state = exception_enter();
diff -puN arch/x86/mm/mpx.c~x86-fpu-rework-mpx-types arch/x86/mm/mpx.c
--- a/arch/x86/mm/mpx.c~x86-fpu-rework-mpx-types	2015-09-02 15:52:55.421141112 -0700
+++ b/arch/x86/mm/mpx.c	2015-09-02 15:52:55.426141340 -0700
@@ -274,7 +274,8 @@ bad_opcode:
  */
 siginfo_t *mpx_generate_siginfo(struct pt_regs *regs)
 {
-	const struct bndreg *bndregs, *bndreg;
+	const struct mpx_bndreg_state *bndregs;
+	const struct mpx_bndreg *bndreg;
 	siginfo_t *info = NULL;
 	struct insn insn;
 	uint8_t bndregno;
@@ -301,7 +302,7 @@ siginfo_t *mpx_generate_siginfo(struct p
 		goto err_out;
 	}
 	/* now go select the individual register in the set of 4 */
-	bndreg = &bndregs[bndregno];
+	bndreg = &bndregs->bndreg[bndregno];
 
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info) {
@@ -343,7 +344,7 @@ err_out:
 
 static __user void *mpx_get_bounds_dir(void)
 {
-	const struct bndcsr *bndcsr;
+	const struct mpx_bndcsr *bndcsr;
 
 	if (!cpu_feature_enabled(X86_FEATURE_MPX))
 		return MPX_INVALID_BOUNDS_DIR;
@@ -526,7 +527,7 @@ out_unmap:
 static int do_mpx_bt_fault(void)
 {
 	unsigned long bd_entry, bd_base;
-	const struct bndcsr *bndcsr;
+	const struct mpx_bndcsr *bndcsr;
 	struct mm_struct *mm = current->mm;
 
 	bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR);
_

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 09/15] x86, fpu: add helper xfeature_enabled() instead of test_bit()
  2015-09-02 23:31 [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Dave Hansen
                   ` (9 preceding siblings ...)
  2015-09-02 23:31 ` [PATCH 12/15] x86, fpu: add C structures for AVX-512 state components Dave Hansen
@ 2015-09-02 23:31 ` Dave Hansen
  2015-09-14 12:22   ` [tip:x86/fpu] x86/fpu: Add xfeature_enabled() helper " tip-bot for Dave Hansen
  2015-09-02 23:31 ` [PATCH 11/15] x86, fpu: rework YMM definition Dave Hansen
                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Dave Hansen @ 2015-09-02 23:31 UTC (permalink / raw)
  To: dave; +Cc: dave.hansen, mingo, x86, bp, fenghua.yu, tim.c.chen, linux-kernel


From: Dave Hansen <dave.hansen@linux.intel.com>

We currently use test_bit() in a few places to see if an xfeature
is enabled.  It ends up being a bit ugly because 'xfeatures_mask'
is a u64 and test_bit wants an 'unsigned long' so it requires a
cast.  The *_bit() functions are also techincally atomic, which
we have no need for here.

So, remove the test_bit()s and replace with the new
xfeature_enabled() helper.

This also provides a central place to add a comment about the
future need to support 'system xstates'.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Borislav Petkov <bp@alien8.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
---

 b/arch/x86/kernel/fpu/xstate.c |   16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff -puN arch/x86/kernel/fpu/xstate.c~use-xfeature_enabled arch/x86/kernel/fpu/xstate.c
--- a/arch/x86/kernel/fpu/xstate.c~use-xfeature_enabled	2015-09-02 15:52:54.829114131 -0700
+++ b/arch/x86/kernel/fpu/xstate.c	2015-09-02 16:23:59.357839810 -0700
@@ -226,6 +226,16 @@ static void __init print_xstate_features
 }
 
 /*
+ * Note that in the future we will likely need a pair of
+ * functions here: one for user xstates and the other for
+ * system xstates.  For now, they are the same.
+ */
+static int xfeature_enabled(enum xfeature xfeature)
+{
+	return !!(xfeatures_mask & (1UL << xfeature));
+}
+
+/*
  * This function sets up offsets and sizes of all extended states in
  * xsave area. This supports both standard format and compacted format
  * of the xsave aread.
@@ -245,7 +255,7 @@ static void __init setup_xstate_comp(voi
 
 	if (!cpu_has_xsaves) {
 		for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
-			if (test_bit(i, (unsigned long *)&xfeatures_mask)) {
+			if (xfeature_enabled(i)) {
 				xstate_comp_offsets[i] = xstate_offsets[i];
 				xstate_comp_sizes[i] = xstate_sizes[i];
 			}
@@ -257,7 +267,7 @@ static void __init setup_xstate_comp(voi
 	  	FXSAVE_SIZE + XSAVE_HDR_SIZE;
 
 	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
-		if (test_bit(i, (unsigned long *)&xfeatures_mask))
+		if (xfeature_enabled(i))
 			xstate_comp_sizes[i] = xstate_sizes[i];
 		else
 			xstate_comp_sizes[i] = 0;
@@ -319,7 +329,7 @@ static unsigned int __init calculate_xst
 
 	calculated_xstate_size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
 	for (i = FIRST_EXTENDED_XFEATURE; i < 64; i++) {
-		if (test_bit(i, (unsigned long *)&xfeatures_mask)) {
+		if (xfeature_enabled(i)) {
 			cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
 			calculated_xstate_size += eax;
 		}
_

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 14/15] x86, fpu: check to ensure increasing-offset xstate offsets
  2015-09-02 23:31 [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Dave Hansen
                   ` (12 preceding siblings ...)
  2015-09-02 23:31 ` [PATCH 13/15] x86, fpu: correct and check XSAVE xstate size calculations Dave Hansen
@ 2015-09-02 23:31 ` Dave Hansen
  2015-09-14 12:24   ` [tip:x86/fpu] x86/fpu: Check " tip-bot for Dave Hansen
  2015-09-02 23:31 ` [PATCH 15/15] x86, fpu: check CPU-provided sizes against struct declarations Dave Hansen
  2015-09-14 10:07 ` [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Ingo Molnar
  15 siblings, 1 reply; 35+ messages in thread
From: Dave Hansen @ 2015-09-02 23:31 UTC (permalink / raw)
  To: dave; +Cc: dave.hansen, mingo, x86, bp, fenghua.yu, tim.c.chen, linux-kernel


From: Dave Hansen <dave.hansen@linux.intel.com>

The xstate CPUID leaves enumerate where each state component is
inside the XSAVE buffer, along with the size of the entire
buffer.  Our new XSAVE sanity-checking code extrapolates an
expected _total_ buffer size by looking at the last component
that it encounters.

That method requires that the highest-numbered component also
be the one with the highest offset.  This is a pretty safe
assumption, but let's add some code to ensure it stays true.

To make this check work correctly, we also need to ensure we
only consider the offsets from enabled features because the
offset register (ebx) will return 0 on unsupported features.

This also means that we will preserve the -1's that we
initialized xstate_offsets/sizes[] with.  That will help
find bugs.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Borislav Petkov <bp@alien8.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
---

 b/arch/x86/kernel/fpu/xstate.c |   35 ++++++++++++++++++++++++-----------
 1 file changed, 24 insertions(+), 11 deletions(-)

diff -puN arch/x86/kernel/fpu/xstate.c~x86-fpu-increasing-offset-assumption arch/x86/kernel/fpu/xstate.c
--- a/arch/x86/kernel/fpu/xstate.c~x86-fpu-increasing-offset-assumption	2015-09-02 16:23:52.556530877 -0700
+++ b/arch/x86/kernel/fpu/xstate.c	2015-09-02 16:23:52.560531059 -0700
@@ -185,18 +185,41 @@ void fpu__init_cpu_xstate(void)
 }
 
 /*
+ * Note that in the future we will likely need a pair of
+ * functions here: one for user xstates and the other for
+ * system xstates.  For now, they are the same.
+ */
+static int xfeature_enabled(enum xfeature xfeature)
+{
+	return !!(xfeatures_mask & (1UL << xfeature));
+}
+
+/*
  * Record the offsets and sizes of various xstates contained
  * in the XSAVE state memory layout.
  */
 static void __init setup_xstate_features(void)
 {
 	u32 eax, ebx, ecx, edx, i;
+	/* start at the beginnning of the "extended state" */
+	unsigned int last_good_offset = offsetof(struct xregs_state,
+						 extended_state_area);
 
 	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
-		cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
+		if (!xfeature_enabled(i))
+			continue;
 
+		cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
 		xstate_offsets[i] = ebx;
 		xstate_sizes[i] = eax;
+		/*
+		 * In our xstate size checks, we assume that the
+		 * highest-numbered xstate feature has the
+		 * highest offset in the buffer.  Ensure it does.
+		 */
+		WARN_ONCE(last_good_offset > xstate_offsets[i],
+			"x86/fpu: misordered xstate at %d\n", last_good_offset);
+		last_good_offset = xstate_offsets[i];
 
 		printk(KERN_INFO "x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n", i, ebx, i, eax);
 	}
@@ -226,16 +249,6 @@ static void __init print_xstate_features
 }
 
 /*
- * Note that in the future we will likely need a pair of
- * functions here: one for user xstates and the other for
- * system xstates.  For now, they are the same.
- */
-static int xfeature_enabled(enum xfeature xfeature)
-{
-	return !!(xfeatures_mask & (1UL << xfeature));
-}
-
-/*
  * This function sets up offsets and sizes of all extended states in
  * xsave area. This supports both standard format and compacted format
  * of the xsave aread.
_

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 13/15] x86, fpu: correct and check XSAVE xstate size calculations
  2015-09-02 23:31 [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Dave Hansen
                   ` (11 preceding siblings ...)
  2015-09-02 23:31 ` [PATCH 11/15] x86, fpu: rework YMM definition Dave Hansen
@ 2015-09-02 23:31 ` Dave Hansen
  2015-09-14 12:23   ` [tip:x86/fpu] x86/fpu: Correct " tip-bot for Dave Hansen
  2015-09-02 23:31 ` [PATCH 14/15] x86, fpu: check to ensure increasing-offset xstate offsets Dave Hansen
                   ` (2 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Dave Hansen @ 2015-09-02 23:31 UTC (permalink / raw)
  To: dave; +Cc: dave.hansen, mingo, bp, fenghua.yu, hpa, x86, tim.c.chen,
	linux-kernel


From: Dave Hansen <dave.hansen@linux.intel.com>

Note: our xsaves support is currently broken and disabled.  This
patch does not fix it, but it is an incremental improvement.
This might be useful to someone backporting the entire set of
XSAVES patches at some point, but it should not be backported
alone.

Ingo said he wanted something like this (bullets 2 and 3):

	http://lkml.kernel.org/r/20150808091508.GB32641@gmail.com

There are currently two xsave buffer formats: standard and
compacted.  The standard format is waht 'XSAVE' and 'XSAVEOPT'
produce while 'XSAVES' and 'XSAVEC' produce a compacted-formet
buffer.  (The kernel never uses XSAVEC)

But, the XSAVES buffer *ALSO* contains "system state components"
which are never saved by a plain XSAVE.  So, XSAVES has two
things that might make its buffer differently-sized from an
XSAVE-produced one.

The current code assumes that an XSAVES buffer's size is simply
the sum of the sizes of the (user) states which are supported.
This seems to work in most cases, but it is not consistent with
what the SDM says, and it breaks if we 'align' a component in the
buffer.  The calculation is also unnecessary work since the CPU
*tells* us the size of the buffer directly.

This patch just reads the size of the buffer right out of the
CPUID leaf instead of trying to derive it.

But, blindly trusting the CPU like this is dangerous.  We add
a verification pass in do_extra_xstate_size_checks() to ensure
that the size we calculate matches with what we see from the
hardware.  When it comes down to it, we trust but verify the
CPU.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
---

 b/arch/x86/kernel/fpu/xstate.c |  184 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 174 insertions(+), 10 deletions(-)

diff -puN arch/x86/kernel/fpu/xstate.c~fix-xstate_size-calculation arch/x86/kernel/fpu/xstate.c
--- a/arch/x86/kernel/fpu/xstate.c~fix-xstate_size-calculation	2015-09-02 15:52:57.581239555 -0700
+++ b/arch/x86/kernel/fpu/xstate.c	2015-09-02 16:22:58.807089430 -0700
@@ -312,27 +312,190 @@ static void __init setup_init_fpu_buf(vo
 	copy_xregs_to_kernel_booting(&init_fpstate.xsave);
 }
 
+static int xfeature_is_supervisor(int xfeature_nr)
+{
+	/*
+	 * We currently do not support supervisor states, but if
+	 * we did, we could find out like this.
+	 *
+	 * SDM says: If state component i is a user state component,
+	 * ECX[0] return 0; if state component i is a supervisor
+	 * state component, ECX[0] returns 1.
+	u32 eax, ebx, ecx, edx;
+	cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx;
+	return !!(ecx & 1);
+	*/
+	return 0;
+}
+/*
+static int xfeature_is_user(int xfeature_nr)
+{
+	return !xfeature_is_supervisor(xfeature_nr);
+}
+*/
+
+/*
+ * This check is important because it is easy to get XSTATE_*
+ * confused with XSTATE_BIT_*.
+ */
+#define CHECK_XFEATURE(nr) do {		\
+	WARN_ON(nr < FIRST_EXTENDED_XFEATURE);	\
+	WARN_ON(nr >= XFEATURE_MAX);	\
+} while (0)
+
+/*
+ * We could cache this like xstate_size[], but we only use
+ * it here, so it would be a waste of space.
+ */
+static int xfeature_is_aligned(int xfeature_nr)
+{
+	u32 eax, ebx, ecx, edx;
+
+	CHECK_XFEATURE(xfeature_nr);
+	cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx);
+	/*
+	 * The value returned by ECX[1] indicates the alignment
+	 * of state component i when the compacted format
+	 * of the extended region of an XSAVE area is used
+	 */
+	return !!(ecx & 2);
+}
+
+static int xfeature_uncompacted_offset(int xfeature_nr)
+{
+	u32 eax, ebx, ecx, edx;
+
+	CHECK_XFEATURE(xfeature_nr);
+	cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx);
+	return ebx;
+}
+
+static int xfeature_size(int xfeature_nr)
+{
+	u32 eax, ebx, ecx, edx;
+
+	CHECK_XFEATURE(xfeature_nr);
+	cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx);
+	return eax;
+}
+
+/*
+ * 'XSAVES' implies two different things:
+ * 1. saving of supervisor/system state
+ * 2. using the compacted format
+ *
+ * Use this function when dealing with the compacted format so
+ * that it is obvious which aspect of 'XSAVES' is being handled
+ * by the calling code.
+ */
+static int using_compacted_format(void)
+{
+	return cpu_has_xsaves;
+}
+
+static void __xstate_dump_leaves(void)
+{
+	int i;
+	u32 eax, ebx, ecx, edx;
+	static int should_dump = 1;
+
+	if (!should_dump)
+		return;
+	should_dump = 0;
+	/*
+	 * Dump out a few leaves past the ones that we support
+	 * just in case there are some goodies up there
+	 */
+	for (i = 0; i < XFEATURE_MAX + 10; i++) {
+		cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
+		pr_warn("CPUID[%02x, %02x]: eax=%08x ebx=%08x ecx=%08x edx=%08x\n",
+			XSTATE_CPUID, i, eax, ebx, ecx, edx);
+	}
+}
+
+#define XSTATE_WARN_ON(x) do {							\
+	if (WARN_ONCE(x, "XSAVE consistency problem, dumping leaves")) {	\
+		__xstate_dump_leaves();						\
+	}									\
+} while (0)
+
+/*
+ * This essentially double-checks what the cpu told us about
+ * how large the XSAVE buffer needs to be.  We are recalculating
+ * it to be safe.
+ */
+static void do_extra_xstate_size_checks(void)
+{
+	int paranoid_xstate_size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
+	int i;
+
+	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
+		if (!xfeature_enabled(i))
+			continue;
+		/*
+		 * Supervisor state components can be managed only by
+		 * XSAVES, which is compacted-format only.
+		 */
+		if (!using_compacted_format())
+			XSTATE_WARN_ON(xfeature_is_supervisor(i));
+
+		/* Align from the end of the previous feature */
+		if (xfeature_is_aligned(i))
+			paranoid_xstate_size = ALIGN(paranoid_xstate_size, 64);
+		/*
+		 * The offset of a given state in the non-compacted
+		 * format is given to us in a CPUID leaf.  We check
+		 * them for being ordered (increasing offsets) in
+		 * setup_xstate_features().
+		 */
+		if (!using_compacted_format())
+			paranoid_xstate_size = xfeature_uncompacted_offset(i);
+		/*
+		 * The compacted-format offset always depends on where
+		 * the previous state ended.
+		 */
+		paranoid_xstate_size += xfeature_size(i);
+	}
+	XSTATE_WARN_ON(paranoid_xstate_size != xstate_size);
+}
+
 /*
  * Calculate total size of enabled xstates in XCR0/xfeatures_mask.
+ *
+ * Note the SDM's wording here.  "sub-function 0" only enumerates
+ * the size of the *user* states.  If we use it to size a buffer
+ * that we use 'XSAVES' on, we could potentially overflow the
+ * buffer because 'XSAVES' saves system states too.
+ *
+ * Note that we do not currently set any bits on IA32_XSS so
+ * 'XCR0 | IA32_XSS == XCR0' for now.
  */
 static unsigned int __init calculate_xstate_size(void)
 {
 	unsigned int eax, ebx, ecx, edx;
 	unsigned int calculated_xstate_size;
-	int i;
 
 	if (!cpu_has_xsaves) {
+		/*
+		 * - CPUID function 0DH, sub-function 0:
+		 *    EBX enumerates the size (in bytes) required by
+		 *    the XSAVE instruction for an XSAVE area
+		 *    containing all the *user* state components
+		 *    corresponding to bits currently set in XCR0.
+		 */
 		cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);
 		calculated_xstate_size = ebx;
-		return calculated_xstate_size;
-	}
-
-	calculated_xstate_size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
-	for (i = FIRST_EXTENDED_XFEATURE; i < 64; i++) {
-		if (xfeature_enabled(i)) {
-			cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
-			calculated_xstate_size += eax;
-		}
+	} else {
+		/*
+		 * - CPUID function 0DH, sub-function 1:
+		 *    EBX enumerates the size (in bytes) required by
+		 *    the XSAVES instruction for an XSAVE area
+		 *    containing all the state components
+		 *    corresponding to bits currently set in
+		 *    XCR0 | IA32_XSS.
+		 */
+		cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx);
+		calculated_xstate_size = ebx;
 	}
 	return calculated_xstate_size;
 }
@@ -365,6 +528,7 @@ static int init_xstate_size(void)
 	 * make it known to the world that we need more space.
 	 */
 	xstate_size = possible_xstate_size;
+	do_extra_xstate_size_checks();
 	return 0;
 }
 
_

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 15/15] x86, fpu: check CPU-provided sizes against struct declarations
  2015-09-02 23:31 [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Dave Hansen
                   ` (13 preceding siblings ...)
  2015-09-02 23:31 ` [PATCH 14/15] x86, fpu: check to ensure increasing-offset xstate offsets Dave Hansen
@ 2015-09-02 23:31 ` Dave Hansen
  2015-09-14 12:24   ` [tip:x86/fpu] x86/fpu: Check " tip-bot for Dave Hansen
  2015-09-14 10:07 ` [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Ingo Molnar
  15 siblings, 1 reply; 35+ messages in thread
From: Dave Hansen @ 2015-09-02 23:31 UTC (permalink / raw)
  To: dave; +Cc: dave.hansen, mingo, x86, bp, fenghua.yu, tim.c.chen, linux-kernel


From: Dave Hansen <dave.hansen@linux.intel.com>

Changes from v2:
 * remove XSTATE_RESERVED check, since it is gone now

--

From: Dave Hansen <dave.hansen@linux.intel.com>

We now have C structures defined for each of the XSAVE state
components that we support.  This patch adds checks during our
verification pass to ensure that the CPU-provided data
enumerated in CPUID leaves matches our C structures.

If not, we warn and dump all the XSAVE CPUID leaves.

Note: this *actually* found an inconsistency with the MPX
'bndcsr' state.  The hardware pads it out differently from
our C structures.  This patch caught it and warned.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Borislav Petkov <bp@alien8.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
---

 b/arch/x86/kernel/fpu/xstate.c |   45 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff -puN arch/x86/kernel/fpu/xstate.c~x86-fpu-check-against-struct-declarations arch/x86/kernel/fpu/xstate.c
--- a/arch/x86/kernel/fpu/xstate.c~x86-fpu-check-against-struct-declarations	2015-09-02 16:26:46.232419598 -0700
+++ b/arch/x86/kernel/fpu/xstate.c	2015-09-02 16:26:46.236419780 -0700
@@ -432,6 +432,49 @@ static void __xstate_dump_leaves(void)
 	}									\
 } while (0)
 
+#define XCHECK_SZ(sz, nr, nr_macro, __struct) do {			\
+	if ((nr == nr_macro) &&						\
+	    WARN_ONCE(sz != sizeof(__struct),				\
+		"%s: struct is %zu bytes, cpu state %d bytes\n",	\
+		__stringify(nr_macro), sizeof(__struct), sz)) {		\
+		__xstate_dump_leaves();					\
+	}								\
+} while (0)
+
+/*
+ * We have a C struct for each 'xstate'.  We need to ensure
+ * that our software representation matches what the CPU
+ * tells us about the state's size.
+ */
+static void check_xstate_against_struct(int nr)
+{
+	/*
+	 * Ask the CPU for the size of the state.
+	 */
+	int sz = xfeature_size(nr);
+	/*
+	 * Match each CPU state with the corresponding software
+	 * structure.
+	 */
+	XCHECK_SZ(sz, nr, XFEATURE_YMM,       struct ymmh_struct);
+	XCHECK_SZ(sz, nr, XFEATURE_BNDREGS,   struct mpx_bndreg_state);
+	XCHECK_SZ(sz, nr, XFEATURE_BNDCSR,    struct mpx_bndcsr_state);
+	XCHECK_SZ(sz, nr, XFEATURE_OPMASK,    struct avx_512_opmask_state);
+	XCHECK_SZ(sz, nr, XFEATURE_ZMM_Hi256, struct avx_512_zmm_uppers_state);
+	XCHECK_SZ(sz, nr, XFEATURE_Hi16_ZMM,  struct avx_512_hi16_state);
+
+	/*
+	 * Make *SURE* to add any feature numbers in below if
+	 * there are "holes" in the xsave state component
+	 * numbers.
+	 */
+	if ((nr < XFEATURE_YMM) ||
+	    (nr >= XFEATURE_MAX)) {
+		WARN_ONCE(1, "no structure for xstate: %d\n", nr);
+		XSTATE_WARN_ON(1);
+	}
+}
+
 /*
  * This essentially double-checks what the cpu told us about
  * how large the XSAVE buffer needs to be.  We are recalculating
@@ -445,6 +488,8 @@ static void do_extra_xstate_size_checks(
 	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
 		if (!xfeature_enabled(i))
 			continue;
+
+		check_xstate_against_struct(i);
 		/*
 		 * Supervisor state components can be managed only by
 		 * XSAVES, which is compacted-format only.
_

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks
  2015-09-02 23:31 [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Dave Hansen
                   ` (14 preceding siblings ...)
  2015-09-02 23:31 ` [PATCH 15/15] x86, fpu: check CPU-provided sizes against struct declarations Dave Hansen
@ 2015-09-14 10:07 ` Ingo Molnar
  15 siblings, 0 replies; 35+ messages in thread
From: Ingo Molnar @ 2015-09-14 10:07 UTC (permalink / raw)
  To: Dave Hansen
  Cc: mingo, x86, bp, fenghua.yu, tim.c.chen, linux-kernel,
	Linus Torvalds, Andy Lutomirski, Denys Vlasenko, Brian Gerst,
	Peter Zijlstra, Thomas Gleixner, Oleg Nesterov


* Dave Hansen <dave@sr71.net> wrote:

> Changes in v4:
>  * Fix up a few compile errors/warnings
> 
> Changes in v3:
>  * rework XSTATE_* macros using Ingo's suggested naming
>  * change state size printk to be in decimal
>  * add some more sanity-checking to detect and work around
>    an undersized 'xregs_state'
>  * remove "nr_" from some of the names used.
> 
> Changes in v2:
>  * remove references to Processor Trace XSAVE state
>    (will defer to another patch set)
>  * Remove some cruft from last patch
>  * move last_good_offset fix in to the patch that
>    introduced it
> 
> These patches make some updates to the x86 XSAVE code.
> 
> They have been build and boot tested including on hardware
> and/or simulators with AVX-512 and MPX.  It boots in all
> of the tested configurations without hitting any of the
> new warnings in this code.  I even added the Memory
> Protecion Keys (the xfeature after MPX) patches on top of
> this and everything works fine.
> 
> There are basically 5 things going on here:
>  * removal of the LWP (lightweight profiling) code
>  * naming and type cleanups
>  * removal of xfeatures_nr variable
>  * addition of AVX-512 C structures
>  * new sanity checks of XSAVE buffer sizing

Ok, very nice! I've applied your series to tip:x86/fpu and will push it out unless 
testing finds any problems.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [tip:x86/fpu] x86/fpu: Print xfeature buffer size in decimal
  2015-09-02 23:31 ` [PATCH 01/15] x86, fpu: print xfeature buffer size in decimal Dave Hansen
@ 2015-09-14 12:19   ` tip-bot for Dave Hansen
  0 siblings, 0 replies; 35+ messages in thread
From: tip-bot for Dave Hansen @ 2015-09-14 12:19 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: dvlasenk, luto, torvalds, linux-kernel, fenghua.yu, tglx, mingo,
	dave.hansen, hpa, peterz, bp, brgerst, tim.c.chen

Commit-ID:  b0815359590f496f80e355a74319b6dc77010951
Gitweb:     http://git.kernel.org/tip/b0815359590f496f80e355a74319b6dc77010951
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Wed, 2 Sep 2015 16:31:24 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 14 Sep 2015 12:07:55 +0200

x86/fpu: Print xfeature buffer size in decimal

This is utterly a personal taste thing, but I find it way easier
to read structure sizes in decimal than in hex.

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/20150902233124.1A8B04A8@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/fpu/xstate.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 62fc001..b790dcb 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -187,7 +187,7 @@ static void __init setup_xstate_features(void)
 		xstate_offsets[leaf] = ebx;
 		xstate_sizes[leaf] = eax;
 
-		printk(KERN_INFO "x86/fpu: xstate_offset[%d]: %04x, xstate_sizes[%d]: %04x\n", leaf, ebx, leaf, eax);
+		printk(KERN_INFO "x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n", leaf, ebx, leaf, eax);
 	}
 }
 
@@ -357,7 +357,7 @@ void __init fpu__init_system_xstate(void)
 	setup_init_fpu_buf();
 	setup_xstate_comp();
 
-	pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is 0x%x bytes, using '%s' format.\n",
+	pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n",
 		xfeatures_mask,
 		xstate_size,
 		cpu_has_xsaves ? "compacted" : "standard");

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [tip:x86/fpu] x86/fpu: Move XSAVE-disabling code to a helper
  2015-09-02 23:31 ` [PATCH 02/15] x86, fpu: move XSAVE-disabling code to a helper Dave Hansen
@ 2015-09-14 12:19   ` tip-bot for Dave Hansen
  0 siblings, 0 replies; 35+ messages in thread
From: tip-bot for Dave Hansen @ 2015-09-14 12:19 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: dvlasenk, torvalds, mingo, dave.hansen, hpa, fenghua.yu, brgerst,
	tim.c.chen, tglx, bp, luto, linux-kernel, peterz

Commit-ID:  0a265375028b241a9173b7c569dd2368ba97fcd4
Gitweb:     http://git.kernel.org/tip/0a265375028b241a9173b7c569dd2368ba97fcd4
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Wed, 2 Sep 2015 16:31:24 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 14 Sep 2015 12:07:56 +0200

x86/fpu: Move XSAVE-disabling code to a helper

When we want to _completely_ disable XSAVE support as far as
the kernel is concerned, we have a big set of feature flags
to clear.  We currently only do this in cases where the user
asks for it to be disabled, but we are about to expand the
places where we do it to handle errors too.

Move the code in to xstate.c, and put it in the xstate.h
header.  We will use it in the next patch too.

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/20150902233124.EA9A70E5@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/fpu/xstate.h |  1 +
 arch/x86/kernel/fpu/init.c        | 12 +-----------
 arch/x86/kernel/fpu/xstate.c      | 19 +++++++++++++++++++
 3 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h
index 4656b25..d5a9b73 100644
--- a/arch/x86/include/asm/fpu/xstate.h
+++ b/arch/x86/include/asm/fpu/xstate.h
@@ -40,6 +40,7 @@ extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS];
 
 extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask);
 
+void fpu__xstate_clear_all_cpu_caps(void);
 void *get_xsave_addr(struct xregs_state *xsave, int xstate);
 const void *get_xsave_field_ptr(int xstate_field);
 
diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c
index d14e9ac..0a250af 100644
--- a/arch/x86/kernel/fpu/init.c
+++ b/arch/x86/kernel/fpu/init.c
@@ -354,17 +354,7 @@ static int __init x86_noxsave_setup(char *s)
 	if (strlen(s))
 		return 0;
 
-	setup_clear_cpu_cap(X86_FEATURE_XSAVE);
-	setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
-	setup_clear_cpu_cap(X86_FEATURE_XSAVEC);
-	setup_clear_cpu_cap(X86_FEATURE_XSAVES);
-	setup_clear_cpu_cap(X86_FEATURE_AVX);
-	setup_clear_cpu_cap(X86_FEATURE_AVX2);
-	setup_clear_cpu_cap(X86_FEATURE_AVX512F);
-	setup_clear_cpu_cap(X86_FEATURE_AVX512PF);
-	setup_clear_cpu_cap(X86_FEATURE_AVX512ER);
-	setup_clear_cpu_cap(X86_FEATURE_AVX512CD);
-	setup_clear_cpu_cap(X86_FEATURE_MPX);
+	fpu__xstate_clear_all_cpu_caps();
 
 	return 1;
 }
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index b790dcb..2ada11c 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -39,6 +39,25 @@ static unsigned int xstate_comp_offsets[sizeof(xfeatures_mask)*8];
 static unsigned int xfeatures_nr;
 
 /*
+ * Clear all of the X86_FEATURE_* bits that are unavailable
+ * when the CPU has no XSAVE support.
+ */
+void fpu__xstate_clear_all_cpu_caps(void)
+{
+	setup_clear_cpu_cap(X86_FEATURE_XSAVE);
+	setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
+	setup_clear_cpu_cap(X86_FEATURE_XSAVEC);
+	setup_clear_cpu_cap(X86_FEATURE_XSAVES);
+	setup_clear_cpu_cap(X86_FEATURE_AVX);
+	setup_clear_cpu_cap(X86_FEATURE_AVX2);
+	setup_clear_cpu_cap(X86_FEATURE_AVX512F);
+	setup_clear_cpu_cap(X86_FEATURE_AVX512PF);
+	setup_clear_cpu_cap(X86_FEATURE_AVX512ER);
+	setup_clear_cpu_cap(X86_FEATURE_AVX512CD);
+	setup_clear_cpu_cap(X86_FEATURE_MPX);
+}
+
+/*
  * Return whether the system supports a given xfeature.
  *
  * Also return the name of the (most advanced) feature that the caller requested:

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [tip:x86/fpu] x86/fpu: Remove XSTATE_RESERVE
  2015-09-02 23:31 ` [PATCH 03/15] x86, fpu: remove XSTATE_RESERVE Dave Hansen
@ 2015-09-14 12:20   ` tip-bot for Dave Hansen
  0 siblings, 0 replies; 35+ messages in thread
From: tip-bot for Dave Hansen @ 2015-09-14 12:20 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tim.c.chen, mingo, dave.hansen, torvalds, peterz, luto, dvlasenk,
	brgerst, hpa, bp, tglx, linux-kernel, fenghua.yu

Commit-ID:  4109ca066b6b899ac7549bf3aac94b178ac95891
Gitweb:     http://git.kernel.org/tip/4109ca066b6b899ac7549bf3aac94b178ac95891
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Wed, 2 Sep 2015 16:31:25 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 14 Sep 2015 12:07:56 +0200

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>
---
 arch/x86/include/asm/fpu/types.h | 15 +++++-----
 arch/x86/kernel/fpu/xstate.c     | 60 ++++++++++++++++++++++++++++++++++------
 2 files changed, 59 insertions(+), 16 deletions(-)

diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h
index c49c517..6aaafe0 100644
--- a/arch/x86/include/asm/fpu/types.h
+++ b/arch/x86/include/asm/fpu/types.h
@@ -159,22 +159,19 @@ struct xstate_header {
 	u64				reserved[6];
 } __attribute__((packed));
 
-/* New processor state extensions should be added here: */
-#define XSTATE_RESERVE			(sizeof(struct ymmh_struct) + \
-					 sizeof(struct lwp_struct)  + \
-					 sizeof(struct mpx_struct)  )
 /*
  * This is our most modern FPU state format, as saved by the XSAVE
  * and restored by the XRSTOR instructions.
  *
  * It consists of a legacy fxregs portion, an xstate header and
- * subsequent fixed size areas as defined by the xstate header.
- * Not all CPUs support all the extensions.
+ * subsequent areas as defined by the xstate header.  Not all CPUs
+ * support all the extensions, so the size of the extended area
+ * can vary quite a bit between CPUs.
  */
 struct xregs_state {
 	struct fxregs_state		i387;
 	struct xstate_header		header;
-	u8				__reserved[XSTATE_RESERVE];
+	u8				extended_state_area[0];
 } __attribute__ ((packed, aligned (64)));
 
 /*
@@ -182,7 +179,9 @@ struct xregs_state {
  * put together, so that we can pick the right one runtime.
  *
  * The size of the structure is determined by the largest
- * member - which is the xsave area:
+ * member - which is the xsave area.  The padding is there
+ * to ensure that statically-allocated task_structs (just
+ * the init_task today) have enough space.
  */
 union fpregs_state {
 	struct fregs_state		fsave;
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 2ada11c..769603a 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -312,24 +312,64 @@ static void __init setup_init_fpu_buf(void)
 /*
  * Calculate total size of enabled xstates in XCR0/xfeatures_mask.
  */
-static void __init init_xstate_size(void)
+static unsigned int __init calculate_xstate_size(void)
 {
 	unsigned int eax, ebx, ecx, edx;
+	unsigned int calculated_xstate_size;
 	int i;
 
 	if (!cpu_has_xsaves) {
 		cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);
-		xstate_size = ebx;
-		return;
+		calculated_xstate_size = ebx;
+		return calculated_xstate_size;
 	}
 
-	xstate_size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
+	calculated_xstate_size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
 	for (i = 2; i < 64; i++) {
 		if (test_bit(i, (unsigned long *)&xfeatures_mask)) {
 			cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
-			xstate_size += eax;
+			calculated_xstate_size += eax;
 		}
 	}
+	return calculated_xstate_size;
+}
+
+/*
+ * Will the runtime-enumerated 'xstate_size' fit in the init
+ * task's statically-allocated buffer?
+ */
+static bool is_supported_xstate_size(unsigned int test_xstate_size)
+{
+	if (test_xstate_size <= sizeof(union fpregs_state))
+		return true;
+
+	pr_warn("x86/fpu: xstate buffer too small (%zu < %d), disabling xsave\n",
+			sizeof(union fpregs_state), test_xstate_size);
+	return false;
+}
+
+static int init_xstate_size(void)
+{
+	/* Recompute the context size for enabled features: */
+	unsigned int possible_xstate_size = calculate_xstate_size();
+
+	/* Ensure we have the space to store all enabled: */
+	if (!is_supported_xstate_size(possible_xstate_size))
+		return -EINVAL;
+
+	/*
+	 * The size is OK, we are definitely going to use xsave,
+	 * make it known to the world that we need more space.
+	 */
+	xstate_size = possible_xstate_size;
+	return 0;
+}
+
+void fpu__init_disable_system_xstate(void)
+{
+	xfeatures_mask = 0;
+	cr4_clear_bits(X86_CR4_OSXSAVE);
+	fpu__xstate_clear_all_cpu_caps();
 }
 
 /*
@@ -340,6 +380,7 @@ void __init fpu__init_system_xstate(void)
 {
 	unsigned int eax, ebx, ecx, edx;
 	static int on_boot_cpu = 1;
+	int err;
 
 	WARN_ON_FPU(!on_boot_cpu);
 	on_boot_cpu = 0;
@@ -367,9 +408,12 @@ void __init fpu__init_system_xstate(void)
 
 	/* Enable xstate instructions to be able to continue with initialization: */
 	fpu__init_cpu_xstate();
-
-	/* Recompute the context size for enabled features: */
-	init_xstate_size();
+	err = init_xstate_size();
+	if (err) {
+		/* something went wrong, boot without any XSAVE support */
+		fpu__init_disable_system_xstate();
+		return;
+	}
 
 	update_regset_xstate_info(xstate_size, xfeatures_mask);
 	fpu__init_prepare_fx_sw_frame();

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [tip:x86/fpu] x86/fpu: Remove partial LWP support definitions
  2015-09-02 23:31 ` [PATCH 04/15] x86, fpu: kill LWP support Dave Hansen
@ 2015-09-14 12:20   ` tip-bot for Dave Hansen
  0 siblings, 0 replies; 35+ messages in thread
From: tip-bot for Dave Hansen @ 2015-09-14 12:20 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, luto, torvalds, dvlasenk, dave.hansen, bp, mingo, brgerst,
	peterz, fenghua.yu, tim.c.chen, tglx, linux-kernel

Commit-ID:  75933433d666c2ab13a7a93f4ec1e6f000a94ffc
Gitweb:     http://git.kernel.org/tip/75933433d666c2ab13a7a93f4ec1e6f000a94ffc
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Wed, 2 Sep 2015 16:31:25 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 14 Sep 2015 12:07:56 +0200

x86/fpu: Remove partial LWP support definitions

LightWeight Profiling was evidently an AMD profiling feature
that we never got around to implementing.  Remove the references
to it.

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.7E602284@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/fpu/types.h | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h
index 6aaafe0..5dc1a18 100644
--- a/arch/x86/include/asm/fpu/types.h
+++ b/arch/x86/include/asm/fpu/types.h
@@ -132,11 +132,6 @@ struct ymmh_struct {
 	u8				ymmh_space[256];
 };
 
-/* We don't support LWP yet: */
-struct lwp_struct {
-	u8				reserved[128];
-};
-
 /* Intel MPX support: */
 struct bndreg {
 	u64				lower_bound;

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [tip:x86/fpu] x86/fpu: Rename XSAVE macros
  2015-09-02 23:31 ` [PATCH 05/15] x86, fpu: XSAVE macro renames Dave Hansen
@ 2015-09-14 12:21   ` tip-bot for Dave Hansen
  2015-09-23 10:49     ` Borislav Petkov
  0 siblings, 1 reply; 35+ messages in thread
From: tip-bot for Dave Hansen @ 2015-09-14 12:21 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: torvalds, hpa, dave.hansen, linux-kernel, mingo, peterz,
	fenghua.yu, brgerst, bp, dvlasenk, tglx, tim.c.chen, luto

Commit-ID:  d91cab78133d33b1dfd3d3fa7167fcbf74fb5f99
Gitweb:     http://git.kernel.org/tip/d91cab78133d33b1dfd3d3fa7167fcbf74fb5f99
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Wed, 2 Sep 2015 16:31:26 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 14 Sep 2015 12:21:46 +0200

x86/fpu: Rename XSAVE macros

There are two concepts that have some confusing naming:
 1. Extended State Component numbers (currently called
    XFEATURE_BIT_*)
 2. Extended State Component masks (currently called XSTATE_*)

The numbers are (currently) from 0-9.  State component 3 is the
bounds registers for MPX, for instance.

But when we want to enable "state component 3", we go set a bit
in XCR0.  The bit we set is 1<<3.  We can check to see if a
state component feature is enabled by looking at its bit.

The current 'xfeature_bit's are at best xfeature bit _numbers_.
Calling them bits is at best inconsistent with ending the enum
list with 'XFEATURES_NR_MAX'.

This patch renames the enum to be 'xfeature'.  These also
happen to be what the Intel documentation calls a "state
component".

We also want to differentiate these from the "XSTATE_*" macros.
The "XSTATE_*" macros are a mask, and we rename them to match.

These macros are reasonably widely used so this patch is a
wee bit big, but this really is just a rename.

The only non-mechanical part of this is the

	s/XSTATE_EXTEND_MASK/XFEATURE_MASK_EXTEND/

We need a better name for it, but that's another patch.

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/20150902233126.38653250@viggo.jf.intel.com
[ Ported to v4.3-rc1. ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/crypto/camellia_aesni_avx2_glue.c |  3 +-
 arch/x86/crypto/camellia_aesni_avx_glue.c  |  3 +-
 arch/x86/crypto/cast5_avx_glue.c           |  3 +-
 arch/x86/crypto/cast6_avx_glue.c           |  3 +-
 arch/x86/crypto/chacha20_glue.c            |  2 +-
 arch/x86/crypto/poly1305_glue.c            |  2 +-
 arch/x86/crypto/serpent_avx2_glue.c        |  3 +-
 arch/x86/crypto/serpent_avx_glue.c         |  3 +-
 arch/x86/crypto/sha1_ssse3_glue.c          |  2 +-
 arch/x86/crypto/sha256_ssse3_glue.c        |  2 +-
 arch/x86/crypto/sha512_ssse3_glue.c        |  2 +-
 arch/x86/crypto/twofish_avx_glue.c         |  2 +-
 arch/x86/include/asm/fpu/types.h           | 44 +++++++++++++++++-------------
 arch/x86/include/asm/fpu/xstate.h          | 14 ++++++----
 arch/x86/kernel/fpu/init.c                 |  6 ++--
 arch/x86/kernel/fpu/regset.c               |  4 +--
 arch/x86/kernel/fpu/signal.c               |  6 ++--
 arch/x86/kernel/fpu/xstate.c               | 36 +++++++++++++-----------
 arch/x86/kernel/traps.c                    |  2 +-
 arch/x86/kvm/cpuid.c                       |  4 +--
 arch/x86/kvm/x86.c                         | 27 +++++++++---------
 arch/x86/kvm/x86.h                         |  6 ++--
 arch/x86/mm/mpx.c                          |  6 ++--
 23 files changed, 103 insertions(+), 82 deletions(-)

diff --git a/arch/x86/crypto/camellia_aesni_avx2_glue.c b/arch/x86/crypto/camellia_aesni_avx2_glue.c
index 4c65c70..d844569 100644
--- a/arch/x86/crypto/camellia_aesni_avx2_glue.c
+++ b/arch/x86/crypto/camellia_aesni_avx2_glue.c
@@ -567,7 +567,8 @@ static int __init camellia_aesni_init(void)
 		return -ENODEV;
 	}
 
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+				&feature_name)) {
 		pr_info("CPU feature '%s' is not supported.\n", feature_name);
 		return -ENODEV;
 	}
diff --git a/arch/x86/crypto/camellia_aesni_avx_glue.c b/arch/x86/crypto/camellia_aesni_avx_glue.c
index 80a0e43..12e729b 100644
--- a/arch/x86/crypto/camellia_aesni_avx_glue.c
+++ b/arch/x86/crypto/camellia_aesni_avx_glue.c
@@ -554,7 +554,8 @@ static int __init camellia_aesni_init(void)
 {
 	const char *feature_name;
 
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+				&feature_name)) {
 		pr_info("CPU feature '%s' is not supported.\n", feature_name);
 		return -ENODEV;
 	}
diff --git a/arch/x86/crypto/cast5_avx_glue.c b/arch/x86/crypto/cast5_avx_glue.c
index be00aa4..8648158 100644
--- a/arch/x86/crypto/cast5_avx_glue.c
+++ b/arch/x86/crypto/cast5_avx_glue.c
@@ -469,7 +469,8 @@ static int __init cast5_init(void)
 {
 	const char *feature_name;
 
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+				&feature_name)) {
 		pr_info("CPU feature '%s' is not supported.\n", feature_name);
 		return -ENODEV;
 	}
diff --git a/arch/x86/crypto/cast6_avx_glue.c b/arch/x86/crypto/cast6_avx_glue.c
index 5dbba72..fca4595 100644
--- a/arch/x86/crypto/cast6_avx_glue.c
+++ b/arch/x86/crypto/cast6_avx_glue.c
@@ -591,7 +591,8 @@ static int __init cast6_init(void)
 {
 	const char *feature_name;
 
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+				&feature_name)) {
 		pr_info("CPU feature '%s' is not supported.\n", feature_name);
 		return -ENODEV;
 	}
diff --git a/arch/x86/crypto/chacha20_glue.c b/arch/x86/crypto/chacha20_glue.c
index effe216..722bace 100644
--- a/arch/x86/crypto/chacha20_glue.c
+++ b/arch/x86/crypto/chacha20_glue.c
@@ -130,7 +130,7 @@ static int __init chacha20_simd_mod_init(void)
 
 #ifdef CONFIG_AS_AVX2
 	chacha20_use_avx2 = cpu_has_avx && cpu_has_avx2 &&
-			    cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, NULL);
+			    cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL);
 #endif
 	return crypto_register_alg(&alg);
 }
diff --git a/arch/x86/crypto/poly1305_glue.c b/arch/x86/crypto/poly1305_glue.c
index f7170d7..4264a3d 100644
--- a/arch/x86/crypto/poly1305_glue.c
+++ b/arch/x86/crypto/poly1305_glue.c
@@ -184,7 +184,7 @@ static int __init poly1305_simd_mod_init(void)
 
 #ifdef CONFIG_AS_AVX2
 	poly1305_use_avx2 = cpu_has_avx && cpu_has_avx2 &&
-			    cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, NULL);
+			    cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL);
 	alg.descsize = sizeof(struct poly1305_simd_desc_ctx);
 	if (poly1305_use_avx2)
 		alg.descsize += 10 * sizeof(u32);
diff --git a/arch/x86/crypto/serpent_avx2_glue.c b/arch/x86/crypto/serpent_avx2_glue.c
index 7d838dc..6d19834 100644
--- a/arch/x86/crypto/serpent_avx2_glue.c
+++ b/arch/x86/crypto/serpent_avx2_glue.c
@@ -542,7 +542,8 @@ static int __init init(void)
 		pr_info("AVX2 instructions are not detected.\n");
 		return -ENODEV;
 	}
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+				&feature_name)) {
 		pr_info("CPU feature '%s' is not supported.\n", feature_name);
 		return -ENODEV;
 	}
diff --git a/arch/x86/crypto/serpent_avx_glue.c b/arch/x86/crypto/serpent_avx_glue.c
index da7dafc..5dc3702 100644
--- a/arch/x86/crypto/serpent_avx_glue.c
+++ b/arch/x86/crypto/serpent_avx_glue.c
@@ -597,7 +597,8 @@ static int __init serpent_init(void)
 {
 	const char *feature_name;
 
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+				&feature_name)) {
 		pr_info("CPU feature '%s' is not supported.\n", feature_name);
 		return -ENODEV;
 	}
diff --git a/arch/x86/crypto/sha1_ssse3_glue.c b/arch/x86/crypto/sha1_ssse3_glue.c
index 7c48e8b..00212c3 100644
--- a/arch/x86/crypto/sha1_ssse3_glue.c
+++ b/arch/x86/crypto/sha1_ssse3_glue.c
@@ -121,7 +121,7 @@ static struct shash_alg alg = {
 #ifdef CONFIG_AS_AVX
 static bool __init avx_usable(void)
 {
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, NULL)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
 		if (cpu_has_avx)
 			pr_info("AVX detected but unusable.\n");
 		return false;
diff --git a/arch/x86/crypto/sha256_ssse3_glue.c b/arch/x86/crypto/sha256_ssse3_glue.c
index f8097fc..0e0e85a 100644
--- a/arch/x86/crypto/sha256_ssse3_glue.c
+++ b/arch/x86/crypto/sha256_ssse3_glue.c
@@ -130,7 +130,7 @@ static struct shash_alg algs[] = { {
 #ifdef CONFIG_AS_AVX
 static bool __init avx_usable(void)
 {
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, NULL)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
 		if (cpu_has_avx)
 			pr_info("AVX detected but unusable.\n");
 		return false;
diff --git a/arch/x86/crypto/sha512_ssse3_glue.c b/arch/x86/crypto/sha512_ssse3_glue.c
index 2edad7b..0c8c38c 100644
--- a/arch/x86/crypto/sha512_ssse3_glue.c
+++ b/arch/x86/crypto/sha512_ssse3_glue.c
@@ -129,7 +129,7 @@ static struct shash_alg algs[] = { {
 #ifdef CONFIG_AS_AVX
 static bool __init avx_usable(void)
 {
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, NULL)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
 		if (cpu_has_avx)
 			pr_info("AVX detected but unusable.\n");
 		return false;
diff --git a/arch/x86/crypto/twofish_avx_glue.c b/arch/x86/crypto/twofish_avx_glue.c
index c2bd0ce..6f3738c 100644
--- a/arch/x86/crypto/twofish_avx_glue.c
+++ b/arch/x86/crypto/twofish_avx_glue.c
@@ -558,7 +558,7 @@ static int __init twofish_init(void)
 {
 	const char *feature_name;
 
-	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
 		pr_info("CPU feature '%s' is not supported.\n", feature_name);
 		return -ENODEV;
 	}
diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h
index 5dc1a18..9f20d10 100644
--- a/arch/x86/include/asm/fpu/types.h
+++ b/arch/x86/include/asm/fpu/types.h
@@ -95,30 +95,36 @@ struct swregs_state {
 /*
  * List of XSAVE features Linux knows about:
  */
-enum xfeature_bit {
-	XSTATE_BIT_FP,
-	XSTATE_BIT_SSE,
-	XSTATE_BIT_YMM,
-	XSTATE_BIT_BNDREGS,
-	XSTATE_BIT_BNDCSR,
-	XSTATE_BIT_OPMASK,
-	XSTATE_BIT_ZMM_Hi256,
-	XSTATE_BIT_Hi16_ZMM,
+enum xfeature {
+	XFEATURE_FP,
+	XFEATURE_SSE,
+	/*
+	 * Values above here are "legacy states".
+	 * Those below are "extended states".
+	 */
+	XFEATURE_YMM,
+	XFEATURE_BNDREGS,
+	XFEATURE_BNDCSR,
+	XFEATURE_OPMASK,
+	XFEATURE_ZMM_Hi256,
+	XFEATURE_Hi16_ZMM,
 
 	XFEATURES_NR_MAX,
 };
 
-#define XSTATE_FP		(1 << XSTATE_BIT_FP)
-#define XSTATE_SSE		(1 << XSTATE_BIT_SSE)
-#define XSTATE_YMM		(1 << XSTATE_BIT_YMM)
-#define XSTATE_BNDREGS		(1 << XSTATE_BIT_BNDREGS)
-#define XSTATE_BNDCSR		(1 << XSTATE_BIT_BNDCSR)
-#define XSTATE_OPMASK		(1 << XSTATE_BIT_OPMASK)
-#define XSTATE_ZMM_Hi256	(1 << XSTATE_BIT_ZMM_Hi256)
-#define XSTATE_Hi16_ZMM		(1 << XSTATE_BIT_Hi16_ZMM)
+#define XFEATURE_MASK_FP		(1 << XFEATURE_FP)
+#define XFEATURE_MASK_SSE		(1 << XFEATURE_SSE)
+#define XFEATURE_MASK_YMM		(1 << XFEATURE_YMM)
+#define XFEATURE_MASK_BNDREGS		(1 << XFEATURE_BNDREGS)
+#define XFEATURE_MASK_BNDCSR		(1 << XFEATURE_BNDCSR)
+#define XFEATURE_MASK_OPMASK		(1 << XFEATURE_OPMASK)
+#define XFEATURE_MASK_ZMM_Hi256		(1 << XFEATURE_ZMM_Hi256)
+#define XFEATURE_MASK_Hi16_ZMM		(1 << XFEATURE_Hi16_ZMM)
 
-#define XSTATE_FPSSE		(XSTATE_FP | XSTATE_SSE)
-#define XSTATE_AVX512		(XSTATE_OPMASK | XSTATE_ZMM_Hi256 | XSTATE_Hi16_ZMM)
+#define XFEATURE_MASK_FPSSE		(XFEATURE_MASK_FP | XFEATURE_MASK_SSE)
+#define XFEATURE_MASK_AVX512		(XFEATURE_MASK_OPMASK \
+					 | XFEATURE_MASK_ZMM_Hi256 \
+					 | XFEATURE_MASK_Hi16_ZMM)
 
 /*
  * There are 16x 256-bit AVX registers named YMM0-YMM15.
diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h
index d5a9b73..3a6c89b 100644
--- a/arch/x86/include/asm/fpu/xstate.h
+++ b/arch/x86/include/asm/fpu/xstate.h
@@ -6,7 +6,7 @@
 #include <linux/uaccess.h>
 
 /* Bit 63 of XCR0 is reserved for future expansion */
-#define XSTATE_EXTEND_MASK	(~(XSTATE_FPSSE | (1ULL << 63)))
+#define XFEATURE_MASK_EXTEND	(~(XFEATURE_MASK_FPSSE | (1ULL << 63)))
 
 #define XSTATE_CPUID		0x0000000d
 
@@ -19,14 +19,18 @@
 #define XSAVE_YMM_OFFSET    (XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET)
 
 /* Supported features which support lazy state saving */
-#define XSTATE_LAZY	(XSTATE_FP | XSTATE_SSE | XSTATE_YMM		      \
-			| XSTATE_OPMASK | XSTATE_ZMM_Hi256 | XSTATE_Hi16_ZMM)
+#define XFEATURE_MASK_LAZY	(XFEATURE_MASK_FP | \
+				 XFEATURE_MASK_SSE | \
+				 XFEATURE_MASK_YMM | \
+				 XFEATURE_MASK_OPMASK |	\
+				 XFEATURE_MASK_ZMM_Hi256 | \
+				 XFEATURE_MASK_Hi16_ZMM)
 
 /* Supported features which require eager state saving */
-#define XSTATE_EAGER	(XSTATE_BNDREGS | XSTATE_BNDCSR)
+#define XFEATURE_MASK_EAGER	(XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR)
 
 /* All currently supported features */
-#define XCNTXT_MASK	(XSTATE_LAZY | XSTATE_EAGER)
+#define XCNTXT_MASK	(XFEATURE_MASK_LAZY | XFEATURE_MASK_EAGER)
 
 #ifdef CONFIG_X86_64
 #define REX_PREFIX	"0x48, "
diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c
index 0a250af..be39b5f 100644
--- a/arch/x86/kernel/fpu/init.c
+++ b/arch/x86/kernel/fpu/init.c
@@ -290,11 +290,11 @@ static void __init fpu__init_system_ctx_switch(void)
 	if (cpu_has_xsaveopt && eagerfpu != DISABLE)
 		eagerfpu = ENABLE;
 
-	if (xfeatures_mask & XSTATE_EAGER) {
+	if (xfeatures_mask & XFEATURE_MASK_EAGER) {
 		if (eagerfpu == DISABLE) {
 			pr_err("x86/fpu: eagerfpu switching disabled, disabling the following xstate features: 0x%llx.\n",
-			       xfeatures_mask & XSTATE_EAGER);
-			xfeatures_mask &= ~XSTATE_EAGER;
+			       xfeatures_mask & XFEATURE_MASK_EAGER);
+			xfeatures_mask &= ~XFEATURE_MASK_EAGER;
 		} else {
 			eagerfpu = ENABLE;
 		}
diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c
index dc60810..0bc3490 100644
--- a/arch/x86/kernel/fpu/regset.c
+++ b/arch/x86/kernel/fpu/regset.c
@@ -66,7 +66,7 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
 	 * presence of FP and SSE state.
 	 */
 	if (cpu_has_xsave)
-		fpu->state.xsave.header.xfeatures |= XSTATE_FPSSE;
+		fpu->state.xsave.header.xfeatures |= XFEATURE_MASK_FPSSE;
 
 	return ret;
 }
@@ -326,7 +326,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset,
 	 * presence of FP.
 	 */
 	if (cpu_has_xsave)
-		fpu->state.xsave.header.xfeatures |= XSTATE_FP;
+		fpu->state.xsave.header.xfeatures |= XFEATURE_MASK_FP;
 	return ret;
 }
 
diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
index 50ec9af..eb03267 100644
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@ -107,7 +107,7 @@ static inline int save_xstate_epilog(void __user *buf, int ia32_frame)
 	 * header as well as change any contents in the memory layout.
 	 * xrestore as part of sigreturn will capture all the changes.
 	 */
-	xfeatures |= XSTATE_FPSSE;
+	xfeatures |= XFEATURE_MASK_FPSSE;
 
 	err |= __put_user(xfeatures, (__u32 *)&x->header.xfeatures);
 
@@ -207,7 +207,7 @@ sanitize_restored_xstate(struct task_struct *tsk,
 		 * layout and not enabled by the OS.
 		 */
 		if (fx_only)
-			header->xfeatures = XSTATE_FPSSE;
+			header->xfeatures = XFEATURE_MASK_FPSSE;
 		else
 			header->xfeatures &= (xfeatures_mask & xfeatures);
 	}
@@ -230,7 +230,7 @@ static inline int copy_user_to_fpregs_zeroing(void __user *buf, u64 xbv, int fx_
 {
 	if (use_xsave()) {
 		if ((unsigned long)buf % 64 || fx_only) {
-			u64 init_bv = xfeatures_mask & ~XSTATE_FPSSE;
+			u64 init_bv = xfeatures_mask & ~XFEATURE_MASK_FPSSE;
 			copy_kernel_to_xregs(&init_fpstate.xsave, init_bv);
 			return copy_user_to_fxregs(buf);
 		} else {
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 769603a..d6f0be9 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -72,7 +72,7 @@ int cpu_has_xfeatures(u64 xfeatures_needed, const char **feature_name)
 		/*
 		 * So we use FLS here to be able to print the most advanced
 		 * feature that was requested but is missing. So if a driver
-		 * asks about "XSTATE_SSE | XSTATE_YMM" we'll print the
+		 * asks about "XFEATURE_MASK_SSE | XFEATURE_MASK_YMM" we'll print the
 		 * missing AVX feature - this is the most informative message
 		 * to users:
 		 */
@@ -131,7 +131,7 @@ void fpstate_sanitize_xstate(struct fpu *fpu)
 	/*
 	 * FP is in init state
 	 */
-	if (!(xfeatures & XSTATE_FP)) {
+	if (!(xfeatures & XFEATURE_MASK_FP)) {
 		fx->cwd = 0x37f;
 		fx->swd = 0;
 		fx->twd = 0;
@@ -144,7 +144,7 @@ void fpstate_sanitize_xstate(struct fpu *fpu)
 	/*
 	 * SSE is in init state
 	 */
-	if (!(xfeatures & XSTATE_SSE))
+	if (!(xfeatures & XFEATURE_MASK_SSE))
 		memset(&fx->xmm_space[0], 0, 256);
 
 	/*
@@ -223,14 +223,14 @@ static void __init print_xstate_feature(u64 xstate_mask)
  */
 static void __init print_xstate_features(void)
 {
-	print_xstate_feature(XSTATE_FP);
-	print_xstate_feature(XSTATE_SSE);
-	print_xstate_feature(XSTATE_YMM);
-	print_xstate_feature(XSTATE_BNDREGS);
-	print_xstate_feature(XSTATE_BNDCSR);
-	print_xstate_feature(XSTATE_OPMASK);
-	print_xstate_feature(XSTATE_ZMM_Hi256);
-	print_xstate_feature(XSTATE_Hi16_ZMM);
+	print_xstate_feature(XFEATURE_MASK_FP);
+	print_xstate_feature(XFEATURE_MASK_SSE);
+	print_xstate_feature(XFEATURE_MASK_YMM);
+	print_xstate_feature(XFEATURE_MASK_BNDREGS);
+	print_xstate_feature(XFEATURE_MASK_BNDCSR);
+	print_xstate_feature(XFEATURE_MASK_OPMASK);
+	print_xstate_feature(XFEATURE_MASK_ZMM_Hi256);
+	print_xstate_feature(XFEATURE_MASK_Hi16_ZMM);
 }
 
 /*
@@ -365,7 +365,11 @@ static int init_xstate_size(void)
 	return 0;
 }
 
-void fpu__init_disable_system_xstate(void)
+/*
+ * We enabled the XSAVE hardware, but something went wrong and
+ * we can not use it.  Disable it.
+ */
+static void fpu__init_disable_system_xstate(void)
 {
 	xfeatures_mask = 0;
 	cr4_clear_bits(X86_CR4_OSXSAVE);
@@ -398,7 +402,7 @@ void __init fpu__init_system_xstate(void)
 	cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);
 	xfeatures_mask = eax + ((u64)edx << 32);
 
-	if ((xfeatures_mask & XSTATE_FPSSE) != XSTATE_FPSSE) {
+	if ((xfeatures_mask & XFEATURE_MASK_FPSSE) != XFEATURE_MASK_FPSSE) {
 		pr_err("x86/fpu: FP/SSE not present amongst the CPU's xstate features: 0x%llx.\n", xfeatures_mask);
 		BUG();
 	}
@@ -451,7 +455,7 @@ void fpu__resume_cpu(void)
  * Inputs:
  *	xstate: the thread's storage area for all FPU data
  *	xstate_feature: state which is defined in xsave.h (e.g.
- *	XSTATE_FP, XSTATE_SSE, etc...)
+ *	XFEATURE_MASK_FP, XFEATURE_MASK_SSE, etc...)
  * Output:
  *	address of the state in the xsave area, or NULL if the
  *	field is not present in the xsave buffer.
@@ -502,8 +506,8 @@ EXPORT_SYMBOL_GPL(get_xsave_addr);
  * Note that this only works on the current task.
  *
  * Inputs:
- *	@xsave_state: state which is defined in xsave.h (e.g. XSTATE_FP,
- *	XSTATE_SSE, etc...)
+ *	@xsave_state: state which is defined in xsave.h (e.g. XFEATURE_MASK_FP,
+ *	XFEATURE_MASK_SSE, etc...)
  * Output:
  *	address of the state in the xsave area or NULL if the state
  *	is not present or is in its 'init state'.
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 346eec7..0cd2ac5 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -384,7 +384,7 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
 	 * which is all zeros which indicates MPX was not
 	 * responsible for the exception.
 	 */
-	bndcsr = get_xsave_field_ptr(XSTATE_BNDCSR);
+	bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR);
 	if (!bndcsr)
 		goto exit_trap;
 
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 2fbea25..156441b 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -30,7 +30,7 @@ static u32 xstate_required_size(u64 xstate_bv, bool compacted)
 	int feature_bit = 0;
 	u32 ret = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET;
 
-	xstate_bv &= XSTATE_EXTEND_MASK;
+	xstate_bv &= XFEATURE_MASK_EXTEND;
 	while (xstate_bv) {
 		if (xstate_bv & 0x1) {
 		        u32 eax, ebx, ecx, edx, offset;
@@ -51,7 +51,7 @@ u64 kvm_supported_xcr0(void)
 	u64 xcr0 = KVM_SUPPORTED_XCR0 & host_xcr0;
 
 	if (!kvm_x86_ops->mpx_supported())
-		xcr0 &= ~(XSTATE_BNDREGS | XSTATE_BNDCSR);
+		xcr0 &= ~(XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR);
 
 	return xcr0;
 }
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index a60bdbc..2d4e54d 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -662,9 +662,9 @@ static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
 	/* Only support XCR_XFEATURE_ENABLED_MASK(xcr0) now  */
 	if (index != XCR_XFEATURE_ENABLED_MASK)
 		return 1;
-	if (!(xcr0 & XSTATE_FP))
+	if (!(xcr0 & XFEATURE_MASK_FP))
 		return 1;
-	if ((xcr0 & XSTATE_YMM) && !(xcr0 & XSTATE_SSE))
+	if ((xcr0 & XFEATURE_MASK_YMM) && !(xcr0 & XFEATURE_MASK_SSE))
 		return 1;
 
 	/*
@@ -672,23 +672,24 @@ static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
 	 * saving.  However, xcr0 bit 0 is always set, even if the
 	 * emulated CPU does not support XSAVE (see fx_init).
 	 */
-	valid_bits = vcpu->arch.guest_supported_xcr0 | XSTATE_FP;
+	valid_bits = vcpu->arch.guest_supported_xcr0 | XFEATURE_MASK_FP;
 	if (xcr0 & ~valid_bits)
 		return 1;
 
-	if ((!(xcr0 & XSTATE_BNDREGS)) != (!(xcr0 & XSTATE_BNDCSR)))
+	if ((!(xcr0 & XFEATURE_MASK_BNDREGS)) !=
+	    (!(xcr0 & XFEATURE_MASK_BNDCSR)))
 		return 1;
 
-	if (xcr0 & XSTATE_AVX512) {
-		if (!(xcr0 & XSTATE_YMM))
+	if (xcr0 & XFEATURE_MASK_AVX512) {
+		if (!(xcr0 & XFEATURE_MASK_YMM))
 			return 1;
-		if ((xcr0 & XSTATE_AVX512) != XSTATE_AVX512)
+		if ((xcr0 & XFEATURE_MASK_AVX512) != XFEATURE_MASK_AVX512)
 			return 1;
 	}
 	kvm_put_guest_xcr0(vcpu);
 	vcpu->arch.xcr0 = xcr0;
 
-	if ((xcr0 ^ old_xcr0) & XSTATE_EXTEND_MASK)
+	if ((xcr0 ^ old_xcr0) & XFEATURE_MASK_EXTEND)
 		kvm_update_cpuid(vcpu);
 	return 0;
 }
@@ -2906,7 +2907,7 @@ static void fill_xsave(u8 *dest, struct kvm_vcpu *vcpu)
 	 * Copy each region from the possibly compacted offset to the
 	 * non-compacted offset.
 	 */
-	valid = xstate_bv & ~XSTATE_FPSSE;
+	valid = xstate_bv & ~XFEATURE_MASK_FPSSE;
 	while (valid) {
 		u64 feature = valid & -valid;
 		int index = fls64(feature) - 1;
@@ -2944,7 +2945,7 @@ static void load_xsave(struct kvm_vcpu *vcpu, u8 *src)
 	 * Copy each region from the non-compacted offset to the
 	 * possibly compacted offset.
 	 */
-	valid = xstate_bv & ~XSTATE_FPSSE;
+	valid = xstate_bv & ~XFEATURE_MASK_FPSSE;
 	while (valid) {
 		u64 feature = valid & -valid;
 		int index = fls64(feature) - 1;
@@ -2972,7 +2973,7 @@ static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
 			&vcpu->arch.guest_fpu.state.fxsave,
 			sizeof(struct fxregs_state));
 		*(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)] =
-			XSTATE_FPSSE;
+			XFEATURE_MASK_FPSSE;
 	}
 }
 
@@ -2992,7 +2993,7 @@ static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
 			return -EINVAL;
 		load_xsave(vcpu, (u8 *)guest_xsave->region);
 	} else {
-		if (xstate_bv & ~XSTATE_FPSSE)
+		if (xstate_bv & ~XFEATURE_MASK_FPSSE)
 			return -EINVAL;
 		memcpy(&vcpu->arch.guest_fpu.state.fxsave,
 			guest_xsave->region, sizeof(struct fxregs_state));
@@ -7001,7 +7002,7 @@ static void fx_init(struct kvm_vcpu *vcpu)
 	/*
 	 * Ensure guest xcr0 is valid for loading
 	 */
-	vcpu->arch.xcr0 = XSTATE_FP;
+	vcpu->arch.xcr0 = XFEATURE_MASK_FP;
 
 	vcpu->arch.cr0 |= X86_CR0_ET;
 }
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 2f822cd..f2afa5f 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -180,9 +180,9 @@ int kvm_mtrr_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
 bool kvm_mtrr_check_gfn_range_consistency(struct kvm_vcpu *vcpu, gfn_t gfn,
 					  int page_num);
 
-#define KVM_SUPPORTED_XCR0     (XSTATE_FP | XSTATE_SSE | XSTATE_YMM \
-				| XSTATE_BNDREGS | XSTATE_BNDCSR \
-				| XSTATE_AVX512)
+#define KVM_SUPPORTED_XCR0     (XFEATURE_MASK_FP | XFEATURE_MASK_SSE \
+				| XFEATURE_MASK_YMM | XFEATURE_MASK_BNDREGS \
+				| XFEATURE_MASK_BNDCSR | XFEATURE_MASK_AVX512)
 extern u64 host_xcr0;
 
 extern u64 kvm_supported_xcr0(void);
diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c
index 134948b..f35fc9c 100644
--- a/arch/x86/mm/mpx.c
+++ b/arch/x86/mm/mpx.c
@@ -258,7 +258,7 @@ siginfo_t *mpx_generate_siginfo(struct pt_regs *regs)
 		goto err_out;
 	}
 	/* get bndregs field from current task's xsave area */
-	bndregs = get_xsave_field_ptr(XSTATE_BNDREGS);
+	bndregs = get_xsave_field_ptr(XFEATURE_MASK_BNDREGS);
 	if (!bndregs) {
 		err = -EINVAL;
 		goto err_out;
@@ -315,7 +315,7 @@ static __user void *mpx_get_bounds_dir(void)
 	 * The bounds directory pointer is stored in a register
 	 * only accessible if we first do an xsave.
 	 */
-	bndcsr = get_xsave_field_ptr(XSTATE_BNDCSR);
+	bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR);
 	if (!bndcsr)
 		return MPX_INVALID_BOUNDS_DIR;
 
@@ -492,7 +492,7 @@ static int do_mpx_bt_fault(void)
 	const struct bndcsr *bndcsr;
 	struct mm_struct *mm = current->mm;
 
-	bndcsr = get_xsave_field_ptr(XSTATE_BNDCSR);
+	bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR);
 	if (!bndcsr)
 		return -EINVAL;
 	/*

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [tip:x86/fpu] x86/fpu: Rename XFEATURES_NR_MAX
  2015-09-02 23:31 ` [PATCH 06/15] x86, fpu: rename XFEATURES_NR_MAX Dave Hansen
@ 2015-09-14 12:21   ` tip-bot for Dave Hansen
  0 siblings, 0 replies; 35+ messages in thread
From: tip-bot for Dave Hansen @ 2015-09-14 12:21 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, tim.c.chen, torvalds, luto, hpa, bp, tglx, brgerst,
	dvlasenk, fenghua.yu, peterz, linux-kernel, dave.hansen

Commit-ID:  dad8c4fe8530f28dde73dadd1d588e3aaa507562
Gitweb:     http://git.kernel.org/tip/dad8c4fe8530f28dde73dadd1d588e3aaa507562
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Wed, 2 Sep 2015 16:31:27 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 14 Sep 2015 12:21:57 +0200

x86/fpu: Rename XFEATURES_NR_MAX

This is a logcal followon to the last patch.  It makes the
XFEATURE_MAX naming consistent with the other enum values.
This is what Ingo suggested.

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/20150902233127.A541448F@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/fpu/types.h | 2 +-
 arch/x86/kernel/fpu/xstate.c     | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h
index 9f20d10..8764df3 100644
--- a/arch/x86/include/asm/fpu/types.h
+++ b/arch/x86/include/asm/fpu/types.h
@@ -109,7 +109,7 @@ enum xfeature {
 	XFEATURE_ZMM_Hi256,
 	XFEATURE_Hi16_ZMM,
 
-	XFEATURES_NR_MAX,
+	XFEATURE_MAX,
 };
 
 #define XFEATURE_MASK_FP		(1 << XFEATURE_FP)
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index d6f0be9..f94e236 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -31,8 +31,8 @@ static const char *xfeature_names[] =
  */
 u64 xfeatures_mask __read_mostly;
 
-static unsigned int xstate_offsets[XFEATURES_NR_MAX] = { [ 0 ... XFEATURES_NR_MAX - 1] = -1};
-static unsigned int xstate_sizes[XFEATURES_NR_MAX]   = { [ 0 ... XFEATURES_NR_MAX - 1] = -1};
+static unsigned int xstate_offsets[XFEATURE_MAX] = { [ 0 ... XFEATURE_MAX - 1] = -1};
+static unsigned int xstate_sizes[XFEATURE_MAX]   = { [ 0 ... XFEATURE_MAX - 1] = -1};
 static unsigned int xstate_comp_offsets[sizeof(xfeatures_mask)*8];
 
 /* The number of supported xfeatures in xfeatures_mask: */

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [tip:x86/fpu] x86/fpu: Rework XSTATE_* macros to remove magic '2'
  2015-09-02 23:31 ` [PATCH 07/15] x86, fpu: rework XSTATE_* macros to remove magic '2' Dave Hansen
@ 2015-09-14 12:21   ` tip-bot for Dave Hansen
  0 siblings, 0 replies; 35+ messages in thread
From: tip-bot for Dave Hansen @ 2015-09-14 12:21 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: fenghua.yu, dave.hansen, bp, peterz, linux-kernel, torvalds,
	dvlasenk, luto, hpa, mingo, brgerst, tim.c.chen, tglx

Commit-ID:  8a93c9e0dca131a0bf330ea9d1e57c1bcf3824ad
Gitweb:     http://git.kernel.org/tip/8a93c9e0dca131a0bf330ea9d1e57c1bcf3824ad
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Wed, 2 Sep 2015 16:31:28 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 14 Sep 2015 12:21:58 +0200

x86/fpu: Rework XSTATE_* macros to remove magic '2'

The 'xstate.c' code has a bunch of references to '2'.  This
is because we have a lot more work to do for the "extended"
xstates than the "legacy" ones and state component 2 is the
first "extended" state.

This patch replaces all of the instances of '2' with
FIRST_EXTENDED_XFEATURE, which clearly explains what is
going on.

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/20150902233128.A8C0BF51@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/fpu/types.h |  2 ++
 arch/x86/kernel/fpu/xstate.c     | 13 +++++++------
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h
index 8764df3..9f57930 100644
--- a/arch/x86/include/asm/fpu/types.h
+++ b/arch/x86/include/asm/fpu/types.h
@@ -126,6 +126,8 @@ enum xfeature {
 					 | XFEATURE_MASK_ZMM_Hi256 \
 					 | XFEATURE_MASK_Hi16_ZMM)
 
+#define FIRST_EXTENDED_XFEATURE	XFEATURE_YMM
+
 /*
  * There are 16x 256-bit AVX registers named YMM0-YMM15.
  * The low 128 bits are aliased to the 16 SSE registers (XMM0-XMM15)
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index f94e236..c1a0bf4 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -200,7 +200,7 @@ static void __init setup_xstate_features(void)
 
 	xfeatures_nr = fls64(xfeatures_mask);
 
-	for (leaf = 2; leaf < xfeatures_nr; leaf++) {
+	for (leaf = FIRST_EXTENDED_XFEATURE; leaf < xfeatures_nr; leaf++) {
 		cpuid_count(XSTATE_CPUID, leaf, &eax, &ebx, &ecx, &edx);
 
 		xstate_offsets[leaf] = ebx;
@@ -252,7 +252,7 @@ static void __init setup_xstate_comp(void)
 	xstate_comp_offsets[1] = offsetof(struct fxregs_state, xmm_space);
 
 	if (!cpu_has_xsaves) {
-		for (i = 2; i < xfeatures_nr; i++) {
+		for (i = FIRST_EXTENDED_XFEATURE; i < xfeatures_nr; i++) {
 			if (test_bit(i, (unsigned long *)&xfeatures_mask)) {
 				xstate_comp_offsets[i] = xstate_offsets[i];
 				xstate_comp_sizes[i] = xstate_sizes[i];
@@ -261,15 +261,16 @@ static void __init setup_xstate_comp(void)
 		return;
 	}
 
-	xstate_comp_offsets[2] = FXSAVE_SIZE + XSAVE_HDR_SIZE;
+	xstate_comp_offsets[FIRST_EXTENDED_XFEATURE] =
+		FXSAVE_SIZE + XSAVE_HDR_SIZE;
 
-	for (i = 2; i < xfeatures_nr; i++) {
+	for (i = FIRST_EXTENDED_XFEATURE; i < xfeatures_nr; i++) {
 		if (test_bit(i, (unsigned long *)&xfeatures_mask))
 			xstate_comp_sizes[i] = xstate_sizes[i];
 		else
 			xstate_comp_sizes[i] = 0;
 
-		if (i > 2)
+		if (i > FIRST_EXTENDED_XFEATURE)
 			xstate_comp_offsets[i] = xstate_comp_offsets[i-1]
 					+ xstate_comp_sizes[i-1];
 
@@ -325,7 +326,7 @@ static unsigned int __init calculate_xstate_size(void)
 	}
 
 	calculated_xstate_size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
-	for (i = 2; i < 64; i++) {
+	for (i = FIRST_EXTENDED_XFEATURE; i < 64; i++) {
 		if (test_bit(i, (unsigned long *)&xfeatures_mask)) {
 			cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
 			calculated_xstate_size += eax;

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [tip:x86/fpu] x86/fpu: Remove 'xfeature_nr'
  2015-09-02 23:31 ` [PATCH 08/15] x86, fpu: remove xfeature_nr Dave Hansen
@ 2015-09-14 12:22   ` tip-bot for Dave Hansen
  0 siblings, 0 replies; 35+ messages in thread
From: tip-bot for Dave Hansen @ 2015-09-14 12:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, bp, torvalds, luto, fenghua.yu, tglx, brgerst,
	peterz, dvlasenk, mingo, hpa, tim.c.chen, dave.hansen

Commit-ID:  ee9ae257eb17d3426ee9ab91449a3aa443298b36
Gitweb:     http://git.kernel.org/tip/ee9ae257eb17d3426ee9ab91449a3aa443298b36
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Wed, 2 Sep 2015 16:31:28 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 14 Sep 2015 12:21:59 +0200

x86/fpu: Remove 'xfeature_nr'

xfeature_nr ended up being initialized too late for me to
use it in the "xsave size sanity check" patch which is
later in the series.  I tried to move around its initialization
but realized that it was just as easy to get rid of it.

We only have 9 XFEATURES.  Instead of dynamically calculating
and storing the last feature, just use the compile-time max:
XFEATURES_NR_MAX.  Note that even with 'xfeatures_nr' we can
had "holes" in the xfeatures_mask that we had to deal with.

We also change a 'leaf' variable to be a plain 'i'.  Although
it is used to grab a cpuid leaf in this one loop, all of the
other loops just use an 'i' and I find it much more obvious
to keep the naming consistent across all the similar loops.

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/20150902233128.3F30DF5A@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/fpu/xstate.c | 24 ++++++++----------------
 1 file changed, 8 insertions(+), 16 deletions(-)

diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index c1a0bf4..61ec60b 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -35,9 +35,6 @@ static unsigned int xstate_offsets[XFEATURE_MAX] = { [ 0 ... XFEATURE_MAX - 1] =
 static unsigned int xstate_sizes[XFEATURE_MAX]   = { [ 0 ... XFEATURE_MAX - 1] = -1};
 static unsigned int xstate_comp_offsets[sizeof(xfeatures_mask)*8];
 
-/* The number of supported xfeatures in xfeatures_mask: */
-static unsigned int xfeatures_nr;
-
 /*
  * Clear all of the X86_FEATURE_* bits that are unavailable
  * when the CPU has no XSAVE support.
@@ -190,23 +187,18 @@ void fpu__init_cpu_xstate(void)
 /*
  * Record the offsets and sizes of various xstates contained
  * in the XSAVE state memory layout.
- *
- * ( Note that certain features might be non-present, for them
- *   we'll have 0 offset and 0 size. )
  */
 static void __init setup_xstate_features(void)
 {
-	u32 eax, ebx, ecx, edx, leaf;
-
-	xfeatures_nr = fls64(xfeatures_mask);
+	u32 eax, ebx, ecx, edx, i;
 
-	for (leaf = FIRST_EXTENDED_XFEATURE; leaf < xfeatures_nr; leaf++) {
-		cpuid_count(XSTATE_CPUID, leaf, &eax, &ebx, &ecx, &edx);
+	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
+		cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
 
-		xstate_offsets[leaf] = ebx;
-		xstate_sizes[leaf] = eax;
+		xstate_offsets[i] = ebx;
+		xstate_sizes[i] = eax;
 
-		printk(KERN_INFO "x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n", leaf, ebx, leaf, eax);
+		printk(KERN_INFO "x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n", i, ebx, i, eax);
 	}
 }
 
@@ -252,7 +244,7 @@ static void __init setup_xstate_comp(void)
 	xstate_comp_offsets[1] = offsetof(struct fxregs_state, xmm_space);
 
 	if (!cpu_has_xsaves) {
-		for (i = FIRST_EXTENDED_XFEATURE; i < xfeatures_nr; i++) {
+		for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
 			if (test_bit(i, (unsigned long *)&xfeatures_mask)) {
 				xstate_comp_offsets[i] = xstate_offsets[i];
 				xstate_comp_sizes[i] = xstate_sizes[i];
@@ -264,7 +256,7 @@ static void __init setup_xstate_comp(void)
 	xstate_comp_offsets[FIRST_EXTENDED_XFEATURE] =
 		FXSAVE_SIZE + XSAVE_HDR_SIZE;
 
-	for (i = FIRST_EXTENDED_XFEATURE; i < xfeatures_nr; i++) {
+	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
 		if (test_bit(i, (unsigned long *)&xfeatures_mask))
 			xstate_comp_sizes[i] = xstate_sizes[i];
 		else

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [tip:x86/fpu] x86/fpu: Add xfeature_enabled() helper instead of test_bit()
  2015-09-02 23:31 ` [PATCH 09/15] x86, fpu: add helper xfeature_enabled() instead of test_bit() Dave Hansen
@ 2015-09-14 12:22   ` tip-bot for Dave Hansen
  0 siblings, 0 replies; 35+ messages in thread
From: tip-bot for Dave Hansen @ 2015-09-14 12:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: bp, luto, mingo, brgerst, tglx, fenghua.yu, tim.c.chen, peterz,
	linux-kernel, dvlasenk, torvalds, hpa, dave.hansen

Commit-ID:  633d54c47a5bedfb42f10e6a63eeeebd35abdb4c
Gitweb:     http://git.kernel.org/tip/633d54c47a5bedfb42f10e6a63eeeebd35abdb4c
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Wed, 2 Sep 2015 16:31:29 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 14 Sep 2015 12:21:59 +0200

x86/fpu: Add xfeature_enabled() helper instead of test_bit()

We currently use test_bit() in a few places to see if an
xfeature is enabled.  It ends up being a bit ugly because
'xfeatures_mask' is a u64 and test_bit wants an 'unsigned long'
so it requires a cast.  The *_bit() functions are also
techincally atomic, which we have no need for here.

So, remove the test_bit()s and replace with the new
xfeature_enabled() helper.

This also provides a central place to add a comment about the
future need to support 'system xstates'.

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/20150902233129.B1534F86@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/fpu/xstate.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 61ec60b..ba6b6e0 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -226,6 +226,16 @@ static void __init print_xstate_features(void)
 }
 
 /*
+ * Note that in the future we will likely need a pair of
+ * functions here: one for user xstates and the other for
+ * system xstates.  For now, they are the same.
+ */
+static int xfeature_enabled(enum xfeature xfeature)
+{
+	return !!(xfeatures_mask & (1UL << xfeature));
+}
+
+/*
  * This function sets up offsets and sizes of all extended states in
  * xsave area. This supports both standard format and compacted format
  * of the xsave aread.
@@ -245,7 +255,7 @@ static void __init setup_xstate_comp(void)
 
 	if (!cpu_has_xsaves) {
 		for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
-			if (test_bit(i, (unsigned long *)&xfeatures_mask)) {
+			if (xfeature_enabled(i)) {
 				xstate_comp_offsets[i] = xstate_offsets[i];
 				xstate_comp_sizes[i] = xstate_sizes[i];
 			}
@@ -257,7 +267,7 @@ static void __init setup_xstate_comp(void)
 		FXSAVE_SIZE + XSAVE_HDR_SIZE;
 
 	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
-		if (test_bit(i, (unsigned long *)&xfeatures_mask))
+		if (xfeature_enabled(i))
 			xstate_comp_sizes[i] = xstate_sizes[i];
 		else
 			xstate_comp_sizes[i] = 0;
@@ -319,7 +329,7 @@ static unsigned int __init calculate_xstate_size(void)
 
 	calculated_xstate_size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
 	for (i = FIRST_EXTENDED_XFEATURE; i < 64; i++) {
-		if (test_bit(i, (unsigned long *)&xfeatures_mask)) {
+		if (xfeature_enabled(i)) {
 			cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
 			calculated_xstate_size += eax;
 		}

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [tip:x86/fpu] x86/fpu/mpx: Rework MPX 'xstate' types
  2015-09-02 23:31 ` [PATCH 10/15] x86, fpu: rework MPX 'xstate' types Dave Hansen
@ 2015-09-14 12:22   ` tip-bot for Dave Hansen
  0 siblings, 0 replies; 35+ messages in thread
From: tip-bot for Dave Hansen @ 2015-09-14 12:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: fenghua.yu, torvalds, linux-kernel, luto, peterz, mingo, tglx,
	dvlasenk, bp, hpa, dave.hansen, tim.c.chen, brgerst

Commit-ID:  1126cb4535c4ff172c37a412a6bd25d6b47a1901
Gitweb:     http://git.kernel.org/tip/1126cb4535c4ff172c37a412a6bd25d6b47a1901
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Wed, 2 Sep 2015 16:31:29 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 14 Sep 2015 12:22:00 +0200

x86/fpu/mpx: Rework MPX 'xstate' types

MPX includes two separate "extended state components".  There is
no real need to have an 'mpx_struct' because we never really
manage the states together.

We also separate out the actual data in 'mpx_bndcsr_state' from
the padding.  We will shortly be checking the state sizes
against our structures and need them to match.  For consistency,
we also ensure to prefix these types with 'mpx_'.

Lastly, we add some comments to mirror some of the descriptions
in the Intel documents (SDM) of the various state components.

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/20150902233129.384B73EB@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/fpu/types.h | 29 +++++++++++++++++++++++------
 arch/x86/include/asm/trace/mpx.h |  7 ++++---
 arch/x86/kernel/traps.c          |  2 +-
 arch/x86/mm/mpx.c                |  9 +++++----
 4 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h
index 9f57930..4d8c200 100644
--- a/arch/x86/include/asm/fpu/types.h
+++ b/arch/x86/include/asm/fpu/types.h
@@ -141,20 +141,37 @@ struct ymmh_struct {
 };
 
 /* Intel MPX support: */
-struct bndreg {
+
+struct mpx_bndreg {
 	u64				lower_bound;
 	u64				upper_bound;
 } __packed;
+/*
+ * State component 3 is used for the 4 128-bit bounds registers
+ */
+struct mpx_bndreg_state {
+	struct mpx_bndreg		bndreg[4];
+} __packed;
 
-struct bndcsr {
+/*
+ * State component 4 is used for the 64-bit user-mode MPX
+ * configuration register BNDCFGU and the 64-bit MPX status
+ * register BNDSTATUS.  We call the pair "BNDCSR".
+ */
+struct mpx_bndcsr {
 	u64				bndcfgu;
 	u64				bndstatus;
 } __packed;
 
-struct mpx_struct {
-	struct bndreg			bndreg[4];
-	struct bndcsr			bndcsr;
-};
+/*
+ * The BNDCSR state is padded out to be 64-bytes in size.
+ */
+struct mpx_bndcsr_state {
+	union {
+		struct mpx_bndcsr		bndcsr;
+		u8				pad_to_64_bytes[64];
+	};
+} __packed;
 
 struct xstate_header {
 	u64				xfeatures;
diff --git a/arch/x86/include/asm/trace/mpx.h b/arch/x86/include/asm/trace/mpx.h
index 173dd3b..0f492fc 100644
--- a/arch/x86/include/asm/trace/mpx.h
+++ b/arch/x86/include/asm/trace/mpx.h
@@ -11,7 +11,7 @@
 TRACE_EVENT(mpx_bounds_register_exception,
 
 	TP_PROTO(void *addr_referenced,
-		 const struct bndreg *bndreg),
+		 const struct mpx_bndreg *bndreg),
 	TP_ARGS(addr_referenced, bndreg),
 
 	TP_STRUCT__entry(
@@ -44,7 +44,7 @@ TRACE_EVENT(mpx_bounds_register_exception,
 
 TRACE_EVENT(bounds_exception_mpx,
 
-	TP_PROTO(const struct bndcsr *bndcsr),
+	TP_PROTO(const struct mpx_bndcsr *bndcsr),
 	TP_ARGS(bndcsr),
 
 	TP_STRUCT__entry(
@@ -116,7 +116,8 @@ TRACE_EVENT(mpx_new_bounds_table,
 /*
  * This gets used outside of MPX-specific code, so we need a stub.
  */
-static inline void trace_bounds_exception_mpx(const struct bndcsr *bndcsr)
+static inline
+void trace_bounds_exception_mpx(const struct mpx_bndcsr *bndcsr)
 {
 }
 
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 0cd2ac5..ade185a 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -361,7 +361,7 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
 
 dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
 {
-	const struct bndcsr *bndcsr;
+	const struct mpx_bndcsr *bndcsr;
 	siginfo_t *info;
 
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c
index f35fc9c..b0ae85f 100644
--- a/arch/x86/mm/mpx.c
+++ b/arch/x86/mm/mpx.c
@@ -237,7 +237,8 @@ bad_opcode:
  */
 siginfo_t *mpx_generate_siginfo(struct pt_regs *regs)
 {
-	const struct bndreg *bndregs, *bndreg;
+	const struct mpx_bndreg_state *bndregs;
+	const struct mpx_bndreg *bndreg;
 	siginfo_t *info = NULL;
 	struct insn insn;
 	uint8_t bndregno;
@@ -264,7 +265,7 @@ siginfo_t *mpx_generate_siginfo(struct pt_regs *regs)
 		goto err_out;
 	}
 	/* now go select the individual register in the set of 4 */
-	bndreg = &bndregs[bndregno];
+	bndreg = &bndregs->bndreg[bndregno];
 
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info) {
@@ -306,7 +307,7 @@ err_out:
 
 static __user void *mpx_get_bounds_dir(void)
 {
-	const struct bndcsr *bndcsr;
+	const struct mpx_bndcsr *bndcsr;
 
 	if (!cpu_feature_enabled(X86_FEATURE_MPX))
 		return MPX_INVALID_BOUNDS_DIR;
@@ -489,7 +490,7 @@ out_unmap:
 static int do_mpx_bt_fault(void)
 {
 	unsigned long bd_entry, bd_base;
-	const struct bndcsr *bndcsr;
+	const struct mpx_bndcsr *bndcsr;
 	struct mm_struct *mm = current->mm;
 
 	bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR);

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [tip:x86/fpu] x86/fpu: Rework YMM definition
  2015-09-02 23:31 ` [PATCH 11/15] x86, fpu: rework YMM definition Dave Hansen
@ 2015-09-14 12:23   ` tip-bot for Dave Hansen
  0 siblings, 0 replies; 35+ messages in thread
From: tip-bot for Dave Hansen @ 2015-09-14 12:23 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: luto, brgerst, hpa, dvlasenk, tim.c.chen, linux-kernel, peterz,
	mingo, fenghua.yu, bp, tglx, torvalds, dave.hansen

Commit-ID:  83aa3c45307228af4329cbb915a2f2142e5479ad
Gitweb:     http://git.kernel.org/tip/83aa3c45307228af4329cbb915a2f2142e5479ad
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Wed, 2 Sep 2015 16:31:29 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 14 Sep 2015 12:22:00 +0200

x86/fpu: Rework YMM definition

We are about to rework all of the "extended state" definitions.
This makes the 'ymm' naming consistent with the AVX-512 types
we will introduce later.

We also add a convenience type: "reg_128_bit" so that we do
not have to spell out our arithmetic.

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/20150902233129.B4EB045F@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/fpu/types.h | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h
index 4d8c200..eb0c9a2 100644
--- a/arch/x86/include/asm/fpu/types.h
+++ b/arch/x86/include/asm/fpu/types.h
@@ -128,17 +128,23 @@ enum xfeature {
 
 #define FIRST_EXTENDED_XFEATURE	XFEATURE_YMM
 
+struct reg_128_bit {
+	u8      regbytes[128/8];
+};
+
 /*
+ * State component 2:
+ *
  * There are 16x 256-bit AVX registers named YMM0-YMM15.
  * The low 128 bits are aliased to the 16 SSE registers (XMM0-XMM15)
- * and are stored in 'struct fxregs_state::xmm_space[]'.
+ * and are stored in 'struct fxregs_state::xmm_space[]' in the
+ * "legacy" area.
  *
- * The high 128 bits are stored here:
- *    16x 128 bits == 256 bytes.
+ * The high 128 bits are stored here.
  */
 struct ymmh_struct {
-	u8				ymmh_space[256];
-};
+	struct reg_128_bit              hi_ymm[16];
+} __packed;
 
 /* Intel MPX support: */
 

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [tip:x86/fpu] x86/fpu: Add C structures for AVX-512 state components
  2015-09-02 23:31 ` [PATCH 12/15] x86, fpu: add C structures for AVX-512 state components Dave Hansen
@ 2015-09-14 12:23   ` tip-bot for Dave Hansen
  0 siblings, 0 replies; 35+ messages in thread
From: tip-bot for Dave Hansen @ 2015-09-14 12:23 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, brgerst, dave.hansen, fenghua.yu, tglx, mingo,
	torvalds, peterz, bp, tim.c.chen, dvlasenk, hpa, luto

Commit-ID:  060dd0f712562925662c65b90d225d82304764f7
Gitweb:     http://git.kernel.org/tip/060dd0f712562925662c65b90d225d82304764f7
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Wed, 2 Sep 2015 16:31:29 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 14 Sep 2015 12:22:01 +0200

x86/fpu: Add C structures for AVX-512 state components

AVX-512 has 3 separate state components:

  1. opmask registers
  2. zmm upper half of registers 0-15
  3. new zmm registers (16-31)

This patch adds C structures for the three components along with
a few comments mostly lifted from the SDM to explain what they
do.  This will allow us to check our structures against what the
hardware tells us about the sizes of the components.

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/20150902233129.F2433B98@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/fpu/types.h | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h
index eb0c9a2..1c6f6ac 100644
--- a/arch/x86/include/asm/fpu/types.h
+++ b/arch/x86/include/asm/fpu/types.h
@@ -131,6 +131,12 @@ enum xfeature {
 struct reg_128_bit {
 	u8      regbytes[128/8];
 };
+struct reg_256_bit {
+	u8	regbytes[256/8];
+};
+struct reg_512_bit {
+	u8	regbytes[512/8];
+};
 
 /*
  * State component 2:
@@ -179,6 +185,33 @@ struct mpx_bndcsr_state {
 	};
 } __packed;
 
+/* AVX-512 Components: */
+
+/*
+ * State component 5 is used for the 8 64-bit opmask registers
+ * k0-k7 (opmask state).
+ */
+struct avx_512_opmask_state {
+	u64				opmask_reg[8];
+} __packed;
+
+/*
+ * State component 6 is used for the upper 256 bits of the
+ * registers ZMM0-ZMM15. These 16 256-bit values are denoted
+ * ZMM0_H-ZMM15_H (ZMM_Hi256 state).
+ */
+struct avx_512_zmm_uppers_state {
+	struct reg_256_bit		zmm_upper[16];
+} __packed;
+
+/*
+ * State component 7 is used for the 16 512-bit registers
+ * ZMM16-ZMM31 (Hi16_ZMM state).
+ */
+struct avx_512_hi16_state {
+	struct reg_512_bit		hi16_zmm[16];
+} __packed;
+
 struct xstate_header {
 	u64				xfeatures;
 	u64				xcomp_bv;

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [tip:x86/fpu] x86/fpu: Correct and check XSAVE xstate size calculations
  2015-09-02 23:31 ` [PATCH 13/15] x86, fpu: correct and check XSAVE xstate size calculations Dave Hansen
@ 2015-09-14 12:23   ` tip-bot for Dave Hansen
  0 siblings, 0 replies; 35+ messages in thread
From: tip-bot for Dave Hansen @ 2015-09-14 12:23 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: dvlasenk, brgerst, tglx, peterz, torvalds, linux-kernel, hpa,
	fenghua.yu, dave.hansen, mingo, tim.c.chen, bp, luto

Commit-ID:  65ac2e9baa7deebe3e9588769d44d85555e05619
Gitweb:     http://git.kernel.org/tip/65ac2e9baa7deebe3e9588769d44d85555e05619
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Wed, 2 Sep 2015 16:31:30 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 14 Sep 2015 12:22:01 +0200

x86/fpu: Correct and check XSAVE xstate size calculations

Note: our xsaves support is currently broken and disabled.  This
patch does not fix it, but it is an incremental improvement.

This might be useful to someone backporting the entire set of
XSAVES patches at some point, but it should not be backported
alone.

Ingo said he wanted something like this (bullets 2 and 3):

  http://lkml.kernel.org/r/20150808091508.GB32641@gmail.com

There are currently two xsave buffer formats: standard and
compacted.  The standard format is waht 'XSAVE' and 'XSAVEOPT'
produce while 'XSAVES' and 'XSAVEC' produce a compacted-formet
buffer.  (The kernel never uses XSAVEC)

But, the XSAVES buffer *ALSO* contains "system state components"
which are never saved by a plain XSAVE.  So, XSAVES has two
things that might make its buffer differently-sized from an
XSAVE-produced one.

The current code assumes that an XSAVES buffer's size is simply
the sum of the sizes of the (user) states which are supported.
This seems to work in most cases, but it is not consistent with
what the SDM says, and it breaks if we 'align' a component in
the buffer.  The calculation is also unnecessary work since the
CPU *tells* us the size of the buffer directly.

This patch just reads the size of the buffer right out of the
CPUID leaf instead of trying to derive it.

But, blindly trusting the CPU like this is dangerous.  We add
a verification pass in do_extra_xstate_size_checks() to ensure
that the size we calculate matches with what we see from the
hardware.  When it comes down to it, we trust but verify the
CPU.

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/20150902233130.234FE1EC@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/fpu/xstate.c | 184 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 174 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index ba6b6e0..4704955 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -312,27 +312,190 @@ static void __init setup_init_fpu_buf(void)
 	copy_xregs_to_kernel_booting(&init_fpstate.xsave);
 }
 
+static int xfeature_is_supervisor(int xfeature_nr)
+{
+	/*
+	 * We currently do not support supervisor states, but if
+	 * we did, we could find out like this.
+	 *
+	 * SDM says: If state component i is a user state component,
+	 * ECX[0] return 0; if state component i is a supervisor
+	 * state component, ECX[0] returns 1.
+	u32 eax, ebx, ecx, edx;
+	cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx;
+	return !!(ecx & 1);
+	*/
+	return 0;
+}
+/*
+static int xfeature_is_user(int xfeature_nr)
+{
+	return !xfeature_is_supervisor(xfeature_nr);
+}
+*/
+
+/*
+ * This check is important because it is easy to get XSTATE_*
+ * confused with XSTATE_BIT_*.
+ */
+#define CHECK_XFEATURE(nr) do {		\
+	WARN_ON(nr < FIRST_EXTENDED_XFEATURE);	\
+	WARN_ON(nr >= XFEATURE_MAX);	\
+} while (0)
+
+/*
+ * We could cache this like xstate_size[], but we only use
+ * it here, so it would be a waste of space.
+ */
+static int xfeature_is_aligned(int xfeature_nr)
+{
+	u32 eax, ebx, ecx, edx;
+
+	CHECK_XFEATURE(xfeature_nr);
+	cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx);
+	/*
+	 * The value returned by ECX[1] indicates the alignment
+	 * of state component i when the compacted format
+	 * of the extended region of an XSAVE area is used
+	 */
+	return !!(ecx & 2);
+}
+
+static int xfeature_uncompacted_offset(int xfeature_nr)
+{
+	u32 eax, ebx, ecx, edx;
+
+	CHECK_XFEATURE(xfeature_nr);
+	cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx);
+	return ebx;
+}
+
+static int xfeature_size(int xfeature_nr)
+{
+	u32 eax, ebx, ecx, edx;
+
+	CHECK_XFEATURE(xfeature_nr);
+	cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx);
+	return eax;
+}
+
+/*
+ * 'XSAVES' implies two different things:
+ * 1. saving of supervisor/system state
+ * 2. using the compacted format
+ *
+ * Use this function when dealing with the compacted format so
+ * that it is obvious which aspect of 'XSAVES' is being handled
+ * by the calling code.
+ */
+static int using_compacted_format(void)
+{
+	return cpu_has_xsaves;
+}
+
+static void __xstate_dump_leaves(void)
+{
+	int i;
+	u32 eax, ebx, ecx, edx;
+	static int should_dump = 1;
+
+	if (!should_dump)
+		return;
+	should_dump = 0;
+	/*
+	 * Dump out a few leaves past the ones that we support
+	 * just in case there are some goodies up there
+	 */
+	for (i = 0; i < XFEATURE_MAX + 10; i++) {
+		cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
+		pr_warn("CPUID[%02x, %02x]: eax=%08x ebx=%08x ecx=%08x edx=%08x\n",
+			XSTATE_CPUID, i, eax, ebx, ecx, edx);
+	}
+}
+
+#define XSTATE_WARN_ON(x) do {							\
+	if (WARN_ONCE(x, "XSAVE consistency problem, dumping leaves")) {	\
+		__xstate_dump_leaves();						\
+	}									\
+} while (0)
+
+/*
+ * This essentially double-checks what the cpu told us about
+ * how large the XSAVE buffer needs to be.  We are recalculating
+ * it to be safe.
+ */
+static void do_extra_xstate_size_checks(void)
+{
+	int paranoid_xstate_size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
+	int i;
+
+	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
+		if (!xfeature_enabled(i))
+			continue;
+		/*
+		 * Supervisor state components can be managed only by
+		 * XSAVES, which is compacted-format only.
+		 */
+		if (!using_compacted_format())
+			XSTATE_WARN_ON(xfeature_is_supervisor(i));
+
+		/* Align from the end of the previous feature */
+		if (xfeature_is_aligned(i))
+			paranoid_xstate_size = ALIGN(paranoid_xstate_size, 64);
+		/*
+		 * The offset of a given state in the non-compacted
+		 * format is given to us in a CPUID leaf.  We check
+		 * them for being ordered (increasing offsets) in
+		 * setup_xstate_features().
+		 */
+		if (!using_compacted_format())
+			paranoid_xstate_size = xfeature_uncompacted_offset(i);
+		/*
+		 * The compacted-format offset always depends on where
+		 * the previous state ended.
+		 */
+		paranoid_xstate_size += xfeature_size(i);
+	}
+	XSTATE_WARN_ON(paranoid_xstate_size != xstate_size);
+}
+
 /*
  * Calculate total size of enabled xstates in XCR0/xfeatures_mask.
+ *
+ * Note the SDM's wording here.  "sub-function 0" only enumerates
+ * the size of the *user* states.  If we use it to size a buffer
+ * that we use 'XSAVES' on, we could potentially overflow the
+ * buffer because 'XSAVES' saves system states too.
+ *
+ * Note that we do not currently set any bits on IA32_XSS so
+ * 'XCR0 | IA32_XSS == XCR0' for now.
  */
 static unsigned int __init calculate_xstate_size(void)
 {
 	unsigned int eax, ebx, ecx, edx;
 	unsigned int calculated_xstate_size;
-	int i;
 
 	if (!cpu_has_xsaves) {
+		/*
+		 * - CPUID function 0DH, sub-function 0:
+		 *    EBX enumerates the size (in bytes) required by
+		 *    the XSAVE instruction for an XSAVE area
+		 *    containing all the *user* state components
+		 *    corresponding to bits currently set in XCR0.
+		 */
 		cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);
 		calculated_xstate_size = ebx;
-		return calculated_xstate_size;
-	}
-
-	calculated_xstate_size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
-	for (i = FIRST_EXTENDED_XFEATURE; i < 64; i++) {
-		if (xfeature_enabled(i)) {
-			cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
-			calculated_xstate_size += eax;
-		}
+	} else {
+		/*
+		 * - CPUID function 0DH, sub-function 1:
+		 *    EBX enumerates the size (in bytes) required by
+		 *    the XSAVES instruction for an XSAVE area
+		 *    containing all the state components
+		 *    corresponding to bits currently set in
+		 *    XCR0 | IA32_XSS.
+		 */
+		cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx);
+		calculated_xstate_size = ebx;
 	}
 	return calculated_xstate_size;
 }
@@ -365,6 +528,7 @@ static int init_xstate_size(void)
 	 * make it known to the world that we need more space.
 	 */
 	xstate_size = possible_xstate_size;
+	do_extra_xstate_size_checks();
 	return 0;
 }
 

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [tip:x86/fpu] x86/fpu: Check to ensure increasing-offset xstate offsets
  2015-09-02 23:31 ` [PATCH 14/15] x86, fpu: check to ensure increasing-offset xstate offsets Dave Hansen
@ 2015-09-14 12:24   ` tip-bot for Dave Hansen
  0 siblings, 0 replies; 35+ messages in thread
From: tip-bot for Dave Hansen @ 2015-09-14 12:24 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: brgerst, dvlasenk, torvalds, peterz, mingo, tglx, luto,
	tim.c.chen, dave.hansen, fenghua.yu, bp, linux-kernel, hpa

Commit-ID:  e6e888f96b4a531886f3bf29ba9af0b6f1026365
Gitweb:     http://git.kernel.org/tip/e6e888f96b4a531886f3bf29ba9af0b6f1026365
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Wed, 2 Sep 2015 16:31:30 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 14 Sep 2015 12:22:02 +0200

x86/fpu: Check to ensure increasing-offset xstate offsets

The xstate CPUID leaves enumerate where each state component is
inside the XSAVE buffer, along with the size of the entire
buffer.  Our new XSAVE sanity-checking code extrapolates an
expected _total_ buffer size by looking at the last component
that it encounters.

That method requires that the highest-numbered component also
be the one with the highest offset.  This is a pretty safe
assumption, but let's add some code to ensure it stays true.

To make this check work correctly, we also need to ensure we
only consider the offsets from enabled features because the
offset register (ebx) will return 0 on unsupported features.

This also means that we will preserve the -1's that we
initialized xstate_offsets/sizes[] with.  That will help
find bugs.

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/20150902233130.0843AB15@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/fpu/xstate.c | 35 ++++++++++++++++++++++++-----------
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 4704955..a8297f2 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -185,18 +185,41 @@ void fpu__init_cpu_xstate(void)
 }
 
 /*
+ * Note that in the future we will likely need a pair of
+ * functions here: one for user xstates and the other for
+ * system xstates.  For now, they are the same.
+ */
+static int xfeature_enabled(enum xfeature xfeature)
+{
+	return !!(xfeatures_mask & (1UL << xfeature));
+}
+
+/*
  * Record the offsets and sizes of various xstates contained
  * in the XSAVE state memory layout.
  */
 static void __init setup_xstate_features(void)
 {
 	u32 eax, ebx, ecx, edx, i;
+	/* start at the beginnning of the "extended state" */
+	unsigned int last_good_offset = offsetof(struct xregs_state,
+						 extended_state_area);
 
 	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
-		cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
+		if (!xfeature_enabled(i))
+			continue;
 
+		cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
 		xstate_offsets[i] = ebx;
 		xstate_sizes[i] = eax;
+		/*
+		 * In our xstate size checks, we assume that the
+		 * highest-numbered xstate feature has the
+		 * highest offset in the buffer.  Ensure it does.
+		 */
+		WARN_ONCE(last_good_offset > xstate_offsets[i],
+			"x86/fpu: misordered xstate at %d\n", last_good_offset);
+		last_good_offset = xstate_offsets[i];
 
 		printk(KERN_INFO "x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n", i, ebx, i, eax);
 	}
@@ -226,16 +249,6 @@ static void __init print_xstate_features(void)
 }
 
 /*
- * Note that in the future we will likely need a pair of
- * functions here: one for user xstates and the other for
- * system xstates.  For now, they are the same.
- */
-static int xfeature_enabled(enum xfeature xfeature)
-{
-	return !!(xfeatures_mask & (1UL << xfeature));
-}
-
-/*
  * This function sets up offsets and sizes of all extended states in
  * xsave area. This supports both standard format and compacted format
  * of the xsave aread.

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [tip:x86/fpu] x86/fpu: Check CPU-provided sizes against struct declarations
  2015-09-02 23:31 ` [PATCH 15/15] x86, fpu: check CPU-provided sizes against struct declarations Dave Hansen
@ 2015-09-14 12:24   ` tip-bot for Dave Hansen
  0 siblings, 0 replies; 35+ messages in thread
From: tip-bot for Dave Hansen @ 2015-09-14 12:24 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, luto, torvalds, mingo, tim.c.chen, peterz,
	dave.hansen, hpa, bp, fenghua.yu, brgerst, dvlasenk, tglx

Commit-ID:  ef78f2a4bf84d8db9f36868decca2dc24e02a6af
Gitweb:     http://git.kernel.org/tip/ef78f2a4bf84d8db9f36868decca2dc24e02a6af
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Wed, 2 Sep 2015 16:31:31 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 14 Sep 2015 12:22:02 +0200

x86/fpu: Check CPU-provided sizes against struct declarations

We now have C structures defined for each of the XSAVE state
components that we support.  This patch adds checks during our
verification pass to ensure that the CPU-provided data
enumerated in CPUID leaves matches our C structures.

If not, we warn and dump all the XSAVE CPUID leaves.

Note: this *actually* found an inconsistency with the MPX
'bndcsr' state.  The hardware pads it out differently from
our C structures.  This patch caught it and warned.

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/20150902233131.A8DB36DA@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/fpu/xstate.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index a8297f2..6454f27 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -432,6 +432,49 @@ static void __xstate_dump_leaves(void)
 	}									\
 } while (0)
 
+#define XCHECK_SZ(sz, nr, nr_macro, __struct) do {			\
+	if ((nr == nr_macro) &&						\
+	    WARN_ONCE(sz != sizeof(__struct),				\
+		"%s: struct is %zu bytes, cpu state %d bytes\n",	\
+		__stringify(nr_macro), sizeof(__struct), sz)) {		\
+		__xstate_dump_leaves();					\
+	}								\
+} while (0)
+
+/*
+ * We have a C struct for each 'xstate'.  We need to ensure
+ * that our software representation matches what the CPU
+ * tells us about the state's size.
+ */
+static void check_xstate_against_struct(int nr)
+{
+	/*
+	 * Ask the CPU for the size of the state.
+	 */
+	int sz = xfeature_size(nr);
+	/*
+	 * Match each CPU state with the corresponding software
+	 * structure.
+	 */
+	XCHECK_SZ(sz, nr, XFEATURE_YMM,       struct ymmh_struct);
+	XCHECK_SZ(sz, nr, XFEATURE_BNDREGS,   struct mpx_bndreg_state);
+	XCHECK_SZ(sz, nr, XFEATURE_BNDCSR,    struct mpx_bndcsr_state);
+	XCHECK_SZ(sz, nr, XFEATURE_OPMASK,    struct avx_512_opmask_state);
+	XCHECK_SZ(sz, nr, XFEATURE_ZMM_Hi256, struct avx_512_zmm_uppers_state);
+	XCHECK_SZ(sz, nr, XFEATURE_Hi16_ZMM,  struct avx_512_hi16_state);
+
+	/*
+	 * Make *SURE* to add any feature numbers in below if
+	 * there are "holes" in the xsave state component
+	 * numbers.
+	 */
+	if ((nr < XFEATURE_YMM) ||
+	    (nr >= XFEATURE_MAX)) {
+		WARN_ONCE(1, "no structure for xstate: %d\n", nr);
+		XSTATE_WARN_ON(1);
+	}
+}
+
 /*
  * This essentially double-checks what the cpu told us about
  * how large the XSAVE buffer needs to be.  We are recalculating
@@ -445,6 +488,8 @@ static void do_extra_xstate_size_checks(void)
 	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
 		if (!xfeature_enabled(i))
 			continue;
+
+		check_xstate_against_struct(i);
 		/*
 		 * Supervisor state components can be managed only by
 		 * XSAVES, which is compacted-format only.

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [tip:x86/fpu] x86/fpu: Rename XSAVE macros
  2015-09-14 12:21   ` [tip:x86/fpu] x86/fpu: Rename XSAVE macros tip-bot for Dave Hansen
@ 2015-09-23 10:49     ` Borislav Petkov
  2015-09-24  7:24       ` [tip:x86/fpu] x86/fpu: Fixup uninitialized feature_name warning tip-bot for Borislav Petkov
  0 siblings, 1 reply; 35+ messages in thread
From: Borislav Petkov @ 2015-09-23 10:49 UTC (permalink / raw)
  To: Dave Hansen
  Cc: linux-tip-commits, torvalds, hpa, dave.hansen, linux-kernel,
	mingo, peterz, fenghua.yu, brgerst, dvlasenk, tglx, tim.c.chen,
	luto

On Mon, Sep 14, 2015 at 05:21:07AM -0700, tip-bot for Dave Hansen wrote:
> Commit-ID:  d91cab78133d33b1dfd3d3fa7167fcbf74fb5f99
> Gitweb:     http://git.kernel.org/tip/d91cab78133d33b1dfd3d3fa7167fcbf74fb5f99
> Author:     Dave Hansen <dave.hansen@linux.intel.com>
> AuthorDate: Wed, 2 Sep 2015 16:31:26 -0700
> Committer:  Ingo Molnar <mingo@kernel.org>
> CommitDate: Mon, 14 Sep 2015 12:21:46 +0200
> 
> x86/fpu: Rename XSAVE macros
> 
> There are two concepts that have some confusing naming:
>  1. Extended State Component numbers (currently called
>     XFEATURE_BIT_*)
>  2. Extended State Component masks (currently called XSTATE_*)
> 
> The numbers are (currently) from 0-9.  State component 3 is the
> bounds registers for MPX, for instance.
> 
> But when we want to enable "state component 3", we go set a bit
> in XCR0.  The bit we set is 1<<3.  We can check to see if a
> state component feature is enabled by looking at its bit.
> 
> The current 'xfeature_bit's are at best xfeature bit _numbers_.
> Calling them bits is at best inconsistent with ending the enum
> list with 'XFEATURES_NR_MAX'.
> 
> This patch renames the enum to be 'xfeature'.  These also
> happen to be what the Intel documentation calls a "state
> component".
> 
> We also want to differentiate these from the "XSTATE_*" macros.
> The "XSTATE_*" macros are a mask, and we rename them to match.
> 
> These macros are reasonably widely used so this patch is a
> wee bit big, but this really is just a rename.
> 
> The only non-mechanical part of this is the
> 
> 	s/XSTATE_EXTEND_MASK/XFEATURE_MASK_EXTEND/
> 
> We need a better name for it, but that's another patch.
> 
> 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/20150902233126.38653250@viggo.jf.intel.com
> [ Ported to v4.3-rc1. ]
> Signed-off-by: Ingo Molnar <mingo@kernel.org>
> ---

...

> @@ -558,7 +558,7 @@ static int __init twofish_init(void)
>  {
>  	const char *feature_name;
>  
> -	if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
> +	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
>  		pr_info("CPU feature '%s' is not supported.\n", feature_name);
>  		return -ENODEV;
>  	}

---
From: Borislav Petkov <bp@suse.de>
Date: Wed, 23 Sep 2015 12:44:59 +0200
Subject: [PATCH] x86/crypto: Fixup uninitialized feature_name warning

Hand in &feature_name to cpu_has_xfeatures() as it is supposed to. Fixes
an uninitialized warning.

Fixes: d91cab78133d ("x86/fpu: Rename XSAVE macros")
Signed-off-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/crypto/twofish_avx_glue.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/crypto/twofish_avx_glue.c b/arch/x86/crypto/twofish_avx_glue.c
index 6f3738ced95e..b7a3904b953c 100644
--- a/arch/x86/crypto/twofish_avx_glue.c
+++ b/arch/x86/crypto/twofish_avx_glue.c
@@ -558,7 +558,7 @@ static int __init twofish_init(void)
 {
 	const char *feature_name;
 
-	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, &feature_name)) {
 		pr_info("CPU feature '%s' is not supported.\n", feature_name);
 		return -ENODEV;
 	}
-- 
2.3.5

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [tip:x86/fpu] x86/fpu: Fixup uninitialized feature_name warning
  2015-09-23 10:49     ` Borislav Petkov
@ 2015-09-24  7:24       ` tip-bot for Borislav Petkov
  0 siblings, 0 replies; 35+ messages in thread
From: tip-bot for Borislav Petkov @ 2015-09-24  7:24 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, bp, torvalds, peterz, tglx, hpa, linux-kernel, dave.hansen

Commit-ID:  158ecc39185b885420e5136b803b29be2bbec7fb
Gitweb:     http://git.kernel.org/tip/158ecc39185b885420e5136b803b29be2bbec7fb
Author:     Borislav Petkov <bp@suse.de>
AuthorDate: Wed, 23 Sep 2015 12:49:01 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Thu, 24 Sep 2015 09:21:20 +0200

x86/fpu: Fixup uninitialized feature_name warning

Hand in &feature_name to cpu_has_xfeatures() as it is supposed
to. Fixes an uninitialized warning.

Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: brgerst@gmail.com
Cc: dvlasenk@redhat.com
Cc: fenghua.yu@intel.com
Cc: luto@amacapital.net
Cc: tim.c.chen@linux.intel.com
Fixes: d91cab78133d ("x86/fpu: Rename XSAVE macros")
Link: http://lkml.kernel.org/r/20150923104901.GA3538@pd.tnic
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/crypto/twofish_avx_glue.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/crypto/twofish_avx_glue.c b/arch/x86/crypto/twofish_avx_glue.c
index 6f3738c..b7a3904 100644
--- a/arch/x86/crypto/twofish_avx_glue.c
+++ b/arch/x86/crypto/twofish_avx_glue.c
@@ -558,7 +558,7 @@ static int __init twofish_init(void)
 {
 	const char *feature_name;
 
-	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, &feature_name)) {
 		pr_info("CPU feature '%s' is not supported.\n", feature_name);
 		return -ENODEV;
 	}

^ permalink raw reply related	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2015-09-24  7:25 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-02 23:31 [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Dave Hansen
2015-09-02 23:31 ` [PATCH 02/15] x86, fpu: move XSAVE-disabling code to a helper Dave Hansen
2015-09-14 12:19   ` [tip:x86/fpu] x86/fpu: Move " tip-bot for Dave Hansen
2015-09-02 23:31 ` [PATCH 01/15] x86, fpu: print xfeature buffer size in decimal Dave Hansen
2015-09-14 12:19   ` [tip:x86/fpu] x86/fpu: Print " tip-bot for Dave Hansen
2015-09-02 23:31 ` [PATCH 04/15] x86, fpu: kill LWP support Dave Hansen
2015-09-14 12:20   ` [tip:x86/fpu] x86/fpu: Remove partial LWP support definitions tip-bot for Dave Hansen
2015-09-02 23:31 ` [PATCH 03/15] x86, fpu: remove XSTATE_RESERVE Dave Hansen
2015-09-14 12:20   ` [tip:x86/fpu] x86/fpu: Remove XSTATE_RESERVE tip-bot for Dave Hansen
2015-09-02 23:31 ` [PATCH 05/15] x86, fpu: XSAVE macro renames Dave Hansen
2015-09-14 12:21   ` [tip:x86/fpu] x86/fpu: Rename XSAVE macros tip-bot for Dave Hansen
2015-09-23 10:49     ` Borislav Petkov
2015-09-24  7:24       ` [tip:x86/fpu] x86/fpu: Fixup uninitialized feature_name warning tip-bot for Borislav Petkov
2015-09-02 23:31 ` [PATCH 06/15] x86, fpu: rename XFEATURES_NR_MAX Dave Hansen
2015-09-14 12:21   ` [tip:x86/fpu] x86/fpu: Rename XFEATURES_NR_MAX tip-bot for Dave Hansen
2015-09-02 23:31 ` [PATCH 08/15] x86, fpu: remove xfeature_nr Dave Hansen
2015-09-14 12:22   ` [tip:x86/fpu] x86/fpu: Remove 'xfeature_nr' tip-bot for Dave Hansen
2015-09-02 23:31 ` [PATCH 07/15] x86, fpu: rework XSTATE_* macros to remove magic '2' Dave Hansen
2015-09-14 12:21   ` [tip:x86/fpu] x86/fpu: Rework " tip-bot for Dave Hansen
2015-09-02 23:31 ` [PATCH 10/15] x86, fpu: rework MPX 'xstate' types Dave Hansen
2015-09-14 12:22   ` [tip:x86/fpu] x86/fpu/mpx: Rework " tip-bot for Dave Hansen
2015-09-02 23:31 ` [PATCH 12/15] x86, fpu: add C structures for AVX-512 state components Dave Hansen
2015-09-14 12:23   ` [tip:x86/fpu] x86/fpu: Add " tip-bot for Dave Hansen
2015-09-02 23:31 ` [PATCH 09/15] x86, fpu: add helper xfeature_enabled() instead of test_bit() Dave Hansen
2015-09-14 12:22   ` [tip:x86/fpu] x86/fpu: Add xfeature_enabled() helper " tip-bot for Dave Hansen
2015-09-02 23:31 ` [PATCH 11/15] x86, fpu: rework YMM definition Dave Hansen
2015-09-14 12:23   ` [tip:x86/fpu] x86/fpu: Rework " tip-bot for Dave Hansen
2015-09-02 23:31 ` [PATCH 13/15] x86, fpu: correct and check XSAVE xstate size calculations Dave Hansen
2015-09-14 12:23   ` [tip:x86/fpu] x86/fpu: Correct " tip-bot for Dave Hansen
2015-09-02 23:31 ` [PATCH 14/15] x86, fpu: check to ensure increasing-offset xstate offsets Dave Hansen
2015-09-14 12:24   ` [tip:x86/fpu] x86/fpu: Check " tip-bot for Dave Hansen
2015-09-02 23:31 ` [PATCH 15/15] x86, fpu: check CPU-provided sizes against struct declarations Dave Hansen
2015-09-14 12:24   ` [tip:x86/fpu] x86/fpu: Check " tip-bot for Dave Hansen
2015-09-14 10:07 ` [PATCH 00/15] [v4] x86, fpu: XSAVE cleanups and sanity checks Ingo Molnar
  -- strict thread matches above, loose matches on Subject: below --
2015-08-31 22:20 [PATCH 00/15] [v3] " Dave Hansen
2015-08-31 22:20 ` [PATCH 14/15] x86, fpu: check to ensure increasing-offset xstate offsets Dave Hansen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.