All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] x86/fpu/state: Fix XSAVES issues - Part 1
@ 2016-05-12 16:34 Yu-cheng Yu
  2016-05-12 16:34 ` [PATCH 1/4] x86/fpu/xstate: Define and use fpu_user_xstate_size Yu-cheng Yu
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Yu-cheng Yu @ 2016-05-12 16:34 UTC (permalink / raw)
  To: linux-kernel, x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar
  Cc: Dave Hansen, Andy Lutomirski, Sai Praneeth Prakhya,
	Ravi V. Shankar, Fenghua Yu, Yu-cheng Yu

This is Part 1 of previous 13 XSAVES patches. Break it down to
smaller series. There are no code changes; only minor fixes in
the titles.

Fenghua Yu (3):
  x86/fpu/xstate: Define and use fpu_user_xstate_size
  x86/fpu/xstate: Rename xstate_size to fpu_kernel_xstate_size to
    distinguish from fpu_user_xstate_size
  x86/fpu/xstate: Keep init_fpstate.xsave.header.xfeatures as zero for
    init optimization

Yu-cheng Yu (1):
  x86/fpu/xstate: Copy xstate registers directly to signal frame when
    compacted format is in use

 arch/x86/include/asm/fpu/xstate.h |  2 +-
 arch/x86/include/asm/processor.h  |  3 +-
 arch/x86/kernel/fpu/core.c        |  7 +--
 arch/x86/kernel/fpu/init.c        | 21 +++++----
 arch/x86/kernel/fpu/signal.c      | 32 ++++++++++----
 arch/x86/kernel/fpu/xstate.c      | 92 +++++++++++++++++++++++----------------
 6 files changed, 98 insertions(+), 59 deletions(-)

-- 
1.9.1

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

* [PATCH 1/4] x86/fpu/xstate: Define and use fpu_user_xstate_size
  2016-05-12 16:34 [PATCH 0/4] x86/fpu/state: Fix XSAVES issues - Part 1 Yu-cheng Yu
@ 2016-05-12 16:34 ` Yu-cheng Yu
  2016-05-12 16:34 ` [PATCH 2/4] x86/fpu/xstate: Rename xstate_size to fpu_kernel_xstate_size to distinguish from fpu_user_xstate_size Yu-cheng Yu
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Yu-cheng Yu @ 2016-05-12 16:34 UTC (permalink / raw)
  To: linux-kernel, x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar
  Cc: Dave Hansen, Andy Lutomirski, Sai Praneeth Prakhya,
	Ravi V. Shankar, Fenghua Yu, Yu-cheng Yu

From: Fenghua Yu <fenghua.yu@intel.com>

The kernel xstate area can be in standard or compacted format;
it is always in standard format for user mode. When XSAVES is
enabled, the kernel uses the compacted format and it is necessary
to use a separate fpu_user_xstate_size for signal/ptrace frames.

Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
[yu-cheng.yu@intel.com: rebase to current, rename to fpu_user_xstate_size]
Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
Reviewed-by: Dave Hansen <dave.hansen@intel.com>
---
 arch/x86/include/asm/fpu/xstate.h |  1 -
 arch/x86/include/asm/processor.h  |  1 +
 arch/x86/kernel/fpu/init.c        |  5 ++-
 arch/x86/kernel/fpu/signal.c      | 27 ++++++++++----
 arch/x86/kernel/fpu/xstate.c      | 76 ++++++++++++++++++++++++---------------
 5 files changed, 73 insertions(+), 37 deletions(-)

diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h
index 38951b0..16df2c4 100644
--- a/arch/x86/include/asm/fpu/xstate.h
+++ b/arch/x86/include/asm/fpu/xstate.h
@@ -39,7 +39,6 @@
 #define REX_PREFIX
 #endif
 
-extern unsigned int xstate_size;
 extern u64 xfeatures_mask;
 extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS];
 
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 9264476..8d5df3f 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -368,6 +368,7 @@ DECLARE_PER_CPU(struct irq_stack *, softirq_stack);
 #endif	/* X86_64 */
 
 extern unsigned int xstate_size;
+extern unsigned int fpu_user_xstate_size;
 
 struct perf_event;
 
diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c
index 54c86ff..824d422 100644
--- a/arch/x86/kernel/fpu/init.c
+++ b/arch/x86/kernel/fpu/init.c
@@ -195,7 +195,7 @@ static void __init fpu__init_task_struct_size(void)
 }
 
 /*
- * Set up the xstate_size based on the legacy FPU context size.
+ * Set up the user and kernel xstate_size based on the legacy FPU context size.
  *
  * We set this up first, and later it will be overwritten by
  * fpu__init_system_xstate() if the CPU knows about xstates.
@@ -226,6 +226,9 @@ static void __init fpu__init_system_xstate_size_legacy(void)
 		else
 			xstate_size = sizeof(struct fregs_state);
 	}
+
+	fpu_user_xstate_size = xstate_size;
+
 	/*
 	 * Quirk: we don't yet handle the XSAVES* instructions
 	 * correctly, as we don't correctly convert between
diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
index 31c6a60..23572a9 100644
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@ -31,7 +31,7 @@ static inline int check_for_xstate(struct fxregs_state __user *buf,
 	/* Check for the first magic field and other error scenarios. */
 	if (fx_sw->magic1 != FP_XSTATE_MAGIC1 ||
 	    fx_sw->xstate_size < min_xstate_size ||
-	    fx_sw->xstate_size > xstate_size ||
+	    fx_sw->xstate_size > fpu_user_xstate_size ||
 	    fx_sw->xstate_size > fx_sw->extended_size)
 		return -1;
 
@@ -88,7 +88,8 @@ static inline int save_xstate_epilog(void __user *buf, int ia32_frame)
 	if (!use_xsave())
 		return err;
 
-	err |= __put_user(FP_XSTATE_MAGIC2, (__u32 *)(buf + xstate_size));
+	err |= __put_user(FP_XSTATE_MAGIC2,
+			  (__u32 *)(buf + fpu_user_xstate_size));
 
 	/*
 	 * Read the xfeatures which we copied (directly from the cpu or
@@ -125,7 +126,7 @@ static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf)
 	else
 		err = copy_fregs_to_user((struct fregs_state __user *) buf);
 
-	if (unlikely(err) && __clear_user(buf, xstate_size))
+	if (unlikely(err) && __clear_user(buf, fpu_user_xstate_size))
 		err = -EFAULT;
 	return err;
 }
@@ -175,8 +176,19 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)
 		if (ia32_fxstate)
 			copy_fxregs_to_kernel(&tsk->thread.fpu);
 	} else {
+		/*
+		 * It is a *bug* if kernel uses compacted-format for xsave
+		 * area and we copy it out directly to a signal frame. It
+		 * should have been handled above by saving the registers
+		 * directly.
+		 */
+		if (boot_cpu_has(X86_FEATURE_XSAVES)) {
+			WARN_ONCE(1, "x86/fpu: saving compacted-format xsave area to a signal frame!\n");
+			return -1;
+		}
+
 		fpstate_sanitize_xstate(&tsk->thread.fpu);
-		if (__copy_to_user(buf_fx, xsave, xstate_size))
+		if (__copy_to_user(buf_fx, xsave, fpu_user_xstate_size))
 			return -1;
 	}
 
@@ -341,7 +353,8 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
 
 static inline int xstate_sigframe_size(void)
 {
-	return use_xsave() ? xstate_size + FP_XSTATE_MAGIC2_SIZE : xstate_size;
+	return use_xsave() ? fpu_user_xstate_size + FP_XSTATE_MAGIC2_SIZE :
+			fpu_user_xstate_size;
 }
 
 /*
@@ -385,12 +398,12 @@ fpu__alloc_mathframe(unsigned long sp, int ia32_frame,
  */
 void fpu__init_prepare_fx_sw_frame(void)
 {
-	int size = xstate_size + FP_XSTATE_MAGIC2_SIZE;
+	int size = fpu_user_xstate_size + FP_XSTATE_MAGIC2_SIZE;
 
 	fx_sw_reserved.magic1 = FP_XSTATE_MAGIC1;
 	fx_sw_reserved.extended_size = size;
 	fx_sw_reserved.xfeatures = xfeatures_mask;
-	fx_sw_reserved.xstate_size = xstate_size;
+	fx_sw_reserved.xstate_size = fpu_user_xstate_size;
 
 	if (config_enabled(CONFIG_IA32_EMULATION) ||
 	    config_enabled(CONFIG_X86_32)) {
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index b48ef35..dfac87d 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -44,6 +44,13 @@ static unsigned int xstate_sizes[XFEATURE_MAX]   = { [ 0 ... XFEATURE_MAX - 1] =
 static unsigned int xstate_comp_offsets[sizeof(xfeatures_mask)*8];
 
 /*
+ * The XSAVE area of kernel can be in standard or compacted format;
+ * it is always in standard format for user mode. This is the user
+ * mode standard format size used for signal and ptrace frames.
+ */
+unsigned int fpu_user_xstate_size;
+
+/*
  * Clear all of the X86_FEATURE_* bits that are unavailable
  * when the CPU has no XSAVE support.
  */
@@ -171,7 +178,7 @@ void fpstate_sanitize_xstate(struct fpu *fpu)
 	 */
 	while (xfeatures) {
 		if (xfeatures & 0x1) {
-			int offset = xstate_offsets[feature_bit];
+			int offset = xstate_comp_offsets[feature_bit];
 			int size = xstate_sizes[feature_bit];
 
 			memcpy((void *)fx + offset,
@@ -533,8 +540,9 @@ static void do_extra_xstate_size_checks(void)
 	XSTATE_WARN_ON(paranoid_xstate_size != xstate_size);
 }
 
+
 /*
- * Calculate total size of enabled xstates in XCR0/xfeatures_mask.
+ * Get 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
@@ -544,34 +552,33 @@ static void do_extra_xstate_size_checks(void)
  * 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)
+static unsigned int __init get_xsaves_size(void)
 {
 	unsigned int eax, ebx, ecx, edx;
-	unsigned int calculated_xstate_size;
+	/*
+	 * - 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);
+	return ebx;
+}
 
-	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;
-	} 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;
+static unsigned int __init get_xsave_size(void)
+{
+	unsigned int eax, ebx, ecx, edx;
+	/*
+	 * - 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);
+	return ebx;
 }
 
 /*
@@ -591,7 +598,15 @@ static bool is_supported_xstate_size(unsigned int test_xstate_size)
 static int init_xstate_size(void)
 {
 	/* Recompute the context size for enabled features: */
-	unsigned int possible_xstate_size = calculate_xstate_size();
+	unsigned int possible_xstate_size;
+	unsigned int xsave_size;
+
+	xsave_size = get_xsave_size();
+
+	if (cpu_has_xsaves)
+		possible_xstate_size = get_xsaves_size();
+	else
+		possible_xstate_size = xsave_size;
 
 	/* Ensure we have the space to store all enabled: */
 	if (!is_supported_xstate_size(possible_xstate_size))
@@ -603,6 +618,11 @@ static int init_xstate_size(void)
 	 */
 	xstate_size = possible_xstate_size;
 	do_extra_xstate_size_checks();
+
+	/*
+	 * User space is always in standard format.
+	 */
+	fpu_user_xstate_size = xsave_size;
 	return 0;
 }
 
-- 
1.9.1

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

* [PATCH 2/4] x86/fpu/xstate: Rename xstate_size to fpu_kernel_xstate_size to distinguish from fpu_user_xstate_size
  2016-05-12 16:34 [PATCH 0/4] x86/fpu/state: Fix XSAVES issues - Part 1 Yu-cheng Yu
  2016-05-12 16:34 ` [PATCH 1/4] x86/fpu/xstate: Define and use fpu_user_xstate_size Yu-cheng Yu
