[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID:
<SN6PR02MB415756D1829740F6E8AC11D1D4D82@SN6PR02MB4157.namprd02.prod.outlook.com>
Date: Thu, 20 Mar 2025 16:23:33 +0000
From: Michael Kelley <mhklinux@...look.com>
To: "H. Peter Anvin (Intel)" <hpa@...or.com>, "Xin Li (Intel)"
<xin@...or.com>, "Borislav Petkov (AMD)" <bp@...en8.de>, Ingo Molnar
<mingo@...nel.org>, Nikolay Borisov <nik.borisov@...e.com>, Linus Torvalds
<torvalds@...ux-foundation.org>, "x86@...nel.org" <x86@...nel.org>
CC: "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: RE: [tip: x86/core] x86/cpufeatures: Generate the
<asm/cpufeaturemasks.h> header based on build config
From: tip-bot2@...utronix.de <tip-bot2@...utronix.de> Sent: Wednesday, March 19, 2025 4:04 AM
>
> The following commit has been merged into the x86/core branch of tip:
>
> Commit-ID: 841326332bcb13ae4e6cd456350bf566a402b45e
> Gitweb: https://lore.kernel.org/all/20250305184725.3341760-3-xin@zytor.com/
> Author: H. Peter Anvin (Intel) <hpa@...or.com>
> AuthorDate: Wed, 05 Mar 2025 10:47:22 -08:00
> Committer: Ingo Molnar <mingo@...nel.org>
> CommitterDate: Wed, 19 Mar 2025 11:15:11 +01:00
>
> x86/cpufeatures: Generate the <asm/cpufeaturemasks.h> header based on build config
This commit is producing a subtle change in build behavior, as seen in linux-next.
In the current behavior, assume the kernel has been fully built. Then if nothing
is changed but the modified time on the .config file (and the contents of .config
are unchanged), a new build runs
SYNC include/config/auto.conf.cmd
and figures out that nothing has changed, so it does nothing.
With this commit, changing the modified time on .config causes cpufeaturemasks.h
to be rebuilt, and then all dependencies on cpufeaturemasks.h are also rebuilt. It
doesn't figure out that nothing has changed in .config. A fair amount of
unnecessary rebuilding is done.
I'm seeing this changed behavior specifically with the make-kpkg script on
Ubuntu 20.04. It's not clear why make-kpkg is updating the modified time
on .config, but prior to this commit, that update had no negative effect.
I don't know if anything can be done about this change in behavior, as
Makefiles and build dependencies aren't my expertise. But I wanted to
point out what's happening.
Michael
>
> Introduce an AWK script to auto-generate the <asm/cpufeaturemasks.h> header
> with required and disabled feature masks based on <asm/cpufeatures.h>
> and the current build config.
>
> Thus for any CPU feature with a build config, e.g., X86_FRED, simply add:
>
> config X86_DISABLED_FEATURE_FRED
> def_bool y
> depends on !X86_FRED
>
> to arch/x86/Kconfig.cpufeatures, instead of adding a conditional CPU
> feature disable flag, e.g., DISABLE_FRED.
>
> Lastly, the generated required and disabled feature masks will be added to
> their corresponding feature masks for this particular compile-time
> configuration.
>
> [ Xin: build integration improvements ]
> [ mingo: Improved changelog and comments ]
>
> Signed-off-by: H. Peter Anvin (Intel) <hpa@...or.com>
> Signed-off-by: Xin Li (Intel) <xin@...or.com>
> Signed-off-by: Borislav Petkov (AMD) <bp@...en8.de>
> Signed-off-by: Ingo Molnar <mingo@...nel.org>
> Reviewed-by: Nikolay Borisov <nik.borisov@...e.com>
> Cc: Linus Torvalds <torvalds@...ux-foundation.org>
> Link:
> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2
> Fr%2F20250305184725.3341760-3-
> xin%40zytor.com&data=05%7C02%7C%7C6243cf4a3cb84dbe135208dd66d70d34%7C84
> df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C638779796029571293%7CUnknown%
> 7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMi
> IsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=TSpia2XulsyZ%2BwNqB
> 2tdp66Z4hbaojEHgZ0x%2BUi2OF8%3D&reserved=0
> ---
> arch/x86/Makefile | 15 +++++-
> 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/cpufeaturemasks.awk | 81 +++++++++++++++++++++++++++++-
> 9 files changed, 105 insertions(+), 12 deletions(-)
> create mode 100755 arch/x86/tools/cpufeaturemasks.awk
>
> diff --git a/arch/x86/Makefile b/arch/x86/Makefile
> index 6784129..a607769 100644
> --- a/arch/x86/Makefile
> +++ b/arch/x86/Makefile
> @@ -269,6 +269,21 @@ archheaders:
> $(Q)$(MAKE) $(build)=arch/x86/entry/syscalls all
>
> ###
> +# <asm/cpufeaturemasks.h> header generation
> +
> +cpufeaturemasks.hdr := arch/x86/include/generated/asm/cpufeaturemasks.h
> +cpufeaturemasks.awk := $(srctree)/arch/x86/tools/cpufeaturemasks.awk
> +cpufeatures_hdr := $(srctree)/arch/x86/include/asm/cpufeatures.h
> +targets += $(cpufeaturemasks.hdr)
> +quiet_cmd_gen_featuremasks = GEN $@
> + cmd_gen_featuremasks = $(AWK) -f $(cpufeaturemasks.awk) $(cpufeatures_hdr)
> $(KCONFIG_CONFIG) > $@
> +
> +$(cpufeaturemasks.hdr): $(cpufeaturemasks.awk) $(cpufeatures_hdr)
> $(KCONFIG_CONFIG) FORCE
> + $(shell mkdir -p $(dir $@))
> + $(call if_changed,gen_featuremasks)
> +archprepare: $(cpufeaturemasks.hdr)
> +
> +###
> # Kernel objects
>
> libs-y += arch/x86/lib/
> diff --git a/arch/x86/boot/cpucheck.c b/arch/x86/boot/cpucheck.c
> index 0aae4d4..f82de8d 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/cpufeaturemasks.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 d75237b..0cabdac 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 da0ccc5..22d730b 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/cpufeaturemasks.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 58f4dde..4566000 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 += cpufeaturemasks.h
>
> generic-y += early_ioremap.h
> generic-y += fprobe.h
> diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
> index e955da3..d54db88 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/cpufeaturemasks.h>
>
> enum cpuid_leafs
> {
> diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
> index 8770dc1..c0462be 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 1258a58..37ad437 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/cpufeaturemasks.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/cpufeaturemasks.awk
> b/arch/x86/tools/cpufeaturemasks.awk
> new file mode 100755
> index 0000000..59757ca
> --- /dev/null
> +++ b/arch/x86/tools/cpufeaturemasks.awk
> @@ -0,0 +1,81 @@
> +#!/usr/bin/awk
> +#
> +# Convert cpufeatures.h to a list of compile-time masks
> +# Note: this blithely assumes that each word has at least one
> +# feature defined in it; if not, something else is wrong!
> +#
> +
> +BEGIN {
> + printf "#ifndef _ASM_X86_CPUFEATUREMASKS_H\n";
> + printf "#define _ASM_X86_CPUFEATUREMASKS_H\n\n";
> +
> + file = 0
> +}
> +
> +FNR == 1 {
> + ++file;
> +
> + # arch/x86/include/asm/cpufeatures.h
> + if (file == 1)
> + FS = "[ \t()*+]+";
> +
> + # .config
> + if (file == 2)
> + FS = "=";
> +}
> +
> +# Create a dictionary of sorts, containing all defined feature bits
> +file == 1 && $1 ~ /^#define$/ && $2 ~ /^X86_FEATURE_/ {
> + nfeat = $3 * $4 + $5;
> + feat = $2;
> + sub(/^X86_FEATURE_/, "", feat);
> + feats[nfeat] = feat;
> +}
> +file == 1 && $1 ~ /^#define$/ && $2 == "NCAPINTS" {
> + ncapints = int($3);
> +}
> +
> +# Create a dictionary featstat[REQUIRED|DISABLED, FEATURE_NAME] = on | off
> +file == 2 && $1 ~ /^CONFIG_X86_(REQUIRED|DISABLED)_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++) {
> + feat = feats[i*32 + j];
> + if (featstat[s, feat]) {
> + nfstr = fstr " " feat;
> + if (length(nfstr) > 72) {
> + printf " * %s\n", fstr;
> + nfstr = " " feat;
> + }
> + fstr = nfstr;
> + mask += (2 ^ j);
> + }
> + }
> + masks[i] = mask;
> + }
> + printf " * %s\n */\n", fstr;
> +
> + for (i = 0; i < ncapints; i++)
> + printf "#define %s_MASK%d\t0x%08xU\n", s, i, masks[i];
> +
> + printf "#define %s_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS !=
> %d)\n\n", s, ncapints;
> + }
> +
> + printf "#endif /* _ASM_X86_CPUFEATUREMASKS_H */\n";
> +}
Powered by blists - more mailing lists