1 /* Test CPU feature data against /proc/cpuinfo.
2 This file is part of the GNU C Library.
3 Copyright (C) 2012-2023 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 ")")
99 #define CHECK_PROC_ACTIVE(str, name) \
100 check_proc (#str, " "#str" ", CPU_FEATURE_USABLE (name), \
101 CPU_FEATURE_USABLE (name), \
102 "CPU_FEATURE_USABLE (" #name ")")
105 do_test (int argc
, char **argv
)
108 const struct cpu_features
*cpu_features
= __get_cpu_features ();
111 fails
+= CHECK_PROC (acpi
, ACPI
);
112 fails
+= CHECK_PROC (adx
, ADX
);
113 fails
+= CHECK_PROC (apic
, APIC
);
114 fails
+= CHECK_PROC (aes
, AES
);
115 fails
+= CHECK_PROC (amx_bf16
, AMX_BF16
);
116 fails
+= CHECK_PROC (amx_int8
, AMX_INT8
);
117 fails
+= CHECK_PROC (amx_tile
, AMX_TILE
);
118 fails
+= CHECK_PROC (arch_capabilities
, ARCH_CAPABILITIES
);
119 fails
+= CHECK_PROC (avx
, AVX
);
120 fails
+= CHECK_PROC (avx2
, AVX2
);
121 fails
+= CHECK_PROC (avx512_4fmaps
, AVX512_4FMAPS
);
122 fails
+= CHECK_PROC (avx512_4vnniw
, AVX512_4VNNIW
);
123 fails
+= CHECK_PROC (avx512_bf16
, AVX512_BF16
);
124 fails
+= CHECK_PROC (avx512_bitalg
, AVX512_BITALG
);
125 fails
+= CHECK_PROC (avx512ifma
, AVX512_IFMA
);
126 fails
+= CHECK_PROC (avx512vbmi
, AVX512_VBMI
);
127 fails
+= CHECK_PROC (avx512_vbmi2
, AVX512_VBMI2
);
128 fails
+= CHECK_PROC (avx512_vnni
, AVX512_VNNI
);
129 fails
+= CHECK_PROC (avx512_vp2intersect
, AVX512_VP2INTERSECT
);
130 fails
+= CHECK_PROC (avx512_vpopcntdq
, AVX512_VPOPCNTDQ
);
131 fails
+= CHECK_PROC (avx512bw
, AVX512BW
);
132 fails
+= CHECK_PROC (avx512cd
, AVX512CD
);
133 fails
+= CHECK_PROC (avx512er
, AVX512ER
);
134 fails
+= CHECK_PROC (avx512dq
, AVX512DQ
);
135 fails
+= CHECK_PROC (avx512f
, AVX512F
);
136 fails
+= CHECK_PROC (avx512pf
, AVX512PF
);
137 fails
+= CHECK_PROC (avx512vl
, AVX512VL
);
138 fails
+= CHECK_PROC (bmi1
, BMI1
);
139 fails
+= CHECK_PROC (bmi2
, BMI2
);
140 fails
+= CHECK_PROC (cldemote
, CLDEMOTE
);
141 fails
+= CHECK_PROC (clflushopt
, CLFLUSHOPT
);
142 fails
+= CHECK_PROC (clflush
, CLFSH
);
143 fails
+= CHECK_PROC (clwb
, CLWB
);
144 fails
+= CHECK_PROC (cmov
, CMOV
);
145 fails
+= CHECK_PROC (cx16
, CMPXCHG16B
);
146 fails
+= CHECK_PROC (cnxt_id
, CNXT_ID
);
147 fails
+= CHECK_PROC (core_capabilities
, CORE_CAPABILITIES
);
148 fails
+= CHECK_PROC (cx8
, CX8
);
149 fails
+= CHECK_PROC (dca
, DCA
);
150 fails
+= CHECK_PROC (de
, DE
);
151 fails
+= CHECK_PROC (zero_fcs_fds
, DEPR_FPU_CS_DS
);
152 fails
+= CHECK_PROC (dts
, DS
);
153 fails
+= CHECK_PROC (ds_cpl
, DS_CPL
);
154 fails
+= CHECK_PROC (dtes64
, DTES64
);
155 fails
+= CHECK_PROC (est
, EIST
);
156 fails
+= CHECK_PROC (enqcmd
, ENQCMD
);
157 fails
+= CHECK_PROC (erms
, ERMS
);
158 fails
+= CHECK_PROC (f16c
, F16C
);
159 fails
+= CHECK_PROC (fma
, FMA
);
160 fails
+= CHECK_PROC (fma4
, FMA4
);
161 fails
+= CHECK_PROC (fpu
, FPU
);
162 fails
+= CHECK_PROC (fsgsbase
, FSGSBASE
);
163 fails
+= CHECK_PROC (fsrm
, FSRM
);
164 fails
+= CHECK_PROC (fxsr
, FXSR
);
165 fails
+= CHECK_PROC (gfni
, GFNI
);
166 fails
+= CHECK_PROC (hle
, HLE
);
167 fails
+= CHECK_PROC (ht
, HTT
);
168 fails
+= CHECK_PROC (hybrid
, HYBRID
);
169 if (cpu_features
->basic
.kind
== arch_kind_intel
)
171 fails
+= CHECK_PROC (ibrs
, IBRS_IBPB
);
172 fails
+= CHECK_PROC (stibp
, STIBP
);
174 else if (cpu_features
->basic
.kind
== arch_kind_amd
)
176 fails
+= CHECK_PROC (ibpb
, AMD_IBPB
);
178 /* The IBRS feature on AMD processors is reported using the Intel feature
179 * on KVM guests (synthetic bit). In both cases the cpuinfo entry is the
181 if (HAS_CPU_FEATURE (IBRS_IBPB
))
182 fails
+= CHECK_PROC (ibrs
, IBRS_IBPB
);
184 fails
+= CHECK_PROC (ibrs
, AMD_IBRS
);
185 fails
+= CHECK_PROC (stibp
, AMD_STIBP
);
187 fails
+= CHECK_PROC (ibt
, IBT
);
188 fails
+= CHECK_PROC (invariant_tsc
, INVARIANT_TSC
);
189 fails
+= CHECK_PROC (invpcid
, INVPCID
);
190 fails
+= CHECK_PROC (flush_l1d
, L1D_FLUSH
);
191 fails
+= CHECK_PROC (lahf_lm
, LAHF64_SAHF64
);
192 fails
+= CHECK_PROC (lm
, LM
);
193 fails
+= CHECK_PROC (lwp
, LWP
);
194 fails
+= CHECK_PROC (abm
, LZCNT
);
195 fails
+= CHECK_PROC (mca
, MCA
);
196 fails
+= CHECK_PROC (mce
, MCE
);
197 fails
+= CHECK_PROC (md_clear
, MD_CLEAR
);
198 fails
+= CHECK_PROC (mmx
, MMX
);
199 fails
+= CHECK_PROC (monitor
, MONITOR
);
200 fails
+= CHECK_PROC (movbe
, MOVBE
);
201 fails
+= CHECK_PROC (movdiri
, MOVDIRI
);
202 fails
+= CHECK_PROC (movdir64b
, MOVDIR64B
);
203 fails
+= CHECK_PROC (mpx
, MPX
);
204 fails
+= CHECK_PROC (msr
, MSR
);
205 fails
+= CHECK_PROC (mtrr
, MTRR
);
206 fails
+= CHECK_PROC (nx
, NX
);
207 fails
+= CHECK_PROC (ospke
, OSPKE
);
209 /* NB: /proc/cpuinfo doesn't report this feature. */
210 fails
+= CHECK_PROC (osxsave
, OSXSAVE
);
212 fails
+= CHECK_PROC (pae
, PAE
);
213 fails
+= CHECK_PROC (pdpe1gb
, PAGE1GB
);
214 fails
+= CHECK_PROC (pat
, PAT
);
215 fails
+= CHECK_PROC (pbe
, PBE
);
216 fails
+= CHECK_PROC (pcid
, PCID
);
217 fails
+= CHECK_PROC (pclmulqdq
, PCLMULQDQ
);
218 fails
+= CHECK_PROC (pconfig
, PCONFIG
);
219 fails
+= CHECK_PROC (pdcm
, PDCM
);
220 fails
+= CHECK_PROC (pge
, PGE
);
221 fails
+= CHECK_PROC (pks
, PKS
);
222 fails
+= CHECK_PROC (pku
, PKU
);
223 fails
+= CHECK_PROC (popcnt
, POPCNT
);
224 fails
+= CHECK_PROC (3dnowprefetch
, PREFETCHW
);
226 /* NB: /proc/cpuinfo doesn't report this feature. */
227 fails
+= CHECK_PROC (prefetchwt1
, PREFETCHWT1
);
230 /* NB: /proc/cpuinfo doesn't report this feature. */
231 fails
+= CHECK_PROC (ptwrite
, PTWRITE
);
233 fails
+= CHECK_PROC (pse
, PSE
);
234 fails
+= CHECK_PROC (pse36
, PSE_36
);
235 fails
+= CHECK_PROC (psn
, PSN
);
236 fails
+= CHECK_PROC (rdpid
, RDPID
);
237 fails
+= CHECK_PROC (rdrand
, RDRAND
);
238 fails
+= CHECK_PROC (rdseed
, RDSEED
);
239 fails
+= CHECK_PROC (rdt_a
, RDT_A
);
240 fails
+= CHECK_PROC (cqm
, RDT_M
);
241 fails
+= CHECK_PROC (rdtscp
, RDTSCP
);
242 fails
+= CHECK_PROC (rtm
, RTM
);
243 fails
+= CHECK_PROC (sdbg
, SDBG
);
244 fails
+= CHECK_PROC (sep
, SEP
);
245 fails
+= CHECK_PROC (serialize
, SERIALIZE
);
246 fails
+= CHECK_PROC (sgx
, SGX
);
247 fails
+= CHECK_PROC (sgx_lc
, SGX_LC
);
248 fails
+= CHECK_PROC (sha_ni
, SHA
);
249 fails
+= CHECK_PROC (shstk
, SHSTK
);
250 fails
+= CHECK_PROC (smap
, SMAP
);
251 fails
+= CHECK_PROC (smep
, SMEP
);
252 fails
+= CHECK_PROC (smx
, SMX
);
253 fails
+= CHECK_PROC (ss
, SS
);
254 if (cpu_features
->basic
.kind
== arch_kind_intel
)
255 fails
+= CHECK_PROC (ssbd
, SSBD
);
256 else if (cpu_features
->basic
.kind
== arch_kind_amd
)
258 /* This feature is implemented in 2 different ways on AMD processors:
259 newer systems provides AMD_SSBD (function 8000_0008, EBX[24]),
260 while older system proviseds AMD_VIRT_SSBD (function 8000_008,
261 EBX[25]). However for AMD_VIRT_SSBD, kernel shows both 'ssbd'
262 and 'virt_ssbd' on /proc/cpuinfo; while for AMD_SSBD only 'ssbd'
264 if (HAS_CPU_FEATURE (AMD_SSBD
))
265 fails
+= CHECK_PROC (ssbd
, AMD_SSBD
);
266 else if (HAS_CPU_FEATURE (AMD_VIRT_SSBD
))
267 fails
+= CHECK_PROC (virt_ssbd
, AMD_VIRT_SSBD
);
269 fails
+= CHECK_PROC (sse
, SSE
);
270 fails
+= CHECK_PROC (sse2
, SSE2
);
271 fails
+= CHECK_PROC (pni
, SSE3
);
272 fails
+= CHECK_PROC (sse4_1
, SSE4_1
);
273 fails
+= CHECK_PROC (sse4_2
, SSE4_2
);
274 fails
+= CHECK_PROC (sse4a
, SSE4A
);
275 fails
+= CHECK_PROC (ssse3
, SSSE3
);
276 fails
+= CHECK_PROC (svm
, SVM
);
278 /* NB: SYSCALL_SYSRET is 64-bit only. */
279 fails
+= CHECK_PROC (syscall
, SYSCALL_SYSRET
);
281 fails
+= CHECK_PROC (tbm
, TBM
);
282 fails
+= CHECK_PROC (tm
, TM
);
283 fails
+= CHECK_PROC (tm2
, TM2
);
284 fails
+= CHECK_PROC (intel_pt
, TRACE
);
285 fails
+= CHECK_PROC (tsc
, TSC
);
286 fails
+= CHECK_PROC (tsc_adjust
, TSC_ADJUST
);
287 fails
+= CHECK_PROC (tsc_deadline_timer
, TSC_DEADLINE
);
288 fails
+= CHECK_PROC (tsxldtrk
, TSXLDTRK
);
289 fails
+= CHECK_PROC (umip
, UMIP
);
290 fails
+= CHECK_PROC (vaes
, VAES
);
291 fails
+= CHECK_PROC (vme
, VME
);
292 fails
+= CHECK_PROC (vmx
, VMX
);
293 fails
+= CHECK_PROC (vpclmulqdq
, VPCLMULQDQ
);
294 fails
+= CHECK_PROC (waitpkg
, WAITPKG
);
295 fails
+= CHECK_PROC (wbnoinvd
, WBNOINVD
);
296 fails
+= CHECK_PROC (x2apic
, X2APIC
);
297 fails
+= CHECK_PROC (xfd
, XFD
);
298 fails
+= CHECK_PROC (xgetbv1
, XGETBV_ECX_1
);
299 fails
+= CHECK_PROC (xop
, XOP
);
300 fails
+= CHECK_PROC (xsave
, XSAVE
);
301 fails
+= CHECK_PROC (xsavec
, XSAVEC
);
302 fails
+= CHECK_PROC (xsaveopt
, XSAVEOPT
);
303 fails
+= CHECK_PROC (xsaves
, XSAVES
);
304 fails
+= CHECK_PROC (xtpr
, XTPRUPDCTRL
);
306 fails
+= CHECK_PROC_ACTIVE (fsgsbase
, FSGSBASE
);
308 printf ("%d differences between /proc/cpuinfo and glibc code.\n", fails
);
313 #include "../../../test-skeleton.c"