b1dca6
commit 04bba1e5d84b6fd8d3a3b006bc240cd5d241ee30
b1dca6
Author: H.J. Lu <hjl.tools@gmail.com>
b1dca6
Date:   Wed Aug 5 13:51:56 2020 -0700
b1dca6
b1dca6
    x86: Set CPU usable feature bits conservatively [BZ #26552]
b1dca6
    
b1dca6
    Set CPU usable feature bits only for CPU features which are usable in
b1dca6
    user space and whose usability can be detected from user space, excluding
b1dca6
    features like FSGSBASE whose enable bit can only be checked in the kernel.
b1dca6
b1dca6
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
b1dca6
index f13a1df4555c7000..6954728c47d0126b 100644
b1dca6
--- a/sysdeps/x86/cpu-features.c
b1dca6
+++ b/sysdeps/x86/cpu-features.c
b1dca6
@@ -44,107 +44,55 @@ extern void TUNABLE_CALLBACK (set_x86_shstk) (tunable_val_t *)
b1dca6
 static void
b1dca6
 update_usable (struct cpu_features *cpu_features)
b1dca6
 {
b1dca6
-  /* Before COMMON_CPUID_INDEX_80000001, copy the cpuid array elements to
b1dca6
-     the usable array.  */
b1dca6
-  unsigned int i;
b1dca6
-  for (i = 0; i < COMMON_CPUID_INDEX_80000001; i++)
b1dca6
-    cpu_features->features[i].usable = cpu_features->features[i].cpuid;
b1dca6
-
b1dca6
-  /* Before COMMON_CPUID_INDEX_80000001, clear the unknown usable bits
b1dca6
-     and the always zero bits.  */
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_1_ECX_16);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_1_ECX_31);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_1_EDX_10);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_1_EDX_20);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_1_EDX_30);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_EBX_6);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_EBX_22);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_ECX_13);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_ECX_15);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_ECX_16);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_ECX_23);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_ECX_24);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_ECX_26);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_EDX_0);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_EDX_1);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_EDX_5);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_EDX_6);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_EDX_7);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_EDX_9);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_EDX_11);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_EDX_12);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_EDX_13);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_EDX_17);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_EDX_19);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_EDX_21);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, INDEX_7_EDX_23);
b1dca6
-
b1dca6
-  /* EAX/EBX from COMMON_CPUID_INDEX_1 and EAX from COMMON_CPUID_INDEX_7
b1dca6
-     aren't used for CPU feature detection.  */
b1dca6
-  cpu_features->features[COMMON_CPUID_INDEX_1].usable.eax = 0;
b1dca6
-  cpu_features->features[COMMON_CPUID_INDEX_1].usable.ebx = 0;
b1dca6
-  cpu_features->features[COMMON_CPUID_INDEX_7].usable.eax = 0;
b1dca6
-
b1dca6
-  /* Starting from COMMON_CPUID_INDEX_80000001, copy the cpuid bits to
b1dca6
-     usable bits.  */
b1dca6
+  /* Copy the cpuid bits to usable bits for CPU featuress whose usability
b1dca6
+     in user space can be detected without additonal OS support.  */
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, SSE3);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, PCLMULQDQ);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, SSSE3);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, CMPXCHG16B);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, SSE4_1);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, SSE4_2);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, MOVBE);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, POPCNT);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, AES);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, OSXSAVE);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, TSC);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, CX8);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, CMOV);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, CLFSH);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, MMX);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, FXSR);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, SSE);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, SSE2);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, HTT);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, BMI1);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, HLE);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, BMI2);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, ERMS);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, RTM);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, RDSEED);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, ADX);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, CLFLUSHOPT);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, CLWB);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, SHA);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, PREFETCHWT1);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, OSPKE);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, WAITPKG);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, GFNI);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, RDPID);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, CLDEMOTE);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, MOVDIRI);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, MOVDIR64B);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, FSRM);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, SERIALIZE);
b1dca6
+  CPU_FEATURE_SET_USABLE (cpu_features, TSXLDTRK);
b1dca6
   CPU_FEATURE_SET_USABLE (cpu_features, LAHF64_SAHF64);
