[PATCH v3] x86: Clear feature bits disabled at compile-time

Maciej Wieczor-Retman posted 1 patch 2 months, 1 week ago
There is a newer version of this series
arch/x86/kernel/cpu/common.c       | 3 ++-
arch/x86/tools/cpufeaturemasks.awk | 6 ++++++
2 files changed, 8 insertions(+), 1 deletion(-)
[PATCH v3] x86: Clear feature bits disabled at compile-time
Posted by Maciej Wieczor-Retman 2 months, 1 week ago
If some config options are disabled during compile time, they still are
enumerated in macros that use the x86_capability bitmask - cpu_has() or
this_cpu_has().

The features are also visible in /proc/cpuinfo even though they are not
enabled - which is contrary to what the documentation states about the
file. Examples of such feature flags are lam, fred, sgx, ibrs_enhanced,
split_lock_detect, user_shstk, avx_vnni and enqcmd.

Add a DISABLED_MASK_INITIALIZER() macro that creates an initializer list
filled with DISABLED_MASKx bitmasks.

Initialize the cpu_caps_cleared array with the autogenerated disabled
bitmask.

Fixes: ea4e3bef4c94 ("Documentation/x86: Add documentation for /proc/cpuinfo feature flags")
Reported-by: Farrah Chen <farrah.chen@intel.com>
Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
Cc: <stable@vger.kernel.org>
---
Changelog v3:
- Remove Fixes: tags, keep only one at the point where the documentation
  changed and promised feature bits wouldn't show up if they're not
  enabled.
- Don't use a helper to initialize cpu_caps_cleared, just statically
  initialize it.
- Remove changes to cpu_caps_set.
- Rewrite patch message to account for changes.

Changelog v2:
- Redo the patch to utilize a more generic solution, not just fix the
  LAM and FRED feature bits.
- Note more feature flags that shouldn't be present.
- Add fixes and cc tags.

 arch/x86/kernel/cpu/common.c       | 3 ++-
 arch/x86/tools/cpufeaturemasks.awk | 6 ++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 77afca95cced..061e91922725 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -704,7 +704,8 @@ static const char *table_lookup_model(struct cpuinfo_x86 *c)
 }
 
 /* Aligned to unsigned long to avoid split lock in atomic bitmap ops */
-__u32 cpu_caps_cleared[NCAPINTS + NBUGINTS] __aligned(sizeof(unsigned long));
+__u32 cpu_caps_cleared[NCAPINTS + NBUGINTS] __aligned(sizeof(unsigned long)) =
+	DISABLED_MASK_INIT_VALUES;
 __u32 cpu_caps_set[NCAPINTS + NBUGINTS] __aligned(sizeof(unsigned long));
 
 #ifdef CONFIG_X86_32
diff --git a/arch/x86/tools/cpufeaturemasks.awk b/arch/x86/tools/cpufeaturemasks.awk
index 173d5bf2d999..6ebaa27f1275 100755
--- a/arch/x86/tools/cpufeaturemasks.awk
+++ b/arch/x86/tools/cpufeaturemasks.awk
@@ -84,5 +84,11 @@ END {
 		printf "\t) & (1U << ((x) & 31)))\n\n";
 	}
 
+		printf "\n#define DISABLED_MASK_INIT_VALUES\t\t\t\\";
+		printf "\n\t{\t\t\t\t\t\t\\";
+		for (i = 0; i < ncapints; i++)
+			printf "\n\t\tDISABLED_MASK%d,\t\t\t\\", i;
+		printf "\n\t}\n\n";
+
 	printf "#endif /* _ASM_X86_CPUFEATUREMASKS_H */\n";
 }
-- 
2.49.0
Re: [PATCH v3] x86: Clear feature bits disabled at compile-time
Posted by Maciej Wieczor-Retman 2 months, 1 week ago
Hello Greg,

I'd like to ask you for guidence on how to proceed with backporting this change
to the 5.10 stable kernel and newer ones.

I prepared a patch that is applicable on 5.10.240, and doesn't use the 6.14
disabled feature bit infrastructure - the disabled bitmask is simply open coded.
And as far as I tested the patch compiles and works in QEMU.

I wanted to ask if I should submit that patch to the stable ML separately? If
so, should I do it for 5.10 only or all the stable ones separately? (if they
have different lenghts of the disabled bitmask) Or do you prefer to backport it
/ apply it yourself?

