1 /* Test CPU feature data against /proc/cpuinfo.
2 This file is part of the GNU C Library.
3 Copyright (C) 2012-2022 Free Software Foundation, Inc.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 #include <cpu-features.h>
25 static char *cpu_flags
;
27 /* Search for flags in /proc/cpuinfo and store line
37 f
= fopen ("/proc/cpuinfo", "r");
40 printf ("cannot open /proc/cpuinfo\n");
44 while ((read
= getline (&line
, &len
, f
)) != -1)
46 if (strncmp (line
, "flags", 5) == 0)
48 cpu_flags
= strdup (line
);
57 check_proc (const char *proc_name
, const char *search_name
, int flag
,
58 int active
, const char *name
)
62 printf ("Checking %s:\n", name
);
63 printf (" %s: %d\n", name
, flag
);
64 char *str
= strstr (cpu_flags
, search_name
);
67 /* If searching for " XXX " failed, try " XXX\n". */
68 size_t len
= strlen (search_name
);
70 if (len
>= sizeof buffer
)
72 memcpy (buffer
, search_name
, len
+ 1);
73 buffer
[len
- 1] = '\n';
74 str
= strstr (cpu_flags
, buffer
);
78 printf (" cpuinfo (%s): %d\n", proc_name
, found
);
83 printf (" *** failure ***\n");
86 printf (" *** missing in /proc/cpuinfo ***\n");
91 return (found
!= flag
);
94 #define CHECK_PROC(str, name) \
95 check_proc (#str, " "#str" ", HAS_CPU_FEATURE (name), \
96 CPU_FEATURE_USABLE (name), \
97 "HAS_CPU_FEATURE (" #name ")")
100 do_test (int argc
, char **argv
)
103 const struct cpu_features
*cpu_features
= __get_cpu_features ();
106 fails
+= CHECK_PROC (acpi
, ACPI
);
107 fails
+= CHECK_PROC (adx
, ADX
);
108 fails
+= CHECK_PROC (apic
, APIC
);
109 fails
+= CHECK_PROC (aes
, AES
);
110 fails
+= CHECK_PROC (amx_bf16
, AMX_BF16
);
111 fails
+= CHECK_PROC (amx_int8
, AMX_INT8
);
112 fails
+= CHECK_PROC (amx_tile
, AMX_TILE
);
113 fails
+= CHECK_PROC (arch_capabilities
, ARCH_CAPABILITIES
);
114 fails
+= CHECK_PROC (avx
, AVX
);
115 fails
+= CHECK_PROC (avx2
, AVX2
);
116 fails
+= CHECK_PROC (avx512_4fmaps
, AVX512_4FMAPS
);
117 fails
+= CHECK_PROC (avx512_4vnniw
, AVX512_4VNNIW
);
118 fails
+= CHECK_PROC (avx512_bf16
, AVX512_BF16
);
119 fails
+= CHECK_PROC (avx512_bitalg
, AVX512_BITALG
);
120 fails
+= CHECK_PROC (avx512ifma
, AVX512_IFMA
);
121 fails
+= CHECK_PROC (avx512vbmi
, AVX512_VBMI
);
122 fails
+= CHECK_PROC (avx512_vbmi2
, AVX512_VBMI2
);
123 fails
+= CHECK_PROC (avx512_vnni
, AVX512_VNNI
);
124 fails
+= CHECK_PROC (avx512_vp2intersect
, AVX512_VP2INTERSECT
);
125 fails
+= CHECK_PROC (avx512_vpopcntdq
, AVX512_VPOPCNTDQ
);
126 fails
+= CHECK_PROC (avx512bw
, AVX512BW
);
127 fails
+= CHECK_PROC (avx512cd
, AVX512CD
);
128 fails
+= CHECK_PROC (avx512er
, AVX512ER
);
129 fails
+= CHECK_PROC (avx512dq
, AVX512DQ
);
130 fails
+= CHECK_PROC (avx512f
, AVX512F
);
131 fails
+= CHECK_PROC (avx512pf
, AVX512PF
);
132 fails
+= CHECK_PROC (avx512vl
, AVX512VL
);
133 fails
+= CHECK_PROC (bmi1
, BMI1
);
134 fails
+= CHECK_PROC (bmi2
, BMI2
);
135 fails
+= CHECK_PROC (cldemote
, CLDEMOTE
);
136 fails
+= CHECK_PROC (clflushopt
, CLFLUSHOPT
);
137 fails
+= CHECK_PROC (clflush
, CLFSH
);
138 fails
+= CHECK_PROC (clwb
, CLWB
);
139 fails
+= CHECK_PROC (cmov
, CMOV
);
140 fails
+= CHECK_PROC (cx16
, CMPXCHG16B
);
141 fails
+= CHECK_PROC (cnxt_id
, CNXT_ID
);
142 fails
+= CHECK_PROC (core_capabilities
, CORE_CAPABILITIES
);
143 fails
+= CHECK_PROC (cx8
, CX8
);
144 fails
+= CHECK_PROC (dca
, DCA
);
145 fails
+= CHECK_PROC (de
, DE
);
146 fails
+= CHECK_PROC (zero_fcs_fds
, DEPR_FPU_CS_DS
);
147 fails
+= CHECK_PROC (dts
, DS
);
148 fails
+= CHECK_PROC (ds_cpl
, DS_CPL
);
149 fails
+= CHECK_PROC (dtes64
, DTES64
);
150 fails
+= CHECK_PROC (est
, EIST
);
151 fails
+= CHECK_PROC (enqcmd
, ENQCMD
);
152 fails
+= CHECK_PROC (erms
, ERMS
);
153 fails
+= CHECK_PROC (f16c
, F16C
);
154 fails
+= CHECK_PROC (fma
, FMA
);
155 fails
+= CHECK_PROC (fma4
, FMA4
);
156 fails
+= CHECK_PROC (fpu
, FPU
);
157 fails
+= CHECK_PROC (fsgsbase
, FSGSBASE
);
158 fails
+= CHECK_PROC (fsrm
, FSRM
);
159 fails
+= CHECK_PROC (fxsr
, FXSR
);
160 fails
+= CHECK_PROC (gfni
, GFNI
);
161 fails
+= CHECK_PROC (hle
, HLE
);
162 fails
+= CHECK_PROC (ht
, HTT
);
163 fails
+= CHECK_PROC (hybrid
, HYBRID
);
164 if (cpu_features
->basic
.kind
== arch_kind_intel
)
166 fails
+= CHECK_PROC (ibrs
, IBRS_IBPB
);
167 fails
+= CHECK_PROC (stibp
, STIBP
);
169 else if (cpu_features
->basic
.kind
== arch_kind_amd
)
171 fails
+= CHECK_PROC (ibpb
, AMD_IBPB
);
173 /* The IBRS feature on AMD processors is reported using the Intel feature
174 * on KVM guests (synthetic bit). In both cases the cpuinfo entry is the
176 if (HAS_CPU_FEATURE (IBRS_IBPB
))
177 fails
+= CHECK_PROC (ibrs
, IBRS_IBPB
);
179 fails
+= CHECK_PROC (ibrs
, AMD_IBRS
);
180 fails
+= CHECK_PROC (stibp
, AMD_STIBP
);
182 fails
+= CHECK_PROC (ibt
, IBT
);
183 fails
+= CHECK_PROC (invariant_tsc
, INVARIANT_TSC
);
184 fails
+= CHECK_PROC (invpcid
, INVPCID
);
185 fails
+= CHECK_PROC (flush_l1d
, L1D_FLUSH
);
186 fails
+= CHECK_PROC (lahf_lm
, LAHF64_SAHF64
);
187 fails
+= CHECK_PROC (lm
, LM
);
188 fails
+= CHECK_PROC (lwp
, LWP
);
189 fails
+= CHECK_PROC (abm
, LZCNT
);
190 fails
+= CHECK_PROC (mca
, MCA
);
191 fails
+= CHECK_PROC (mce
, MCE
);
192 fails
+= CHECK_PROC (md_clear
, MD_CLEAR
);
193 fails
+= CHECK_PROC (mmx
, MMX
);
194 fails
+= CHECK_PROC (monitor
, MONITOR
);
195 fails
+= CHECK_PROC (movbe
, MOVBE
);
196 fails
+= CHECK_PROC (movdiri
, MOVDIRI
);
197 fails
+= CHECK_PROC (movdir64b
, MOVDIR64B
);
198 fails
+= CHECK_PROC (mpx
, MPX
);
199 fails
+= CHECK_PROC (msr
, MSR
);
200 fails
+= CHECK_PROC (mtrr
, MTRR
);
201 fails
+= CHECK_PROC (nx
, NX
);
202 fails
+= CHECK_PROC (ospke
, OSPKE
);
204 /* NB: /proc/cpuinfo doesn't report this feature. */
205 fails
+= CHECK_PROC (osxsave
, OSXSAVE
);
207 fails
+= CHECK_PROC (pae
, PAE
);
208 fails
+= CHECK_PROC (pdpe1gb
, PAGE1GB
);
209 fails
+= CHECK_PROC (pat
, PAT
);
210 fails
+= CHECK_PROC (pbe
, PBE
);
211 fails
+= CHECK_PROC (pcid
, PCID
);
212 fails
+= CHECK_PROC (pclmulqdq
, PCLMULQDQ
);
213 fails
+= CHECK_PROC (pconfig
, PCONFIG
);
214 fails
+= CHECK_PROC (pdcm
, PDCM
);
215 fails
+= CHECK_PROC (pge
, PGE
);
216 fails
+= CHECK_PROC (pks
, PKS
);
217 fails
+= CHECK_PROC (pku
, PKU
);
218 fails
+= CHECK_PROC (popcnt
, POPCNT
);
219 fails
+= CHECK_PROC (3dnowprefetch
, PREFETCHW
);
220 fails
+= CHECK_PROC (prefetchwt1
, PREFETCHWT1
);
222 /* NB: /proc/cpuinfo doesn't report this feature. */
223 fails
+= CHECK_PROC (ptwrite
, PTWRITE
);
225 fails
+= CHECK_PROC (pse
, PSE
);
226 fails
+= CHECK_PROC (pse36
, PSE_36
);
227 fails
+= CHECK_PROC (psn
, PSN
);
228 fails
+= CHECK_PROC (rdpid
, RDPID
);
229 fails
+= CHECK_PROC (rdrand
, RDRAND
);
230 fails
+= CHECK_PROC (rdseed
, RDSEED
);
231 fails
+= CHECK_PROC (rdt_a
, RDT_A
);
232 fails
+= CHECK_PROC (cqm
, RDT_M
);
233 fails
+= CHECK_PROC (rdtscp
, RDTSCP
);
234 fails
+= CHECK_PROC (rtm
, RTM
);
235 fails
+= CHECK_PROC (sdbg
, SDBG
);
236 fails
+= CHECK_PROC (sep
, SEP
);
237 fails
+= CHECK_PROC (serialize
, SERIALIZE
);
238 fails
+= CHECK_PROC (sgx
, SGX
);
239 fails
+= CHECK_PROC (sgx_lc
, SGX_LC
);
240 fails
+= CHECK_PROC (sha_ni
, SHA
);
241 fails
+= CHECK_PROC (shstk
, SHSTK
);
242 fails
+= CHECK_PROC (smap
, SMAP
);
243 fails
+= CHECK_PROC (smep
, SMEP
);
244 fails
+= CHECK_PROC (smx
, SMX
);
245 fails
+= CHECK_PROC (ss
, SS
);
246 if (cpu_features
->basic
.kind
== arch_kind_intel
)
247 fails
+= CHECK_PROC (ssbd
, SSBD
);
248 else if (cpu_features
->basic
.kind
== arch_kind_amd
)
250 /* This feature is implemented in 2 different ways on AMD processors:
251 newer systems provides AMD_SSBD (function 8000_0008, EBX[24]),
252 while older system proviseds AMD_VIRT_SSBD (function 8000_008,
253 EBX[25]). However for AMD_VIRT_SSBD, kernel shows both 'ssbd'
254 and 'virt_ssbd' on /proc/cpuinfo; while for AMD_SSBD only 'ssbd'
256 if (HAS_CPU_FEATURE (AMD_SSBD
))
257 fails
+= CHECK_PROC (ssbd
, AMD_SSBD
);
258 else if (HAS_CPU_FEATURE (AMD_VIRT_SSBD
))
259 fails
+= CHECK_PROC (virt_ssbd
, AMD_VIRT_SSBD
);
261 fails
+= CHECK_PROC (sse
, SSE
);
262 fails
+= CHECK_PROC (sse2
, SSE2
);
263 fails
+= CHECK_PROC (pni
, SSE3
);
264 fails
+= CHECK_PROC (sse4_1
, SSE4_1
);
265 fails
+= CHECK_PROC (sse4_2
, SSE4_2
);
266 fails
+= CHECK_PROC (sse4a
, SSE4A
);
267 fails
+= CHECK_PROC (ssse3
, SSSE3
);
268 fails
+= CHECK_PROC (svm
, SVM
);
270 /* NB: SYSCALL_SYSRET is 64-bit only. */
271 fails
+= CHECK_PROC (syscall
, SYSCALL_SYSRET
);
273 fails
+= CHECK_PROC (tbm
, TBM
);
274 fails
+= CHECK_PROC (tm
, TM
);
275 fails
+= CHECK_PROC (tm2
, TM2
);
276 fails
+= CHECK_PROC (intel_pt
, TRACE
);
277 fails
+= CHECK_PROC (tsc
, TSC
);
278 fails
+= CHECK_PROC (tsc_adjust
, TSC_ADJUST
);
279 fails
+= CHECK_PROC (tsc_deadline_timer
, TSC_DEADLINE
);
280 fails
+= CHECK_PROC (tsxldtrk
, TSXLDTRK
);
281 fails
+= CHECK_PROC (umip
, UMIP
);
282 fails
+= CHECK_PROC (vaes
, VAES
);
283 fails
+= CHECK_PROC (vme
, VME
);
284 fails
+= CHECK_PROC (vmx
, VMX
);
285 fails
+= CHECK_PROC (vpclmulqdq
, VPCLMULQDQ
);
286 fails
+= CHECK_PROC (waitpkg
, WAITPKG
);
287 fails
+= CHECK_PROC (wbnoinvd
, WBNOINVD
);
288 fails
+= CHECK_PROC (x2apic
, X2APIC
);
289 fails
+= CHECK_PROC (xfd
, XFD
);
290 fails
+= CHECK_PROC (xgetbv1
, XGETBV_ECX_1
);
291 fails
+= CHECK_PROC (xop
, XOP
);
292 fails
+= CHECK_PROC (xsave
, XSAVE
);
293 fails
+= CHECK_PROC (xsavec
, XSAVEC
);
294 fails
+= CHECK_PROC (xsaveopt
, XSAVEOPT
);
295 fails
+= CHECK_PROC (xsaves
, XSAVES
);
296 fails
+= CHECK_PROC (xtpr
, XTPRUPDCTRL
);
298 printf ("%d differences between /proc/cpuinfo and glibc code.\n", fails
);
303 #include "../../../test-skeleton.c"