]>
Commit | Line | Data |
---|---|---|
ea4e3bef KMP |
1 | .. SPDX-License-Identifier: GPL-2.0 |
2 | ||
3 | ================= | |
4 | x86 Feature Flags | |
5 | ================= | |
6 | ||
7 | Introduction | |
8 | ============ | |
9 | ||
10 | On x86, flags appearing in /proc/cpuinfo have an X86_FEATURE definition | |
11 | in arch/x86/include/asm/cpufeatures.h. If the kernel cares about a feature | |
12 | or KVM want to expose the feature to a KVM guest, it can and should have | |
13 | an X86_FEATURE_* defined. These flags represent hardware features as | |
14 | well as software features. | |
15 | ||
16 | If users want to know if a feature is available on a given system, they | |
17 | try to find the flag in /proc/cpuinfo. If a given flag is present, it | |
18 | means that the kernel supports it and is currently making it available. | |
19 | If such flag represents a hardware feature, it also means that the | |
20 | hardware supports it. | |
21 | ||
22 | If the expected flag does not appear in /proc/cpuinfo, things are murkier. | |
23 | Users need to find out the reason why the flag is missing and find the way | |
24 | how to enable it, which is not always easy. There are several factors that | |
25 | can explain missing flags: the expected feature failed to enable, the feature | |
26 | is missing in hardware, platform firmware did not enable it, the feature is | |
27 | disabled at build or run time, an old kernel is in use, or the kernel does | |
28 | not support the feature and thus has not enabled it. In general, /proc/cpuinfo | |
29 | shows features which the kernel supports. For a full list of CPUID flags | |
30 | which the CPU supports, use tools/arch/x86/kcpuid. | |
31 | ||
32 | How are feature flags created? | |
33 | ============================== | |
34 | ||
35 | a: Feature flags can be derived from the contents of CPUID leaves. | |
36 | ------------------------------------------------------------------ | |
37 | These feature definitions are organized mirroring the layout of CPUID | |
38 | leaves and grouped in words with offsets as mapped in enum cpuid_leafs | |
39 | in cpufeatures.h (see arch/x86/include/asm/cpufeatures.h for details). | |
40 | If a feature is defined with a X86_FEATURE_<name> definition in | |
41 | cpufeatures.h, and if it is detected at run time, the flags will be | |
42 | displayed accordingly in /proc/cpuinfo. For example, the flag "avx2" | |
43 | comes from X86_FEATURE_AVX2 in cpufeatures.h. | |
44 | ||
45 | b: Flags can be from scattered CPUID-based features. | |
46 | ---------------------------------------------------- | |
47 | Hardware features enumerated in sparsely populated CPUID leaves get | |
48 | software-defined values. Still, CPUID needs to be queried to determine | |
49 | if a given feature is present. This is done in init_scattered_cpuid_features(). | |
50 | For instance, X86_FEATURE_CQM_LLC is defined as 11*32 + 0 and its presence is | |
51 | checked at runtime in the respective CPUID leaf [EAX=f, ECX=0] bit EDX[1]. | |
52 | ||
53 | The intent of scattering CPUID leaves is to not bloat struct | |
54 | cpuinfo_x86.x86_capability[] unnecessarily. For instance, the CPUID leaf | |
55 | [EAX=7, ECX=0] has 30 features and is dense, but the CPUID leaf [EAX=7, EAX=1] | |
56 | has only one feature and would waste 31 bits of space in the x86_capability[] | |
57 | array. Since there is a struct cpuinfo_x86 for each possible CPU, the wasted | |
58 | memory is not trivial. | |
59 | ||
60 | c: Flags can be created synthetically under certain conditions for hardware features. | |
61 | ------------------------------------------------------------------------------------- | |
62 | Examples of conditions include whether certain features are present in | |
63 | MSR_IA32_CORE_CAPS or specific CPU models are identified. If the needed | |
64 | conditions are met, the features are enabled by the set_cpu_cap or | |
65 | setup_force_cpu_cap macros. For example, if bit 5 is set in MSR_IA32_CORE_CAPS, | |
66 | the feature X86_FEATURE_SPLIT_LOCK_DETECT will be enabled and | |
67 | "split_lock_detect" will be displayed. The flag "ring3mwait" will be | |
68 | displayed only when running on INTEL_FAM6_XEON_PHI_[KNL|KNM] processors. | |
69 | ||
70 | d: Flags can represent purely software features. | |
71 | ------------------------------------------------ | |
72 | These flags do not represent hardware features. Instead, they represent a | |
73 | software feature implemented in the kernel. For example, Kernel Page Table | |
74 | Isolation is purely software feature and its feature flag X86_FEATURE_PTI is | |
75 | also defined in cpufeatures.h. | |
76 | ||
77 | Naming of Flags | |
78 | =============== | |
79 | ||
80 | The script arch/x86/kernel/cpu/mkcapflags.sh processes the | |
81 | #define X86_FEATURE_<name> from cpufeatures.h and generates the | |
82 | x86_cap/bug_flags[] arrays in kernel/cpu/capflags.c. The names in the | |
83 | resulting x86_cap/bug_flags[] are used to populate /proc/cpuinfo. The naming | |
84 | of flags in the x86_cap/bug_flags[] are as follows: | |
85 | ||
86 | a: The name of the flag is from the string in X86_FEATURE_<name> by default. | |
87 | ---------------------------------------------------------------------------- | |
88 | By default, the flag <name> in /proc/cpuinfo is extracted from the respective | |
89 | X86_FEATURE_<name> in cpufeatures.h. For example, the flag "avx2" is from | |
90 | X86_FEATURE_AVX2. | |
91 | ||
92 | b: The naming can be overridden. | |
93 | -------------------------------- | |
94 | If the comment on the line for the #define X86_FEATURE_* starts with a | |
95 | double-quote character (""), the string inside the double-quote characters | |
96 | will be the name of the flags. For example, the flag "sse4_1" comes from | |
97 | the comment "sse4_1" following the X86_FEATURE_XMM4_1 definition. | |
98 | ||
99 | There are situations in which overriding the displayed name of the flag is | |
100 | needed. For instance, /proc/cpuinfo is a userspace interface and must remain | |
101 | constant. If, for some reason, the naming of X86_FEATURE_<name> changes, one | |
102 | shall override the new naming with the name already used in /proc/cpuinfo. | |
103 | ||
104 | c: The naming override can be "", which means it will not appear in /proc/cpuinfo. | |
105 | ---------------------------------------------------------------------------------- | |
106 | The feature shall be omitted from /proc/cpuinfo if it does not make sense for | |
107 | the feature to be exposed to userspace. For example, X86_FEATURE_ALWAYS is | |
108 | defined in cpufeatures.h but that flag is an internal kernel feature used | |
109 | in the alternative runtime patching functionality. So, its name is overridden | |
110 | with "". Its flag will not appear in /proc/cpuinfo. | |
111 | ||
112 | Flags are missing when one or more of these happen | |
113 | ================================================== | |
114 | ||
115 | a: The hardware does not enumerate support for it. | |
116 | -------------------------------------------------- | |
117 | For example, when a new kernel is running on old hardware or the feature is | |
118 | not enabled by boot firmware. Even if the hardware is new, there might be a | |
119 | problem enabling the feature at run time, the flag will not be displayed. | |
120 | ||
121 | b: The kernel does not know about the flag. | |
122 | ------------------------------------------- | |
123 | For example, when an old kernel is running on new hardware. | |
124 | ||
125 | c: The kernel disabled support for it at compile-time. | |
126 | ------------------------------------------------------ | |
127 | For example, if 5-level-paging is not enabled when building (i.e., | |
128 | CONFIG_X86_5LEVEL is not selected) the flag "la57" will not show up [#f1]_. | |
129 | Even though the feature will still be detected via CPUID, the kernel disables | |
130 | it by clearing via setup_clear_cpu_cap(X86_FEATURE_LA57). | |
131 | ||
132 | d: The feature is disabled at boot-time. | |
133 | ---------------------------------------- | |
134 | A feature can be disabled either using a command-line parameter or because | |
135 | it failed to be enabled. The command-line parameter clearcpuid= can be used | |
136 | to disable features using the feature number as defined in | |
137 | /arch/x86/include/asm/cpufeatures.h. For instance, User Mode Instruction | |
138 | Protection can be disabled using clearcpuid=514. The number 514 is calculated | |
139 | from #define X86_FEATURE_UMIP (16*32 + 2). | |
140 | ||
141 | In addition, there exists a variety of custom command-line parameters that | |
142 | disable specific features. The list of parameters includes, but is not limited | |
143 | to, nofsgsbase, nosmap, and nosmep. 5-level paging can also be disabled using | |
144 | "no5lvl". SMAP and SMEP are disabled with the aforementioned parameters, | |
145 | respectively. | |
146 | ||
147 | e: The feature was known to be non-functional. | |
148 | ---------------------------------------------- | |
149 | The feature was known to be non-functional because a dependency was | |
150 | missing at runtime. For example, AVX flags will not show up if XSAVE feature | |
151 | is disabled since they depend on XSAVE feature. Another example would be broken | |
152 | CPUs and them missing microcode patches. Due to that, the kernel decides not to | |
153 | enable a feature. | |
154 | ||
155 | .. [#f1] 5-level paging uses linear address of 57 bits. |