Skip to content

Commit 8413263

Browse files
H. Peter Anvin (Intel)Ingo Molnar
authored andcommitted
x86/cpufeatures: Generate the <asm/cpufeaturemasks.h> header based on build config
Introduce an AWK script to auto-generate the <asm/cpufeaturemasks.h> header with required and disabled feature masks based on <asm/cpufeatures.h> and the current build config. Thus for any CPU feature with a build config, e.g., X86_FRED, simply add: config X86_DISABLED_FEATURE_FRED def_bool y depends on !X86_FRED to arch/x86/Kconfig.cpufeatures, instead of adding a conditional CPU feature disable flag, e.g., DISABLE_FRED. Lastly, the generated required and disabled feature masks will be added to their corresponding feature masks for this particular compile-time configuration. [ Xin: build integration improvements ] [ mingo: Improved changelog and comments ] Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com> Signed-off-by: Xin Li (Intel) <xin@zytor.com> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Signed-off-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Nikolay Borisov <nik.borisov@suse.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Link: https://lore.kernel.org/r/20250305184725.3341760-3-xin@zytor.com
1 parent 3d37d93 commit 8413263

File tree

9 files changed

+105
-12
lines changed

9 files changed

+105
-12
lines changed

arch/x86/Makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,21 @@ archscripts: scripts_basic
268268
archheaders:
269269
$(Q)$(MAKE) $(build)=arch/x86/entry/syscalls all
270270

271+
###
272+
# <asm/cpufeaturemasks.h> header generation
273+
274+
cpufeaturemasks.hdr := arch/x86/include/generated/asm/cpufeaturemasks.h
275+
cpufeaturemasks.awk := $(srctree)/arch/x86/tools/cpufeaturemasks.awk
276+
cpufeatures_hdr := $(srctree)/arch/x86/include/asm/cpufeatures.h
277+
targets += $(cpufeaturemasks.hdr)
278+
quiet_cmd_gen_featuremasks = GEN $@
279+
cmd_gen_featuremasks = $(AWK) -f $(cpufeaturemasks.awk) $(cpufeatures_hdr) $(KCONFIG_CONFIG) > $@
280+
281+
$(cpufeaturemasks.hdr): $(cpufeaturemasks.awk) $(cpufeatures_hdr) $(KCONFIG_CONFIG) FORCE
282+
$(shell mkdir -p $(dir $@))
283+
$(call if_changed,gen_featuremasks)
284+
archprepare: $(cpufeaturemasks.hdr)
285+
271286
###
272287
# Kernel objects
273288

arch/x86/boot/cpucheck.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@
2222
# include "boot.h"
2323
#endif
2424
#include <linux/types.h>
25+
#include <asm/cpufeaturemasks.h>
2526
#include <asm/intel-family.h>
2627
#include <asm/processor-flags.h>
27-
#include <asm/required-features.h>
2828
#include <asm/msr-index.h>
29+
2930
#include "string.h"
3031
#include "msr.h"
3132

arch/x86/boot/cpuflags.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#include "bitops.h"
44

55
#include <asm/processor-flags.h>
6-
#include <asm/required-features.h>
76
#include <asm/msr-index.h>
87
#include "cpuflags.h"
98

arch/x86/boot/mkcpustr.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212

1313
#include <stdio.h>
1414

15-
#include "../include/asm/required-features.h"
16-
#include "../include/asm/disabled-features.h"
1715
#include "../include/asm/cpufeatures.h"
1816
#include "../include/asm/vmxfeatures.h"
1917
#include "../kernel/cpu/capflags.c"
@@ -23,6 +21,7 @@ int main(void)
2321
int i, j;
2422
const char *str;
2523

24+
printf("#include <asm/cpufeaturemasks.h>\n\n");
2625
printf("static const char x86_cap_strs[] =\n");
2726

