From nobody Mon Apr 6 09:16:05 2026 Received: from mail-106119.protonmail.ch (mail-106119.protonmail.ch [79.135.106.119]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EBF043B47E0 for ; Fri, 20 Mar 2026 12:50:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.135.106.119 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774011033; cv=none; b=Hl84e4Z/gU358bHh4ViYIE7WWx48uX1JrxRgpKmi+5WiKBxGZQ1kJlZRDwv3AxW140L5/DIkSftNS3gf+p/9LeRYmgFI834ZSzBtzaLkm0DhKeVj/ldWOGTBeVfT94J5CPWE/ueh0yEkJuXtwSWxaRelwCabNK9NyY1UE2+7vLc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774011033; c=relaxed/simple; bh=42ClJ3mgjFdiqXPJ7+sQawcD/PiBFkaC7lPt56nfUmY=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QUu9kFvl5Odpvs3YHCZEkcZiuI6BguVwktK7X2a3ug4IW+7g0bByVBm5HOHuQYhYAoYLoRR2uuBucWYOfnWHQGYWoI13WUPh2o9O/amUYnm7rS3ne73VpG6r3MrKG2hllg2GVvfa5Jxp1OpBYjcZr5inHCvbpYluURCfcsIZZEY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=q2/f7bwp; arc=none smtp.client-ip=79.135.106.119 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="q2/f7bwp" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774011028; x=1774270228; bh=WyN+SH5fx2qFhOO+ienZswuT99oZzI2AUK4818Nlb7U=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=q2/f7bwpzPA6NNbpcQ8Sv6PEbdjYt7/4abcnC1Hb4y2zzUgbLeqeidcS+5NXwk6SW VZjImW/sUdxrAmXisN4YzM4q0ieP9INuD3sDDLOSYd+fpIA0T6Wd7QNsASMzMmsh3P UhsjUpT2rRjgGdpQG0DhdZLuWeOHl33P1szZLYaRt+beLc9/GBOC30jz/y0fxdGS6c owYPzOOMAnqDNgKsRRRC0kaXlw9eG3Ab7UibcPJzBHp/8lWvUAjfiFKU+70ofsjegp FhAMtTfocu0xS+mXlsoKtZFsX/ZeJDHEf0kJ8cxab8wGom+dRhnGqoIXVPrFjMP3LK BElK9uPIG5xuQ== Date: Fri, 20 Mar 2026 12:50:25 +0000 To: tglx@kernel.org, peterz@infradead.org, xin@zytor.com, maciej.wieczor-retman@intel.com, babu.moger@amd.com, chang.seok.bae@intel.com, sohil.mehta@intel.com, dave.hansen@linux.intel.com, jpoimboe@kernel.org, elena.reshetova@intel.com, hpa@zytor.com, pawan.kumar.gupta@linux.intel.com, ak@linux.intel.com, darwi@linutronix.de, bp@alien8.de, mingo@redhat.com From: Maciej Wieczor-Retman Cc: x86@kernel.org, linux-kernel@vger.kernel.org, m.wieczorretman@pm.me Subject: [PATCH v11 3/4] x86/cpu: Do a sanity check on required feature bits Message-ID: <7312c9f2feab8aea4612ed9a1841e8c22f5f69b1.1774008873.git.m.wieczorretman@pm.me> In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: 0f9b6bce2a71302bb674e39d149f12f5aedf764a Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maciej Wieczor-Retman After CPU identification concludes, do a sanity check by comparing the final x86_capability bitmask with the pre-defined required feature bits. Because for_each_set_bit() expects 64-bit values and feature bitmasks are 32-bit use DECLARE_BITMAP() to avoid unaligned memory accesses if NCAPINTS is ever an odd number. Signed-off-by: Maciej Wieczor-Retman --- 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 | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 0e318f3d56cb..92159a0963c8 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -2005,6 +2005,38 @@ const char *x86_cap_name(unsigned int bit, char *buf) return buf; } =20 +/* + * As a sanity check compare the final x86_capability bitmask with the ini= tial + * predefined required feature bits. + */ +static void verify_required_features(const struct cpuinfo_x86 *c) +{ + u32 required_features[NCAPINTS] =3D REQUIRED_MASK_INIT; + DECLARE_BITMAP(missing, NCAPINTS * 32); + char cap_buf[X86_CAP_BUF_SIZE]; + u32 *missing_u32; + unsigned int i; + u32 error =3D 0; + + memset(missing, 0, sizeof(missing)); + missing_u32 =3D (u32 *)missing; + + for (i =3D 0; i < NCAPINTS; i++) { + missing_u32[i] =3D ~c->x86_capability[i] & required_features[i]; + error |=3D missing_u32[i]; + } + + if (!error) + return; + + /* At least one required feature is missing */ + pr_warn("CPU %d: missing required feature(s):", c->cpu_index); + for_each_set_bit(i, missing, NCAPINTS * 32) + pr_cont(" %s", x86_cap_name(i, cap_buf)); + 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... */ @@ -2134,6 +2166,8 @@ static void identify_cpu(struct cpuinfo_x86 *c) mcheck_cpu_init(c); =20 numa_add_cpu(smp_processor_id()); + + verify_required_features(c); } =20 /* --=20 2.53.0