Module Name:    src
Committed By:   martin
Date:           Sat Jul 20 14:20:57 UTC 2024

Modified Files:
        src/sys/arch/x86/include [netbsd-9]: specialreg.h
        src/sys/arch/x86/x86 [netbsd-9]: identcpu.c

Log Message:
Pull up following revision(s) (requested by andvar in ticket #1855):

        sys/arch/x86/x86/identcpu.c: revision 1.129
        sys/arch/x86/include/specialreg.h: revision 1.212
        sys/arch/x86/x86/identcpu.c: revision 1.130

Disable the VIA Alternate Instructions according the VIA documentation:
* C7 and above do not support ALTINST, do not check or attempt to disable them.
* For VIA C3 Nehemiah check extended feature flags for support and status,
  do no attempt to disable when AIS is not supported or enabled.
* For pre-Nehemiah models explicitly disable, if they are in the range
  of documented models, flags aren't present to check the status on
  these models.

Note: for pre-Nehemiah may be other functional side effects depdending
on the version and stepping.

Explicit disabling of ALTINST was introduced with rev. 1.84 following
the discovery of some VIA CPUs having these instructions enabled by default
leading to the potential backdoor (aka rosenbrindge).

Unfortunately, implementation used a wrong check (ACE supported flag),
which can be true for the later models, still supporting padlock features.

Setting ALTINST bit on those may have unexpected side effects like VIA C7 CPUID
instruction for temperature sensor not reporting correct value or
`cpuctl identify' not reporting certain CPU features. Similar side effects
can be observed even for Nehemiah models not supporting AIS instructions. This
change should limit possibility of such issues to only the pre-Nehemiah models,
not covered at all in the previous implementation.

Feature Control Register (FCR) macros were unified under one group and
consistent naming while implementing the change. Few comments updated as well.
patch reviewed by Riastradh@ (thank you)

PR kern/58370

Move determination of the largest VIA CPU extended function value
to the intended place where the checks are performed.
Currently the value can be overridden while checking for the padlock features,
and failing the check for max function value as a result.


To generate a diff of this commit:
cvs rdiff -u -r1.150.2.15 -r1.150.2.16 src/sys/arch/x86/include/specialreg.h
cvs rdiff -u -r1.93.2.5 -r1.93.2.6 src/sys/arch/x86/x86/identcpu.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/include/specialreg.h
diff -u src/sys/arch/x86/include/specialreg.h:1.150.2.15 src/sys/arch/x86/include/specialreg.h:1.150.2.16
--- src/sys/arch/x86/include/specialreg.h:1.150.2.15	Sat Jul 29 09:48:51 2023
+++ src/sys/arch/x86/include/specialreg.h	Sat Jul 20 14:20:57 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: specialreg.h,v 1.150.2.15 2023/07/29 09:48:51 martin Exp $	*/
+/*	$NetBSD: specialreg.h,v 1.150.2.16 2024/07/20 14:20:57 martin Exp $	*/
 
 /*
  * Copyright (c) 2014-2020 The NetBSD Foundation, Inc.
@@ -1099,8 +1099,12 @@
 
 /*
  * Centaur Extended Feature flags.
- * CPUID FnC000_0001
+ * CPUID FnC000_0001 (VIA "Nehemiah" or later)
  */
+#define CPUID_VIA_HAS_AIS	__BIT(0)	/* Alternate Instruction Set supported */
+						/* (VIA "Nehemiah" only) */
+#define CPUID_VIA_DO_AIS	__BIT(1)	/* Alternate Instruction Set enabled */
+						/* (VIA "Nehemiah" only) */
 #define CPUID_VIA_HAS_RNG	__BIT(2)	/* Random number generator */
 #define CPUID_VIA_DO_RNG	__BIT(3)
 #define CPUID_VIA_HAS_ACE	__BIT(6)	/* AES Encryption */
@@ -1288,7 +1292,7 @@
 #define  MSR_X2APIC_SELF_IPI		0x03f	/* SELF IPI (W) */
 
 /*
- * VIA "Nehemiah" MSRs
+ * VIA "Nehemiah" or later MSRs
  */
 #define MSR_VIA_RNG		0x0000110b
 #define MSR_VIA_RNG_ENABLE	0x00000040
@@ -1296,15 +1300,10 @@
 #define MSR_VIA_RNG_NOISE_A	0x00000000
 #define MSR_VIA_RNG_NOISE_B	0x00000100
 #define MSR_VIA_RNG_2NOISE	0x00000300
-#define MSR_VIA_ACE		0x00001107
-#define 	VIA_ACE_ALTINST	0x00000001
-#define 	VIA_ACE_ECX8	0x00000002
-#define 	VIA_ACE_ENABLE	0x10000000
-
-/*
- * VIA "Eden" MSRs
- */
-#define MSR_VIA_FCR		MSR_VIA_ACE
+#define MSR_VIA_FCR		0x00001107	/* Feature Control Register */
+#define 	VIA_FCR_ACE_ENABLE	0x10000000	/* Enable PadLock (ex. RNG) */
+#define 	VIA_FCR_CX8_REPORT	0x00000002	/* Enable CX8 CPUID reporting */
+#define 	VIA_FCR_ALTINST_ENABLE	0x00000001	/* Enable ALTINST (C3 only) */
 
 /*
  * AMD K6/K7 MSRs.

Index: src/sys/arch/x86/x86/identcpu.c
diff -u src/sys/arch/x86/x86/identcpu.c:1.93.2.5 src/sys/arch/x86/x86/identcpu.c:1.93.2.6
--- src/sys/arch/x86/x86/identcpu.c:1.93.2.5	Fri Dec 24 12:58:14 2021
+++ src/sys/arch/x86/x86/identcpu.c	Sat Jul 20 14:20:57 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: identcpu.c,v 1.93.2.5 2021/12/24 12:58:14 martin Exp $	*/
+/*	$NetBSD: identcpu.c,v 1.93.2.6 2024/07/20 14:20:57 martin 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.93.2.5 2021/12/24 12:58:14 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.93.2.6 2024/07/20 14:20:57 martin Exp $");
 
 #include "opt_xen.h"
 
@@ -450,10 +450,6 @@ cpu_probe_c3(struct cpu_info *ci)
 	model = CPUID_TO_MODEL(ci->ci_signature);
 	stepping = CPUID_TO_STEPPING(ci->ci_signature);
 
-	/* Determine the largest extended function value. */
-	x86_cpuid(0x80000000, descs);
-	lfunc = descs[0];
-
 	if (family == 6) {
 		/*
 		 * VIA Eden ESP.
@@ -468,11 +464,45 @@ cpu_probe_c3(struct cpu_info *ci)
 		 *    bit in the FCR MSR.
 		 */
 		ci->ci_feat_val[0] |= CPUID_CX8;
-		wrmsr(MSR_VIA_FCR, rdmsr(MSR_VIA_FCR) | VIA_ACE_ECX8);
+		wrmsr(MSR_VIA_FCR, rdmsr(MSR_VIA_FCR) | VIA_FCR_CX8_REPORT);
+
+		/*
+		 * For reference on VIA Alternate Instructions, see the VIA C3
+		 * Processor Alternate Instruction Set Application Note, 2002.
+		 * http://www.bitsavers.org/components/viaTechnologies/C3-ais-appnote.pdf
+		 *
+		 * Disable unsafe ALTINST mode for VIA C3 processors, if necessary.
+		 *
+		 * This is done for the security reasons, as some CPUs were
+		 * found with ALTINST enabled by default.  This functionality
+		 * has ability to bypass many x86 architecture memory
+		 * protections and privilege checks, exposing a possibility
+		 * for backdoors and should not be enabled unintentionally.
+		 */
+		if (model > 0x5 && model < 0xA) {
+			int disable_ais = 0;
+			x86_cpuid(0xc0000000, descs);
+			lfunc = descs[0];
+			/* Check AIS flags first if supported ("Nehemiah"). */
+			if (lfunc >= 0xc0000001) {
+				x86_cpuid(0xc0000001, descs);
+				lfunc = descs[3];
+				if ((lfunc & CPUID_VIA_HAS_AIS)
+				    && (lfunc & CPUID_VIA_DO_AIS)) {
+					disable_ais = 1;
+				}
+			} else	/* Explicitly disable AIS for pre-CX5L CPUs. */
+				disable_ais = 1;
+
+			if (disable_ais) {
+				msr = rdmsr(MSR_VIA_FCR);
+				wrmsr(MSR_VIA_FCR, msr & ~VIA_FCR_ALTINST_ENABLE);
+			}
+		}
 	}
 
 	if (family > 6 || model > 0x9 || (model == 0x9 && stepping >= 3)) {
-		/* VIA Nehemiah or Esther. */
+		/* VIA Nehemiah or later. */
 		x86_cpuid(0xc0000000, descs);
 		lfunc = descs[0];
 		if (lfunc >= 0xc0000001) {	/* has ACE, RNG */
@@ -540,17 +570,15 @@ cpu_probe_c3(struct cpu_info *ci)
 		    }
 
 		    if (ace_enable) {
-			msr = rdmsr(MSR_VIA_ACE);
-			wrmsr(MSR_VIA_ACE, msr | VIA_ACE_ENABLE);
+			msr = rdmsr(MSR_VIA_FCR);
+			wrmsr(MSR_VIA_FCR, msr | VIA_FCR_ACE_ENABLE);
 		    }
 		}
 	}
 
-	/* Explicitly disable unsafe ALTINST mode. */
-	if (ci->ci_feat_val[4] & CPUID_VIA_DO_ACE) {
-		msr = rdmsr(MSR_VIA_ACE);
-		wrmsr(MSR_VIA_ACE, msr & ~VIA_ACE_ALTINST);
-	}
+	/* Determine the largest extended function value. */
+	x86_cpuid(0x80000000, descs);
+	lfunc = descs[0];
 
 	/*
 	 * Determine L1 cache/TLB info.

Reply via email to