]>
Commit | Line | Data |
---|---|---|
96203980 L |
1 | /* Test CPU feature data against /proc/cpuinfo. |
2 | This file is part of the GNU C Library. | |
2b778ceb | 3 | Copyright (C) 2012-2021 Free Software Foundation, Inc. |
96203980 L |
4 | |
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. | |
9 | ||
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. | |
14 | ||
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/>. */ | |
18 | ||
19 | #include <sys/platform/x86.h> | |
20 | #include <stdio.h> | |
21 | #include <stdlib.h> | |
22 | #include <string.h> | |
23 | ||
24 | static char *cpu_flags; | |
25 | ||
26 | /* Search for flags in /proc/cpuinfo and store line | |
27 | in cpu_flags. */ | |
28 | void | |
29 | get_cpuinfo (void) | |
30 | { | |
31 | FILE *f; | |
32 | char *line = NULL; | |
33 | size_t len = 0; | |
34 | ssize_t read; | |
35 | ||
36 | f = fopen ("/proc/cpuinfo", "r"); | |
37 | if (f == NULL) | |
38 | { | |
39 | printf ("cannot open /proc/cpuinfo\n"); | |
40 | exit (1); | |
41 | } | |
42 | ||
43 | while ((read = getline (&line, &len, f)) != -1) | |
44 | { | |
45 | if (strncmp (line, "flags", 5) == 0) | |
46 | { | |
47 | cpu_flags = strdup (line); | |
48 | break; | |
49 | } | |
50 | } | |
51 | fclose (f); | |
52 | free (line); | |
53 | } | |
54 | ||
55 | int | |
56 | check_proc (const char *proc_name, int flag, int usable, const char *name) | |
57 | { | |
58 | int found = 0; | |
59 | ||
60 | printf ("Checking %s:\n", name); | |
61 | if (!usable) | |
62 | { | |
63 | printf (" %s: insufficient usable info, skipped\n", name); | |
64 | return 0; | |
65 | } | |
66 | printf (" %s: %d\n", name, flag); | |
67 | if (strstr (cpu_flags, proc_name) != NULL) | |
68 | found = 1; | |
69 | printf (" cpuinfo (%s): %d\n", proc_name, found); | |
70 | ||
71 | if (found != flag) | |
72 | printf (" *** failure ***\n"); | |
73 | ||
74 | return (found != flag); | |
75 | } | |
76 | ||
77 | #define CHECK_PROC(str, name) \ | |
78 | check_proc (#str, HAS_CPU_FEATURE (name), CPU_FEATURE_USABLE (name), \ | |
79 | "HAS_CPU_FEATURE (" #name ")"); | |
80 | ||
81 | static int | |
82 | do_test (int argc, char **argv) | |
83 | { | |
84 | int fails = 0; | |
85 | ||
86 | get_cpuinfo (); | |
87 | fails += CHECK_PROC (acpi, ACPI); | |
88 | fails += CHECK_PROC (adx, ADX); | |
89 | fails += CHECK_PROC (apic, APIC); | |
90 | fails += CHECK_PROC (aes, AES); | |
91 | fails += CHECK_PROC (amx_bf16, AMX_BF16); | |
92 | fails += CHECK_PROC (amx_int8, AMX_INT8); | |
93 | fails += CHECK_PROC (amx_tile, AMX_TILE); | |
94 | fails += CHECK_PROC (arch_capabilities, ARCH_CAPABILITIES); | |
95 | fails += CHECK_PROC (avx, AVX); | |
96 | fails += CHECK_PROC (avx2, AVX2); | |
97 | fails += CHECK_PROC (avx512_4fmaps, AVX512_4FMAPS); | |
98 | fails += CHECK_PROC (avx512_4vnniw, AVX512_4VNNIW); | |
99 | fails += CHECK_PROC (avx512_bf16, AVX512_BF16); | |
100 | fails += CHECK_PROC (avx512_bitalg, AVX512_BITALG); | |
101 | fails += CHECK_PROC (avx512ifma, AVX512_IFMA); | |
102 | fails += CHECK_PROC (avx512_vbmi, AVX512_VBMI); | |
103 | fails += CHECK_PROC (avx512_vbmi2, AVX512_VBMI2); | |
104 | fails += CHECK_PROC (avx512_vnni, AVX512_VNNI); | |
105 | fails += CHECK_PROC (avx512_vp2intersect, AVX512_VP2INTERSECT); | |
106 | fails += CHECK_PROC (avx512_vpopcntdq, AVX512_VPOPCNTDQ); | |
107 | fails += CHECK_PROC (avx512bw, AVX512BW); | |
108 | fails += CHECK_PROC (avx512cd, AVX512CD); | |
109 | fails += CHECK_PROC (avx512er, AVX512ER); | |
110 | fails += CHECK_PROC (avx512dq, AVX512DQ); | |
111 | fails += CHECK_PROC (avx512f, AVX512F); | |
112 | fails += CHECK_PROC (avx512pf, AVX512PF); | |
113 | fails += CHECK_PROC (avx512vl, AVX512VL); | |
114 | fails += CHECK_PROC (bmi1, BMI1); | |
115 | fails += CHECK_PROC (bmi2, BMI2); | |
116 | fails += CHECK_PROC (cldemote, CLDEMOTE); | |
117 | fails += CHECK_PROC (clflushopt, CLFLUSHOPT); | |
118 | fails += CHECK_PROC (clflush, CLFSH); | |
119 | fails += CHECK_PROC (clwb, CLWB); | |
120 | fails += CHECK_PROC (cmov, CMOV); | |
121 | fails += CHECK_PROC (cx16, CMPXCHG16B); | |
122 | fails += CHECK_PROC (cnxt_id, CNXT_ID); | |
123 | fails += CHECK_PROC (core_capabilities, CORE_CAPABILITIES); | |
124 | fails += CHECK_PROC (cx8, CX8); | |
125 | fails += CHECK_PROC (dca, DCA); | |
126 | fails += CHECK_PROC (de, DE); | |
127 | fails += CHECK_PROC (zero_fcs_fds, DEPR_FPU_CS_DS); | |
128 | fails += CHECK_PROC (ds, DS); | |
129 | fails += CHECK_PROC (ds_cpl, DS_CPL); | |
130 | fails += CHECK_PROC (dtes64, DTES64); | |
131 | fails += CHECK_PROC (est, EIST); | |
132 | fails += CHECK_PROC (enqcmd, ENQCMD); | |
133 | fails += CHECK_PROC (erms, ERMS); | |
134 | fails += CHECK_PROC (f16c, F16C); | |
135 | fails += CHECK_PROC (fma, FMA); | |
136 | fails += CHECK_PROC (fma4, FMA4); | |
137 | fails += CHECK_PROC (fpu, FPU); | |
138 | fails += CHECK_PROC (fsgsbase, FSGSBASE); | |
139 | fails += CHECK_PROC (fsrm, FSRM); | |
140 | fails += CHECK_PROC (fxsr, FXSR); | |
141 | fails += CHECK_PROC (gfni, GFNI); | |
142 | fails += CHECK_PROC (hle, HLE); | |
143 | fails += CHECK_PROC (ht, HTT); | |
144 | fails += CHECK_PROC (hybrid, HYBRID); | |
145 | fails += CHECK_PROC (ibrs, IBRS_IBPB); | |
146 | fails += CHECK_PROC (ibt, IBT); | |
147 | fails += CHECK_PROC (invariant_tsc, INVARIANT_TSC); | |
148 | fails += CHECK_PROC (invpcid, INVPCID); | |
149 | fails += CHECK_PROC (flush_l1d, L1D_FLUSH); | |
150 | fails += CHECK_PROC (lahf_lm, LAHF64_SAHF64); | |
151 | fails += CHECK_PROC (lm, LM); | |
152 | fails += CHECK_PROC (lwp, LWP); | |
153 | fails += CHECK_PROC (abm, LZCNT); | |
154 | fails += CHECK_PROC (mca, MCA); | |
155 | fails += CHECK_PROC (mce, MCE); | |
156 | fails += CHECK_PROC (md_clear, MD_CLEAR); | |
157 | fails += CHECK_PROC (mmx, MMX); | |
158 | fails += CHECK_PROC (monitor, MONITOR); | |
159 | fails += CHECK_PROC (movbe, MOVBE); | |
160 | fails += CHECK_PROC (movdiri, MOVDIRI); | |
161 | fails += CHECK_PROC (movdir64b, MOVDIR64B); | |
162 | fails += CHECK_PROC (mpx, MPX); | |
163 | fails += CHECK_PROC (msr, MSR); | |
164 | fails += CHECK_PROC (mtrr, MTRR); | |
165 | fails += CHECK_PROC (nx, NX); | |
166 | fails += CHECK_PROC (ospke, OSPKE); | |
167 | #if 0 | |
168 | /* NB: /proc/cpuinfo doesn't report this feature. */ | |
169 | fails += CHECK_PROC (osxsave, OSXSAVE); | |
170 | #endif | |
171 | fails += CHECK_PROC (pae, PAE); | |
172 | fails += CHECK_PROC (pdpe1gb, PAGE1GB); | |
173 | fails += CHECK_PROC (pat, PAT); | |
174 | fails += CHECK_PROC (pbe, PBE); | |
175 | fails += CHECK_PROC (pcid, PCID); | |
176 | fails += CHECK_PROC (pclmulqdq, PCLMULQDQ); | |
177 | fails += CHECK_PROC (pconfig, PCONFIG); | |
178 | fails += CHECK_PROC (pdcm, PDCM); | |
179 | fails += CHECK_PROC (pge, PGE); | |
180 | fails += CHECK_PROC (pks, PKS); | |
181 | fails += CHECK_PROC (pku, PKU); | |
182 | fails += CHECK_PROC (popcnt, POPCNT); | |
183 | fails += CHECK_PROC (3dnowprefetch, PREFETCHW); | |
184 | fails += CHECK_PROC (prefetchwt1, PREFETCHWT1); | |
185 | fails += CHECK_PROC (pse, PSE); | |
186 | fails += CHECK_PROC (pse36, PSE_36); | |
187 | fails += CHECK_PROC (psn, PSN); | |
188 | fails += CHECK_PROC (rdpid, RDPID); | |
189 | fails += CHECK_PROC (rdrand, RDRAND); | |
190 | fails += CHECK_PROC (rdseed, RDSEED); | |
191 | fails += CHECK_PROC (rdt_a, RDT_A); | |
192 | fails += CHECK_PROC (cqm, RDT_M); | |
193 | fails += CHECK_PROC (rdtscp, RDTSCP); | |
194 | fails += CHECK_PROC (rtm, RTM); | |
195 | fails += CHECK_PROC (sdbg, SDBG); | |
196 | fails += CHECK_PROC (sep, SEP); | |
197 | fails += CHECK_PROC (serialize, SERIALIZE); | |
198 | fails += CHECK_PROC (sgx, SGX); | |
199 | fails += CHECK_PROC (sgx_lc, SGX_LC); | |
200 | fails += CHECK_PROC (sha_ni, SHA); | |
201 | fails += CHECK_PROC (shstk, SHSTK); | |
202 | fails += CHECK_PROC (smap, SMAP); | |
203 | fails += CHECK_PROC (smep, SMEP); | |
204 | fails += CHECK_PROC (smx, SMX); | |
205 | fails += CHECK_PROC (ss, SS); | |
206 | fails += CHECK_PROC (ssbd, SSBD); | |
207 | fails += CHECK_PROC (sse, SSE); | |
208 | fails += CHECK_PROC (sse2, SSE2); | |
209 | fails += CHECK_PROC (sse3, SSE3); | |
210 | fails += CHECK_PROC (sse4_1, SSE4_1); | |
211 | fails += CHECK_PROC (sse4_2, SSE4_2); | |
212 | fails += CHECK_PROC (sse4a, SSE4A); | |
213 | fails += CHECK_PROC (ssse3, SSSE3); | |
214 | fails += CHECK_PROC (stibp, STIBP); | |
215 | fails += CHECK_PROC (svm, SVM); | |
216 | #ifdef __x86_64__ | |
217 | /* NB: SYSCALL_SYSRET is 64-bit only. */ | |
218 | fails += CHECK_PROC (syscall, SYSCALL_SYSRET); | |
219 | #endif | |
220 | fails += CHECK_PROC (tbm, TBM); | |
221 | fails += CHECK_PROC (tm, TM); | |
222 | fails += CHECK_PROC (tm2, TM2); | |
223 | fails += CHECK_PROC (intel_pt, TRACE); | |
224 | fails += CHECK_PROC (tsc, TSC); | |
225 | fails += CHECK_PROC (tsc_adjust, TSC_ADJUST); | |
226 | fails += CHECK_PROC (tsc_deadline, TSC_DEADLINE); | |
227 | fails += CHECK_PROC (tsxldtrk, TSXLDTRK); | |
228 | fails += CHECK_PROC (umip, UMIP); | |
229 | fails += CHECK_PROC (vaes, VAES); | |
230 | fails += CHECK_PROC (vme, VME); | |
231 | fails += CHECK_PROC (vmx, VMX); | |
232 | fails += CHECK_PROC (vpclmulqdq, VPCLMULQDQ); | |
233 | fails += CHECK_PROC (waitpkg, WAITPKG); | |
234 | fails += CHECK_PROC (wbnoinvd, WBNOINVD); | |
235 | fails += CHECK_PROC (x2apic, X2APIC); | |
236 | fails += CHECK_PROC (xfd, XFD); | |
237 | fails += CHECK_PROC (xgetbv1, XGETBV_ECX_1); | |
238 | fails += CHECK_PROC (xop, XOP); | |
239 | fails += CHECK_PROC (xsave, XSAVE); | |
240 | fails += CHECK_PROC (xsavec, XSAVEC); | |
241 | fails += CHECK_PROC (xsaveopt, XSAVEOPT); | |
242 | fails += CHECK_PROC (xsaves, XSAVES); | |
243 | fails += CHECK_PROC (xtpr, XTPRUPDCTRL); | |
244 | ||
245 | printf ("%d differences between /proc/cpuinfo and glibc code.\n", fails); | |
246 | ||
247 | return (fails != 0); | |
248 | } | |
249 | ||
250 | #include "../../../test-skeleton.c" |