|
| 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. |
0 commit comments