* [PATCH v3 0/4] x86/cpufeatures: Automatically generate required and disabled feature masks
@ 2024-06-22 17:14 Xin Li (Intel)
2024-06-22 17:14 ` [PATCH v3 1/4] x86/cpufeatures: Add {required,disabled} feature configs Xin Li (Intel)
` (4 more replies)
0 siblings, 5 replies; 16+ messages in thread
From: Xin Li (Intel) @ 2024-06-22 17:14 UTC (permalink / raw)
To: linux-kernel, linux-perf-users
Cc: tglx, mingo, bp, dave.hansen, x86, hpa, will, peterz, akpm, acme,
namhyung, brgerst
The x86 build process first generates required and disabled feature
masks based on current build config, and then uses these generated
masks to compile the source code. When a CPU feature is not enabled
in a build config, e.g., when CONFIG_X86_FRED=n, its feature disable
flag, i.e., DISABLE_FRED, needs to be properly defined and added to
a specific disabled CPU features mask in <asm/disabled-features.h>,
as the following patch does:
https://lore.kernel.org/all/20231205105030.8698-8-xin3.li@intel.com/.
As a result, the FRED feature bit is surely cleared in the generated
kernel binary when CONFIG_X86_FRED=n.
Recently there is another case to repeat the same exercise for the
AMD SEV-SNP CPU feature:
https://lore.kernel.org/all/20240126041126.1927228-2-michael.roth@amd.com/.
https://lore.kernel.org/all/20240126041126.1927228-23-michael.roth@amd.com/.
It was one thing when there were four of CPU feature masks, but with
over 20 it is going to cause mistakes, e.g.,
https://lore.kernel.org/lkml/aaed79d5-d683-d1bc-7ba1-b33c8d6db618@suse.com/.
We want to eliminate the stupidly repeated exercise to manually assign
features to CPU feature words through introducing an AWK script to
automatically generate a header with required and disabled CPU feature
masks based on current build config, and this patch set does that.
Changes since v2:
* Remove AWK code that generates extra debugging comments (Brian Gerst).
* Move SSE_MASK to verify_cpu.S, the only place it is used (Brian Gerst).
* Add a patch to generate macros {REQUIRED|DISABLED}_MASK_BIT_SET in the
new AWK script (Brian Gerst).
Changes since v1:
* Keep the X86_{REQUIRED,DISABLED}_FEATURE_ prefixes solely in
arch/x86/Kconfig.cpufeatures (Borislav Petkov).
* Explain how config option names X86_{REQUIRED,DISABLED}_FEATURE_<name>
are formed (Borislav Petkov).
* Remove code generating unused macros {REQUIRED,DISABLED}_FEATURE(x)
to tell if a CPU feature, e.g., X86_FEATURE_FRED, is a required or
disabled feature for this particular compile-time configuration.
H. Peter Anvin (Intel) (2):
x86/cpufeatures: Add {required,disabled} feature configs
x86/cpufeatures: Generate a feature mask header based on build config
Xin Li (Intel) (2):
x86/cpufeatures: Remove {disabled,required}-features.h
x86/cpufeatures: Use AWK to generate {REQUIRED|DISABLED}_MASK_BIT_SET
arch/x86/Kconfig | 4 +-
arch/x86/Kconfig.cpu | 12 +-
arch/x86/Kconfig.cpufeatures | 197 ++++++++++++++++++
arch/x86/Makefile | 17 +-
arch/x86/boot/cpucheck.c | 3 +-
arch/x86/boot/cpuflags.c | 1 -
arch/x86/boot/mkcpustr.c | 3 +-
arch/x86/include/asm/Kbuild | 1 +
arch/x86/include/asm/asm-prototypes.h | 2 +-
arch/x86/include/asm/atomic64_32.h | 2 +-
arch/x86/include/asm/bitops.h | 4 +-
arch/x86/include/asm/cmpxchg_32.h | 2 +-
arch/x86/include/asm/cpufeature.h | 70 +------
arch/x86/include/asm/cpufeatures.h | 8 -
arch/x86/include/asm/disabled-features.h | 161 --------------
arch/x86/include/asm/required-features.h | 105 ----------
arch/x86/kernel/verify_cpu.S | 4 +
arch/x86/lib/Makefile | 2 +-
arch/x86/lib/cmpxchg8b_emu.S | 2 +-
arch/x86/tools/featuremasks.awk | 94 +++++++++
lib/atomic64_test.c | 2 +-
tools/arch/x86/include/asm/cpufeatures.h | 8 -
.../arch/x86/include/asm/disabled-features.h | 161 --------------
.../arch/x86/include/asm/required-features.h | 105 ----------
tools/perf/check-headers.sh | 2 -
25 files changed, 327 insertions(+), 645 deletions(-)
create mode 100644 arch/x86/Kconfig.cpufeatures
delete mode 100644 arch/x86/include/asm/disabled-features.h
delete mode 100644 arch/x86/include/asm/required-features.h
create mode 100755 arch/x86/tools/featuremasks.awk
delete mode 100644 tools/arch/x86/include/asm/disabled-features.h
delete mode 100644 tools/arch/x86/include/asm/required-features.h
base-commit: aedd5b6d65f7db9af616404985fc8361373690be
--
2.45.2
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v3 1/4] x86/cpufeatures: Add {required,disabled} feature configs
2024-06-22 17:14 [PATCH v3 0/4] x86/cpufeatures: Automatically generate required and disabled feature masks Xin Li (Intel)
@ 2024-06-22 17:14 ` Xin Li (Intel)
2024-06-22 17:14 ` [PATCH v3 2/4] x86/cpufeatures: Generate a feature mask header based on build config Xin Li (Intel)
` (3 subsequent siblings)
4 siblings, 0 replies; 16+ messages in thread
From: Xin Li (Intel) @ 2024-06-22 17:14 UTC (permalink / raw)
To: linux-kernel, linux-perf-users
Cc: tglx, mingo, bp, dave.hansen, x86, hpa, will, peterz, akpm, acme,
namhyung, brgerst
From: "H. Peter Anvin (Intel)" <hpa@zytor.com>
Required and disabled feature masks completely rely on build configs,
i.e., once a build config is fixed, so are the feature masks. To prepare
for auto-generating a header with required and disabled feature masks
based on a build config, add feature Kconfig items:
- X86_REQUIRED_FEATURE_x
- X86_DISABLED_FEATURE_x
each of which may be set to "y" if and only if its preconditions from
current build config are met.
X86_CMPXCHG64 and X86_CMOV are required features, thus rename them to
X86_REQUIRED_FEATURE_CX8 and X86_REQUIRED_FEATURE_CMOV.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Signed-off-by: Xin Li (Intel) <xin@zytor.com>
---
Changes since v1:
* Keep the X86_{REQUIRED,DISABLED}_FEATURE_ prefixes solely in
arch/x86/Kconfig.cpufeatures (Borislav Petkov).
* Explain how config option names X86_{REQUIRED,DISABLED}_FEATURE_<name>
are formed (Borislav Petkov).
---
arch/x86/Kconfig | 4 +-
arch/x86/Kconfig.cpu | 12 +-
arch/x86/Kconfig.cpufeatures | 197 ++++++++++++++++++
arch/x86/include/asm/asm-prototypes.h | 2 +-
arch/x86/include/asm/atomic64_32.h | 2 +-
arch/x86/include/asm/bitops.h | 4 +-
arch/x86/include/asm/cmpxchg_32.h | 2 +-
arch/x86/include/asm/required-features.h | 4 +-
arch/x86/lib/Makefile | 2 +-
arch/x86/lib/cmpxchg8b_emu.S | 2 +-
lib/atomic64_test.c | 2 +-
.../arch/x86/include/asm/required-features.h | 4 +-
12 files changed, 213 insertions(+), 24 deletions(-)
create mode 100644 arch/x86/Kconfig.cpufeatures
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index e30ea4129d2c..087f36305913 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -123,7 +123,7 @@ config X86
select ARCH_SUPPORTS_LTO_CLANG
select ARCH_SUPPORTS_LTO_CLANG_THIN
select ARCH_USE_BUILTIN_BSWAP
- select ARCH_USE_CMPXCHG_LOCKREF if X86_CMPXCHG64
+ select ARCH_USE_CMPXCHG_LOCKREF if X86_REQUIRED_FEATURE_CX8
select ARCH_USE_MEMTEST
select ARCH_USE_QUEUED_RWLOCKS
select ARCH_USE_QUEUED_SPINLOCKS
@@ -3091,4 +3091,6 @@ config HAVE_ATOMIC_IOMAP
source "arch/x86/kvm/Kconfig"
+source "arch/x86/Kconfig.cpufeatures"
+
source "arch/x86/Kconfig.assembler"
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 2a7279d80460..c439f9c61101 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -366,21 +366,11 @@ config X86_HAVE_PAE
def_bool y
depends on MCRUSOE || MEFFICEON || MCYRIXIII || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC7 || MCORE2 || MATOM || X86_64
-config X86_CMPXCHG64
- def_bool y
- depends on X86_HAVE_PAE || M586TSC || M586MMX || MK6 || MK7
-
-# this should be set for all -march=.. options where the compiler
-# generates cmov.
-config X86_CMOV
- def_bool y
- depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX)
-
config X86_MINIMUM_CPU_FAMILY
int
default "64" if X86_64
default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCORE2 || MK7 || MK8)
- default "5" if X86_32 && X86_CMPXCHG64
+ default "5" if X86_32 && X86_REQUIRED_FEATURE_CX8
default "4"
config X86_DEBUGCTLMSR
diff --git a/arch/x86/Kconfig.cpufeatures b/arch/x86/Kconfig.cpufeatures
new file mode 100644
index 000000000000..5ed24e45df87
--- /dev/null
+++ b/arch/x86/Kconfig.cpufeatures
@@ -0,0 +1,197 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# x86 feature bits (see arch/x86/include/asm/cpufeatures.h) that are
+# either REQUIRED to be enabled, or DISABLED (always ignored) for this
+# particular compile-time configuration. The tests for these features
+# are turned into compile-time constants via the generated
+# <asm/featuremasks.h>.
+#
+# The naming of these variables *must* match asm/cpufeatures.h, e.g.,
+# X86_FEATURE_ALWAYS <==> X86_REQUIRED_FEATURE_ALWAYS
+# X86_FEATURE_FRED <==> X86_DISABLED_FEATURE_FRED
+#
+# And these REQUIRED and DISABLED config options are manipulated in an
+# AWK script as the following example:
+#
+# +----------------------+
+# | X86_FRED = y ? |
+# +----------------------+
+# / \
+# Y / \ N
+# +-------------------------------------+ +-------------------------------+
+# | X86_DISABLED_FEATURE_FRED undefined | | X86_DISABLED_FEATURE_FRED = y |
+# +-------------------------------------+ +-------------------------------+
+# |
+# |
+# +-------------------------------------------+ |
+# | X86_FEATURE_FRED: feature word 12, bit 17 | ---->|
+# +-------------------------------------------+ |
+# |
+# |
+# +-------------------------------+
+# | set bit 17 of DISABLED_MASK12 |
+# +-------------------------------+
+#
+
+config X86_REQUIRED_FEATURE_ALWAYS
+ def_bool y
+
+config X86_REQUIRED_FEATURE_NOPL
+ def_bool y
+ depends on X86_64 || X86_P6_NOP
+
+config X86_REQUIRED_FEATURE_CX8
+ def_bool y
+ depends on X86_HAVE_PAE || M586TSC || M586MMX || MK6 || MK7
+
+# this should be set for all -march=.. options where the compiler
+# generates cmov.
+config X86_REQUIRED_FEATURE_CMOV
+ def_bool y
+ depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX)
+
+# this should be set for all -march= options where the compiler
+# generates movbe.
+config X86_REQUIRED_FEATURE_MOVBE
+ def_bool y
+ depends on MATOM
+
+config X86_REQUIRED_FEATURE_CPUID
+ def_bool y
+ depends on X86_64
+
+config X86_REQUIRED_FEATURE_UP
+ def_bool y
+ depends on !SMP
+
+config X86_REQUIRED_FEATURE_FPU
+ def_bool y
+ depends on !MATH_EMULATION
+
+config X86_REQUIRED_FEATURE_PAE
+ def_bool y
+ depends on X86_64 || X86_PAE
+
+config X86_REQUIRED_FEATURE_PSE
+ def_bool y
+ depends on X86_64 && !PARAVIRT_XXL
+
+config X86_REQUIRED_FEATURE_PGE
+ def_bool y
+ depends on X86_64 && !PARAVIRT_XXL
+
+config X86_REQUIRED_FEATURE_MSR
+ def_bool y
+ depends on X86_64
+
+config X86_REQUIRED_FEATURE_FXSR
+ def_bool y
+ depends on X86_64
+
+config X86_REQUIRED_FEATURE_XMM
+ def_bool y
+ depends on X86_64
+
+config X86_REQUIRED_FEATURE_XMM2
+ def_bool y
+ depends on X86_64
+
+config X86_REQUIRED_FEATURE_LM
+ def_bool y
+ depends on X86_64
+
+config X86_DISABLED_FEATURE_UMIP
+ def_bool y
+ depends on !X86_UMIP
+
+config X86_DISABLED_FEATURE_VME
+ def_bool y
+ depends on X86_64
+
+config X86_DISABLED_FEATURE_K6_MTRR
+ def_bool y
+ depends on X86_64
+
+config X86_DISABLED_FEATURE_CYRIX_ARR
+ def_bool y
+ depends on X86_64
+
+config X86_DISABLED_FEATURE_CENTAUR_MCR
+ def_bool y
+ depends on X86_64
+
+config X86_DISABLED_FEATURE_PCID
+ def_bool y
+ depends on !X86_64
+
+config X86_DISABLED_FEATURE_PKU
+ def_bool y
+ depends on !X86_INTEL_MEMORY_PROTECTION_KEYS
+
+config X86_DISABLED_FEATURE_OSPKE
+ def_bool y
+ depends on !X86_INTEL_MEMORY_PROTECTION_KEYS
+
+config X86_DISABLED_FEATURE_LA57
+ def_bool y
+ depends on !X86_5LEVEL
+
+config X86_DISABLED_FEATURE_PTI
+ def_bool y
+ depends on !MITIGATION_PAGE_TABLE_ISOLATION
+
+config X86_DISABLED_FEATURE_RETPOLINE
+ def_bool y
+ depends on !MITIGATION_RETPOLINE
+
+config X86_DISABLED_FEATURE_RETPOLINE_LFENCE
+ def_bool y
+ depends on !MITIGATION_RETPOLINE
+
+config X86_DISABLED_FEATURE_RETHUNK
+ def_bool y
+ depends on !MITIGATION_RETHUNK
+
+config X86_DISABLED_FEATURE_UNRET
+ def_bool y
+ depends on !MITIGATION_UNRET_ENTRY
+
+config X86_DISABLED_FEATURE_CALL_DEPTH
+ def_bool y
+ depends on !MITIGATION_CALL_DEPTH_TRACKING
+
+config X86_DISABLED_FEATURE_LAM
+ def_bool y
+ depends on !ADDRESS_MASKING
+
+config X86_DISABLED_FEATURE_ENQCMD
+ def_bool y
+ depends on !INTEL_IOMMU_SVM
+
+config X86_DISABLED_FEATURE_SGX
+ def_bool y
+ depends on !X86_SGX
+
+config X86_DISABLED_FEATURE_XENPV
+ def_bool y
+ depends on !XEN_PV
+
+config X86_DISABLED_FEATURE_TDX_GUEST
+ def_bool y
+ depends on !INTEL_TDX_GUEST
+
+config X86_DISABLED_FEATURE_USER_SHSTK
+ def_bool y
+ depends on !X86_USER_SHADOW_STACK
+
+config X86_DISABLED_FEATURE_IBT
+ def_bool y
+ depends on !X86_KERNEL_IBT
+
+config X86_DISABLED_FEATURE_FRED
+ def_bool y
+ depends on !X86_FRED
+
+config X86_DISABLED_FEATURE_SEV_SNP
+ def_bool y
+ depends on !KVM_AMD_SEV
diff --git a/arch/x86/include/asm/asm-prototypes.h b/arch/x86/include/asm/asm-prototypes.h
index 25466c4d2134..7fbb52143b13 100644
--- a/arch/x86/include/asm/asm-prototypes.h
+++ b/arch/x86/include/asm/asm-prototypes.h
@@ -16,7 +16,7 @@
#include <asm/gsseg.h>
#include <asm/nospec-branch.h>
-#ifndef CONFIG_X86_CMPXCHG64
+#ifndef CONFIG_X86_REQUIRED_FEATURE_CX8
extern void cmpxchg8b_emu(void);
#endif
diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h
index 8db2ec4d6cda..f3438f8709bb 100644
--- a/arch/x86/include/asm/atomic64_32.h
+++ b/arch/x86/include/asm/atomic64_32.h
@@ -48,7 +48,7 @@ static __always_inline s64 arch_atomic64_read_nonatomic(const atomic64_t *v)
ATOMIC64_EXPORT(atomic64_##sym)
#endif
-#ifdef CONFIG_X86_CMPXCHG64
+#ifdef CONFIG_X86_REQUIRED_FEATURE_CX8
#define __alternative_atomic64(f, g, out, in...) \
asm volatile("call %c[func]" \
: out : [func] "i" (atomic64_##g##_cx8), ## in)
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h
index b96d45944c59..ff6444311704 100644
--- a/arch/x86/include/asm/bitops.h
+++ b/arch/x86/include/asm/bitops.h
@@ -321,7 +321,7 @@ static __always_inline int variable_ffs(int x)
asm("bsfl %1,%0"
: "=r" (r)
: ASM_INPUT_RM (x), "0" (-1));
-#elif defined(CONFIG_X86_CMOV)
+#elif defined(CONFIG_X86_REQUIRED_FEATURE_CMOV)
asm("bsfl %1,%0\n\t"
"cmovzl %2,%0"
: "=&r" (r) : "rm" (x), "r" (-1));
@@ -378,7 +378,7 @@ static __always_inline int fls(unsigned int x)
asm("bsrl %1,%0"
: "=r" (r)
: ASM_INPUT_RM (x), "0" (-1));
-#elif defined(CONFIG_X86_CMOV)
+#elif defined(CONFIG_X86_REQUIRED_FEATURE_CMOV)
asm("bsrl %1,%0\n\t"
"cmovzl %2,%0"
: "=&r" (r) : "rm" (x), "rm" (-1));
diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h
index ed2797f132ce..2d875a8dbbb2 100644
--- a/arch/x86/include/asm/cmpxchg_32.h
+++ b/arch/x86/include/asm/cmpxchg_32.h
@@ -69,7 +69,7 @@ static __always_inline bool __try_cmpxchg64_local(volatile u64 *ptr, u64 *oldp,
return __arch_try_cmpxchg64(ptr, oldp, new,);
}
-#ifdef CONFIG_X86_CMPXCHG64
+#ifdef CONFIG_X86_REQUIRED_FEATURE_CX8
#define arch_cmpxchg64 __cmpxchg64
diff --git a/arch/x86/include/asm/required-features.h b/arch/x86/include/asm/required-features.h
index e9187ddd3d1f..cef8104c103c 100644
--- a/arch/x86/include/asm/required-features.h
+++ b/arch/x86/include/asm/required-features.h
@@ -23,13 +23,13 @@
# define NEED_PAE 0
#endif
-#ifdef CONFIG_X86_CMPXCHG64
+#ifdef CONFIG_X86_REQUIRED_FEATURE_CX8
# define NEED_CX8 (1<<(X86_FEATURE_CX8 & 31))
#else
# define NEED_CX8 0
#endif
-#if defined(CONFIG_X86_CMOV) || defined(CONFIG_X86_64)
+#if defined(CONFIG_X86_REQUIRED_FEATURE_CMOV) || defined(CONFIG_X86_64)
# define NEED_CMOV (1<<(X86_FEATURE_CMOV & 31))
#else
# define NEED_CMOV 0
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 98583a9dbab3..9d4e96157e81 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -49,7 +49,7 @@ ifeq ($(CONFIG_X86_32),y)
lib-y += string_32.o
lib-y += memmove_32.o
lib-y += cmpxchg8b_emu.o
-ifneq ($(CONFIG_X86_CMPXCHG64),y)
+ifneq ($(CONFIG_X86_REQUIRED_FEATURE_CX8),y)
lib-y += atomic64_386_32.o
endif
else
diff --git a/arch/x86/lib/cmpxchg8b_emu.S b/arch/x86/lib/cmpxchg8b_emu.S
index 1c96be769adc..4bc06bd1aee1 100644
--- a/arch/x86/lib/cmpxchg8b_emu.S
+++ b/arch/x86/lib/cmpxchg8b_emu.S
@@ -7,7 +7,7 @@
.text
-#ifndef CONFIG_X86_CMPXCHG64
+#ifndef CONFIG_X86_REQUIRED_FEATURE_CX8
/*
* Emulate 'cmpxchg8b (%esi)' on UP
diff --git a/lib/atomic64_test.c b/lib/atomic64_test.c
index d9d170238165..e68bde45b962 100644
--- a/lib/atomic64_test.c
+++ b/lib/atomic64_test.c
@@ -254,7 +254,7 @@ static __init int test_atomics_init(void)
pr_info("passed for %s platform %s CX8 and %s SSE\n",
#ifdef CONFIG_X86_64
"x86-64",
-#elif defined(CONFIG_X86_CMPXCHG64)
+#elif defined(CONFIG_X86_REQUIRED_FEATURE_CX8)
"i586+",
#else
"i386+",
diff --git a/tools/arch/x86/include/asm/required-features.h b/tools/arch/x86/include/asm/required-features.h
index e9187ddd3d1f..cef8104c103c 100644
--- a/tools/arch/x86/include/asm/required-features.h
+++ b/tools/arch/x86/include/asm/required-features.h
@@ -23,13 +23,13 @@
# define NEED_PAE 0
#endif
-#ifdef CONFIG_X86_CMPXCHG64
+#ifdef CONFIG_X86_REQUIRED_FEATURE_CX8
# define NEED_CX8 (1<<(X86_FEATURE_CX8 & 31))
#else
# define NEED_CX8 0
#endif
-#if defined(CONFIG_X86_CMOV) || defined(CONFIG_X86_64)
+#if defined(CONFIG_X86_REQUIRED_FEATURE_CMOV) || defined(CONFIG_X86_64)
# define NEED_CMOV (1<<(X86_FEATURE_CMOV & 31))
#else
# define NEED_CMOV 0
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 2/4] x86/cpufeatures: Generate a feature mask header based on build config
2024-06-22 17:14 [PATCH v3 0/4] x86/cpufeatures: Automatically generate required and disabled feature masks Xin Li (Intel)
2024-06-22 17:14 ` [PATCH v3 1/4] x86/cpufeatures: Add {required,disabled} feature configs Xin Li (Intel)
@ 2024-06-22 17:14 ` Xin Li (Intel)
2024-06-26 11:36 ` Nikolay Borisov
2024-06-22 17:14 ` [PATCH v3 3/4] x86/cpufeatures: Remove {disabled,required}-features.h Xin Li (Intel)
` (2 subsequent siblings)
4 siblings, 1 reply; 16+ messages in thread
From: Xin Li (Intel) @ 2024-06-22 17:14 UTC (permalink / raw)
To: linux-kernel, linux-perf-users
Cc: tglx, mingo, bp, dave.hansen, x86, hpa, will, peterz, akpm, acme,
namhyung, brgerst
From: "H. Peter Anvin (Intel)" <hpa@zytor.com>
Introduce an AWK script to auto-generate a header with required and
disabled feature masks based on <asm/cpufeatures.h> and 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 ]
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Signed-off-by: Xin Li (Intel) <xin@zytor.com>
---
Changes since v2:
* Remove AWK code that generates extra debugging comments (Brian Gerst).
* Move SSE_MASK to verify_cpu.S, the only place it is used (Brian Gerst).
Change since v1:
* Remove code generating unused macros {REQUIRED,DISABLED}_FEATURE(x)
to tell if a CPU feature, e.g., X86_FEATURE_FRED, is a required or
disabled feature for this particular compile-time configuration.
---
arch/x86/Makefile | 17 +++++-
arch/x86/boot/cpucheck.c | 3 +-
arch/x86/boot/cpuflags.c | 1 -
arch/x86/boot/mkcpustr.c | 3 +-
arch/x86/include/asm/Kbuild | 1 +
arch/x86/include/asm/cpufeature.h | 1 +
arch/x86/include/asm/cpufeatures.h | 8 ---
arch/x86/kernel/verify_cpu.S | 4 ++
arch/x86/tools/featuremasks.awk | 84 ++++++++++++++++++++++++++++++
9 files changed, 108 insertions(+), 14 deletions(-)
create mode 100755 arch/x86/tools/featuremasks.awk
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 801fd85c3ef6..211c0820b150 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -261,9 +261,22 @@ archscripts: scripts_basic
$(Q)$(MAKE) $(build)=arch/x86/tools relocs
###
-# Syscall table generation
+# Feature masks header and syscall table generation
-archheaders:
+out := arch/x86/include/generated/asm
+featuremasks_hdr := featuremasks.h
+featuremasks_awk := $(srctree)/arch/x86/tools/featuremasks.awk
+cpufeatures_hdr := $(srctree)/arch/x86/include/asm/cpufeatures.h
+quiet_cmd_gen_featuremasks = GEN $@
+ cmd_gen_featuremasks = $(AWK) -f $(featuremasks_awk) $(cpufeatures_hdr) $(KCONFIG_CONFIG) > $@
+
+$(out)/$(featuremasks_hdr): $(featuremasks_awk) $(cpufeatures_hdr) $(KCONFIG_CONFIG) FORCE
+ $(shell mkdir -p $(out))
+ $(call if_changed,gen_featuremasks)
+
+targets += $(out)/$(featuremasks_hdr)
+
+archheaders: $(out)/$(featuremasks_hdr)
$(Q)$(MAKE) $(build)=arch/x86/entry/syscalls all
###
diff --git a/arch/x86/boot/cpucheck.c b/arch/x86/boot/cpucheck.c
index 0aae4d4ed615..8d03a741d1b2 100644
--- a/arch/x86/boot/cpucheck.c
+++ b/arch/x86/boot/cpucheck.c
@@ -22,10 +22,11 @@
# include "boot.h"
#endif
#include <linux/types.h>
+#include <asm/featuremasks.h>
#include <asm/intel-family.h>
#include <asm/processor-flags.h>
-#include <asm/required-features.h>
#include <asm/msr-index.h>
+
#include "string.h"
#include "msr.h"
diff --git a/arch/x86/boot/cpuflags.c b/arch/x86/boot/cpuflags.c
index d75237ba7ce9..0cabdacb2a2f 100644
--- a/arch/x86/boot/cpuflags.c
+++ b/arch/x86/boot/cpuflags.c
@@ -3,7 +3,6 @@
#include "bitops.h"
#include <asm/processor-flags.h>
-#include <asm/required-features.h>
#include <asm/msr-index.h>
#include "cpuflags.h"
diff --git a/arch/x86/boot/mkcpustr.c b/arch/x86/boot/mkcpustr.c
index da0ccc5de538..b90110109675 100644
--- a/arch/x86/boot/mkcpustr.c
+++ b/arch/x86/boot/mkcpustr.c
@@ -12,8 +12,6 @@
#include <stdio.h>
-#include "../include/asm/required-features.h"
-#include "../include/asm/disabled-features.h"
#include "../include/asm/cpufeatures.h"
#include "../include/asm/vmxfeatures.h"
#include "../kernel/cpu/capflags.c"
@@ -23,6 +21,7 @@ int main(void)
int i, j;
const char *str;
+ printf("#include <asm/featuremasks.h>\n\n");
printf("static const char x86_cap_strs[] =\n");
for (i = 0; i < NCAPINTS; i++) {
diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild
index a192bdea69e2..29c3481f40fc 100644
--- a/arch/x86/include/asm/Kbuild
+++ b/arch/x86/include/asm/Kbuild
@@ -8,6 +8,7 @@ generated-y += syscalls_x32.h
generated-y += unistd_32_ia32.h
generated-y += unistd_64_x32.h
generated-y += xen-hypercalls.h
+generated-y += featuremasks.h
generic-y += early_ioremap.h
generic-y += mcs_spinlock.h
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 0b9611da6c53..8332f596ba3c 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -9,6 +9,7 @@
#include <asm/asm.h>
#include <linux/bitops.h>
#include <asm/alternative.h>
+#include <asm/featuremasks.h>
enum cpuid_leafs
{
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 6007462e03d6..4a297a8a376c 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -2,14 +2,6 @@
#ifndef _ASM_X86_CPUFEATURES_H
#define _ASM_X86_CPUFEATURES_H
-#ifndef _ASM_X86_REQUIRED_FEATURES_H
-#include <asm/required-features.h>
-#endif
-
-#ifndef _ASM_X86_DISABLED_FEATURES_H
-#include <asm/disabled-features.h>
-#endif
-
/*
* Defines x86 CPU feature bits
*/
diff --git a/arch/x86/kernel/verify_cpu.S b/arch/x86/kernel/verify_cpu.S
index 1258a5872d12..a23a65d5d177 100644
--- a/arch/x86/kernel/verify_cpu.S
+++ b/arch/x86/kernel/verify_cpu.S
@@ -29,8 +29,12 @@
*/
#include <asm/cpufeatures.h>
+#include <asm/featuremasks.h>
#include <asm/msr-index.h>
+#define SSE_MASK \
+ (REQUIRED_MASK0 & ((1<<(X86_FEATURE_XMM & 31)) | (1<<(X86_FEATURE_XMM2 & 31))))
+
SYM_FUNC_START_LOCAL(verify_cpu)
pushf # Save caller passed flags
push $0 # Kill any dangerous flags
diff --git a/arch/x86/tools/featuremasks.awk b/arch/x86/tools/featuremasks.awk
new file mode 100755
index 000000000000..989b021e73d3
--- /dev/null
+++ b/arch/x86/tools/featuremasks.awk
@@ -0,0 +1,84 @@
+#!/usr/bin/awk
+#
+# Convert cpufeatures.h to a list of compile-time masks
+# Note: this blithly assumes that each word has at least one
+# feature defined in it; if not, something else is wrong!
+#
+
+BEGIN {
+ printf "#ifndef _ASM_X86_FEATUREMASKS_H\n";
+ printf "#define _ASM_X86_FEATUREMASKS_H\n\n";
+
+ file = 0
+}
+
+BEGINFILE {
+ switch (++file) {
+ case 1: # cpufeatures.h
+ FPAT = "#[ \t]*[a-z]+|[A-Za-z0-9_]+|[^ \t]";
+ break;
+ case 2: # .config
+ FPAT = "CONFIG_[A-Z0-9_]+|is not set|[yn]";
+ break;
+ }
+}
+
+file == 1 && $1 ~ /^#[ \t]*define$/ && $2 ~ /^X86_FEATURE_/ &&
+$3 == "(" && $5 == "*" && $7 == "+" && $9 == ")" {
+ nfeat = $4 * $6 + $8;
+ feat = $2;
+ sub(/^X86_FEATURE_/, "", feat);
+ feats[nfeat] = feat;
+}
+file == 1 && $1 ~ /^#[ \t]*define$/ && $2 == "NCAPINTS" {
+ ncapints = strtonum($3);
+}
+
+file == 2 && $1 ~ /^CONFIG_X86_[A-Z]*_FEATURE_/ {
+ on = ($2 == "y");
+ if (split($1, fs, "CONFIG_X86_|_FEATURE_") == 3)
+ featstat[fs[2], fs[3]] = on;
+}
+
+END {
+ sets[1] = "REQUIRED";
+ sets[2] = "DISABLED";
+
+ for (ns in sets) {
+ s = sets[ns];
+
+ printf "/*\n";
+ printf " * %s features:\n", s;
+ printf " *\n";
+ fstr = "";
+ for (i = 0; i < ncapints; i++) {
+ mask = 0;
+ for (j = 0; j < 32; j++) {
+ nfeat = i*32 + j;
+ feat = feats[nfeat];
+ if (feat) {
+ st = !!featstat[s, feat];
+ if (st) {
+ nfstr = fstr " " feat;
+ if (length(nfstr) > 72) {
+ printf " * %s\n", fstr;
+ nfstr = " " feat;
+ }
+ fstr = nfstr;
+ }
+ mask += st * (2 ^ j);
+ }
+ }
+ masks[i] = mask;
+ }
+ printf " * %s\n */\n\n", fstr;
+
+ for (i = 0; i < ncapints; i++) {
+ printf "#define %s_MASK%d\t0x%08x\n", s, i, masks[i];
+ }
+
+ printf "#define %s_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != %d)\n\n", s, ncapints;
+ }
+
+ printf "#endif /* _ASM_X86_FEATUREMASKS_H */\n";
+}
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 3/4] x86/cpufeatures: Remove {disabled,required}-features.h
2024-06-22 17:14 [PATCH v3 0/4] x86/cpufeatures: Automatically generate required and disabled feature masks Xin Li (Intel)
2024-06-22 17:14 ` [PATCH v3 1/4] x86/cpufeatures: Add {required,disabled} feature configs Xin Li (Intel)
2024-06-22 17:14 ` [PATCH v3 2/4] x86/cpufeatures: Generate a feature mask header based on build config Xin Li (Intel)
@ 2024-06-22 17:14 ` Xin Li (Intel)
2024-06-22 17:14 ` [PATCH v3 4/4] x86/cpufeatures: Use AWK to generate {REQUIRED|DISABLED}_MASK_BIT_SET Xin Li (Intel)
2024-06-22 17:31 ` [PATCH v3 0/4] x86/cpufeatures: Automatically generate required and disabled feature masks Xin Li
4 siblings, 0 replies; 16+ messages in thread
From: Xin Li (Intel) @ 2024-06-22 17:14 UTC (permalink / raw)
To: linux-kernel, linux-perf-users
Cc: tglx, mingo, bp, dave.hansen, x86, hpa, will, peterz, akpm, acme,
namhyung, brgerst
The functionalities of {disabled,required}-features.h are replaced
with the auto-generated header cpufeature_masks.h. Thus they are no
longer needed. So delete them.
None of the macros defined in {disabled,required}-features.h is used
in tools, delete them too.
Signed-off-by: Xin Li (Intel) <xin@zytor.com>
---
arch/x86/include/asm/disabled-features.h | 161 ------------------
arch/x86/include/asm/required-features.h | 105 ------------
tools/arch/x86/include/asm/cpufeatures.h | 8 -
.../arch/x86/include/asm/disabled-features.h | 161 ------------------
.../arch/x86/include/asm/required-features.h | 105 ------------
| 2 -
6 files changed, 542 deletions(-)
delete mode 100644 arch/x86/include/asm/disabled-features.h
delete mode 100644 arch/x86/include/asm/required-features.h
delete mode 100644 tools/arch/x86/include/asm/disabled-features.h
delete mode 100644 tools/arch/x86/include/asm/required-features.h
diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h
deleted file mode 100644
index c492bdc97b05..000000000000
--- a/arch/x86/include/asm/disabled-features.h
+++ /dev/null
@@ -1,161 +0,0 @@
-#ifndef _ASM_X86_DISABLED_FEATURES_H
-#define _ASM_X86_DISABLED_FEATURES_H
-
-/* These features, although they might be available in a CPU
- * will not be used because the compile options to support
- * them are not present.
- *
- * This code allows them to be checked and disabled at
- * compile time without an explicit #ifdef. Use
- * cpu_feature_enabled().
- */
-
-#ifdef CONFIG_X86_UMIP
-# define DISABLE_UMIP 0
-#else
-# define DISABLE_UMIP (1<<(X86_FEATURE_UMIP & 31))
-#endif
-
-#ifdef CONFIG_X86_64
-# define DISABLE_VME (1<<(X86_FEATURE_VME & 31))
-# define DISABLE_K6_MTRR (1<<(X86_FEATURE_K6_MTRR & 31))
-# define DISABLE_CYRIX_ARR (1<<(X86_FEATURE_CYRIX_ARR & 31))
-# define DISABLE_CENTAUR_MCR (1<<(X86_FEATURE_CENTAUR_MCR & 31))
-# define DISABLE_PCID 0
-#else
-# define DISABLE_VME 0
-# define DISABLE_K6_MTRR 0
-# define DISABLE_CYRIX_ARR 0
-# define DISABLE_CENTAUR_MCR 0
-# define DISABLE_PCID (1<<(X86_FEATURE_PCID & 31))
-#endif /* CONFIG_X86_64 */
-
-#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
-# define DISABLE_PKU 0
-# define DISABLE_OSPKE 0
-#else
-# define DISABLE_PKU (1<<(X86_FEATURE_PKU & 31))
-# define DISABLE_OSPKE (1<<(X86_FEATURE_OSPKE & 31))
-#endif /* CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS */
-
-#ifdef CONFIG_X86_5LEVEL
-# define DISABLE_LA57 0
-#else
-# define DISABLE_LA57 (1<<(X86_FEATURE_LA57 & 31))
-#endif
-
-#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
-# define DISABLE_PTI 0
-#else
-# define DISABLE_PTI (1 << (X86_FEATURE_PTI & 31))
-#endif
-
-#ifdef CONFIG_MITIGATION_RETPOLINE
-# define DISABLE_RETPOLINE 0
-#else
-# define DISABLE_RETPOLINE ((1 << (X86_FEATURE_RETPOLINE & 31)) | \
- (1 << (X86_FEATURE_RETPOLINE_LFENCE & 31)))
-#endif
-
-#ifdef CONFIG_MITIGATION_RETHUNK
-# define DISABLE_RETHUNK 0
-#else
-# define DISABLE_RETHUNK (1 << (X86_FEATURE_RETHUNK & 31))
-#endif
-
-#ifdef CONFIG_MITIGATION_UNRET_ENTRY
-# define DISABLE_UNRET 0
-#else
-# define DISABLE_UNRET (1 << (X86_FEATURE_UNRET & 31))
-#endif
-
-#ifdef CONFIG_MITIGATION_CALL_DEPTH_TRACKING
-# define DISABLE_CALL_DEPTH_TRACKING 0
-#else
-# define DISABLE_CALL_DEPTH_TRACKING (1 << (X86_FEATURE_CALL_DEPTH & 31))
-#endif
-
-#ifdef CONFIG_ADDRESS_MASKING
-# define DISABLE_LAM 0
-#else
-# define DISABLE_LAM (1 << (X86_FEATURE_LAM & 31))
-#endif
-
-#ifdef CONFIG_INTEL_IOMMU_SVM
-# define DISABLE_ENQCMD 0
-#else
-# define DISABLE_ENQCMD (1 << (X86_FEATURE_ENQCMD & 31))
-#endif
-
-#ifdef CONFIG_X86_SGX
-# define DISABLE_SGX 0
-#else
-# define DISABLE_SGX (1 << (X86_FEATURE_SGX & 31))
-#endif
-
-#ifdef CONFIG_XEN_PV
-# define DISABLE_XENPV 0
-#else
-# define DISABLE_XENPV (1 << (X86_FEATURE_XENPV & 31))
-#endif
-
-#ifdef CONFIG_INTEL_TDX_GUEST
-# define DISABLE_TDX_GUEST 0
-#else
-# define DISABLE_TDX_GUEST (1 << (X86_FEATURE_TDX_GUEST & 31))
-#endif
-
-#ifdef CONFIG_X86_USER_SHADOW_STACK
-#define DISABLE_USER_SHSTK 0
-#else
-#define DISABLE_USER_SHSTK (1 << (X86_FEATURE_USER_SHSTK & 31))
-#endif
-
-#ifdef CONFIG_X86_KERNEL_IBT
-#define DISABLE_IBT 0
-#else
-#define DISABLE_IBT (1 << (X86_FEATURE_IBT & 31))
-#endif
-
-#ifdef CONFIG_X86_FRED
-# define DISABLE_FRED 0
-#else
-# define DISABLE_FRED (1 << (X86_FEATURE_FRED & 31))
-#endif
-
-#ifdef CONFIG_KVM_AMD_SEV
-#define DISABLE_SEV_SNP 0
-#else
-#define DISABLE_SEV_SNP (1 << (X86_FEATURE_SEV_SNP & 31))
-#endif
-
-/*
- * Make sure to add features to the correct mask
- */
-#define DISABLED_MASK0 (DISABLE_VME)
-#define DISABLED_MASK1 0
-#define DISABLED_MASK2 0
-#define DISABLED_MASK3 (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR)
-#define DISABLED_MASK4 (DISABLE_PCID)
-#define DISABLED_MASK5 0
-#define DISABLED_MASK6 0
-#define DISABLED_MASK7 (DISABLE_PTI)
-#define DISABLED_MASK8 (DISABLE_XENPV|DISABLE_TDX_GUEST)
-#define DISABLED_MASK9 (DISABLE_SGX)
-#define DISABLED_MASK10 0
-#define DISABLED_MASK11 (DISABLE_RETPOLINE|DISABLE_RETHUNK|DISABLE_UNRET| \
- DISABLE_CALL_DEPTH_TRACKING|DISABLE_USER_SHSTK)
-#define DISABLED_MASK12 (DISABLE_FRED|DISABLE_LAM)
-#define DISABLED_MASK13 0
-#define DISABLED_MASK14 0
-#define DISABLED_MASK15 0
-#define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE|DISABLE_LA57|DISABLE_UMIP| \
- DISABLE_ENQCMD)
-#define DISABLED_MASK17 0
-#define DISABLED_MASK18 (DISABLE_IBT)
-#define DISABLED_MASK19 (DISABLE_SEV_SNP)
-#define DISABLED_MASK20 0
-#define DISABLED_MASK21 0
-#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 22)
-
-#endif /* _ASM_X86_DISABLED_FEATURES_H */
diff --git a/arch/x86/include/asm/required-features.h b/arch/x86/include/asm/required-features.h
deleted file mode 100644
index cef8104c103c..000000000000
--- a/arch/x86/include/asm/required-features.h
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef _ASM_X86_REQUIRED_FEATURES_H
-#define _ASM_X86_REQUIRED_FEATURES_H
-
-/* Define minimum CPUID feature set for kernel These bits are checked
- really early to actually display a visible error message before the
- kernel dies. Make sure to assign features to the proper mask!
-
- Some requirements that are not in CPUID yet are also in the
- CONFIG_X86_MINIMUM_CPU_FAMILY which is checked too.
-
- The real information is in arch/x86/Kconfig.cpu, this just converts
- the CONFIGs into a bitmask */
-
-#ifndef CONFIG_MATH_EMULATION
-# define NEED_FPU (1<<(X86_FEATURE_FPU & 31))
-#else
-# define NEED_FPU 0
-#endif
-
-#if defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64)
-# define NEED_PAE (1<<(X86_FEATURE_PAE & 31))
-#else
-# define NEED_PAE 0
-#endif
-
-#ifdef CONFIG_X86_REQUIRED_FEATURE_CX8
-# define NEED_CX8 (1<<(X86_FEATURE_CX8 & 31))
-#else
-# define NEED_CX8 0
-#endif
-
-#if defined(CONFIG_X86_REQUIRED_FEATURE_CMOV) || defined(CONFIG_X86_64)
-# define NEED_CMOV (1<<(X86_FEATURE_CMOV & 31))
-#else
-# define NEED_CMOV 0
-#endif
-
-# define NEED_3DNOW 0
-
-#if defined(CONFIG_X86_P6_NOP) || defined(CONFIG_X86_64)
-# define NEED_NOPL (1<<(X86_FEATURE_NOPL & 31))
-#else
-# define NEED_NOPL 0
-#endif
-
-#ifdef CONFIG_MATOM
-# define NEED_MOVBE (1<<(X86_FEATURE_MOVBE & 31))
-#else
-# define NEED_MOVBE 0
-#endif
-
-#ifdef CONFIG_X86_64
-#ifdef CONFIG_PARAVIRT_XXL
-/* Paravirtualized systems may not have PSE or PGE available */
-#define NEED_PSE 0
-#define NEED_PGE 0
-#else
-#define NEED_PSE (1<<(X86_FEATURE_PSE) & 31)
-#define NEED_PGE (1<<(X86_FEATURE_PGE) & 31)
-#endif
-#define NEED_MSR (1<<(X86_FEATURE_MSR & 31))
-#define NEED_FXSR (1<<(X86_FEATURE_FXSR & 31))
-#define NEED_XMM (1<<(X86_FEATURE_XMM & 31))
-#define NEED_XMM2 (1<<(X86_FEATURE_XMM2 & 31))
-#define NEED_LM (1<<(X86_FEATURE_LM & 31))
-#else
-#define NEED_PSE 0
-#define NEED_MSR 0
-#define NEED_PGE 0
-#define NEED_FXSR 0
-#define NEED_XMM 0
-#define NEED_XMM2 0
-#define NEED_LM 0
-#endif
-
-#define REQUIRED_MASK0 (NEED_FPU|NEED_PSE|NEED_MSR|NEED_PAE|\
- NEED_CX8|NEED_PGE|NEED_FXSR|NEED_CMOV|\
- NEED_XMM|NEED_XMM2)
-#define SSE_MASK (NEED_XMM|NEED_XMM2)
-
-#define REQUIRED_MASK1 (NEED_LM|NEED_3DNOW)
-
-#define REQUIRED_MASK2 0
-#define REQUIRED_MASK3 (NEED_NOPL)
-#define REQUIRED_MASK4 (NEED_MOVBE)
-#define REQUIRED_MASK5 0
-#define REQUIRED_MASK6 0
-#define REQUIRED_MASK7 0
-#define REQUIRED_MASK8 0
-#define REQUIRED_MASK9 0
-#define REQUIRED_MASK10 0
-#define REQUIRED_MASK11 0
-#define REQUIRED_MASK12 0
-#define REQUIRED_MASK13 0
-#define REQUIRED_MASK14 0
-#define REQUIRED_MASK15 0
-#define REQUIRED_MASK16 0
-#define REQUIRED_MASK17 0
-#define REQUIRED_MASK18 0
-#define REQUIRED_MASK19 0
-#define REQUIRED_MASK20 0
-#define REQUIRED_MASK21 0
-#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 22)
-
-#endif /* _ASM_X86_REQUIRED_FEATURES_H */
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h
index 3c7434329661..05503448b94d 100644
--- a/tools/arch/x86/include/asm/cpufeatures.h
+++ b/tools/arch/x86/include/asm/cpufeatures.h
@@ -2,14 +2,6 @@
#ifndef _ASM_X86_CPUFEATURES_H
#define _ASM_X86_CPUFEATURES_H
-#ifndef _ASM_X86_REQUIRED_FEATURES_H
-#include <asm/required-features.h>
-#endif
-
-#ifndef _ASM_X86_DISABLED_FEATURES_H
-#include <asm/disabled-features.h>
-#endif
-
/*
* Defines x86 CPU feature bits
*/
diff --git a/tools/arch/x86/include/asm/disabled-features.h b/tools/arch/x86/include/asm/disabled-features.h
deleted file mode 100644
index c492bdc97b05..000000000000
--- a/tools/arch/x86/include/asm/disabled-features.h
+++ /dev/null
@@ -1,161 +0,0 @@
-#ifndef _ASM_X86_DISABLED_FEATURES_H
-#define _ASM_X86_DISABLED_FEATURES_H
-
-/* These features, although they might be available in a CPU
- * will not be used because the compile options to support
- * them are not present.
- *
- * This code allows them to be checked and disabled at
- * compile time without an explicit #ifdef. Use
- * cpu_feature_enabled().
- */
-
-#ifdef CONFIG_X86_UMIP
-# define DISABLE_UMIP 0
-#else
-# define DISABLE_UMIP (1<<(X86_FEATURE_UMIP & 31))
-#endif
-
-#ifdef CONFIG_X86_64
-# define DISABLE_VME (1<<(X86_FEATURE_VME & 31))
-# define DISABLE_K6_MTRR (1<<(X86_FEATURE_K6_MTRR & 31))
-# define DISABLE_CYRIX_ARR (1<<(X86_FEATURE_CYRIX_ARR & 31))
-# define DISABLE_CENTAUR_MCR (1<<(X86_FEATURE_CENTAUR_MCR & 31))
-# define DISABLE_PCID 0
-#else
-# define DISABLE_VME 0
-# define DISABLE_K6_MTRR 0
-# define DISABLE_CYRIX_ARR 0
-# define DISABLE_CENTAUR_MCR 0
-# define DISABLE_PCID (1<<(X86_FEATURE_PCID & 31))
-#endif /* CONFIG_X86_64 */
-
-#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
-# define DISABLE_PKU 0
-# define DISABLE_OSPKE 0
-#else
-# define DISABLE_PKU (1<<(X86_FEATURE_PKU & 31))
-# define DISABLE_OSPKE (1<<(X86_FEATURE_OSPKE & 31))
-#endif /* CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS */
-
-#ifdef CONFIG_X86_5LEVEL
-# define DISABLE_LA57 0
-#else
-# define DISABLE_LA57 (1<<(X86_FEATURE_LA57 & 31))
-#endif
-
-#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
-# define DISABLE_PTI 0
-#else
-# define DISABLE_PTI (1 << (X86_FEATURE_PTI & 31))
-#endif
-
-#ifdef CONFIG_MITIGATION_RETPOLINE
-# define DISABLE_RETPOLINE 0
-#else
-# define DISABLE_RETPOLINE ((1 << (X86_FEATURE_RETPOLINE & 31)) | \
- (1 << (X86_FEATURE_RETPOLINE_LFENCE & 31)))
-#endif
-
-#ifdef CONFIG_MITIGATION_RETHUNK
-# define DISABLE_RETHUNK 0
-#else
-# define DISABLE_RETHUNK (1 << (X86_FEATURE_RETHUNK & 31))
-#endif
-
-#ifdef CONFIG_MITIGATION_UNRET_ENTRY
-# define DISABLE_UNRET 0
-#else
-# define DISABLE_UNRET (1 << (X86_FEATURE_UNRET & 31))
-#endif
-
-#ifdef CONFIG_MITIGATION_CALL_DEPTH_TRACKING
-# define DISABLE_CALL_DEPTH_TRACKING 0
-#else
-# define DISABLE_CALL_DEPTH_TRACKING (1 << (X86_FEATURE_CALL_DEPTH & 31))
-#endif
-
-#ifdef CONFIG_ADDRESS_MASKING
-# define DISABLE_LAM 0
-#else
-# define DISABLE_LAM (1 << (X86_FEATURE_LAM & 31))
-#endif
-
-#ifdef CONFIG_INTEL_IOMMU_SVM
-# define DISABLE_ENQCMD 0
-#else
-# define DISABLE_ENQCMD (1 << (X86_FEATURE_ENQCMD & 31))
-#endif
-
-#ifdef CONFIG_X86_SGX
-# define DISABLE_SGX 0
-#else
-# define DISABLE_SGX (1 << (X86_FEATURE_SGX & 31))
-#endif
-
-#ifdef CONFIG_XEN_PV
-# define DISABLE_XENPV 0
-#else
-# define DISABLE_XENPV (1 << (X86_FEATURE_XENPV & 31))
-#endif
-
-#ifdef CONFIG_INTEL_TDX_GUEST
-# define DISABLE_TDX_GUEST 0
-#else
-# define DISABLE_TDX_GUEST (1 << (X86_FEATURE_TDX_GUEST & 31))
-#endif
-
-#ifdef CONFIG_X86_USER_SHADOW_STACK
-#define DISABLE_USER_SHSTK 0
-#else
-#define DISABLE_USER_SHSTK (1 << (X86_FEATURE_USER_SHSTK & 31))
-#endif
-
-#ifdef CONFIG_X86_KERNEL_IBT
-#define DISABLE_IBT 0
-#else
-#define DISABLE_IBT (1 << (X86_FEATURE_IBT & 31))
-#endif
-
-#ifdef CONFIG_X86_FRED
-# define DISABLE_FRED 0
-#else
-# define DISABLE_FRED (1 << (X86_FEATURE_FRED & 31))
-#endif
-
-#ifdef CONFIG_KVM_AMD_SEV
-#define DISABLE_SEV_SNP 0
-#else
-#define DISABLE_SEV_SNP (1 << (X86_FEATURE_SEV_SNP & 31))
-#endif
-
-/*
- * Make sure to add features to the correct mask
- */
-#define DISABLED_MASK0 (DISABLE_VME)
-#define DISABLED_MASK1 0
-#define DISABLED_MASK2 0
-#define DISABLED_MASK3 (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR)
-#define DISABLED_MASK4 (DISABLE_PCID)
-#define DISABLED_MASK5 0
-#define DISABLED_MASK6 0
-#define DISABLED_MASK7 (DISABLE_PTI)
-#define DISABLED_MASK8 (DISABLE_XENPV|DISABLE_TDX_GUEST)
-#define DISABLED_MASK9 (DISABLE_SGX)
-#define DISABLED_MASK10 0
-#define DISABLED_MASK11 (DISABLE_RETPOLINE|DISABLE_RETHUNK|DISABLE_UNRET| \
- DISABLE_CALL_DEPTH_TRACKING|DISABLE_USER_SHSTK)
-#define DISABLED_MASK12 (DISABLE_FRED|DISABLE_LAM)
-#define DISABLED_MASK13 0
-#define DISABLED_MASK14 0
-#define DISABLED_MASK15 0
-#define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE|DISABLE_LA57|DISABLE_UMIP| \
- DISABLE_ENQCMD)
-#define DISABLED_MASK17 0
-#define DISABLED_MASK18 (DISABLE_IBT)
-#define DISABLED_MASK19 (DISABLE_SEV_SNP)
-#define DISABLED_MASK20 0
-#define DISABLED_MASK21 0
-#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 22)
-
-#endif /* _ASM_X86_DISABLED_FEATURES_H */
diff --git a/tools/arch/x86/include/asm/required-features.h b/tools/arch/x86/include/asm/required-features.h
deleted file mode 100644
index cef8104c103c..000000000000
--- a/tools/arch/x86/include/asm/required-features.h
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef _ASM_X86_REQUIRED_FEATURES_H
-#define _ASM_X86_REQUIRED_FEATURES_H
-
-/* Define minimum CPUID feature set for kernel These bits are checked
- really early to actually display a visible error message before the
- kernel dies. Make sure to assign features to the proper mask!
-
- Some requirements that are not in CPUID yet are also in the
- CONFIG_X86_MINIMUM_CPU_FAMILY which is checked too.
-
- The real information is in arch/x86/Kconfig.cpu, this just converts
- the CONFIGs into a bitmask */
-
-#ifndef CONFIG_MATH_EMULATION
-# define NEED_FPU (1<<(X86_FEATURE_FPU & 31))
-#else
-# define NEED_FPU 0
-#endif
-
-#if defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64)
-# define NEED_PAE (1<<(X86_FEATURE_PAE & 31))
-#else
-# define NEED_PAE 0
-#endif
-
-#ifdef CONFIG_X86_REQUIRED_FEATURE_CX8
-# define NEED_CX8 (1<<(X86_FEATURE_CX8 & 31))
-#else
-# define NEED_CX8 0
-#endif
-
-#if defined(CONFIG_X86_REQUIRED_FEATURE_CMOV) || defined(CONFIG_X86_64)
-# define NEED_CMOV (1<<(X86_FEATURE_CMOV & 31))
-#else
-# define NEED_CMOV 0
-#endif
-
-# define NEED_3DNOW 0
-
-#if defined(CONFIG_X86_P6_NOP) || defined(CONFIG_X86_64)
-# define NEED_NOPL (1<<(X86_FEATURE_NOPL & 31))
-#else
-# define NEED_NOPL 0
-#endif
-
-#ifdef CONFIG_MATOM
-# define NEED_MOVBE (1<<(X86_FEATURE_MOVBE & 31))
-#else
-# define NEED_MOVBE 0
-#endif
-
-#ifdef CONFIG_X86_64
-#ifdef CONFIG_PARAVIRT_XXL
-/* Paravirtualized systems may not have PSE or PGE available */
-#define NEED_PSE 0
-#define NEED_PGE 0
-#else
-#define NEED_PSE (1<<(X86_FEATURE_PSE) & 31)
-#define NEED_PGE (1<<(X86_FEATURE_PGE) & 31)
-#endif
-#define NEED_MSR (1<<(X86_FEATURE_MSR & 31))
-#define NEED_FXSR (1<<(X86_FEATURE_FXSR & 31))
-#define NEED_XMM (1<<(X86_FEATURE_XMM & 31))
-#define NEED_XMM2 (1<<(X86_FEATURE_XMM2 & 31))
-#define NEED_LM (1<<(X86_FEATURE_LM & 31))
-#else
-#define NEED_PSE 0
-#define NEED_MSR 0
-#define NEED_PGE 0
-#define NEED_FXSR 0
-#define NEED_XMM 0
-#define NEED_XMM2 0
-#define NEED_LM 0
-#endif
-
-#define REQUIRED_MASK0 (NEED_FPU|NEED_PSE|NEED_MSR|NEED_PAE|\
- NEED_CX8|NEED_PGE|NEED_FXSR|NEED_CMOV|\
- NEED_XMM|NEED_XMM2)
-#define SSE_MASK (NEED_XMM|NEED_XMM2)
-
-#define REQUIRED_MASK1 (NEED_LM|NEED_3DNOW)
-
-#define REQUIRED_MASK2 0
-#define REQUIRED_MASK3 (NEED_NOPL)
-#define REQUIRED_MASK4 (NEED_MOVBE)
-#define REQUIRED_MASK5 0
-#define REQUIRED_MASK6 0
-#define REQUIRED_MASK7 0
-#define REQUIRED_MASK8 0
-#define REQUIRED_MASK9 0
-#define REQUIRED_MASK10 0
-#define REQUIRED_MASK11 0
-#define REQUIRED_MASK12 0
-#define REQUIRED_MASK13 0
-#define REQUIRED_MASK14 0
-#define REQUIRED_MASK15 0
-#define REQUIRED_MASK16 0
-#define REQUIRED_MASK17 0
-#define REQUIRED_MASK18 0
-#define REQUIRED_MASK19 0
-#define REQUIRED_MASK20 0
-#define REQUIRED_MASK21 0
-#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 22)
-
-#endif /* _ASM_X86_REQUIRED_FEATURES_H */
--git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 672421b858ac..3ef2fd511bc1 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -25,8 +25,6 @@ FILES=(
"include/linux/hash.h"
"include/linux/list-sort.h"
"include/uapi/linux/hw_breakpoint.h"
- "arch/x86/include/asm/disabled-features.h"
- "arch/x86/include/asm/required-features.h"
"arch/x86/include/asm/cpufeatures.h"
"arch/x86/include/asm/inat_types.h"
"arch/x86/include/asm/emulate_prefix.h"
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 4/4] x86/cpufeatures: Use AWK to generate {REQUIRED|DISABLED}_MASK_BIT_SET
2024-06-22 17:14 [PATCH v3 0/4] x86/cpufeatures: Automatically generate required and disabled feature masks Xin Li (Intel)
` (2 preceding siblings ...)
2024-06-22 17:14 ` [PATCH v3 3/4] x86/cpufeatures: Remove {disabled,required}-features.h Xin Li (Intel)
@ 2024-06-22 17:14 ` Xin Li (Intel)
2024-06-23 20:28 ` Brian Gerst
2024-06-22 17:31 ` [PATCH v3 0/4] x86/cpufeatures: Automatically generate required and disabled feature masks Xin Li
4 siblings, 1 reply; 16+ messages in thread
From: Xin Li (Intel) @ 2024-06-22 17:14 UTC (permalink / raw)
To: linux-kernel, linux-perf-users
Cc: tglx, mingo, bp, dave.hansen, x86, hpa, will, peterz, akpm, acme,
namhyung, brgerst
Generate macros {REQUIRED|DISABLED}_MASK_BIT_SET in the newly added AWK
script that generates the required and disabled feature mask header.
Suggested-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: Xin Li (Intel) <xin@zytor.com>
---
arch/x86/include/asm/cpufeature.h | 69 -------------------------------
arch/x86/tools/featuremasks.awk | 12 +++++-
2 files changed, 11 insertions(+), 70 deletions(-)
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 8332f596ba3c..8161dfb3255c 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -55,75 +55,6 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
#define test_cpu_cap(c, bit) \
arch_test_bit(bit, (unsigned long *)((c)->x86_capability))
-/*
- * There are 32 bits/features in each mask word. The high bits
- * (selected with (bit>>5) give us the word number and the low 5
- * bits give us the bit/feature number inside the word.
- * (1UL<<((bit)&31) gives us a mask for the feature_bit so we can
- * see if it is set in the mask word.
- */
-#define CHECK_BIT_IN_MASK_WORD(maskname, word, bit) \
- (((bit)>>5)==(word) && (1UL<<((bit)&31) & maskname##word ))
-
-/*
- * {REQUIRED,DISABLED}_MASK_CHECK below may seem duplicated with the
- * following BUILD_BUG_ON_ZERO() check but when NCAPINTS gets changed, all
- * header macros which use NCAPINTS need to be changed. The duplicated macro
- * use causes the compiler to issue errors for all headers so that all usage
- * sites can be corrected.
- */
-#define REQUIRED_MASK_BIT_SET(feature_bit) \
- ( CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 0, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 1, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 2, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 3, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 4, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 5, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 6, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 7, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 8, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 9, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 10, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 11, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 12, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 13, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 14, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 15, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 16, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 17, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 19, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 20, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 21, feature_bit) || \
- REQUIRED_MASK_CHECK || \
- BUILD_BUG_ON_ZERO(NCAPINTS != 22))
-
-#define DISABLED_MASK_BIT_SET(feature_bit) \
- ( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 0, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 1, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 2, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 3, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 4, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 5, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 6, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 7, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 8, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 9, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 10, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 11, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 12, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 13, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 14, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 15, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 16, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 17, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 19, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 20, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 21, feature_bit) || \
- DISABLED_MASK_CHECK || \
- BUILD_BUG_ON_ZERO(NCAPINTS != 22))
-
#define cpu_has(c, bit) \
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
test_cpu_cap(c, bit))
diff --git a/arch/x86/tools/featuremasks.awk b/arch/x86/tools/featuremasks.awk
index 989b021e73d3..f6fe979a8fae 100755
--- a/arch/x86/tools/featuremasks.awk
+++ b/arch/x86/tools/featuremasks.awk
@@ -77,7 +77,17 @@ END {
printf "#define %s_MASK%d\t0x%08x\n", s, i, masks[i];
}
- printf "#define %s_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != %d)\n\n", s, ncapints;
+ printf "\n#define %s_FEATURE(x)\t\t\t\t\\\n", s;
+ printf "\t((\t\t\t\t\t";
+ for (i = 0; i < ncapints; i++) {
+ if (masks[i])
+ printf "\t\\\n\t\t((x) >> 5) == %2d ? %s_MASK%d :", i, s, i;
+ }
+ printf " 0\t\\\n";
+ printf "\t) & (1 << ((x) & 31)))\n";
+
+ printf "\n#define %s_MASK_BIT_SET(x)\t\t\t\\\n", s;
+ printf "\t(%s_FEATURE(x) || BUILD_BUG_ON_ZERO(NCAPINTS != %d))\n\n", s, ncapints;
}
printf "#endif /* _ASM_X86_FEATUREMASKS_H */\n";
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v3 0/4] x86/cpufeatures: Automatically generate required and disabled feature masks
2024-06-22 17:14 [PATCH v3 0/4] x86/cpufeatures: Automatically generate required and disabled feature masks Xin Li (Intel)
` (3 preceding siblings ...)
2024-06-22 17:14 ` [PATCH v3 4/4] x86/cpufeatures: Use AWK to generate {REQUIRED|DISABLED}_MASK_BIT_SET Xin Li (Intel)
@ 2024-06-22 17:31 ` Xin Li
4 siblings, 0 replies; 16+ messages in thread
From: Xin Li @ 2024-06-22 17:31 UTC (permalink / raw)
To: linux-kernel, linux-perf-users
Cc: tglx, mingo, bp, dave.hansen, x86, hpa, will, peterz, akpm, acme,
namhyung, brgerst
On 6/22/2024 10:14 AM, Xin Li (Intel) wrote:
> The x86 build process first generates required and disabled feature
> masks based on current build config, and then uses these generated
> masks to compile the source code. When a CPU feature is not enabled
> in a build config, e.g., when CONFIG_X86_FRED=n, its feature disable
> flag, i.e., DISABLE_FRED, needs to be properly defined and added to
> a specific disabled CPU features mask in <asm/disabled-features.h>,
> as the following patch does:
> https://lore.kernel.org/all/20231205105030.8698-8-xin3.li@intel.com/.
> As a result, the FRED feature bit is surely cleared in the generated
> kernel binary when CONFIG_X86_FRED=n.
>
> Recently there is another case to repeat the same exercise for the
> AMD SEV-SNP CPU feature:
> https://lore.kernel.org/all/20240126041126.1927228-2-michael.roth@amd.com/.
> https://lore.kernel.org/all/20240126041126.1927228-23-michael.roth@amd.com/.
>
> It was one thing when there were four of CPU feature masks, but with
> over 20 it is going to cause mistakes, e.g.,
> https://lore.kernel.org/lkml/aaed79d5-d683-d1bc-7ba1-b33c8d6db618@suse.com/.
>
> We want to eliminate the stupidly repeated exercise to manually assign
> features to CPU feature words through introducing an AWK script to
> automatically generate a header with required and disabled CPU feature
> masks based on current build config, and this patch set does that.
>
Here is an example of the auto generated feature masks header:
ifndef _ASM_X86_FEATUREMASKS_H
#define _ASM_X86_FEATUREMASKS_H
/*
* REQUIRED features:
*
* FPU PSE MSR PAE CX8 PGE CMOV FXSR XMM XMM2 LM NOPL ALWAYS CPUID
*/
#define REQUIRED_MASK0 0x0700a169
#define REQUIRED_MASK1 0x20000000
#define REQUIRED_MASK2 0x00000000
#define REQUIRED_MASK3 0x02300000
#define REQUIRED_MASK4 0x00000000
#define REQUIRED_MASK5 0x00000000
#define REQUIRED_MASK6 0x00000000
#define REQUIRED_MASK7 0x00000000
#define REQUIRED_MASK8 0x00000000
#define REQUIRED_MASK9 0x00000000
#define REQUIRED_MASK10 0x00000000
#define REQUIRED_MASK11 0x00000000
#define REQUIRED_MASK12 0x00000000
#define REQUIRED_MASK13 0x00000000
#define REQUIRED_MASK14 0x00000000
#define REQUIRED_MASK15 0x00000000
#define REQUIRED_MASK16 0x00000000
#define REQUIRED_MASK17 0x00000000
#define REQUIRED_MASK18 0x00000000
#define REQUIRED_MASK19 0x00000000
#define REQUIRED_MASK20 0x00000000
#define REQUIRED_MASK21 0x00000000
#define REQUIRED_FEATURE(x) \
(( \
((x) >> 5) == 0 ? REQUIRED_MASK0 : \
((x) >> 5) == 1 ? REQUIRED_MASK1 : \
((x) >> 5) == 3 ? REQUIRED_MASK3 : 0 \
) & (1 << ((x) & 31)))
#define REQUIRED_MASK_BIT_SET(x) \
(REQUIRED_FEATURE(x) || BUILD_BUG_ON_ZERO(NCAPINTS != 22))
/*
* DISABLED features:
*
* VME K6_MTRR CYRIX_ARR CENTAUR_MCR XENPV TDX_GUEST UNRET LAM SEV_SNP
*/
#define DISABLED_MASK0 0x00000002
#define DISABLED_MASK1 0x00000000
#define DISABLED_MASK2 0x00000000
#define DISABLED_MASK3 0x0000000e
#define DISABLED_MASK4 0x00000000
#define DISABLED_MASK5 0x00000000
#define DISABLED_MASK6 0x00000000
#define DISABLED_MASK7 0x00000000
#define DISABLED_MASK8 0x00410000
#define DISABLED_MASK9 0x00000000
#define DISABLED_MASK10 0x00000000
#define DISABLED_MASK11 0x00008000
#define DISABLED_MASK12 0x04000000
#define DISABLED_MASK13 0x00000000
#define DISABLED_MASK14 0x00000000
#define DISABLED_MASK15 0x00000000
#define DISABLED_MASK16 0x00000000
#define DISABLED_MASK17 0x00000000
#define DISABLED_MASK18 0x00000000
#define DISABLED_MASK19 0x00000010
#define DISABLED_MASK20 0x00000000
#define DISABLED_MASK21 0x00000000
#define DISABLED_FEATURE(x) \
(( \
((x) >> 5) == 0 ? DISABLED_MASK0 : \
((x) >> 5) == 3 ? DISABLED_MASK3 : \
((x) >> 5) == 8 ? DISABLED_MASK8 : \
((x) >> 5) == 11 ? DISABLED_MASK11 : \
((x) >> 5) == 12 ? DISABLED_MASK12 : \
((x) >> 5) == 19 ? DISABLED_MASK19 : 0 \
) & (1 << ((x) & 31)))
#define DISABLED_MASK_BIT_SET(x) \
(DISABLED_FEATURE(x) || BUILD_BUG_ON_ZERO(NCAPINTS != 22))
#endif /* _ASM_X86_FEATUREMASKS_H */
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 4/4] x86/cpufeatures: Use AWK to generate {REQUIRED|DISABLED}_MASK_BIT_SET
2024-06-22 17:14 ` [PATCH v3 4/4] x86/cpufeatures: Use AWK to generate {REQUIRED|DISABLED}_MASK_BIT_SET Xin Li (Intel)
@ 2024-06-23 20:28 ` Brian Gerst
2024-06-24 7:29 ` Xin Li
` (2 more replies)
0 siblings, 3 replies; 16+ messages in thread
From: Brian Gerst @ 2024-06-23 20:28 UTC (permalink / raw)
To: Xin Li (Intel)
Cc: linux-kernel, linux-perf-users, tglx, mingo, bp, dave.hansen, x86,
hpa, will, peterz, akpm, acme, namhyung
On Sat, Jun 22, 2024 at 1:14 PM Xin Li (Intel) <xin@zytor.com> wrote:
>
> Generate macros {REQUIRED|DISABLED}_MASK_BIT_SET in the newly added AWK
> script that generates the required and disabled feature mask header.
>
> Suggested-by: Brian Gerst <brgerst@gmail.com>
> Signed-off-by: Xin Li (Intel) <xin@zytor.com>
> ---
> arch/x86/include/asm/cpufeature.h | 69 -------------------------------
> arch/x86/tools/featuremasks.awk | 12 +++++-
> 2 files changed, 11 insertions(+), 70 deletions(-)
>
> diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
> index 8332f596ba3c..8161dfb3255c 100644
> --- a/arch/x86/include/asm/cpufeature.h
> +++ b/arch/x86/include/asm/cpufeature.h
> @@ -55,75 +55,6 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
> #define test_cpu_cap(c, bit) \
> arch_test_bit(bit, (unsigned long *)((c)->x86_capability))
>
> -/*
> - * There are 32 bits/features in each mask word. The high bits
> - * (selected with (bit>>5) give us the word number and the low 5
> - * bits give us the bit/feature number inside the word.
> - * (1UL<<((bit)&31) gives us a mask for the feature_bit so we can
> - * see if it is set in the mask word.
> - */
> -#define CHECK_BIT_IN_MASK_WORD(maskname, word, bit) \
> - (((bit)>>5)==(word) && (1UL<<((bit)&31) & maskname##word ))
> -
> -/*
> - * {REQUIRED,DISABLED}_MASK_CHECK below may seem duplicated with the
> - * following BUILD_BUG_ON_ZERO() check but when NCAPINTS gets changed, all
> - * header macros which use NCAPINTS need to be changed. The duplicated macro
> - * use causes the compiler to issue errors for all headers so that all usage
> - * sites can be corrected.
> - */
> -#define REQUIRED_MASK_BIT_SET(feature_bit) \
> - ( CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 0, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 1, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 2, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 3, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 4, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 5, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 6, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 7, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 8, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 9, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 10, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 11, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 12, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 13, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 14, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 15, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 16, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 17, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 19, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 20, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 21, feature_bit) || \
> - REQUIRED_MASK_CHECK || \
> - BUILD_BUG_ON_ZERO(NCAPINTS != 22))
> -
> -#define DISABLED_MASK_BIT_SET(feature_bit) \
> - ( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 0, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 1, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 2, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 3, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 4, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 5, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 6, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 7, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 8, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 9, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 10, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 11, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 12, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 13, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 14, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 15, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 16, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 17, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 19, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 20, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 21, feature_bit) || \
> - DISABLED_MASK_CHECK || \
> - BUILD_BUG_ON_ZERO(NCAPINTS != 22))
> -
> #define cpu_has(c, bit) \
> (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
> test_cpu_cap(c, bit))
> diff --git a/arch/x86/tools/featuremasks.awk b/arch/x86/tools/featuremasks.awk
> index 989b021e73d3..f6fe979a8fae 100755
> --- a/arch/x86/tools/featuremasks.awk
> +++ b/arch/x86/tools/featuremasks.awk
> @@ -77,7 +77,17 @@ END {
> printf "#define %s_MASK%d\t0x%08x\n", s, i, masks[i];
> }
>
> - printf "#define %s_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != %d)\n\n", s, ncapints;
> + printf "\n#define %s_FEATURE(x)\t\t\t\t\\\n", s;
> + printf "\t((\t\t\t\t\t";
> + for (i = 0; i < ncapints; i++) {
> + if (masks[i])
> + printf "\t\\\n\t\t((x) >> 5) == %2d ? %s_MASK%d :", i, s, i;
> + }
> + printf " 0\t\\\n";
> + printf "\t) & (1 << ((x) & 31)))\n";
The original macro had 1UL here. I don't know if it is strictly
necessary in this case since we're using 32-bit masks, but it would
probably be safer.
> +
> + printf "\n#define %s_MASK_BIT_SET(x)\t\t\t\\\n", s;
> + printf "\t(%s_FEATURE(x) || BUILD_BUG_ON_ZERO(NCAPINTS != %d))\n\n", s, ncapints;
Checking NCAPINTS isn't necessary anymore. It was needed when these
macros had to be manually updated, but now if cpufeatures.h changes
this header will be regenerated.
> }
>
> printf "#endif /* _ASM_X86_FEATUREMASKS_H */\n";
> --
> 2.45.2
>
Otherwise, it looks good.
Brian Gerst
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 4/4] x86/cpufeatures: Use AWK to generate {REQUIRED|DISABLED}_MASK_BIT_SET
2024-06-23 20:28 ` Brian Gerst
@ 2024-06-24 7:29 ` Xin Li
2024-06-24 10:24 ` Andrew Cooper
2024-06-24 9:32 ` [PATCH v3A " Xin Li (Intel)
2024-06-27 16:51 ` [PATCH v3 " Xin Li
2 siblings, 1 reply; 16+ messages in thread
From: Xin Li @ 2024-06-24 7:29 UTC (permalink / raw)
To: Brian Gerst
Cc: linux-kernel, linux-perf-users, tglx, mingo, bp, dave.hansen, x86,
hpa, will, peterz, akpm, acme, namhyung
On 6/23/2024 1:28 PM, Brian Gerst wrote:
> On Sat, Jun 22, 2024 at 1:14 PM Xin Li (Intel) <xin@zytor.com> wrote:
>>
>> Generate macros {REQUIRED|DISABLED}_MASK_BIT_SET in the newly added AWK
>> script that generates the required and disabled feature mask header.
>>
>> Suggested-by: Brian Gerst <brgerst@gmail.com>
>> Signed-off-by: Xin Li (Intel) <xin@zytor.com>
>> ---
>> arch/x86/include/asm/cpufeature.h | 69 -------------------------------
>> arch/x86/tools/featuremasks.awk | 12 +++++-
>> 2 files changed, 11 insertions(+), 70 deletions(-)
>>
>> - printf "#define %s_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != %d)\n\n", s, ncapints;
>> + printf "\n#define %s_FEATURE(x)\t\t\t\t\\\n", s;
>> + printf "\t((\t\t\t\t\t";
>> + for (i = 0; i < ncapints; i++) {
>> + if (masks[i])
>> + printf "\t\\\n\t\t((x) >> 5) == %2d ? %s_MASK%d :", i, s, i;
>> + }
>> + printf " 0\t\\\n";
>> + printf "\t) & (1 << ((x) & 31)))\n";
>
> The original macro had 1UL here. I don't know if it is strictly
> necessary in this case since we're using 32-bit masks, but it would
> probably be safer.
I did notice it, but don't think UL is needed.
>> +
>> + printf "\n#define %s_MASK_BIT_SET(x)\t\t\t\\\n", s;
>> + printf "\t(%s_FEATURE(x) || BUILD_BUG_ON_ZERO(NCAPINTS != %d))\n\n", s, ncapints;
>
> Checking NCAPINTS isn't necessary anymore. It was needed when these
> macros had to be manually updated, but now if cpufeatures.h changes
> this header will be regenerated.
Right, it's no longer needed. Let me update this patch.
Thanks!
Xin
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v3A 4/4] x86/cpufeatures: Use AWK to generate {REQUIRED|DISABLED}_MASK_BIT_SET
2024-06-23 20:28 ` Brian Gerst
2024-06-24 7:29 ` Xin Li
@ 2024-06-24 9:32 ` Xin Li (Intel)
2024-06-27 16:51 ` [PATCH v3 " Xin Li
2 siblings, 0 replies; 16+ messages in thread
From: Xin Li (Intel) @ 2024-06-24 9:32 UTC (permalink / raw)
To: linux-kernel, linux-perf-users
Cc: tglx, mingo, bp, dave.hansen, x86, hpa, will, peterz, akpm, acme,
namhyung, brgerst
Generate macros {REQUIRED|DISABLED}_MASK_BIT_SET in the newly added AWK
script that generates the required and disabled feature mask header.
Suggested-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: Xin Li (Intel) <xin@zytor.com>
---
Change since v3:
* Checking NCAPINTS isn't necessary anymore. It was needed when these
macros had to be manually updated, but now if cpufeatures.h changes
this header will be regenerated (Brian Gerst).
---
arch/x86/include/asm/cpufeature.h | 69 -------------------------------
arch/x86/tools/featuremasks.awk | 9 +++-
2 files changed, 8 insertions(+), 70 deletions(-)
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 8332f596ba3c..8161dfb3255c 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -55,75 +55,6 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
#define test_cpu_cap(c, bit) \
arch_test_bit(bit, (unsigned long *)((c)->x86_capability))
-/*
- * There are 32 bits/features in each mask word. The high bits
- * (selected with (bit>>5) give us the word number and the low 5
- * bits give us the bit/feature number inside the word.
- * (1UL<<((bit)&31) gives us a mask for the feature_bit so we can
- * see if it is set in the mask word.
- */
-#define CHECK_BIT_IN_MASK_WORD(maskname, word, bit) \
- (((bit)>>5)==(word) && (1UL<<((bit)&31) & maskname##word ))
-
-/*
- * {REQUIRED,DISABLED}_MASK_CHECK below may seem duplicated with the
- * following BUILD_BUG_ON_ZERO() check but when NCAPINTS gets changed, all
- * header macros which use NCAPINTS need to be changed. The duplicated macro
- * use causes the compiler to issue errors for all headers so that all usage
- * sites can be corrected.
- */
-#define REQUIRED_MASK_BIT_SET(feature_bit) \
- ( CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 0, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 1, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 2, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 3, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 4, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 5, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 6, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 7, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 8, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 9, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 10, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 11, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 12, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 13, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 14, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 15, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 16, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 17, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 19, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 20, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 21, feature_bit) || \
- REQUIRED_MASK_CHECK || \
- BUILD_BUG_ON_ZERO(NCAPINTS != 22))
-
-#define DISABLED_MASK_BIT_SET(feature_bit) \
- ( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 0, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 1, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 2, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 3, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 4, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 5, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 6, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 7, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 8, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 9, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 10, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 11, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 12, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 13, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 14, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 15, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 16, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 17, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 19, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 20, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 21, feature_bit) || \
- DISABLED_MASK_CHECK || \
- BUILD_BUG_ON_ZERO(NCAPINTS != 22))
-
#define cpu_has(c, bit) \
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
test_cpu_cap(c, bit))
diff --git a/arch/x86/tools/featuremasks.awk b/arch/x86/tools/featuremasks.awk
index 989b021e73d3..2a936411c219 100755
--- a/arch/x86/tools/featuremasks.awk
+++ b/arch/x86/tools/featuremasks.awk
@@ -77,7 +77,14 @@ END {
printf "#define %s_MASK%d\t0x%08x\n", s, i, masks[i];
}
- printf "#define %s_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != %d)\n\n", s, ncapints;
+ printf "\n#define %s_MASK_BIT_SET(x)\t\t\t\\\n", s;
+ printf "\t((\t\t\t\t\t";
+ for (i = 0; i < ncapints; i++) {
+ if (masks[i])
+ printf "\t\\\n\t\t((x) >> 5) == %2d ? %s_MASK%d :", i, s, i;
+ }
+ printf " 0\t\\\n";
+ printf "\t) & (1 << ((x) & 31)))\n";
}
printf "#endif /* _ASM_X86_FEATUREMASKS_H */\n";
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v3 4/4] x86/cpufeatures: Use AWK to generate {REQUIRED|DISABLED}_MASK_BIT_SET
2024-06-24 7:29 ` Xin Li
@ 2024-06-24 10:24 ` Andrew Cooper
2024-06-24 17:42 ` Xin Li
2024-06-25 5:22 ` [PATCH v3B " Xin Li (Intel)
0 siblings, 2 replies; 16+ messages in thread
From: Andrew Cooper @ 2024-06-24 10:24 UTC (permalink / raw)
To: Xin Li, Brian Gerst
Cc: linux-kernel, linux-perf-users, tglx, mingo, bp, dave.hansen, x86,
hpa, will, peterz, akpm, acme, namhyung
On 24/06/2024 8:29 am, Xin Li wrote:
> On 6/23/2024 1:28 PM, Brian Gerst wrote:
>> On Sat, Jun 22, 2024 at 1:14 PM Xin Li (Intel) <xin@zytor.com> wrote:
>>> - printf "#define %s_MASK_CHECK
>>> BUILD_BUG_ON_ZERO(NCAPINTS != %d)\n\n", s, ncapints;
>>> + printf "\n#define %s_FEATURE(x)\t\t\t\t\\\n", s;
>>> + printf "\t((\t\t\t\t\t";
>>> + for (i = 0; i < ncapints; i++) {
>>> + if (masks[i])
>>> + printf "\t\\\n\t\t((x) >> 5) == %2d
>>> ? %s_MASK%d :", i, s, i;
>>> + }
>>> + printf " 0\t\\\n";
>>> + printf "\t) & (1 << ((x) & 31)))\n";
>>
>> The original macro had 1UL here. I don't know if it is strictly
>> necessary in this case since we're using 32-bit masks, but it would
>> probably be safer.
>
> I did notice it, but don't think UL is needed.
You do need 1U, or you'll trip UBSAN every time you test feature 31 in a
word.
I'll note that the hypervisor bit is one such example.
~Andrew
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 4/4] x86/cpufeatures: Use AWK to generate {REQUIRED|DISABLED}_MASK_BIT_SET
2024-06-24 10:24 ` Andrew Cooper
@ 2024-06-24 17:42 ` Xin Li
2024-06-25 5:22 ` [PATCH v3B " Xin Li (Intel)
1 sibling, 0 replies; 16+ messages in thread
From: Xin Li @ 2024-06-24 17:42 UTC (permalink / raw)
To: Andrew Cooper, Brian Gerst
Cc: linux-kernel, linux-perf-users, tglx, mingo, bp, dave.hansen, x86,
hpa, will, peterz, akpm, acme, namhyung
On 6/24/2024 3:24 AM, Andrew Cooper wrote:
> On 24/06/2024 8:29 am, Xin Li wrote:
>> On 6/23/2024 1:28 PM, Brian Gerst wrote:
>>> On Sat, Jun 22, 2024 at 1:14 PM Xin Li (Intel) <xin@zytor.com> wrote:
>>>> - printf "#define %s_MASK_CHECK
>>>> BUILD_BUG_ON_ZERO(NCAPINTS != %d)\n\n", s, ncapints;
>>>> + printf "\n#define %s_FEATURE(x)\t\t\t\t\\\n", s;
>>>> + printf "\t((\t\t\t\t\t";
>>>> + for (i = 0; i < ncapints; i++) {
>>>> + if (masks[i])
>>>> + printf "\t\\\n\t\t((x) >> 5) == %2d
>>>> ? %s_MASK%d :", i, s, i;
>>>> + }
>>>> + printf " 0\t\\\n";
>>>> + printf "\t) & (1 << ((x) & 31)))\n";
>>>
>>> The original macro had 1UL here. I don't know if it is strictly
>>> necessary in this case since we're using 32-bit masks, but it would
>>> probably be safer.
>>
>> I did notice it, but don't think UL is needed.
>
> You do need 1U, or you'll trip UBSAN every time you test feature 31 in a
> word.
This is so obvious, how come I totally missed it!
> I'll note that the hypervisor bit is one such example.
What's more, generally bit 31 is nothing special, I find:
#define X86_FEATURE_PBE ( 0*32+31) /* Pending Break Enable */
#define X86_FEATURE_3DNOW ( 1*32+31) /* 3DNow */
#define X86_FEATURE_TSC_KNOWN_FREQ ( 3*32+31) /* TSC has known frequency */
...
Definitely I must append "U".
Thanks!
Xin
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v3B 4/4] x86/cpufeatures: Use AWK to generate {REQUIRED|DISABLED}_MASK_BIT_SET
2024-06-24 10:24 ` Andrew Cooper
2024-06-24 17:42 ` Xin Li
@ 2024-06-25 5:22 ` Xin Li (Intel)
2024-06-27 18:39 ` Brian Gerst
1 sibling, 1 reply; 16+ messages in thread
From: Xin Li (Intel) @ 2024-06-25 5:22 UTC (permalink / raw)
To: linux-kernel, linux-perf-users
Cc: tglx, mingo, bp, dave.hansen, x86, hpa, will, peterz, akpm, acme,
namhyung, brgerst, andrew.cooper3
Generate macros {REQUIRED|DISABLED}_MASK_BIT_SET in the newly added AWK
script that generates the required and disabled feature mask header.
Suggested-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: Xin Li (Intel) <xin@zytor.com>
---
Change since v3A:
* Use '1U' instead of '1' in feature mask shifting (Andrew Cooper).
Change since v3:
* Checking NCAPINTS isn't necessary anymore. It was needed when these
macros had to be manually updated, but now if cpufeatures.h changes
this header will be regenerated (Brian Gerst).
---
arch/x86/include/asm/cpufeature.h | 69 -------------------------------
arch/x86/tools/featuremasks.awk | 9 +++-
2 files changed, 8 insertions(+), 70 deletions(-)
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 8332f596ba3c..8161dfb3255c 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -55,75 +55,6 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
#define test_cpu_cap(c, bit) \
arch_test_bit(bit, (unsigned long *)((c)->x86_capability))
-/*
- * There are 32 bits/features in each mask word. The high bits
- * (selected with (bit>>5) give us the word number and the low 5
- * bits give us the bit/feature number inside the word.
- * (1UL<<((bit)&31) gives us a mask for the feature_bit so we can
- * see if it is set in the mask word.
- */
-#define CHECK_BIT_IN_MASK_WORD(maskname, word, bit) \
- (((bit)>>5)==(word) && (1UL<<((bit)&31) & maskname##word ))
-
-/*
- * {REQUIRED,DISABLED}_MASK_CHECK below may seem duplicated with the
- * following BUILD_BUG_ON_ZERO() check but when NCAPINTS gets changed, all
- * header macros which use NCAPINTS need to be changed. The duplicated macro
- * use causes the compiler to issue errors for all headers so that all usage
- * sites can be corrected.
- */
-#define REQUIRED_MASK_BIT_SET(feature_bit) \
- ( CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 0, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 1, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 2, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 3, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 4, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 5, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 6, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 7, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 8, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 9, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 10, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 11, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 12, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 13, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 14, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 15, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 16, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 17, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 19, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 20, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 21, feature_bit) || \
- REQUIRED_MASK_CHECK || \
- BUILD_BUG_ON_ZERO(NCAPINTS != 22))
-
-#define DISABLED_MASK_BIT_SET(feature_bit) \
- ( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 0, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 1, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 2, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 3, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 4, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 5, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 6, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 7, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 8, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 9, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 10, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 11, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 12, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 13, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 14, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 15, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 16, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 17, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 19, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 20, feature_bit) || \
- CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 21, feature_bit) || \
- DISABLED_MASK_CHECK || \
- BUILD_BUG_ON_ZERO(NCAPINTS != 22))
-
#define cpu_has(c, bit) \
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
test_cpu_cap(c, bit))
diff --git a/arch/x86/tools/featuremasks.awk b/arch/x86/tools/featuremasks.awk
index 989b021e73d3..e0383683e630 100755
--- a/arch/x86/tools/featuremasks.awk
+++ b/arch/x86/tools/featuremasks.awk
@@ -77,7 +77,14 @@ END {
printf "#define %s_MASK%d\t0x%08x\n", s, i, masks[i];
}
- printf "#define %s_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != %d)\n\n", s, ncapints;
+ printf "\n#define %s_MASK_BIT_SET(x)\t\t\t\\\n", s;
+ printf "\t((\t\t\t\t\t";
+ for (i = 0; i < ncapints; i++) {
+ if (masks[i])
+ printf "\t\\\n\t\t((x) >> 5) == %2d ? %s_MASK%d :", i, s, i;
+ }
+ printf " 0\t\\\n";
+ printf "\t) & (1U << ((x) & 31)))\n";
}
printf "#endif /* _ASM_X86_FEATUREMASKS_H */\n";
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v3 2/4] x86/cpufeatures: Generate a feature mask header based on build config
2024-06-22 17:14 ` [PATCH v3 2/4] x86/cpufeatures: Generate a feature mask header based on build config Xin Li (Intel)
@ 2024-06-26 11:36 ` Nikolay Borisov
2024-06-27 16:45 ` Xin Li
0 siblings, 1 reply; 16+ messages in thread
From: Nikolay Borisov @ 2024-06-26 11:36 UTC (permalink / raw)
To: Xin Li (Intel), linux-kernel, linux-perf-users
Cc: tglx, mingo, bp, dave.hansen, x86, hpa, will, peterz, akpm, acme,
namhyung, brgerst
On 22.06.24 г. 20:14 ч., Xin Li (Intel) wrote:
> From: "H. Peter Anvin (Intel)" <hpa@zytor.com>
>
> Introduce an AWK script to auto-generate a header with required and
> disabled feature masks based on <asm/cpufeatures.h> and 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 ]
>
> Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
> Signed-off-by: Xin Li (Intel) <xin@zytor.com>
Overall LGTM, some minor points below.
Reviewed-by: Nikolay Borisov <nik.borisov@suse.com>
<snip>
> diff --git a/arch/x86/tools/featuremasks.awk b/arch/x86/tools/featuremasks.awk
> new file mode 100755
> index 000000000000..989b021e73d3
> --- /dev/null
> +++ b/arch/x86/tools/featuremasks.awk
> @@ -0,0 +1,84 @@
> +#!/usr/bin/awk
> +#
> +# Convert cpufeatures.h to a list of compile-time masks
> +# Note: this blithly assumes that each word has at least one
> +# feature defined in it; if not, something else is wrong!
> +#
> +
> +BEGIN {
> + printf "#ifndef _ASM_X86_FEATUREMASKS_H\n";
> + printf "#define _ASM_X86_FEATUREMASKS_H\n\n";
> +
> + file = 0
> +}
> +
> +BEGINFILE {
> + switch (++file) {
> + case 1: # cpufeatures.h
> + FPAT = "#[ \t]*[a-z]+|[A-Za-z0-9_]+|[^ \t]";
> + break;
> + case 2: # .config
> + FPAT = "CONFIG_[A-Z0-9_]+|is not set|[yn]";
> + break;
> + }
> +}
> +
IMO this script could use a bit of high-level comments. Something like:
# Create a dictionary of sorts, containing all defined feature bits
> +file == 1 && $1 ~ /^#[ \t]*define$/ && $2 ~ /^X86_FEATURE_/ &&
> +$3 == "(" && $5 == "*" && $7 == "+" && $9 == ")" {
> + nfeat = $4 * $6 + $8;
> + feat = $2;
> + sub(/^X86_FEATURE_/, "", feat);
> + feats[nfeat] = feat;
> +}
> +file == 1 && $1 ~ /^#[ \t]*define$/ && $2 == "NCAPINTS" {
> + ncapints = strtonum($3);
> +}
> +
# Create a dictionary featstat[REQUIRED|DISABLED, FEATURE_NAME] = on | off
> +file == 2 && $1 ~ /^CONFIG_X86_[A-Z]*_FEATURE_/ {
> + on = ($2 == "y");
> + if (split($1, fs, "CONFIG_X86_|_FEATURE_") == 3)
> + featstat[fs[2], fs[3]] = on;
> +}
> +
> +END {
> + sets[1] = "REQUIRED";
> + sets[2] = "DISABLED";
> +
> + for (ns in sets) {
> + s = sets[ns];
> +
> + printf "/*\n";
> + printf " * %s features:\n", s;
> + printf " *\n";
> + fstr = "";
> + for (i = 0; i < ncapints; i++) {
> + mask = 0;
> + for (j = 0; j < 32; j++) {
> + nfeat = i*32 + j;
> + feat = feats[nfeat];
> + if (feat) {
> + st = !!featstat[s, feat];
> + if (st) {
> + nfstr = fstr " " feat;
> + if (length(nfstr) > 72) {
> + printf " * %s\n", fstr;
> + nfstr = " " feat;
> + }
> + fstr = nfstr;
> + }
> + mask += st * (2 ^ j);
nit: This expression can be changed to mask += (2 ^j) and moved inside
the 'if (st)' branch. Essentially only add a bit iff that status of the
relevant feature in the kconfig is y, which is signified by the value of
'st' variable.
> + }
> + }
> + masks[i] = mask;
> + }
> + printf " * %s\n */\n\n", fstr;
> +
> + for (i = 0; i < ncapints; i++) {
> + printf "#define %s_MASK%d\t0x%08x\n", s, i, masks[i];
> + }
> +
> + printf "#define %s_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != %d)\n\n", s, ncapints;
> + }
> +
> + printf "#endif /* _ASM_X86_FEATUREMASKS_H */\n";
> +}
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 2/4] x86/cpufeatures: Generate a feature mask header based on build config
2024-06-26 11:36 ` Nikolay Borisov
@ 2024-06-27 16:45 ` Xin Li
0 siblings, 0 replies; 16+ messages in thread
From: Xin Li @ 2024-06-27 16:45 UTC (permalink / raw)
To: Nikolay Borisov, linux-kernel, linux-perf-users
Cc: tglx, mingo, bp, dave.hansen, x86, hpa, will, peterz, akpm, acme,
namhyung, brgerst
On 6/26/2024 4:36 AM, Nikolay Borisov wrote:
>
>
> On 22.06.24 г. 20:14 ч., Xin Li (Intel) wrote:
>> From: "H. Peter Anvin (Intel)" <hpa@zytor.com>
>>
>> Introduce an AWK script to auto-generate a header with required and
>> disabled feature masks based on <asm/cpufeatures.h> and 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 ]
>>
>> Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
>> Signed-off-by: Xin Li (Intel) <xin@zytor.com>
>
> Overall LGTM, some minor points below.
>
>
> Reviewed-by: Nikolay Borisov <nik.borisov@suse.com>
Thanks!
>
>
> <snip>
>
>> diff --git a/arch/x86/tools/featuremasks.awk
>> b/arch/x86/tools/featuremasks.awk
>> new file mode 100755
>> index 000000000000..989b021e73d3
>> --- /dev/null
>> +++ b/arch/x86/tools/featuremasks.awk
>> @@ -0,0 +1,84 @@
>> +#!/usr/bin/awk
>> +#
>> +# Convert cpufeatures.h to a list of compile-time masks
>> +# Note: this blithly assumes that each word has at least one
>> +# feature defined in it; if not, something else is wrong!
>> +#
>> +
>> +BEGIN {
>> + printf "#ifndef _ASM_X86_FEATUREMASKS_H\n";
>> + printf "#define _ASM_X86_FEATUREMASKS_H\n\n";
>> +
>> + file = 0
>> +}
>> +
>> +BEGINFILE {
>> + switch (++file) {
>> + case 1: # cpufeatures.h
>> + FPAT = "#[ \t]*[a-z]+|[A-Za-z0-9_]+|[^ \t]";
>> + break;
>> + case 2: # .config
>> + FPAT = "CONFIG_[A-Z0-9_]+|is not set|[yn]";
>> + break;
>> + }
>> +}
>> +
>
> IMO this script could use a bit of high-level comments. Something like:
>
>
> # Create a dictionary of sorts, containing all defined feature bits
>> +file == 1 && $1 ~ /^#[ \t]*define$/ && $2 ~ /^X86_FEATURE_/ &&
>> +$3 == "(" && $5 == "*" && $7 == "+" && $9 == ")" {
>> + nfeat = $4 * $6 + $8;
>> + feat = $2;
>> + sub(/^X86_FEATURE_/, "", feat);
>> + feats[nfeat] = feat;
>> +}
>
>> +file == 1 && $1 ~ /^#[ \t]*define$/ && $2 == "NCAPINTS" {
>> + ncapints = strtonum($3);
>> +}
>> +
>
> # Create a dictionary featstat[REQUIRED|DISABLED, FEATURE_NAME] = on | off
>
>> +file == 2 && $1 ~ /^CONFIG_X86_[A-Z]*_FEATURE_/ {
>> + on = ($2 == "y");
>> + if (split($1, fs, "CONFIG_X86_|_FEATURE_") == 3)
>> + featstat[fs[2], fs[3]] = on;
>> +}
>> +
>> +END {
>> + sets[1] = "REQUIRED";
>> + sets[2] = "DISABLED";
>> +
>> + for (ns in sets) {
>> + s = sets[ns];
>> +
>> + printf "/*\n";
>> + printf " * %s features:\n", s;
>> + printf " *\n";
>> + fstr = "";
>> + for (i = 0; i < ncapints; i++) {
>> + mask = 0;
>> + for (j = 0; j < 32; j++) {
>> + nfeat = i*32 + j;
>> + feat = feats[nfeat];
>> + if (feat) {
>> + st = !!featstat[s, feat];
>> + if (st) {
>> + nfstr = fstr " " feat;
>> + if (length(nfstr) > 72) {
>> + printf " * %s\n", fstr;
>> + nfstr = " " feat;
>> + }
>> + fstr = nfstr;
>> + }
>> + mask += st * (2 ^ j);
>
> nit: This expression can be changed to mask += (2 ^j) and moved inside
> the 'if (st)' branch. Essentially only add a bit iff that status of the
> relevant feature in the kconfig is y, which is signified by the value of
> 'st' variable.
I will do a polish and send v4.
>
>> + }
>> + }
>> + masks[i] = mask;
>> + }
>> + printf " * %s\n */\n\n", fstr;
>> +
>> + for (i = 0; i < ncapints; i++) {
>> + printf "#define %s_MASK%d\t0x%08x\n", s, i, masks[i];
I should append 'U' here too.
>> + }
>> +
>> + printf "#define %s_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS !=
>> %d)\n\n", s, ncapints;
>> + }
>> +
>> + printf "#endif /* _ASM_X86_FEATUREMASKS_H */\n";
>> +}
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 4/4] x86/cpufeatures: Use AWK to generate {REQUIRED|DISABLED}_MASK_BIT_SET
2024-06-23 20:28 ` Brian Gerst
2024-06-24 7:29 ` Xin Li
2024-06-24 9:32 ` [PATCH v3A " Xin Li (Intel)
@ 2024-06-27 16:51 ` Xin Li
2 siblings, 0 replies; 16+ messages in thread
From: Xin Li @ 2024-06-27 16:51 UTC (permalink / raw)
To: Brian Gerst
Cc: linux-kernel, linux-perf-users, tglx, mingo, bp, dave.hansen, x86,
hpa, will, peterz, akpm, acme, namhyung
On 6/23/2024 1:28 PM, Brian Gerst wrote:
> On Sat, Jun 22, 2024 at 1:14 PM Xin Li (Intel) <xin@zytor.com> wrote:
>>
>> Generate macros {REQUIRED|DISABLED}_MASK_BIT_SET in the newly added AWK
>> script that generates the required and disabled feature mask header.
>>
>> Suggested-by: Brian Gerst <brgerst@gmail.com>
>> Signed-off-by: Xin Li (Intel) <xin@zytor.com>
>> ---
> Checking NCAPINTS isn't necessary anymore. It was needed when these
> macros had to be manually updated, but now if cpufeatures.h changes
> this header will be regenerated.
>
>> }
>>
>> printf "#endif /* _ASM_X86_FEATUREMASKS_H */\n";
>> --
>> 2.45.2
>>
>
> Otherwise, it looks good.
>
Do you mind to give a review-by?
Thanks!
Xin
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3B 4/4] x86/cpufeatures: Use AWK to generate {REQUIRED|DISABLED}_MASK_BIT_SET
2024-06-25 5:22 ` [PATCH v3B " Xin Li (Intel)
@ 2024-06-27 18:39 ` Brian Gerst
0 siblings, 0 replies; 16+ messages in thread
From: Brian Gerst @ 2024-06-27 18:39 UTC (permalink / raw)
To: Xin Li (Intel)
Cc: linux-kernel, linux-perf-users, tglx, mingo, bp, dave.hansen, x86,
hpa, will, peterz, akpm, acme, namhyung, andrew.cooper3
On Tue, Jun 25, 2024 at 1:23 AM Xin Li (Intel) <xin@zytor.com> wrote:
>
> Generate macros {REQUIRED|DISABLED}_MASK_BIT_SET in the newly added AWK
> script that generates the required and disabled feature mask header.
>
> Suggested-by: Brian Gerst <brgerst@gmail.com>
> Signed-off-by: Xin Li (Intel) <xin@zytor.com>
> ---
>
> Change since v3A:
> * Use '1U' instead of '1' in feature mask shifting (Andrew Cooper).
>
> Change since v3:
> * Checking NCAPINTS isn't necessary anymore. It was needed when these
> macros had to be manually updated, but now if cpufeatures.h changes
> this header will be regenerated (Brian Gerst).
> ---
> arch/x86/include/asm/cpufeature.h | 69 -------------------------------
> arch/x86/tools/featuremasks.awk | 9 +++-
> 2 files changed, 8 insertions(+), 70 deletions(-)
>
> diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
> index 8332f596ba3c..8161dfb3255c 100644
> --- a/arch/x86/include/asm/cpufeature.h
> +++ b/arch/x86/include/asm/cpufeature.h
> @@ -55,75 +55,6 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
> #define test_cpu_cap(c, bit) \
> arch_test_bit(bit, (unsigned long *)((c)->x86_capability))
>
> -/*
> - * There are 32 bits/features in each mask word. The high bits
> - * (selected with (bit>>5) give us the word number and the low 5
> - * bits give us the bit/feature number inside the word.
> - * (1UL<<((bit)&31) gives us a mask for the feature_bit so we can
> - * see if it is set in the mask word.
> - */
> -#define CHECK_BIT_IN_MASK_WORD(maskname, word, bit) \
> - (((bit)>>5)==(word) && (1UL<<((bit)&31) & maskname##word ))
> -
> -/*
> - * {REQUIRED,DISABLED}_MASK_CHECK below may seem duplicated with the
> - * following BUILD_BUG_ON_ZERO() check but when NCAPINTS gets changed, all
> - * header macros which use NCAPINTS need to be changed. The duplicated macro
> - * use causes the compiler to issue errors for all headers so that all usage
> - * sites can be corrected.
> - */
> -#define REQUIRED_MASK_BIT_SET(feature_bit) \
> - ( CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 0, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 1, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 2, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 3, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 4, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 5, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 6, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 7, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 8, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 9, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 10, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 11, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 12, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 13, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 14, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 15, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 16, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 17, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 19, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 20, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 21, feature_bit) || \
> - REQUIRED_MASK_CHECK || \
> - BUILD_BUG_ON_ZERO(NCAPINTS != 22))
> -
> -#define DISABLED_MASK_BIT_SET(feature_bit) \
> - ( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 0, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 1, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 2, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 3, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 4, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 5, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 6, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 7, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 8, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 9, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 10, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 11, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 12, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 13, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 14, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 15, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 16, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 17, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 19, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 20, feature_bit) || \
> - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 21, feature_bit) || \
> - DISABLED_MASK_CHECK || \
> - BUILD_BUG_ON_ZERO(NCAPINTS != 22))
> -
> #define cpu_has(c, bit) \
> (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
> test_cpu_cap(c, bit))
> diff --git a/arch/x86/tools/featuremasks.awk b/arch/x86/tools/featuremasks.awk
> index 989b021e73d3..e0383683e630 100755
> --- a/arch/x86/tools/featuremasks.awk
> +++ b/arch/x86/tools/featuremasks.awk
> @@ -77,7 +77,14 @@ END {
> printf "#define %s_MASK%d\t0x%08x\n", s, i, masks[i];
> }
>
> - printf "#define %s_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != %d)\n\n", s, ncapints;
> + printf "\n#define %s_MASK_BIT_SET(x)\t\t\t\\\n", s;
> + printf "\t((\t\t\t\t\t";
> + for (i = 0; i < ncapints; i++) {
> + if (masks[i])
> + printf "\t\\\n\t\t((x) >> 5) == %2d ? %s_MASK%d :", i, s, i;
> + }
> + printf " 0\t\\\n";
> + printf "\t) & (1U << ((x) & 31)))\n";
> }
>
> printf "#endif /* _ASM_X86_FEATUREMASKS_H */\n";
> --
> 2.45.2
>
Reviewed-by: Brian Gerst <brgerst@gmail.com>
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2024-06-27 18:39 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-22 17:14 [PATCH v3 0/4] x86/cpufeatures: Automatically generate required and disabled feature masks Xin Li (Intel)
2024-06-22 17:14 ` [PATCH v3 1/4] x86/cpufeatures: Add {required,disabled} feature configs Xin Li (Intel)
2024-06-22 17:14 ` [PATCH v3 2/4] x86/cpufeatures: Generate a feature mask header based on build config Xin Li (Intel)
2024-06-26 11:36 ` Nikolay Borisov
2024-06-27 16:45 ` Xin Li
2024-06-22 17:14 ` [PATCH v3 3/4] x86/cpufeatures: Remove {disabled,required}-features.h Xin Li (Intel)
2024-06-22 17:14 ` [PATCH v3 4/4] x86/cpufeatures: Use AWK to generate {REQUIRED|DISABLED}_MASK_BIT_SET Xin Li (Intel)
2024-06-23 20:28 ` Brian Gerst
2024-06-24 7:29 ` Xin Li
2024-06-24 10:24 ` Andrew Cooper
2024-06-24 17:42 ` Xin Li
2024-06-25 5:22 ` [PATCH v3B " Xin Li (Intel)
2024-06-27 18:39 ` Brian Gerst
2024-06-24 9:32 ` [PATCH v3A " Xin Li (Intel)
2024-06-27 16:51 ` [PATCH v3 " Xin Li
2024-06-22 17:31 ` [PATCH v3 0/4] x86/cpufeatures: Automatically generate required and disabled feature masks Xin Li
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).