lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 22 Jun 2021 15:25:06 -0700
From:   Dave Hansen <dave.hansen@...ux.intel.com>
To:     linux-mm@...ck.org
Cc:     linux-kernel@...r.kernel.org,
        Dave Hansen <dave.hansen@...ux.intel.com>, tglx@...utronix.de,
        mingo@...hat.com, bp@...en8.de, x86@...nel.org, luto@...nel.org
Subject: [RFC][PATCH 6/8] x86/fpu: update xstate size calculations for non-XSAVE-managed features


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

Now that PKRU will no longer be XSAVE-managed, it needs to be removed
from the XSAVE size calculations.  get_xsaves_size_no_independent()
currently masks independent supervisor features out of XSS, but PKRU
must be masked out of XCR0 instead.

Also, instead of recalculating XSS (and XCR0), just save and restore
them.  This will be more durable in case there are any future changes
to how they are calculated.  The way it is now, the values must be
recalculated exactly in two separate places.

The save/restore approach also makes the code more obvious.  For
instance, the old code does:

	/* Disable independent features. */
	wrmsrl(MSR_IA32_XSS, xfeatures_mask_supervisor());

but the new code does:

	/* Disable independent features. */
	wrmsrl(MSR_IA32_XSS, old_xss & ~xfeatures_mask_independent());

The second is much more obviously correct and the comment could
probably even be removed; it's basically self-documenting.

There is a minor, temporary hack in here.  PKRU is currently not in
xfeatures_mask_fpstate(), even though it is allocated in the fpstate.
To avoid size mismatch warnings, hack it into XCR0 for the size
calculation.

Signed-off-by: Dave Hansen <dave.hansen@...ux.intel.com>
Cc: Thomas Gleixner <tglx@...utronix.de>
Cc: Ingo Molnar <mingo@...hat.com>
Cc: Borislav Petkov <bp@...en8.de>
Cc: x86@...nel.org
Cc: Andy Lutomirski <luto@...nel.org>
---

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

diff -puN arch/x86/kernel/fpu/xstate.c~xsave-checks arch/x86/kernel/fpu/xstate.c
--- a/arch/x86/kernel/fpu/xstate.c~xsave-checks	2021-06-22 14:49:12.547051748 -0700
+++ b/arch/x86/kernel/fpu/xstate.c	2021-06-22 14:49:12.556051748 -0700
@@ -643,14 +643,26 @@ static unsigned int __init get_xsaves_si
  */
 static unsigned int __init get_xsaves_size_no_independent(void)
 {
-	u64 mask = xfeatures_mask_independent();
 	unsigned int size;
+	u64 xfeatures_in_xcr0;
+	u64 old_xss;
+	u64 old_xcr0;
 
-	if (!mask)
-		return get_xsaves_size();
+	/* Stash the old XSAVE control register values: */
+	rdmsrl(MSR_IA32_XSS, old_xss);
+	old_xcr0 = xgetbv(0);
 
 	/* Disable independent features. */
-	wrmsrl(MSR_IA32_XSS, xfeatures_mask_supervisor());
+	wrmsrl(MSR_IA32_XSS, old_xss & ~xfeatures_mask_independent());
+
+	/*
+	 * *Temporarily* (to be removed in a later patch), ennsure there
+	 * is still space for PKRU in the fpstate buffer even though it's
+	 * essentially unused.
+	 */
+	xfeatures_in_xcr0 = xfeatures_mask_fpstate() | XFEATURE_MASK_PKRU;
+	/* Disable user features which are not kept in the fpstate: */
+	xsetbv(XCR_XFEATURE_ENABLED_MASK, old_xcr0 & xfeatures_in_xcr0);
 
 	/*
 	 * Ask the hardware what size is required of the buffer.
@@ -658,8 +670,9 @@ static unsigned int __init get_xsaves_si
 	 */
 	size = get_xsaves_size();
 
-	/* Re-enable independent features so XSAVES will work on them again. */
-	wrmsrl(MSR_IA32_XSS, xfeatures_mask_supervisor() | mask);
+	/* Re-enable original features so XSAVES will work on them again. */
+	wrmsrl(MSR_IA32_XSS, old_xss);
+	xsetbv(XCR_XFEATURE_ENABLED_MASK, old_xcr0);
 
 	return size;
 }
_

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