← Documents Documentation/arch/x86/cpuinfo.rst GitHub 원문 ↗

Linux 6.18.37 · Architecture

x86 Feature Flags

/proc/cpuinfo feature flag의 ABI 의미, CPUID·synthetic·software flag 생성과 누락 사유를 설명합니다.

Source pathDocumentation/arch/x86/cpuinfo.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약과 해설

cpuinfo.rst:1-202

`/proc/cpuinfo` flag는 hardware capability 전부가 아니라 kernel이 알고 enable해 실제 제공하는 feature를 나타냅니다. 존재는 강한 신호지만 부재는 old kernel, build option, boot parameter, missing dependency 등 여러 원인이 있어 capability 부재를 뜻하지 않습니다.

application은 glibc나 CPUID를, user는 `kcpuid` 또는 `cpuid(1)`을 사용해야 합니다. flag name은 노출 순간 stable userspace ABI가 되므로 꼭 필요한 경우에만 지정하고 internal feature는 default로 숨깁니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 =================
4 x86 Feature Flags
5 =================
6
7 Introduction
8 ============
9
10 The list of feature flags in /proc/cpuinfo is not complete and
11 represents an ill-fated attempt from long time ago to put feature flags
12 in an easy to find place for userspace.
13
14 However, the number of feature flags is growing with each CPU generation,
15 leading to unparseable and unwieldy /proc/cpuinfo.
16
17 What is more, those feature flags do not even need to be in that file
18 because userspace doesn't care about them - glibc et al already use
19 CPUID to find out what the target machine supports and what not.
20
21 And even if it doesn't show a particular feature flag - although the CPU
22 still does have support for the respective hardware functionality and
23 said CPU supports CPUID faulting - userspace can simply probe for the
24 feature and figure out if it is supported or not, regardless of whether
25 it is being advertised somewhere.
26
27 Furthermore, those flag strings become an ABI the moment they appear
28 there and maintaining them forever when nothing even uses them is a lot
29 of wasted effort.
30
31 So, the current use of /proc/cpuinfo is to show features which the
32 kernel has *enabled* and *supports*. As in: the CPUID feature flag is
33 there, there's an additional setup which the kernel has done while
34 booting and the functionality is ready to use. A perfect example for
35 that is "user_shstk" where additional code enablement is present in the
36 kernel to support shadow stack for user programs.
37
38 So, if users want to know if a feature is available on a given system,
39 they try to find the flag in /proc/cpuinfo. If a given flag is present,
40 it means that
41
42 * the kernel knows about the feature enough to have an X86_FEATURE bit
43
44 * the kernel supports it and is currently making it available either to
45 userspace or some other part of the kernel
46
47 * if the flag represents a hardware feature the hardware supports it.
48
49 The absence of a flag in /proc/cpuinfo by itself means almost nothing to
50 an end user.
51
52 On the one hand, a feature like "vaes" might be fully available to user
53 applications on a kernel that has not defined X86_FEATURE_VAES and thus
54 there is no "vaes" in /proc/cpuinfo.
55
56 On the other hand, a new kernel running on non-VAES hardware would also
57 have no "vaes" in /proc/cpuinfo. There's no way for an application or
58 user to tell the difference.
59
60 The end result is that the flags field in /proc/cpuinfo is marginally
61 useful for kernel debugging, but not really for anything else.
62 Applications should instead use things like the glibc facilities for
63 querying CPU support. Users should rely on tools like
64 tools/arch/x86/kcpuid and cpuid(1).
65
66 Regarding implementation, flags appearing in /proc/cpuinfo have an
67 X86_FEATURE definition in arch/x86/include/asm/cpufeatures.h. These flags
68 represent hardware features as well as software features.
69
70 If the kernel cares about a feature or KVM want to expose the feature to
71 a KVM guest, it should only then expose it to the guest when the guest
72 needs to parse /proc/cpuinfo. Which, as mentioned above, is highly
73 unlikely. KVM can synthesize the CPUID bit and the KVM guest can simply
74 query CPUID and figure out what the hypervisor supports and what not. As
75 already stated, /proc/cpuinfo is not a dumping ground for useless
76 feature flags.
77
78
79 How are feature flags created?
80 ==============================
81
82 Feature flags can be derived from the contents of CPUID leaves
83 --------------------------------------------------------------
84
85 These feature definitions are organized mirroring the layout of CPUID
86 leaves and grouped in words with offsets as mapped in enum cpuid_leafs
87 in cpufeatures.h (see arch/x86/include/asm/cpufeatures.h for details).
88 If a feature is defined with a X86_FEATURE_<name> definition in
89 cpufeatures.h, and if it is detected at run time, the flags will be
90 displayed accordingly in /proc/cpuinfo. For example, the flag "avx2"
91 comes from X86_FEATURE_AVX2 in cpufeatures.h.
92
93 Flags can be from scattered CPUID-based features
94 ------------------------------------------------
95
96 Hardware features enumerated in sparsely populated CPUID leaves get
97 software-defined values. Still, CPUID needs to be queried to determine
98 if a given feature is present. This is done in init_scattered_cpuid_features().
99 For instance, X86_FEATURE_CQM_LLC is defined as 11*32 + 0 and its presence is
100 checked at runtime in the respective CPUID leaf [EAX=f, ECX=0] bit EDX[1].
101
102 The intent of scattering CPUID leaves is to not bloat struct
103 cpuinfo_x86.x86_capability[] unnecessarily. For instance, the CPUID leaf
104 [EAX=7, ECX=0] has 30 features and is dense, but the CPUID leaf [EAX=7, EAX=1]
105 has only one feature and would waste 31 bits of space in the x86_capability[]
106 array. Since there is a struct cpuinfo_x86 for each possible CPU, the wasted
107 memory is not trivial.
108
109 Flags can be created synthetically under certain conditions for hardware features
110 ---------------------------------------------------------------------------------
111
112 Examples of conditions include whether certain features are present in
113 MSR_IA32_CORE_CAPS or specific CPU models are identified. If the needed
114 conditions are met, the features are enabled by the set_cpu_cap or
115 setup_force_cpu_cap macros. For example, if bit 5 is set in MSR_IA32_CORE_CAPS,
116 the feature X86_FEATURE_SPLIT_LOCK_DETECT will be enabled and
117 "split_lock_detect" will be displayed. The flag "ring3mwait" will be
118 displayed only when running on INTEL_XEON_PHI_[KNL|KNM] processors.
119
120 Flags can represent purely software features
121 --------------------------------------------
122 These flags do not represent hardware features. Instead, they represent a
123 software feature implemented in the kernel. For example, Kernel Page Table
124 Isolation is purely software feature and its feature flag X86_FEATURE_PTI is
125 also defined in cpufeatures.h.
126
127 Naming of Flags
128 ===============
129
130 The script arch/x86/kernel/cpu/mkcapflags.sh processes the
131 #define X86_FEATURE_<name> from cpufeatures.h and generates the
132 x86_cap/bug_flags[] arrays in kernel/cpu/capflags.c. The names in the
133 resulting x86_cap/bug_flags[] are used to populate /proc/cpuinfo. The naming
134 of flags in the x86_cap/bug_flags[] are as follows:
135
136 Flags do not appear by default in /proc/cpuinfo
137 -----------------------------------------------
138
139 Feature flags are omitted by default from /proc/cpuinfo as it does not make
140 sense for the feature to be exposed to userspace in most cases. For example,
141 X86_FEATURE_ALWAYS is defined in cpufeatures.h but that flag is an internal
142 kernel feature used in the alternative runtime patching functionality. So the
143 flag does not appear in /proc/cpuinfo.
144
145 Specify a flag name if absolutely needed
146 ----------------------------------------
147
148 If the comment on the line for the #define X86_FEATURE_* starts with a
149 double-quote character (""), the string inside the double-quote characters
150 will be the name of the flags. For example, the flag "sse4_1" comes from
151 the comment "sse4_1" following the X86_FEATURE_XMM4_1 definition.
152
153 There are situations in which overriding the displayed name of the flag is
154 needed. For instance, /proc/cpuinfo is a userspace interface and must remain
155 constant. If, for some reason, the naming of X86_FEATURE_<name> changes, one
156 shall override the new naming with the name already used in /proc/cpuinfo.
157
158 Flags are missing when one or more of these happen
159 ==================================================
160
161 The hardware does not enumerate support for it
162 ----------------------------------------------
163
164 For example, when a new kernel is running on old hardware or the feature is
165 not enabled by boot firmware. Even if the hardware is new, there might be a
166 problem enabling the feature at run time, the flag will not be displayed.
167
168 The kernel does not know about the flag
169 ---------------------------------------
170
171 For example, when an old kernel is running on new hardware.
172
173 The kernel disabled support for it at compile-time
174 --------------------------------------------------
175
176 For example, if Linear Address Masking (LAM) is not enabled when building (i.e.,
177 CONFIG_ADDRESS_MASKING is not selected) the flag "lam" will not show up.
178 Even though the feature will still be detected via CPUID, the kernel disables
179 it by clearing via setup_clear_cpu_cap(X86_FEATURE_LAM).
180
181 The feature is disabled at boot-time
182 ------------------------------------
183 A feature can be disabled either using a command-line parameter or because
184 it failed to be enabled. The command-line parameter clearcpuid= can be used
185 to disable features using the feature number as defined in
186 /arch/x86/include/asm/cpufeatures.h. For instance, User Mode Instruction
187 Protection can be disabled using clearcpuid=514. The number 514 is calculated
188 from #define X86_FEATURE_UMIP (16*32 + 2).
189
190 In addition, there exists a variety of custom command-line parameters that
191 disable specific features. The list of parameters includes, but is not limited
192 to, nofsgsbase, nosgx, noxsave, etc. 5-level paging can also be disabled using
193 "no5lvl".
194
195 The feature was known to be non-functional
196 ------------------------------------------
197
198 The feature was known to be non-functional because a dependency was
199 missing at runtime. For example, AVX flags will not show up if XSAVE feature
200 is disabled since they depend on XSAVE feature. Another example would be broken
201 CPUs and them missing microcode patches. Due to that, the kernel decides not to
202 enable a feature.
203

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

