From nobody Thu Apr 2 17:17:48 2026 Received: from mail-106118.protonmail.ch (mail-106118.protonmail.ch [79.135.106.118]) (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 D35652F12B3 for ; Fri, 27 Mar 2026 15:11:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.135.106.118 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774624267; cv=none; b=Nm0vmaoc/ncn9gSmmQbMjdtquoNxGSySv5WXRkCXa8AVlSGZuCMvx1BtQWi9epL3pELUuy4ILLaNydkcWo07y1cvIFaSucZI4mFXwnA3qMh5fHAD94jLQ806GqRJcvJmunh15R06IWzkSqzpCUtHbb32WCRLI2yu8qNXu/RyPgs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774624267; c=relaxed/simple; bh=ag+8PwGiW6rIhdxl4ImPJp/eG0OuSURZqsZb6oiM+5w=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=NQt7ucRlUkBqxNVfhx78QD5NxXWvVPkSKSNS+iJ/4nAi2ex0QkrUCm1UxdYukJhak2X8rkMo9ShcbWkFE5apgMpY49Rk3KuSp53P99BM5YnZOTQhtSfKQ+HHOlRmEp/DZsMfuNDAPPPf0emxI9/QyASST8QUAkuUcmRsxlAjG80= 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=SgqkmztY; arc=none smtp.client-ip=79.135.106.118 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="SgqkmztY" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774624263; x=1774883463; bh=kj2KAWi+7/I3BFLvozqp6WSsebcZQhRqe3ZR8ZJLQ6U=; 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=SgqkmztYmugs1ElDmKimqcU2NdIQhGxlivfJoBJCwWlQ3CdL2ge7EX0am4xzMnsmA oSICR3a2sTtDF4dQ4P/kTJqUNjbpsh0qYEXKGKmonF0wHor/Nhz5YEB2HsaQ9H+4Ts Tu+e4bdv1FmtmohPr/+hfDivl0sV9qWCmWMEscRNw+1027S1oo6Vl6RL8f2yKZwD1O VZFRP1YFMdsiYmAOEdqdJ8Pj/oUyTuTDTdYpXLxNBALB3hSUDV5qjTblkiM0sbuNFg hiaXO0EInlurKOEZlNua+aGK+RB+GKpPvCzUdrDHCAUUDocVZPnqsnKy02q7bw1sDS uy8Sw3JKKX/kQ== Date: Fri, 27 Mar 2026 15:10:58 +0000 To: bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com, xin@zytor.com, chang.seok.bae@intel.com, mingo@redhat.com, elena.reshetova@intel.com, maciej.wieczor-retman@intel.com, babu.moger@amd.com, sohil.mehta@intel.com, pawan.kumar.gupta@linux.intel.com, pmladek@suse.com, nik.borisov@suse.com, ptesarik@suse.com, darwi@linutronix.de, tglx@kernel.org, peterz@infradead.org, jpoimboe@kernel.org, ak@linux.intel.com From: Maciej Wieczor-Retman Cc: linux-kernel@vger.kernel.org, x86@kernel.org, m.wieczorretman@pm.me Subject: [PATCH v12 3/4] x86/cpu: Do a sanity check on required feature bits Message-ID: <76b7b70ef4b900b968b632e295ebb84fcbc986a5.1774623092.git.m.wieczorretman@pm.me> In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: fbc08a0d7335e708877a30600b243ab3a347e2c9 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. 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 --- 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; } =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 + 1] =3D REQUIRED_MASK_INIT; + char cap_buf[X86_NAMELESS_FEAT_BUFLEN]; + int i, error =3D 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 =3D 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); =20 numa_add_cpu(smp_processor_id()); + + verify_required_features(c); } =20 /* --=20 2.53.0