@ 2016-05-12 16:34 ` Yu-cheng Yu
  2016-05-12 16:34 ` [PATCH 3/4] x86/fpu/xstate: Keep init_fpstate.xsave.header.xfeatures as zero for init optimization Yu-cheng Yu
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Yu-cheng Yu @ 2016-05-12 16:34 UTC (permalink / raw)
  To: linux-kernel, x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar
  Cc: Dave Hansen, Andy Lutomirski, Sai Praneeth Prakhya,
	Ravi V. Shankar, Fenghua Yu, Yu-cheng Yu

From: Fenghua Yu <fenghua.yu@intel.com>

User space uses standard format xsave area. fpstate in signal frame
should have standard format size.

To explicitly distinguish between xstate size in kernel space and the
one in user space, we rename xstate_size to fpu_kernel_xstate_size.
This patch is not fixing a bug. It just makes kernel code more clear.

Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
[yu-cheng.yu@intel.com: rebase to current, rename to fpu_kernel_xstate_size]
Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
Reviewed-by: Dave Hansen <dave.hansen@intel.com>
---
 arch/x86/include/asm/processor.h |  2 +-
 arch/x86/kernel/fpu/core.c       |  7 ++++---
 arch/x86/kernel/fpu/init.c       | 20 +++++++++++---------
 arch/x86/kernel/fpu/signal.c     |  2 +-
 arch/x86/kernel/fpu/xstate.c     |  8 ++++----
 5 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 8d5df3f..5fd59c6 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -367,7 +367,7 @@ DECLARE_PER_CPU(struct irq_stack *, hardirq_stack);
 DECLARE_PER_CPU(struct irq_stack *, softirq_stack);
 #endif	/* X86_64 */
 
