[PATCH v12 3/4] x86/cpu: Do a sanity check on required feature bits

Maciej Wieczor-Retman posted 4 patches 6 days ago
[PATCH v12 3/4] x86/cpu: Do a sanity check on required feature bits
Posted by Maciej Wieczor-Retman 6 days ago
From: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>

After CPU identification concludes, do a sanity check by comparing the
final x86_capability bitmask with the pre-defined required feature bits.

The NCAPINTS + 1 size of the required_features[] array results from
for_each_set_bit() parsing data in 64-bit chunks. In case NCAPINTS is an
odd number it will still reserve and zero out a 64-bit aligned chunk of
memory which will prevent false positives due to unaligned accesses.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
---
Changelog v12:
- Redo the function into a one loop system instead of two loops
  according to Pawan Gupta's suggestion.
- Add a paragraph to the patch message about the NCAPINTS + 1 array
  size.

Changelog v11:
- Use DECLARE_BITMAP() on missing[] and recast to a u32 pointer for
  iterating. Do it to avoid unaligned memory accesses when later using
  for_each_set_bit() if NCAPINTS is going to ever become an odd number.
  missing[] was previously an u32 array and for_each_set_bit() works on
  unsigned long chunks of memory.
- Add a paragraph about the above to the patch message.
- Remove Peter's acked-by due to more changes.

Changelog v10:
- Shorten the comment before the sanity check.
- cpu -> CPU in the warning.
- NCAPINTS << 5 -> NCAPINTS * 32

Changelog v9:
- REQUIRED_MASK_INITIALIZER -> REQUIRED_MASK_INIT
- Redo the comments.
- Fix reverse xmas order.
- Inside for_each_set_bit: (void *) -> (unsigned long *).
- 16 -> X86_CAP_BUF_SIZE.

Changelog v6:
- Add Peter's acked-by tag.
- Rename patch subject to imperative form.
- Add a char buffer to the x86_cap_name() call.

 arch/x86/kernel/cpu/common.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 7cfd124b3fbf..8ad0da7012dd 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -2003,6 +2003,32 @@ const char *x86_feature_name(unsigned int bit, char *buf)
 	return buf;
 }
 
+/*
+ * As a sanity check compare the final x86_capability bitmask with the initial
+ * predefined required feature bits.
+ */
+static void verify_required_features(const struct cpuinfo_x86 *c)
+{
+	u32 required_features[NCAPINTS + 1] = REQUIRED_MASK_INIT;
+	char cap_buf[X86_NAMELESS_FEAT_BUFLEN];
+	int i, error = 0;
+
+	for_each_set_bit(i, (unsigned long *)required_features, NCAPINTS * 32) {
+		if (test_bit(i, (unsigned long *)c->x86_capability))
+			continue;
+		if (!error)
+			pr_warn("CPU %d: missing required feature(s):", c->cpu_index);
+		pr_cont(" %s", x86_feature_name(i, cap_buf));
+		error = 1;
+	}
+
+	if (!error)
+		return;
+
+	pr_cont("\n");
+	add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
+}
+
 /*
  * This does the hard work of actually picking apart the CPU stuff...
  */
@@ -2132,6 +2158,8 @@ static void identify_cpu(struct cpuinfo_x86 *c)
 	mcheck_cpu_init(c);
 
 	numa_add_cpu(smp_processor_id());
+
+	verify_required_features(c);
 }
 
 /*
-- 
2.53.0
Re: [PATCH v12 3/4] x86/cpu: Do a sanity check on required feature bits
Posted by Pawan Gupta 5 days, 22 hours ago
On Fri, Mar 27, 2026 at 03:10:58PM +0000, Maciej Wieczor-Retman wrote:
> +static void verify_required_features(const struct cpuinfo_x86 *c)
> +{
> +	u32 required_features[NCAPINTS + 1] = REQUIRED_MASK_INIT;
> +	char cap_buf[X86_NAMELESS_FEAT_BUFLEN];
> +	int i, error = 0;
> +
> +	for_each_set_bit(i, (unsigned long *)required_features, NCAPINTS * 32) {
> +		if (test_bit(i, (unsigned long *)c->x86_capability))

This can be simplified to:

		if (test_cpu_cap(c, i))

> +			continue;
> +		if (!error)
> +			pr_warn("CPU %d: missing required feature(s):", c->cpu_index);
> +		pr_cont(" %s", x86_feature_name(i, cap_buf));
> +		error = 1;
> +	}
> +
> +	if (!error)
> +		return;
> +
> +	pr_cont("\n");
> +	add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
> +}
Re: [PATCH v12 3/4] x86/cpu: Do a sanity check on required feature bits
Posted by Maciej Wieczor-Retman 5 days, 22 hours ago
On 2026-03-27 at 10:10:33 -0700, Pawan Gupta wrote:
>On Fri, Mar 27, 2026 at 03:10:58PM +0000, Maciej Wieczor-Retman wrote:
>> +static void verify_required_features(const struct cpuinfo_x86 *c)
>> +{
>> +	u32 required_features[NCAPINTS + 1] = REQUIRED_MASK_INIT;
>> +	char cap_buf[X86_NAMELESS_FEAT_BUFLEN];
>> +	int i, error = 0;
>> +
>> +	for_each_set_bit(i, (unsigned long *)required_features, NCAPINTS * 32) {
>> +		if (test_bit(i, (unsigned long *)c->x86_capability))
>
>This can be simplified to:
>
>		if (test_cpu_cap(c, i))
>

Oh, right, thanks! I'll correct that for v13.

-- 
Kind regards
Maciej Wieczór-Retman