Index: sys/arch/x86/include/specialreg.h =================================================================== RCS file: /cvsroot/src/sys/arch/x86/include/specialreg.h,v retrieving revision 1.211 diff -u -p -r1.211 specialreg.h --- sys/arch/x86/include/specialreg.h 12 May 2024 23:41:10 -0000 1.211 +++ sys/arch/x86/include/specialreg.h 1 Jul 2024 17:29:31 -0000 @@ -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: sys/arch/x86/x86/identcpu.c =================================================================== RCS file: /cvsroot/src/sys/arch/x86/x86/identcpu.c,v retrieving revision 1.129 diff -u -p -r1.129 identcpu.c --- sys/arch/x86/x86/identcpu.c 30 Jun 2024 15:49:56 -0000 1.129 +++ sys/arch/x86/x86/identcpu.c 1 Jul 2024 17:29:32 -0000 @@ -495,11 +495,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 */ @@ -567,18 +601,12 @@ 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];