-extern unsigned int xstate_size;
+extern unsigned int fpu_kernel_xstate_size;
 extern unsigned int fpu_user_xstate_size;
 
 struct perf_event;
diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
index 8e37cc8..dfd29ac 100644
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -222,7 +222,7 @@ void fpstate_init(union fpregs_state *state)
 		return;
 	}
 
-	memset(state, 0, xstate_size);
+	memset(state, 0, fpu_kernel_xstate_size);
 
 	if (cpu_has_fxsr)
 		fpstate_init_fxstate(&state->fxsave);
@@ -247,7 +247,7 @@ int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu)
 	 * leak into the child task:
 	 */
 	if (use_eager_fpu())
-		memset(&dst_fpu->state.xsave, 0, xstate_size);
+		memset(&dst_fpu->state.xsave, 0, fpu_kernel_xstate_size);
 
 	/*
 	 * Save current FPU registers directly into the child
@@ -266,7 +266,8 @@ int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu)
 	 */
 	preempt_disable();
 	if (!copy_fpregs_to_fpstate(dst_fpu)) {
-		memcpy(&src_fpu->state, &dst_fpu->state, xstate_size);
+		memcpy(&src_fpu->state, &dst_fpu->state,
+		       fpu_kernel_xstate_size);
 
 		if (use_eager_fpu())
 			copy_kernel_to_fpregs(&src_fpu->state);
diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c
index 824d422..eccc36b 100644
--- a/arch/x86/kernel/fpu/init.c
+++ b/arch/x86/kernel/fpu/init.c
@@ -145,8 +145,8 @@ static void __init fpu__init_system_generic(void)
  * This is inherent to the XSAVE architecture which puts all state
  * components into a single, continuous memory block:
  */
-unsigned int xstate_size;
-EXPORT_SYMBOL_GPL(xstate_size);
+unsigned int fpu_kernel_xstate_size;
+EXPORT_SYMBOL_GPL(fpu_kernel_xstate_size);
 
 /* Get alignment of the TYPE. */
 #define TYPE_ALIGN(TYPE) offsetof(struct { char x; TYPE test; }, test)
@@ -178,7 +178,7 @@ static void __init fpu__init_task_struct_size(void)
 	 * Add back the dynamically-calculated register state
 	 * size.
 	 */
-	task_size += xstate_size;
+	task_size += fpu_kernel_xstate_size;
 
 	/*
 	 * We dynamically size 'struct fpu', so we require that
@@ -195,7 +195,7 @@ static void __init fpu__init_task_struct_size(void)
 }
 
 /*
- * Set up the user and kernel xstate_size based on the legacy FPU context size.
+ * Set up the user and kernel xstate sizes based on the legacy FPU context size.
  *
  * We set this up first, and later it will be overwritten by
  * fpu__init_system_xstate() if the CPU knows about xstates.
@@ -208,7 +208,7 @@ static void __init fpu__init_system_xstate_size_legacy(void)
 	on_boot_cpu = 0;
 
 	/*
-	 * Note that xstate_size might be overwriten later during
+	 * Note that xstate sizes might be overwritten later during
 	 * fpu__init_system_xstate().
 	 */
 
@@ -219,15 +219,17 @@ static void __init fpu__init_system_xstate_size_legacy(void)
 		 */
 		setup_clear_cpu_cap(X86_FEATURE_XSAVE);
 		setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
-		xstate_size = sizeof(struct swregs_state);
+		fpu_kernel_xstate_size = sizeof(struct swregs_state);
 	} else {
 		if (cpu_has_fxsr)
-			xstate_size = sizeof(struct fxregs_state);
+			fpu_kernel_xstate_size =
+				sizeof(struct fxregs_state);
 		else
-			xstate_size = sizeof(struct fregs_state);
+			fpu_kernel_xstate_size =
+				sizeof(struct fregs_state);
 	}
 