I'm putting the backported patch both as attachment to this message for easier
downloading, and in text below to make commenting on it easier:

	From 7dd94f58d28ac98dc39bebc8ce8479039bc069c8 Mon Sep 17 00:00:00 2001
	From: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
	Date: Thu, 24 Jul 2025 08:34:33 +0200
	Subject: [PATCH] x86: Clear feature bits disabled at compile time

	If some config options are disabled during compile time, they still are
	enumerated in macros that use the x86_capability bitmask - cpu_has() or
	this_cpu_has().

	The features are also visible in /proc/cpuinfo even though they are not
	enabled - which is contrary to what the documentation states about the
	file.

	Mainline upstream kernel autogenerates the disabled masks at compile
	time, but this infrastructure was introduced in the 6.14 kernel. To
	backport this, open code the DISABLED_MASK_INITIALIZER macro instead.

	Initialize the cpu_caps_cleared array with the disabled bitmask.

	Fixes: ea4e3bef4c94 ("Documentation/x86: Add documentation for /proc/cpuinfo feature flags")
	Reported-by: Farrah Chen <farrah.chen@intel.com>
	Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
	Cc: <stable@vger.kernel.org>
	---
	 arch/x86/include/asm/disabled-features.h | 26 ++++++++++++++++++++++++
	 arch/x86/kernel/cpu/common.c             |  3 ++-
	 2 files changed, 28 insertions(+), 1 deletion(-)

	diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h
	index 170c87253340..a84e62cdae57 100644
	--- a/arch/x86/include/asm/disabled-features.h
	+++ b/arch/x86/include/asm/disabled-features.h
	@@ -106,4 +106,30 @@
	 #define DISABLED_MASK21	0
	 #define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 23)
	 
	+#define DISABLED_MASK_INITIALIZER	\
	+	{				\
	+		DISABLED_MASK0,		\
	+		DISABLED_MASK1,		\
	+		DISABLED_MASK2,		\
	+		DISABLED_MASK3,		\
	+		DISABLED_MASK4,		\
	+		DISABLED_MASK5,		\
	+		DISABLED_MASK6,		\
	+		DISABLED_MASK7,		\
	+		DISABLED_MASK8,		\
	+		DISABLED_MASK9,		\
	+		DISABLED_MASK10,	\
	+		DISABLED_MASK11,	\
	+		DISABLED_MASK12,	\
	+		DISABLED_MASK13,	\
	+		DISABLED_MASK14,	\
	+		DISABLED_MASK15,	\
	+		DISABLED_MASK16,	\
	+		DISABLED_MASK17,	\
	+		DISABLED_MASK18,	\
	+		DISABLED_MASK19,	\
	+		DISABLED_MASK20,	\
	+		DISABLED_MASK21,	\
	+	}
	+
	 #endif /* _ASM_X86_DISABLED_FEATURES_H */
	diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
	index 258e28933abe..a3c323acff5f 100644
	--- a/arch/x86/kernel/cpu/common.c
	+++ b/arch/x86/kernel/cpu/common.c
	@@ -588,7 +588,8 @@ static const char *table_lookup_model(struct cpuinfo_x86 *c)
	 }
	 
	 /* Aligned to unsigned long to avoid split lock in atomic bitmap ops */
	-__u32 cpu_caps_cleared[NCAPINTS + NBUGINTS] __aligned(sizeof(unsigned long));
	+__u32 cpu_caps_cleared[NCAPINTS + NBUGINTS] __aligned(sizeof(unsigned long)) =
	+	DISABLED_MASK_INITIALIZER;
	 __u32 cpu_caps_set[NCAPINTS + NBUGINTS] __aligned(sizeof(unsigned long));
	 
	 void load_percpu_segment(int cpu)
	-- 
	2.49.0

-- 
Kind regards
Maciej Wieczór-Retman
From 7dd94f58d28ac98dc39bebc8ce8479039bc069c8 Mon Sep 17 00:00:00 2001
From: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
Date: Thu, 24 Jul 2025 08:34:33 +0200
Subject: [PATCH] x86: Clear feature bits disabled at compile time

If some config options are disabled during compile time, they still are
enumerated in macros that use the x86_capability bitmask - cpu_has() or
this_cpu_has().

The features are also visible in /proc/cpuinfo even though they are not
enabled - which is contrary to what the documentation states about the
file.

Mainline upstream kernel autogenerates the disabled masks at compile
time, but this infrastructure was introduced in the 6.14 kernel. To
backport this, open code the DISABLED_MASK_INITIALIZER macro instead.

Initialize the cpu_caps_cleared array with the disabled bitmask.

Fixes: ea4e3bef4c94 ("Documentation/x86: Add documentation for /proc/cpuinfo feature flags")
Reported-by: Farrah Chen <farrah.chen@intel.com>
Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
Cc: <stable@vger.kernel.org>
---
 arch/x86/include/asm/disabled-features.h | 26 ++++++++++++++++++++++++
 arch/x86/kernel/cpu/common.c             |  3 ++-
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h
index 170c87253340..a84e62cdae57 100644
--- a/arch/x86/include/asm/disabled-features.h
+++ b/arch/x86/include/asm/disabled-features.h
@@ -106,4 +106,30 @@
 #define DISABLED_MASK21	0
 #define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 23)
 