b1dca6
-  CPU_FEATURE_SET_USABLE (cpu_features, SVM);
b1dca6
   CPU_FEATURE_SET_USABLE (cpu_features, LZCNT);
b1dca6
   CPU_FEATURE_SET_USABLE (cpu_features, SSE4A);
b1dca6
   CPU_FEATURE_SET_USABLE (cpu_features, PREFETCHW);
b1dca6
-  CPU_FEATURE_SET_USABLE (cpu_features, XOP);
b1dca6
-  CPU_FEATURE_SET_USABLE (cpu_features, LWP);
b1dca6
-  CPU_FEATURE_SET_USABLE (cpu_features, FMA4);
b1dca6
   CPU_FEATURE_SET_USABLE (cpu_features, TBM);
b1dca6
-  CPU_FEATURE_SET_USABLE (cpu_features, SYSCALL_SYSRET);
b1dca6
-  CPU_FEATURE_SET_USABLE (cpu_features, NX);
b1dca6
-  CPU_FEATURE_SET_USABLE (cpu_features, PAGE1GB);
b1dca6
   CPU_FEATURE_SET_USABLE (cpu_features, RDTSCP);
b1dca6
-  CPU_FEATURE_SET_USABLE (cpu_features, LM);
b1dca6
-  CPU_FEATURE_SET_USABLE (cpu_features, XSAVEOPT);
b1dca6
-  CPU_FEATURE_SET_USABLE (cpu_features, XSAVEC);
b1dca6
-  CPU_FEATURE_SET_USABLE (cpu_features, XGETBV_ECX_1);
b1dca6
-  CPU_FEATURE_SET_USABLE (cpu_features, XSAVES);
b1dca6
-  CPU_FEATURE_SET_USABLE (cpu_features, XFD);
b1dca6
-  CPU_FEATURE_SET_USABLE (cpu_features, INVARIANT_TSC);
b1dca6
   CPU_FEATURE_SET_USABLE (cpu_features, WBNOINVD);
b1dca6
-  CPU_FEATURE_SET_USABLE (cpu_features, AVX512_BF16);
b1dca6
-
b1dca6
-  /* MPX has been deprecated.  */
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, MPX);
b1dca6
-
b1dca6
-  /* Clear the usable bits which require OS support.  */
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, FMA);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, F16C);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX2);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX512F);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX512DQ);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX512_IFMA);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX512PF);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX512ER);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX512CD);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX512BW);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX512VL);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX512_VBMI);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, PKU);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX512_VBMI2);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, VAES);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, VPCLMULQDQ);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX512_VNNI);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX512_BITALG);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX512_VPOPCNTDQ);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX512_4VNNIW);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX512_4FMAPS);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX512_VP2INTERSECT);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AMX_BF16);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AMX_TILE);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AMX_INT8);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, XOP);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, FMA4);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, XSAVEC);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, XFD);
b1dca6
-  CPU_FEATURE_UNSET (cpu_features, AVX512_BF16);
b1dca6
 
b1dca6
   /* Can we call xgetbv?  */
b1dca6
   if (CPU_FEATURES_CPU_P (cpu_features, OSXSAVE))
b1dca6
@@ -243,8 +191,11 @@ update_usable (struct cpu_features *cpu_features)
b1dca6
 	  CPU_FEATURE_SET_USABLE (cpu_features, AMX_INT8);
b1dca6
 	}
b1dca6
 
b1dca6
-
b1dca6
-      /* XFD is usable only when OSXSAVE is enabled.  */
b1dca6
+      /* These features are usable only when OSXSAVE is enabled.  */
b1dca6
+      CPU_FEATURE_SET (cpu_features, XSAVE);
b1dca6
+      CPU_FEATURE_SET_USABLE (cpu_features, XSAVEOPT);
b1dca6
+      CPU_FEATURE_SET_USABLE (cpu_features, XSAVEC);
b1dca6
+      CPU_FEATURE_SET_USABLE (cpu_features, XGETBV_ECX_1);
b1dca6
       CPU_FEATURE_SET_USABLE (cpu_features, XFD);
b1dca6
 
b1dca6
       /* For _dl_runtime_resolve, set xsave_state_size to xsave area