-	fpu_user_xstate_size = xstate_size;
+	fpu_user_xstate_size = fpu_kernel_xstate_size;
 
 	/*
 	 * Quirk: we don't yet handle the XSAVES* instructions
diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
index 23572a9..1454989 100644
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@ -262,7 +262,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
 	int ia32_fxstate = (buf != buf_fx);
 	struct task_struct *tsk = current;
 	struct fpu *fpu = &tsk->thread.fpu;
-	int state_size = xstate_size;
+	int state_size = fpu_kernel_xstate_size;
 	u64 xfeatures = 0;
 	int fx_only = 0;
 
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index dfac87d..875afe9 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -537,7 +537,7 @@ static void do_extra_xstate_size_checks(void)
 		 */
 		paranoid_xstate_size += xfeature_size(i);
 	}
-	XSTATE_WARN_ON(paranoid_xstate_size != xstate_size);
+	XSTATE_WARN_ON(paranoid_xstate_size != fpu_kernel_xstate_size);
 }
 
 
@@ -616,7 +616,7 @@ static int init_xstate_size(void)
 	 * 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;
+	fpu_kernel_xstate_size = possible_xstate_size;
 	do_extra_xstate_size_checks();
 
 	/*
@@ -679,14 +679,14 @@ void __init fpu__init_system_xstate(void)
 		return;
 	}
 
-	update_regset_xstate_info(xstate_size, xfeatures_mask);
+	update_regset_xstate_info(fpu_kernel_xstate_size, xfeatures_mask);
 	fpu__init_prepare_fx_sw_frame();
 	setup_init_fpu_buf();
 	setup_xstate_comp();
 
 	pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n",
 		xfeatures_mask,
-		xstate_size,
+		fpu_kernel_xstate_size,
 		cpu_has_xsaves ? "compacted" : "standard");
 }
 
-- 
1.9.1

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

* [PATCH 3/4] x86/fpu/xstate: Keep init_fpstate.xsave.header.xfeatures as zero for init optimization
  2016-05-12 16:34 [PATCH 0/4] x86/fpu/state: Fix XSAVES issues - Part 1 Yu-cheng Yu
  2016-05-12 16:34 ` [PATCH 1/4] x86/fpu/xstate: Define and use fpu_user_xstate_size Yu-cheng Yu
  2016-05-12 16:34 ` [PATCH 2/4] x86/fpu/xstate: Rename xstate_size to fpu_kernel_xstate_size to distinguish from fpu_user_xstate_size Yu-cheng Yu
@ 2016-05-12 16:34 ` Yu-cheng Yu
  2016-05-12 16:34 ` [PATCH 4/4] x86/fpu/xstate: Copy xstate registers directly to signal frame when compacted format is in use Yu-cheng Yu
  2016-05-20  7:12 ` [PATCH 0/4] x86/fpu/state: Fix XSAVES issues - Part 1 Ingo Molnar
  4 siblings, 0 replies; 10+ messages in thread
From: Yu-cheng Yu @ 2016-05-12 16:34 UTC (permalink / raw)
  To: linux-kernel, x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar
  Cc: Dave Hansen, Andy Lutomirski, Sai Praneeth Prakhya,
	Ravi V. Shankar, Fenghua Yu, Yu-cheng Yu

From: Fenghua Yu <fenghua.yu@intel.com>

Keep init_fpstate.xsave.header.xfeatures as zero for init optimization.
This is important for init optimization that is implemented in processor.
If a bit corresponding to an xstate in xstate_bv is 0, it means the
xstate is in init status and will not be read from memory to the processor
during XRSTOR/XRSTORS instruction. This largely impacts context switch
performance.

Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
Reviewed-by: Dave Hansen <dave.hansen@intel.com>
---
 arch/x86/kernel/fpu/xstate.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 875afe9..5239d4d 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -329,13 +329,11 @@ static void __init setup_init_fpu_buf(void)
 	setup_xstate_features();
 	print_xstate_features();
 
-	if (cpu_has_xsaves) {
+	if (cpu_has_xsaves)
 		init_fpstate.xsave.header.xcomp_bv = (u64)1 << 63 | xfeatures_mask;
-		init_fpstate.xsave.header.xfeatures = xfeatures_mask;
-	}
 
 	/*
-	 * Init all the features state with header_bv being 0x0
+	 * Init all the features state with header.xfeatures being 0x0
 	 */
 	copy_kernel_to_xregs_booting(&init_fpstate.xsave);
 