+#define DISABLED_MASK_INITIALIZER	\
+	{				\
+		DISABLED_MASK0,		\
+		DISABLED_MASK1,		\
+		DISABLED_MASK2,		\
+		DISABLED_MASK3,		\
+		DISABLED_MASK4,		\
+		DISABLED_MASK5,		\
+		DISABLED_MASK6,		\
+		DISABLED_MASK7,		\
+		DISABLED_MASK8,		\
+		DISABLED_MASK9,		\
+		DISABLED_MASK10,	\
+		DISABLED_MASK11,	\
+		DISABLED_MASK12,	\
+		DISABLED_MASK13,	\
+		DISABLED_MASK14,	\
+		DISABLED_MASK15,	\
+		DISABLED_MASK16,	\
+		DISABLED_MASK17,	\
+		DISABLED_MASK18,	\
+		DISABLED_MASK19,	\
+		DISABLED_MASK20,	\
+		DISABLED_MASK21,	\
+	}
+
 #endif /* _ASM_X86_DISABLED_FEATURES_H */
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 258e28933abe..a3c323acff5f 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -588,7 +588,8 @@ static const char *table_lookup_model(struct cpuinfo_x86 *c)
 }
 
 /* Aligned to unsigned long to avoid split lock in atomic bitmap ops */
-__u32 cpu_caps_cleared[NCAPINTS + NBUGINTS] __aligned(sizeof(unsigned long));
+__u32 cpu_caps_cleared[NCAPINTS + NBUGINTS] __aligned(sizeof(unsigned long)) =
+	DISABLED_MASK_INITIALIZER;
 __u32 cpu_caps_set[NCAPINTS + NBUGINTS] __aligned(sizeof(unsigned long));
 
 void load_percpu_segment(int cpu)
-- 
2.49.0

Re: [PATCH v3] x86: Clear feature bits disabled at compile-time
Posted by Greg KH 2 months, 1 week ago
On Thu, Jul 24, 2025 at 12:13:25PM +0200, Maciej Wieczor-Retman wrote:
> Hello Greg,
> 
> I'd like to ask you for guidence on how to proceed with backporting this change
> to the 5.10 stable kernel and newer ones.

Don't worry about it UNTIL your patch lands in Linus's tree.  Then, if
it doesn't apply to a specific stable branch, just send us a working
backport.  Not too complex :)

thanks,

greg k-h
Re: [PATCH v3] x86: Clear feature bits disabled at compile-time
Posted by Maciej Wieczor-Retman 2 months, 1 week ago
On 2025-07-24 at 12:34:38 +0200, Greg KH wrote:
>On Thu, Jul 24, 2025 at 12:13:25PM +0200, Maciej Wieczor-Retman wrote:
>> Hello Greg,
>> 
>> I'd like to ask you for guidence on how to proceed with backporting this change
>> to the 5.10 stable kernel and newer ones.
>
>Don't worry about it UNTIL your patch lands in Linus's tree.  Then, if
>it doesn't apply to a specific stable branch, just send us a working
>backport.  Not too complex :)
>
>thanks,
>
>greg k-h

Thank you :)

-- 
Kind regards
Maciej Wieczór-Retman
Re: [PATCH v3] x86: Clear feature bits disabled at compile-time
Posted by Borislav Petkov 2 months, 1 week ago
On July 24, 2025 12:45:51 PM GMT+03:00, Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com> wrote:
>If some config options are disabled during compile time, they still are
>enumerated in macros that use the x86_capability bitmask - cpu_has() or
>this_cpu_has().
>
>The features are also visible in /proc/cpuinfo even though they are not
>enabled - which is contrary to what the documentation states about the
>file. Examples of such feature flags are lam, fred, sgx, ibrs_enhanced,
>split_lock_detect, user_shstk, avx_vnni and enqcmd.
>
>Add a DISABLED_MASK_INITIALIZER() macro that creates an initializer list

Where?

>filled with DISABLED_MASKx bitmasks.
>
>Initialize the cpu_caps_cleared array with the autogenerated disabled
>bitmask.
>
>Fixes: ea4e3bef4c94 ("Documentation/x86: Add documentation for /proc/cpuinfo feature flags")
>Reported-by: Farrah Chen <farrah.chen@intel.com>
>Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
>Cc: <stable@vger.kernel.org>
>---
>Changelog v3:
>- Remove Fixes: tags, keep only one at the point where the documentation
>  changed and promised feature bits wouldn't show up if they're not
>  enabled.

The behavior was there before. Why do you keep pointing at the patch which documents it?

