diff mbox series

[RFC,3/8] x86/fpu: separate the setup of xfeatures not in fpstate

Message ID 20210622222500.2A850129@viggo.jf.intel.com (mailing list archive)
State New
Headers show
Series x86/pkeys: remove PKRU from kernel XSAVE buffer | expand

Commit Message

Dave Hansen June 22, 2021, 10:25 p.m. UTC
From: Dave Hansen <dave.hansen@linux.intel.com>

The goal of this series is to create a new class of xfeature: one which
is enabled in XCR0 so that XSAVE/XRSTOR continue to work on it, but
where the kernel does not use XSAVE*/XRSTOR* to manage the state or to
maintain it in the thread FPU buffer (fpstate).

Create a new helper in the XSAVE setup code: xstate_fpstate_enabled().
This helper returns whether or not an xfeature is being maintained
inside of the thread's fpstate.

For now, make xstate_fpstate_enabled() function identically to
xfeature_enabled().  This ensures that this series is bisectable
between this point and where PKRU is actually removed from
xfeature_fpstate_enabled().

This series originally introduced xfeatures_mask_fpstate() to mean:
"the set of features found in the kernel fpstate and managed by
XSAVE".  However, upstream ripped me off and made an identically-
named function which refers to the features managed by XSAVE,
which *excludes* PKRU at this juncture.

That means that xfeature_fpstate_enabled() and
xfeatures_mask_fpstate() will diverge until the end of the series.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: x86@kernel.org
Cc: Andy Lutomirski <luto@kernel.org>
---

 b/arch/x86/kernel/fpu/xstate.c |   40 ++++++++++++++++++++++++++++++----------
 1 file changed, 30 insertions(+), 10 deletions(-)
diff mbox series

Patch

diff -puN arch/x86/kernel/fpu/xstate.c~xfeature-setup-fpstate arch/x86/kernel/fpu/xstate.c
--- a/arch/x86/kernel/fpu/xstate.c~xfeature-setup-fpstate	2021-06-22 14:49:08.956051757 -0700
+++ b/arch/x86/kernel/fpu/xstate.c	2021-06-22 14:49:08.965051757 -0700
@@ -156,16 +156,32 @@  void fpu__init_cpu_xstate(void)
 	}
 }
 
+/* Can the XSAVE architecture be used to manage this feature? */
 static bool xfeature_enabled(enum xfeature xfeature)
 {
 	return xfeatures_mask_all & BIT_ULL(xfeature);
 }
 
 /*
+ * Is space for the feature present in the task->thread.fpu
+ * fpstate buffer and is the using XSAVE to context-switch it?
+ */
+static bool xfeature_fpstate_enabled(enum xfeature xfeature)
+{
+	// For bisectability, mirror xfeature_enabled() for now.
+	//return xfeatures_mask_fpstate() & BIT_ULL(xfeature);
+	return xfeature_enabled(xfeature);
+}
+
+/*
  * Record the offsets and sizes of various xstates contained
- * in the XSAVE state memory layout.
+ * in the non-compacted XSAVE state memory layout.
+ *
+ * These are always used in the XSAVE ABIs and are used for
+ * the kernel xstate buffer in cases where XSAVES (and thus
+ * the compacted format) is not supported.
  */
-static void __init setup_xstate_features(void)
+static void __init setup_xfeature_offsets(void)
 {
 	u32 eax, ebx, ecx, edx, i;
 	/* start at the beginning of the "extended state" */
@@ -185,6 +201,10 @@  static void __init setup_xstate_features
 						       xmm_space);
 
 	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
+		/*
+		 * Set up any features enabled that are in the kernel
+		 * xstate buffer *or* the user XSAVE ABIs.
+		 */
 		if (!xfeature_enabled(i))
 			continue;
 
@@ -257,7 +277,7 @@  static int xfeature_is_aligned(int xfeat
 
 	CHECK_XFEATURE(xfeature_nr);
 
-	if (!xfeature_enabled(xfeature_nr)) {
+	if (!xfeature_fpstate_enabled(xfeature_nr)) {
 		WARN_ONCE(1, "Checking alignment of disabled xfeature %d\n",
 			  xfeature_nr);
 		return 0;
@@ -293,7 +313,7 @@  static void __init setup_xstate_comp_off
 
 	if (!boot_cpu_has(X86_FEATURE_XSAVES)) {
 		for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
-			if (xfeature_enabled(i))
+			if (xfeature_fpstate_enabled(i))
 				xstate_comp_offsets[i] = xstate_offsets[i];
 		}
 		return;
@@ -302,7 +322,7 @@  static void __init setup_xstate_comp_off
 	next_offset = FXSAVE_SIZE + XSAVE_HDR_SIZE;
 
 	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
-		if (!xfeature_enabled(i))
+		if (!xfeature_fpstate_enabled(i))
 			continue;
 
 		if (xfeature_is_aligned(i))
@@ -329,7 +349,7 @@  static void __init setup_supervisor_only
 	next_offset = FXSAVE_SIZE + XSAVE_HDR_SIZE;
 
 	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
-		if (!xfeature_enabled(i) || !xfeature_is_supervisor(i))
+		if (!xfeature_fpstate_enabled(i) || !xfeature_is_supervisor(i))
 			continue;
 
 		if (xfeature_is_aligned(i))
@@ -348,7 +368,7 @@  static void __init print_xstate_offset_s
 	int i;
 
 	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
-		if (!xfeature_enabled(i))
+		if (!xfeature_fpstate_enabled(i))
 			continue;
 		pr_info("x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n",
 			 i, xstate_comp_offsets[i], i, xstate_sizes[i]);
@@ -391,7 +411,7 @@  static void __init setup_init_fpu_buf(vo
 	if (!boot_cpu_has(X86_FEATURE_XSAVE))
 		return;
 
-	setup_xstate_features();
+	setup_xfeature_offsets();
 	print_xstate_features();
 
 	if (boot_cpu_has(X86_FEATURE_XSAVES))
@@ -562,7 +582,7 @@  static void do_extra_xstate_size_checks(
 	int i;
 
 	for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
-		if (!xfeature_enabled(i))
+		if (!xfeature_fpstate_enabled(i))
 			continue;
 
 		check_xstate_against_struct(i);
@@ -849,7 +869,7 @@  void fpu__resume_cpu(void)
  */
 static void *__raw_xsave_addr(struct xregs_state *xsave, int xfeature_nr)
 {
-	if (!xfeature_enabled(xfeature_nr)) {
+	if (!xfeature_fpstate_enabled(xfeature_nr)) {
 		WARN_ON_FPU(1);
 		return NULL;
 	}