-- 
1.9.1

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

* [PATCH 4/4] x86/fpu/xstate: Copy xstate registers directly to signal frame when compacted format is in use
  2016-05-12 16:34 [PATCH 0/4] x86/fpu/state: Fix XSAVES issues - Part 1 Yu-cheng Yu
                   ` (2 preceding siblings ...)
  2016-05-12 16:34 ` [PATCH 3/4] x86/fpu/xstate: Keep init_fpstate.xsave.header.xfeatures as zero for init optimization Yu-cheng Yu
@ 2016-05-12 16:34 ` Yu-cheng Yu
  2016-05-20  7:12 ` [PATCH 0/4] x86/fpu/state: Fix XSAVES issues - Part 1 Ingo Molnar
  4 siblings, 0 replies; 10+ messages in thread
From: Yu-cheng Yu @ 2016-05-12 16:34 UTC (permalink / raw)
  To: linux-kernel, x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar
  Cc: Dave Hansen, Andy Lutomirski, Sai Praneeth Prakhya,
	Ravi V. Shankar, Fenghua Yu, Yu-cheng Yu

XSAVES is a kernel instruction and uses a compacted format. When working
with user space, the kernel should provide standard-format, non-supervisor
state data. We cannot do __copy_to_user() from a compacted-format kernel
xstate area to a signal frame.