-- 
Sent from a small device: formatting sucks and brevity is inevitable.
Re: [PATCH v3] x86: Clear feature bits disabled at compile-time
Posted by Maciej Wieczor-Retman 2 months, 1 week ago
On 2025-07-24 at 13:12:33 +0300, Borislav Petkov wrote:
>On July 24, 2025 12:45:51 PM GMT+03:00, Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com> wrote:
>>If some config options are disabled during compile time, they still are
>>enumerated in macros that use the x86_capability bitmask - cpu_has() or
>>this_cpu_has().
>>
>>The features are also visible in /proc/cpuinfo even though they are not
>>enabled - which is contrary to what the documentation states about the
>>file. Examples of such feature flags are lam, fred, sgx, ibrs_enhanced,
>>split_lock_detect, user_shstk, avx_vnni and enqcmd.
>>
>>Add a DISABLED_MASK_INITIALIZER() macro that creates an initializer list
>
>Where?

Oh sorry, must've forgotten to save the changes after I renamed it. Anyway I
just sent the corrected version as RESEND to this message.

>
>>filled with DISABLED_MASKx bitmasks.
>>
>>Initialize the cpu_caps_cleared array with the autogenerated disabled
>>bitmask.
>>
>>Fixes: ea4e3bef4c94 ("Documentation/x86: Add documentation for /proc/cpuinfo feature flags")
>>Reported-by: Farrah Chen <farrah.chen@intel.com>
>>Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
>>Cc: <stable@vger.kernel.org>
>>---
>>Changelog v3:
>>- Remove Fixes: tags, keep only one at the point where the documentation
>>  changed and promised feature bits wouldn't show up if they're not
>>  enabled.
>
>The behavior was there before. Why do you keep pointing at the patch which documents it?

Is my assumption incorrect, that before it was documented, the rules for feature
flags were more loose and afterwards they were more strict? So before that
documentation was written it could be classified under "undefined behavior".

As I wrote in the v2 thread, based on what's in the documentation added at the
commit I pointed out, the behavior is a bug. Features that are disabled -
due to not being compiled - are showing up in /proc/cpuinfo [1].

[1] https://github.com/torvalds/linux/blob/master/Documentation/arch/x86/cpuinfo.rst#the-kernel-disabled-support-for-it-at-compile-time

>
>-- 
>Sent from a small device: formatting sucks and brevity is inevitable.

-- 
Kind regards
Maciej Wieczór-Retman
Re: [PATCH v3] x86: Clear feature bits disabled at compile-time
Posted by Borislav Petkov 2 months, 1 week ago
On Thu, Jul 24, 2025 at 12:59:47PM +0200, Maciej Wieczor-Retman wrote:
> As I wrote in the v2 thread, based on what's in the documentation added at the
> commit I pointed out, the behavior is a bug.

That's all missing the whole idea of Fixes: tags and backports.

Your patch must point to the correct faulty commit which causes this
behavior or to none, which means backport everywhere. And I already
explained this to you.

Pointing to a commit documenting this doesn't make the tree *before*
that all of a sudden not affected.

What I would do is, I'd go through all stable trees and check whether
they're affected. If they are, you craft backports for all of them. You
were already asking Greg what to do.

But pointing to some innocuous commit and deciding that that is the
culprit is not what you should do.

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette
Re: [PATCH v3] x86: Clear feature bits disabled at compile-time
Posted by Maciej Wieczor-Retman 2 months, 1 week ago
On 2025-07-24 at 16:24:52 +0200, Borislav Petkov wrote:
>On Thu, Jul 24, 2025 at 12:59:47PM +0200, Maciej Wieczor-Retman wrote:
>> As I wrote in the v2 thread, based on what's in the documentation added at the
>> commit I pointed out, the behavior is a bug.
>
>That's all missing the whole idea of Fixes: tags and backports.
>
>Your patch must point to the correct faulty commit which causes this
>behavior or to none, which means backport everywhere. And I already
>explained this to you.

Okay, I guess I get it now. At first I tried to point at patches where each
feature was introduced. But that was not helpful to the stable team. In such
cases next time I'll just leave it at none and craft backports as you wrote
below.

>Pointing to a commit documenting this doesn't make the tree *before*
>that all of a sudden not affected.
>
>What I would do is, I'd go through all stable trees and check whether
>they're affected. If they are, you craft backports for all of them. You
>were already asking Greg what to do.
>
>But pointing to some innocuous commit and deciding that that is the
>culprit is not what you should do.
>
>Thx.

Thanks for explaining so thoroughly, I'll keep that in mind :)

>
>-- 
>Regards/Gruss,
>    Boris.
>
>https://people.kernel.org/tglx/notes-about-netiquette

-- 
Kind regards
Maciej Wieczór-Retman