Thread (41 messages) 41 messages, 5 authors, 2019-04-25

Re: [RFC PATCH v6 04/26] x86/fpu/xstate: Introduce XSAVES system states

From: Yu-cheng Yu <hidden>
Date: 2018-12-04 17:13:45
Also in: linux-arch, linux-doc, linux-mm, lkml

On Tue, 2018-12-04 at 17:01 +0100, Borislav Petkov wrote:
On Mon, Nov 19, 2018 at 01:47:47PM -0800, Yu-cheng Yu wrote:
quoted
Control-flow Enforcement (CET) MSR contents are XSAVES system states.
To support CET, introduce XSAVES system states first.

Signed-off-by: Yu-cheng Yu <redacted>
---
 arch/x86/include/asm/fpu/internal.h |  3 +-
 arch/x86/include/asm/fpu/xstate.h   |  4 +-
 arch/x86/kernel/fpu/core.c          |  6 +-
 arch/x86/kernel/fpu/init.c          | 10 ---
 arch/x86/kernel/fpu/xstate.c        | 94 +++++++++++++++++++----------
 5 files changed, 69 insertions(+), 48 deletions(-)
...
quoted
@@ -704,6 +710,7 @@ static int init_xstate_size(void)
  */
 static void fpu__init_disable_system_xstate(void)
 {
+	xfeatures_mask_all = 0;
 	xfeatures_mask_user = 0;
 	cr4_clear_bits(X86_CR4_OSXSAVE);
 	fpu__xstate_clear_all_cpu_caps();
@@ -717,6 +724,8 @@ void __init fpu__init_system_xstate(void)
 {
 	unsigned int eax, ebx, ecx, edx;
 	static int on_boot_cpu __initdata = 1;
+	u64 cpu_system_xfeatures_mask;
+	u64 cpu_user_xfeatures_mask;
So what I had in mind is to not have those local vars but use
xfeatures_mask_user and xfeatures_mask_system here directly...
Ok, I will re-write it.

...
quoted
 
@@ -739,10 +748,23 @@ void __init fpu__init_system_xstate(void)
 		return;
 	}
 
+	/*
+	 * Find user states supported by the processor.
+	 * Only these bits can be set in XCR0.
+	 */
 	cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);
-	xfeatures_mask_user = eax + ((u64)edx << 32);
+	cpu_user_xfeatures_mask = eax + ((u64)edx << 32);
 
-	if ((xfeatures_mask_user & XFEATURE_MASK_FPSSE) !=
XFEATURE_MASK_FPSSE) {
+	/*
+	 * Find system states supported by the processor.
+	 * Only these bits can be set in IA32_XSS MSR.
+	 */
+	cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx);
+	cpu_system_xfeatures_mask = ecx + ((u64)edx << 32);
+
+	xfeatures_mask_all = cpu_user_xfeatures_mask |
cpu_system_xfeatures_mask;
... and not introduce xfeatures_mask_all at all but everywhere you need
all features, to do:

	(xfeatures_mask_user | xfeatures_mask_system)

and work with that.
Then we will do this very often.  Why don't we create all three in the
beginning: xfeatures_mask_all, xfeatures_mask_user, and xfeatures_mask_system?
...
quoted
@@ -1178,7 +1208,7 @@ int copy_kernel_to_xstate(struct xregs_state *xsave,
const void *kbuf)
 	 * The state that came in from userspace was user-state only.
 	 * Mask all the user states out of 'xfeatures':
 	 */
-	xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR;
+	xsave->header.xfeatures &= (xfeatures_mask_all &
~xfeatures_mask_user);
... and this would be

	xsave->header.xfeatures &= xfeatures_mask_system;
Yes.
quoted
 
 	/*
 	 * Add back in the features that came in from userspace:
@@ -1234,7 +1264,7 @@ int copy_user_to_xstate(struct xregs_state *xsave,
const void __user *ubuf)
 	 * The state that came in from userspace was user-state only.
 	 * Mask all the user states out of 'xfeatures':
 	 */
-	xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR;
+	xsave->header.xfeatures &= (xfeatures_mask_all &
~xfeatures_mask_user);
Ditto here.

This way you have *two* mask variables and code queries them only.

Hmmm?

Or am I missing something?
We actually have three.

Yu-cheng
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help