Dave Hansen proposes this method to simplify copy xstate directly to user.
Based on an earlier patch from Fenghua Yu <fenghua.yu@intel.com>

Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
Reviewed-by: Dave Hansen <dave.hansen@intel.com>
---
 arch/x86/include/asm/fpu/xstate.h | 1 +
 arch/x86/kernel/fpu/signal.c      | 3 ++-
 arch/x86/kernel/fpu/xstate.c      | 2 +-
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h
index 16df2c4..d812cf3 100644
--- a/arch/x86/include/asm/fpu/xstate.h
+++ b/arch/x86/include/asm/fpu/xstate.h
@@ -47,5 +47,6 @@ 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);
+int using_compacted_format(void);
 
 #endif
diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
index 1454989..9ce2963 100644
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@ -8,6 +8,7 @@
 #include <asm/fpu/internal.h>
 #include <asm/fpu/signal.h>
 #include <asm/fpu/regset.h>
+#include <asm/fpu/xstate.h>
 
 #include <asm/sigframe.h>
 
@@ -168,7 +169,7 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)
 			sizeof(struct user_i387_ia32_struct), NULL,
 			(struct _fpstate_32 __user *) buf) ? -1 : 1;
 
-	if (fpregs_active()) {
+	if (fpregs_active() || using_compacted_format()) {
 		/* Save the live register state to the user directly. */
 		if (copy_fpregs_to_sigframe(buf_fx))
 			return -1;
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 5239d4d..e00ec6a 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -420,7 +420,7 @@ static int xfeature_size(int xfeature_nr)
  * that it is obvious which aspect of 'XSAVES' is being handled
  * by the calling code.
  */
-static int using_compacted_format(void)
+int using_compacted_format(void)
 {
 	return cpu_has_xsaves;
 }
-- 
1.9.1

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

* Re: [PATCH 0/4] x86/fpu/state: Fix XSAVES issues - Part 1
  2016-05-12 16:34 [PATCH 0/4] x86/fpu/state: Fix XSAVES issues - Part 1 Yu-cheng Yu
                   ` (3 preceding siblings ...)
  2016-05-12 16:34 ` [PATCH 4/4] x86/fpu/xstate: Copy xstate registers directly to signal frame when compacted format is in use Yu-cheng Yu
@ 2016-05-20  7:12 ` Ingo Molnar
  2016-05-20 15:41   ` Yu-cheng Yu
  2016-05-20 16:50   ` Yu-cheng Yu
  4 siblings, 2 replies; 10+ messages in thread
From: Ingo Molnar @ 2016-05-20  7:12 UTC (permalink / raw)
  To: Yu-cheng Yu
  Cc: linux-kernel, x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar,
	Dave Hansen, Andy Lutomirski, Sai Praneeth Prakhya,
	Ravi V. Shankar, Fenghua Yu


* Yu-cheng Yu <yu-cheng.yu@intel.com> wrote:

> This is Part 1 of previous 13 XSAVES patches. Break it down to
> smaller series. There are no code changes; only minor fixes in
> the titles.
> 
> Fenghua Yu (3):
>   x86/fpu/xstate: Define and use fpu_user_xstate_size
>   x86/fpu/xstate: Rename xstate_size to fpu_kernel_xstate_size to
>     distinguish from fpu_user_xstate_size
>   x86/fpu/xstate: Keep init_fpstate.xsave.header.xfeatures as zero for
>     init optimization
> 
> Yu-cheng Yu (1):
>   x86/fpu/xstate: Copy xstate registers directly to signal frame when
>     compacted format is in use
> 
>  arch/x86/include/asm/fpu/xstate.h |  2 +-
>  arch/x86/include/asm/processor.h  |  3 +-
>  arch/x86/kernel/fpu/core.c        |  7 +--
>  arch/x86/kernel/fpu/init.c        | 21 +++++----
>  arch/x86/kernel/fpu/signal.c      | 32 ++++++++++----
>  arch/x86/kernel/fpu/xstate.c      | 92 +++++++++++++++++++++++----------------
>  6 files changed, 98 insertions(+), 59 deletions(-)

Hm, the series does not apply cleanly:

 patching file arch/x86/include/asm/fpu/xstate.h
 patching file arch/x86/include/asm/processor.h
 patching file arch/x86/kernel/fpu/init.c
 patching file arch/x86/kernel/fpu/signal.c
 patching file arch/x86/kernel/fpu/xstate.c
 Hunk #4 FAILED at 552.
 1 out of 6 hunks FAILED -- rejects in file arch/x86/kernel/fpu/xstate.c

which suggests that this series isn't against a recent x86 tree, right?

Thanks,

	Ingo

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

* Re: [PATCH 0/4] x86/fpu/state: Fix XSAVES issues - Part 1
  2016-05-20  7:12 ` [PATCH 0/4] x86/fpu/state: Fix XSAVES issues - Part 1 Ingo Molnar
@ 2016-05-20 15:41   ` Yu-cheng Yu
  2016-05-20 17:41     ` Ingo Molnar
  2016-05-20 16:50   ` Yu-cheng Yu
  1 sibling, 1 reply; 10+ messages in thread
From: Yu-cheng Yu @ 2016-05-20 15:41 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar,
	Dave Hansen, Andy Lutomirski, Sai Praneeth Prakhya,
	Ravi V. Shankar, Fenghua Yu

On Fri, May 20, 2016 at 09:12:00AM +0200, Ingo Molnar wrote:
> Hm, the series does not apply cleanly:
> 
>  patching file arch/x86/include/asm/fpu/xstate.h
>  patching file arch/x86/include/asm/processor.h
>  patching file arch/x86/kernel/fpu/init.c
>  patching file arch/x86/kernel/fpu/signal.c
>  patching file arch/x86/kernel/fpu/xstate.c
>  Hunk #4 FAILED at 552.
>  1 out of 6 hunks FAILED -- rejects in file arch/x86/kernel/fpu/xstate.c
> 
> which suggests that this series isn't against a recent x86 tree, right?

That was based on the latest upstream kernel.  I also keep a version based
on tip/master.  Would it work?

Yu-cheng

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

* Re: [PATCH 0/4] x86/fpu/state: Fix XSAVES issues - Part 1
  2016-05-20  7:12 ` [PATCH 0/4] x86/fpu/state: Fix XSAVES issues - Part 1 Ingo Molnar
  2016-05-20 15:41   ` Yu-cheng Yu
@ 2016-05-20 16:50   ` Yu-cheng Yu
  1 sibling, 0 replies; 10+ messages in thread
From: Yu-cheng Yu @ 2016-05-20 16:50 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar,
	Dave Hansen, Andy Lutomirski, Sai Praneeth Prakhya,
	Ravi V. Shankar, Fenghua Yu

On Fri, May 20, 2016 at 09:12:00AM +0200, Ingo Molnar wrote:
>  patching file arch/x86/include/asm/fpu/xstate.h
>  patching file arch/x86/include/asm/processor.h
>  patching file arch/x86/kernel/fpu/init.c
>  patching file arch/x86/kernel/fpu/signal.c
>  patching file arch/x86/kernel/fpu/xstate.c
>  Hunk #4 FAILED at 552.
>  1 out of 6 hunks FAILED -- rejects in file arch/x86/kernel/fpu/xstate.c
> 
> which suggests that this series isn't against a recent x86 tree, right?

There are differences in tip/master and tip/x86/core.  The main thing is
using boot_cpu_has(X86_FEATURE_XSAVES) or cpu_has_xsaves.  My understanding
is boot_cpu_has() is where we are going and basing on tip/master is easier for
merging?

Thanks,
Yu-cheng
 

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

* Re: [PATCH 0/4] x86/fpu/state: Fix XSAVES issues - Part 1
  2016-05-20 15:41   ` Yu-cheng Yu
@ 2016-05-20 17:41     ` Ingo Molnar
  0 siblings, 0 replies; 10+ messages in thread
From: Ingo Molnar @ 2016-05-20 17:41 UTC (permalink / raw)
  To: Yu-cheng Yu
  Cc: linux-kernel, x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar,
	Dave Hansen, Andy Lutomirski, Sai Praneeth Prakhya,
	Ravi V. Shankar, Fenghua Yu


* Yu-cheng Yu <yu-cheng.yu@intel.com> wrote:

> On Fri, May 20, 2016 at 09:12:00AM +0200, Ingo Molnar wrote:
> > Hm, the series does not apply cleanly:
> > 
> >  patching file arch/x86/include/asm/fpu/xstate.h
> >  patching file arch/x86/include/asm/processor.h
> >  patching file arch/x86/kernel/fpu/init.c
> >  patching file arch/x86/kernel/fpu/signal.c
> >  patching file arch/x86/kernel/fpu/xstate.c
> >  Hunk #4 FAILED at 552.
> >  1 out of 6 hunks FAILED -- rejects in file arch/x86/kernel/fpu/xstate.c
> > 
> > which suggests that this series isn't against a recent x86 tree, right?
> 
> That was based on the latest upstream kernel.  I also keep a version based
> on tip/master.  Would it work?

Yes, tip/master would be fine, or upstream bc231d9ede99 that has the x86 tree 
already merged.

Thanks,

	Ingo.

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

* [PATCH 0/4] x86/fpu/state: Fix XSAVES issues - Part 1
@ 2016-05-20 17:47 Yu-cheng Yu
  0 siblings, 0 replies; 10+ messages in thread
From: Yu-cheng Yu @ 2016-05-20 17:47 UTC (permalink / raw)
  To: linux-kernel, x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar
  Cc: Dave Hansen, Andy Lutomirski, Sai Praneeth Prakhya,
	Ravi V. Shankar, Fenghua Yu, Yu-cheng Yu

** Based on tip/master **

This is Part 1 of previous 13 XSAVES patches. Break it down to
smaller series. There are no code changes; only minor fixes in
the titles.

Fenghua Yu (3):
  x86/fpu/xstate: Define and use fpu_user_xstate_size
  x86/fpu/xstate: Rename xstate_size to fpu_kernel_xstate_size to
    distinguish from fpu_user_xstate_size
  x86/fpu/xstate: Keep init_fpstate.xsave.header.xfeatures as zero for
    init optimization

Yu-cheng Yu (1):
  x86/fpu/xstate: Copy xstate registers directly to signal frame when
    compacted format is in use

 arch/x86/include/asm/fpu/xstate.h |  2 +-
 arch/x86/include/asm/processor.h  |  3 +-
 arch/x86/kernel/fpu/core.c        |  7 +--
 arch/x86/kernel/fpu/init.c        | 21 +++++----
 arch/x86/kernel/fpu/signal.c      | 32 ++++++++++----
 arch/x86/kernel/fpu/xstate.c      | 92 +++++++++++++++++++++++----------------
 6 files changed, 98 insertions(+), 59 deletions(-)

-- 
1.9.1

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

end of thread, other threads:[~2016-05-20 17:52 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-12 16:34 [PATCH 0/4] x86/fpu/state: Fix XSAVES issues - Part 1 Yu-cheng Yu
2016-05-12 16:34 ` [PATCH 1/4] x86/fpu/xstate: Define and use fpu_user_xstate_size Yu-cheng Yu
2016-05-12 16:34 ` [PATCH 2/4] x86/fpu/xstate: Rename xstate_size to fpu_kernel_xstate_size to distinguish from fpu_user_xstate_size Yu-cheng Yu
2016-05-12 16:34 ` [PATCH 3/4] x86/fpu/xstate: Keep init_fpstate.xsave.header.xfeatures as zero for init optimization Yu-cheng Yu
2016-05-12 16:34 ` [PATCH 4/4] x86/fpu/xstate: Copy xstate registers directly to signal frame when compacted format is in use Yu-cheng Yu
2016-05-20  7:12 ` [PATCH 0/4] x86/fpu/state: Fix XSAVES issues - Part 1 Ingo Molnar
2016-05-20 15:41   ` Yu-cheng Yu
2016-05-20 17:41     ` Ingo Molnar
2016-05-20 16:50   ` Yu-cheng Yu
2016-05-20 17:47 Yu-cheng Yu

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.