/proc/cpuinfo flag의 의미와 한계

1-78

이 `GPL-2.0` 문서는 x86 feature flag를 설명합니다. `/proc/cpuinfo`의 feature 목록은 완전하지 않으며, 오래전에 feature를 userspace가 찾기 쉬운 곳에 두려 했던 좋지 않은 시도의 결과입니다. CPU generation마다 flag가 늘어 이 file은 parse하기 어렵고 지나치게 커졌습니다.

userspace는 대부분 이 flag가 필요하지 않습니다. glibc 같은 library는 이미 CPUID로 machine capability를 확인합니다. CPU가 CPUID faulting을 지원한다면 `/proc/cpuinfo`에 특정 flag가 없어도 application이 feature를 probe할 수 있습니다. 반면 한 번 노출한 flag string은 ABI가 되어 사용자가 없어도 영구 유지해야 합니다.

현재 `/proc/cpuinfo`는 kernel이 실제로 enable하고 지원하는 feature를 표시합니다. 즉 CPUID capability뿐 아니라 boot 중 필요한 setup을 마쳐 userspace나 kernel의 다른 부분이 사용할 준비가 된 기능입니다. `user_shstk`는 user program shadow stack을 위한 추가 kernel enablement가 있는 예입니다.

flag가 존재하면 다음 세 조건을 모두 뜻합니다.

  • kernel이 해당 feature를 알아 `X86_FEATURE` bit를 정의하고 있습니다.
  • kernel이 이를 지원하며 현재 userspace 또는 kernel의 다른 부분에 사용할 수 있게 제공하고 있습니다.
  • hardware feature를 나타내는 flag라면 hardware도 이를 지원합니다.

