Module Name:    src
Committed By:   jdolecek
Date:           Sat Jun 23 10:30:22 UTC 2018

Modified Files:
        src/sys/arch/x86/x86: identcpu.c
        src/sys/arch/xen/x86: cpu.c

Log Message:
re-do the XEN XSAVE support, this time to leave all probe code in
cpu_probe_fpu(), and have XEN cpu_init() just act

the xen probe is now guarded by XEN_USE_XSAVE option and XSAVE
support is thus still disabled by default (same as before), so it
wouldn't interfere with maxv's eager fpu rototil, while still
allowing testing for others

PR kern/50332


To generate a diff of this commit:
cvs rdiff -u -r1.76 -r1.77 src/sys/arch/x86/x86/identcpu.c
cvs rdiff -u -r1.121 -r1.122 src/sys/arch/xen/x86/cpu.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x86/x86/identcpu.c
diff -u src/sys/arch/x86/x86/identcpu.c:1.76 src/sys/arch/x86/x86/identcpu.c:1.77
--- src/sys/arch/x86/x86/identcpu.c:1.76	Sat Jun 23 10:02:39 2018
+++ src/sys/arch/x86/x86/identcpu.c	Sat Jun 23 10:30:22 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: identcpu.c,v 1.76 2018/06/23 10:02:39 maxv Exp $	*/
+/*	$NetBSD: identcpu.c,v 1.77 2018/06/23 10:30:22 jdolecek Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.76 2018/06/23 10:02:39 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.77 2018/06/23 10:30:22 jdolecek Exp $");
 
 #include "opt_xen.h"
 
@@ -795,15 +795,23 @@ cpu_probe_fpu(struct cpu_info *ci)
 
 	x86_fpu_save = FPU_SAVE_FXSAVE;
 
-#ifdef XEN
-	/* We don't support XSAVE on Xen. */
-	return;
-#endif
-
 	/* See if xsave (for AVX) is supported */
 	if ((ci->ci_feat_val[1] & CPUID2_XSAVE) == 0)
 		return;
 
+#ifdef XEN
+	/*
+	 * Xen kernel can disable XSAVE via "no-xsave" option, in that case
+	 * XSAVE instructions like xrstor become privileged and trigger
+	 * supervisor trap. OSXSAVE flag seems to be reliably set according
+	 * to whether XSAVE is actually available.
+	 */
+#ifdef XEN_USE_XSAVE
+	if ((ci->ci_feat_val[1] & CPUID2_OSXSAVE) == 0)
+#endif
+		return;
+#endif
+
 	x86_fpu_save = FPU_SAVE_XSAVE;
 
 #if 0 /* XXX PR 52966 */

Index: src/sys/arch/xen/x86/cpu.c
diff -u src/sys/arch/xen/x86/cpu.c:1.121 src/sys/arch/xen/x86/cpu.c:1.122
--- src/sys/arch/xen/x86/cpu.c:1.121	Sat Jun 23 09:51:34 2018
+++ src/sys/arch/xen/x86/cpu.c	Sat Jun 23 10:30:22 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.c,v 1.121 2018/06/23 09:51:34 maxv Exp $	*/
+/*	$NetBSD: cpu.c,v 1.122 2018/06/23 10:30:22 jdolecek Exp $	*/
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.121 2018/06/23 09:51:34 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.122 2018/06/23 10:30:22 jdolecek Exp $");
 
 #include "opt_ddb.h"
 #include "opt_multiprocessor.h"
@@ -527,24 +527,52 @@ cpu_attach_common(device_t parent, devic
 void
 cpu_init(struct cpu_info *ci)
 {
+	uint32_t cr4 = 0;
 
 	/*
 	 * If we have FXSAVE/FXRESTOR, use them.
 	 */
 	if (cpu_feature[0] & CPUID_FXSR) {
-		lcr4(rcr4() | CR4_OSFXSR);
+		cr4 |= CR4_OSFXSR;
 
 		/*
 		 * If we have SSE/SSE2, enable XMM exceptions.
 		 */
 		if (cpu_feature[0] & (CPUID_SSE|CPUID_SSE2))
-			lcr4(rcr4() | CR4_OSXMMEXCPT);
+			cr4 |= CR4_OSXMMEXCPT;
+	}
+
+	/* If xsave is supported, enable it */
+	if (cpu_feature[1] & CPUID2_XSAVE && x86_fpu_save >= FPU_SAVE_XSAVE)
+		cr4 |= CR4_OSXSAVE;
+
+	if (cr4) {
+		cr4 |= rcr4();
+		lcr4(cr4);
 	}
 
 	if (x86_fpu_save >= FPU_SAVE_FXSAVE) {
 		fpuinit_mxcsr_mask();
 	}
 
+	/*
+	 * Changing CR4 register may change cpuid values. For example, setting
+	 * CR4_OSXSAVE sets CPUID2_OSXSAVE. The CPUID2_OSXSAVE is in
+	 * ci_feat_val[1], so update it.
+	 * XXX Other than ci_feat_val[1] might be changed.
+	 */
+	if (cpuid_level >= 1) {
+		u_int descs[4];
+
+		x86_cpuid(1, descs);
+		ci->ci_feat_val[1] = descs[2];
+	}
+
+	/* If xsave is enabled, enable all fpu features */
+	if (cr4 & CR4_OSXSAVE) {
+		wrxcr(0, x86_xsave_features & XCR0_FPU);
+	}
+
 	atomic_or_32(&ci->ci_flags, CPUF_RUNNING);
 }
 

Reply via email to