2827
for (i = 0; i < NCAPINTS; i++) {

arch/x86/include/asm/Kbuild

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ generated-y += syscalls_x32.h
88
generated-y += unistd_32_ia32.h
99
generated-y += unistd_64_x32.h
1010
generated-y += xen-hypercalls.h
11+
generated-y += cpufeaturemasks.h
1112

1213
generic-y += early_ioremap.h
1314
generic-y += fprobe.h

arch/x86/include/asm/cpufeature.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <asm/asm.h>
1010
#include <linux/bitops.h>
1111
#include <asm/alternative.h>
12+
#include <asm/cpufeaturemasks.h>
1213

1314
enum cpuid_leafs
1415
{

arch/x86/include/asm/cpufeatures.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,6 @@
22
#ifndef _ASM_X86_CPUFEATURES_H
33
#define _ASM_X86_CPUFEATURES_H
44

5-
#ifndef _ASM_X86_REQUIRED_FEATURES_H
6-
#include <asm/required-features.h>
7-
#endif
8-
9-
#ifndef _ASM_X86_DISABLED_FEATURES_H
10-
#include <asm/disabled-features.h>
11-
#endif
12-
135
/*
146
* Defines x86 CPU feature bits
157
*/

arch/x86/kernel/verify_cpu.S

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,12 @@
2929
*/
3030

3131
#include <asm/cpufeatures.h>
32+
#include <asm/cpufeaturemasks.h>
3233
#include <asm/msr-index.h>
3334

35+
#define SSE_MASK \
36+
(REQUIRED_MASK0 & ((1<<(X86_FEATURE_XMM & 31)) | (1<<(X86_FEATURE_XMM2 & 31))))
37+
3438
SYM_FUNC_START_LOCAL(verify_cpu)
3539
pushf # Save caller passed flags
3640
push $0 # Kill any dangerous flags

arch/x86/tools/cpufeaturemasks.awk

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#!/usr/bin/awk
2+
#
3+
# Convert cpufeatures.h to a list of compile-time masks
4+
# Note: this blithely assumes that each word has at least one
5+
# feature defined in it; if not, something else is wrong!
6+
#
7+
8+
BEGIN {
9+
printf "#ifndef _ASM_X86_CPUFEATUREMASKS_H\n";
10+
printf "#define _ASM_X86_CPUFEATUREMASKS_H\n\n";
11+
12+
file = 0
13+
}
14+
15+
FNR == 1 {
16+
++file;
17+
18+
# arch/x86/include/asm/cpufeatures.h
19+
if (file == 1)
20+
FS = "[ \t()*+]+";
21+
22+
# .config
23+
if (file == 2)
24+
FS = "=";
25+
}
26+
27+
# Create a dictionary of sorts, containing all defined feature bits
28+
file == 1 && $1 ~ /^#define$/ && $2 ~ /^X86_FEATURE_/ {
29+
nfeat = $3 * $4 + $5;
30+
feat = $2;
31+
sub(/^X86_FEATURE_/, "", feat);
32+
feats[nfeat] = feat;
33+
}
34+
file == 1 && $1 ~ /^#define$/ && $2 == "NCAPINTS" {
35+
ncapints = int($3);
36+
}
37+
38+
# Create a dictionary featstat[REQUIRED|DISABLED, FEATURE_NAME] = on | off
39+
file == 2 && $1 ~ /^CONFIG_X86_(REQUIRED|DISABLED)_FEATURE_/ {
40+
on = ($2 == "y");
41+
if (split($1, fs, "CONFIG_X86_|_FEATURE_") == 3)
42+
featstat[fs[2], fs[3]] = on;
43+
}
44+
45+
END {
46+
sets[1] = "REQUIRED";
47+
sets[2] = "DISABLED";
48+
49+
for (ns in sets) {
50+
s = sets[ns];
51+
52+
printf "/*\n";
53+
printf " * %s features:\n", s;
54+
printf " *\n";
55+
fstr = "";
56+
for (i = 0; i < ncapints; i++) {
57+
mask = 0;
58+
for (j = 0; j < 32; j++) {
59+
feat = feats[i*32 + j];
60+
if (featstat[s, feat]) {
61+
nfstr = fstr " " feat;
62+
if (length(nfstr) > 72) {
63+
printf " * %s\n", fstr;
64+
nfstr = " " feat;
65+
}
66+
fstr = nfstr;
67+
mask += (2 ^ j);
68+
}
69+
}
70+
masks[i] = mask;
71+
}
72+
printf " * %s\n */\n", fstr;
73+
74+
for (i = 0; i < ncapints; i++)
75+
printf "#define %s_MASK%d\t0x%08xU\n", s, i, masks[i];
76+
77+
printf "#define %s_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != %d)\n\n", s, ncapints;
78+
}
79+
80+
printf "#endif /* _ASM_X86_CPUFEATUREMASKS_H */\n";
81+
}

0 commit comments

Comments
 (0)