flag가 없다는 사실만으로 end user가 알 수 있는 것은 거의 없습니다. `vaes` hardware와 userspace support가 있어도 old kernel이 `X86_FEATURE_VAES`를 정의하지 않으면 flag가 없고, new kernel이 non-VAES hardware에서 실행돼도 똑같이 flag가 없습니다.

따라서 flags field는 kernel debugging에는 조금 유용하지만 application capability detection에는 적합하지 않습니다. application은 glibc CPU-query facility를 사용하고 user는 `tools/arch/x86/kcpuid`나 `cpuid(1)`을 사용해야 합니다.

`/proc/cpuinfo`에 나오는 flag는 `arch/x86/include/asm/cpufeatures.h`의 `X86_FEATURE` definition을 가지며 hardware와 software feature를 모두 표현합니다. KVM도 guest가 정말 `/proc/cpuinfo`를 parse해야 할 때만 flag를 노출해야 합니다. 보통은 KVM이 CPUID bit를 synthesize하고 guest가 CPUID를 직접 query하면 되므로 `/proc/cpuinfo`를 불필요한 flag dumping ground로 쓰지 않습니다.

CPUID leaf와 scattered feature

79-108

일반 feature definition은 CPUID leaf layout을 반영해 구성되며 `cpufeatures.h`의 `enum cpuid_leafs` mapping에 따라 word와 offset으로 group됩니다. `X86_FEATURE_<name>`이 정의되고 runtime detection에 성공하면 해당 flag가 `/proc/cpuinfo`에 표시됩니다. 예를 들어 `avx2`는 `X86_FEATURE_AVX2`에서 옵니다.

sparse CPUID leaf의 hardware feature에는 software-defined value를 주지만 존재 여부는 여전히 CPUID로 확인하며 `init_scattered_cpuid_features()`가 수행합니다. 예를 들어 `X86_FEATURE_CQM_LLC`는 `11*32 + 0`으로 정의되고 CPUID leaf `[EAX=f, ECX=0]`의 `EDX[1]`을 runtime에 검사합니다.

scattered layout은 `struct cpuinfo_x86.x86_capability[]`의 불필요한 팽창을 막습니다. `[EAX=7, ECX=0]`은 feature 30개로 dense하지만 원문의 sparse 예인 `[EAX=7, EAX=1]`에는 feature 하나뿐이어서 그대로 word를 할당하면 31 bit를 낭비합니다. possible CPU마다 `struct cpuinfo_x86`가 있으므로 이 낭비는 무시할 수 없습니다.

synthetic hardware flag와 software-only flag

109-126

일부 hardware flag는 CPUID bit를 직접 옮기는 대신 조건을 만족할 때 synthetic하게 생성합니다. 조건에는 `MSR_IA32_CORE_CAPS`의 특정 bit 또는 특정 CPU model 식별이 포함됩니다. 조건을 만족하면 `set_cpu_cap`이나 `setup_force_cpu_cap` macro로 feature를 enable합니다.

예를 들어 `MSR_IA32_CORE_CAPS` bit 5가 설정되면 `X86_FEATURE_SPLIT_LOCK_DETECT`를 enable하고 `split_lock_detect`를 표시합니다. `ring3mwait`은 `INTEL_XEON_PHI_[KNL|KNM]` processor에서만 표시합니다.

flag가 hardware가 아닌 순수 software feature를 나타낼 수도 있습니다. Kernel Page Table Isolation은 kernel이 구현한 software feature이며 `X86_FEATURE_PTI` 역시 `cpufeatures.h`에 정의됩니다.

mkcapflags.sh와 stable flag naming

127-157

`arch/x86/kernel/cpu/mkcapflags.sh`는 `cpufeatures.h`의 `#define X86_FEATURE_<name>`을 처리해 `kernel/cpu/capflags.c`의 `x86_cap/bug_flags[]` array를 생성합니다. 이 array의 name이 `/proc/cpuinfo`를 채웁니다.

대부분 feature를 userspace에 노출할 이유가 없으므로 flag는 default로 생략합니다. 예를 들어 `X86_FEATURE_ALWAYS`는 alternative runtime patching에 쓰는 kernel-internal feature라 `/proc/cpuinfo`에 나오지 않습니다.

정말 name이 필요하면 `#define X86_FEATURE_*` line의 comment를 double-quote character로 시작하고 따옴표 안 string을 flag name으로 사용합니다. `X86_FEATURE_XMM4_1` 뒤 comment `"sse4_1"`이 `sse4_1` flag를 만드는 예입니다.

`/proc/cpuinfo`는 userspace interface이므로 name은 stable해야 합니다. 내부 `X86_FEATURE_<name>` 이름을 바꾸더라도 이미 노출한 이름을 override해 계속 사용해야 합니다.

feature flag가 보이지 않는 이유

158-202
원인설명과 예
hardware가 지원을 enumerate하지 않음new kernel이 old hardware에서 실행되거나 boot firmware가 feature를 enable하지 않은 경우입니다. new hardware라도 runtime enable에 문제가 생기면 표시하지 않습니다.
kernel이 flag를 모름old kernel이 new hardware에서 실행되는 경우입니다.
compile time에 kernel support를 끔예를 들어 `CONFIG_ADDRESS_MASKING` 없이 build하면 CPUID로 LAM을 detect해도 `setup_clear_cpu_cap(X86_FEATURE_LAM)`으로 끄므로 `lam`이 나오지 않습니다.
boot time에 feature를 끔command-line parameter로 disable했거나 enable에 실패한 경우입니다. `clearcpuid=`에 `cpufeatures.h`의 feature number를 주며 UMIP는 `X86_FEATURE_UMIP (16*32 + 2)`이므로 `clearcpuid=514`로 끕니다.
runtime dependency가 없어 non-functionalAVX는 XSAVE에 의존하므로 XSAVE가 disabled이면 AVX flag도 사라집니다. broken CPU에 필요한 microcode patch가 없는 경우도 kernel이 feature를 enable하지 않습니다.

specific feature를 끄는 custom parameter도 많습니다. 예로 `nofsgsbase`, `nosgx`, `noxsave`가 있으며 5-level paging은 `no5lvl`로 끌 수 있습니다.