From nobody Thu Apr 2 15:36:23 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 6843130EF84 for ; Fri, 27 Mar 2026 15:10:57 +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=1774624258; cv=none; b=Zqpdrgp1hxS4fuQuTDJJdKllkjvNJxx1xLBQMUhW8UZTk05sKPaHEgBATUtfvP8J+H2TBLws0SX36pBhx0yDYX7Ojzla98COaa5wt/WC3ecN0Z7WA8FH1KYJnUmGJPEg9mTtu8DYnbg6UT/3+j3xlhQhEroNl+MzpiASYBDHYJ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774624258; c=relaxed/simple; bh=mEEXKUlmkVBIzNV5wtuGiKeQL7kp/lCT/CJFn9Wdi4I=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=uSk870CTy5zHsruA7atFJXa1BwKq1t6m6+webqS2bBYoZ2jic+K6mqHhk+206+QLOTX50sTu9fcr7EOiKRVsMaL1XTAEr5EbshxLB9qIAYTba1yvyL6zsdHJXKlEZbP0QHDRdJOD/GwFBad7iGOuBV4pow4YJChQRkXR5klZYAc= 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=Gaqlt6aU; 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="Gaqlt6aU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774624249; x=1774883449; bh=mWI6Ci0OExEN/NmgLmPa48Tm+LQjRqPyhRE3t1Uth/U=; 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=Gaqlt6aUxhMMhlPp/6ty2fLuu96xv1NLDl5fkam4cVnelieUusOZcoUqe71QU7boA iRlt0ezdrJzOBB+hcTZQpYQ1YX20eXCQQjk9/TIFIltaBbp1+YhMdiJu4qOElBQu4z l7e2Nagz97jOq/igvf+rQKMhcB6HDCxPXxtTlCv/0oiFSH8HSiG2RzMO3r/6id1na+ VGCoh0M3kAebxmr7Hmi1dP4APY44OXZOP4zj2aw06d5P0+JJGH3X/HgHS0Lbo4myD+ 3bQV3KyCTfQ1XuQK6dkjpE/ZxVjaSkEVLz3D6O5ONcPNwIk59JRyf2I8ewXch8eQOC yTjIQu08cS+gQ== Date: Fri, 27 Mar 2026 15:10:46 +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, Farrah Chen Subject: [PATCH v12 1/4] x86/cpu: Clear feature bits disabled at compile-time Message-ID: In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: 1536c57c83be7abb7d9b964ea5054429c2c1cd7d 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 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, user_shstk and enqcmd. Initialize cpu_caps_cleared[] with an autogenerated disabled bitmask. During CPU init, apply_forced_caps() will clear the corresponding bits in struct cpuinfo_x86 for each CPU. Thus features disabled at compile time won't show up in /proc/cpuinfo. No BUGS are defined to be cleared at compile time, therefore only the NCAPINTS part of cpu_caps_cleared[] is initialized using the macro. The NBUGINTS part is set to zero. Reported-by: Farrah Chen Closes: https://bugzilla.kernel.org/show_bug.cgi?id=3D220348 Signed-off-by: Maciej Wieczor-Retman Reviewed-by: Sohil Mehta --- Changelog v10: - Remove examples of feature flags that came from stable kernels. - Redo the patch message a bit with Sohil's suggestions. - Add Sohil's Reviewed-by tag. Changelog v9: - *_MASK_INITIALIZER -> *_MASK_INIT - Remove Cc stable. - Note that the BUGS part of cpu_caps_cleared[] is zeroed. Changelog v6: - Remove patch message portions that are not just describing the diff. 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 a8ff4376c286..76339e988304 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -735,7 +735,8 @@ static const char *table_lookup_model(struct cpuinfo_x8= 6 *c) } =20 /* 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= )) =3D + DISABLED_MASK_INIT; __u32 cpu_caps_set[NCAPINTS + NBUGINTS] __aligned(sizeof(unsigned long)); =20 #ifdef CONFIG_X86_32 diff --git a/arch/x86/tools/cpufeaturemasks.awk b/arch/x86/tools/cpufeature= masks.awk index 173d5bf2d999..9382bd15279a 100755 --- a/arch/x86/tools/cpufeaturemasks.awk +++ b/arch/x86/tools/cpufeaturemasks.awk @@ -82,6 +82,12 @@ END { } printf " 0\t\\\n"; printf "\t) & (1U << ((x) & 31)))\n\n"; + + printf "\n#define %s_MASK_INIT\t\t\t\\", s; + printf "\n\t{\t\t\t\t\t\t\\"; + for (i =3D 0; i < ncapints; i++) + printf "\n\t\t%s_MASK%d,\t\t\t\\", s, i; + printf "\n\t}\n\n"; } =20 printf "#endif /* _ASM_X86_CPUFEATUREMASKS_H */\n"; --=20 2.53.0 From nobody Thu Apr 2 15:36:23 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 4665F2C11D7 for ; Fri, 27 Mar 2026 15:11:07 +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=1774624268; cv=none; b=G/jNyjn9SWR58WLMYflv8GCN36qKgf1tFW0mmmyWWdlXtIpND9GYprPGriJDwdSsN9ebqItNcE984yJKUa+ZwvVb69RNf6cNJCQI0/kD5Gp5eW9/g4BKEHhni4atOkhPjh3mIEz2uCXQ3xpwK6AH59VEiqvEpnkuHnwO7wbpoOM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774624268; c=relaxed/simple; bh=yxxlwmCEyeX6nCx3350jDSoRypoG2h8WFYe+DaBBnoc=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=iMfO7ytXPgBw0KV9YuxqL1+5w7lmRVhElyfZZXTMpDVpte1Z+wH5YJIxbm0XNNKmy+hzn4wlIOFIq8zsYCuMI4yHGHo7ACWnLIHcGLGbSERVsOw0mzkWqL4bKXA2wuAaS5ZCV9Z9GPg2Coz8IimG+k7XY7YOZXXJ3mJhYIyJhEc= 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=JnR2pR7U; 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="JnR2pR7U" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774624258; x=1774883458; bh=WYXAX2wFgyb6ZzOJJJ27vgNubz05pDAJWxgS76VxSsk=; 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=JnR2pR7UZxYNbh4HEOofYqpp+SO9yFB9qv3hQ5sKvqg8bf5cyFFUd7jWQqiESUF8J 0l+/QLYfKj7hEbP8hAnT91kqzOmDZ6+7I+euAzHrEvxNNj7cP7gvRcvPbVU4n9BKFh fq0xHTtVfd+iYsMcnhUP7v1X9Q3lVmA6dsWHO1xAtBQurG1HH172aUg6ka6ZsOjxfE 3NPoM5KaVGS0wYjhNGXSeZqPqr5J2zOb1BFCl/4LODQy19feaNydhxhY7y9PCwbmgc dp3j7uU/AHCMZIjuydXTW5siP9tKQizmHwZ50DgrscMNwpQtnpWjFPRQUaWLFCUcsn ca9iz2uzdWe0w== Date: Fri, 27 Mar 2026 15:10:52 +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 2/4] x86/cpu: Check if feature string is non-zero Message-ID: In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: e44ae0ec68d30d884c38291c2d34a592687cf43e 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 In filter_cpuid_features(), x86_cap_flags[] is accessed based on the features from cpuid_dependent_features[]. However it's not verified whether the string in x86_cap_flags[] is non-zero which could lead to unwanted output. While currently it's not a problem (all the features in the checked list have non-zero strings) it may cause a failure if an entry is added that doesn't have a feature string defined. There are two other places that open code a similar operation of printing out the feature string or if it's not present, the word:bit feature format. Reuse x86_feature_name() as a common helper to validate the presence of feature strings in filter_cpuid_features() as well as unify similar open coded cases. Signed-off-by: Maciej Wieczor-Retman Reviewed-by: Sohil Mehta --- Changelog v12: - Remove Reviewed-by tags. - Redo the patch message so it points out that the problem is not here now but may happen. - Rename - X86_CAP_BUF_SIZE -> X86_NAMELSS_FEAT_BUFLEN - x86_cap_name() -> x86_feature_name() - Move exporting the header to arch/x86/kernel/cpu/cpu.h - Remove x86_bug_flags[] handling from x86_feature_name() since it doesn't interact with the array anywhere. Changelog v11: - Remove one extra tab after X86_CAP_BUF_SIZE. - Add Reviewed-by tags from Sohil and Pawan. Changelog v10: - Reword the patch message a bit. - Move x86_cap_name() declaration and X86_CAP_BUF_SIZE define to asm/cpufeature.h. - Don't include asm/cpu.h in cpuid-deps.c - Extend the comment above x86_cap_name to include information on buffer size that needs to be prepared before calling the function. - Remove the likely(), unlikely() calls since this is not a hot path. Changelog v9: - 16 -> X86_CAP_BUF_SIZE. - Add comment to the x86_cap_name(). Changelog v8: - Move x86_cap_name() declaration from linux/cpu.h to the arch/cpu.h. Include arch/cpu.h in the cpuid-deps.c file instead of linux/cpu.h. Changelog v7: - sizeof(buf) -> 16 - Rebase onto 7.01-rc1. Changelog v6: - Remove parts of the patch message that are redundant and just copy what's visible in the diff. - Redo the helper to use an external char buffer instead of a local static string. arch/x86/kernel/cpu/common.c | 30 +++++++++++++++++++++++++----- arch/x86/kernel/cpu/cpu.h | 4 ++++ arch/x86/kernel/cpu/cpuid-deps.c | 19 +++---------------- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 76339e988304..7cfd124b3fbf 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -678,6 +678,7 @@ cpuid_dependent_features[] =3D { static void filter_cpuid_features(struct cpuinfo_x86 *c, bool warn) { const struct cpuid_dependent_feature *df; + char feature_buf[X86_NAMELESS_FEAT_BUFLEN]; =20 for (df =3D cpuid_dependent_features; df->feature; df++) { =20 @@ -700,7 +701,7 @@ static void filter_cpuid_features(struct cpuinfo_x86 *c= , bool warn) continue; =20 pr_warn("CPU: CPU feature %s disabled, no CPUID level 0x%x\n", - x86_cap_flags[df->feature], df->level); + x86_feature_name(df->feature, feature_buf), df->level); } } =20 @@ -1637,6 +1638,7 @@ static inline bool parse_set_clear_cpuid(char *arg, b= ool set) =20 while (arg) { bool found __maybe_unused =3D false; + char name_buf[X86_NAMELESS_FEAT_BUFLEN]; unsigned int bit; =20 opt =3D strsep(&arg, ","); @@ -1657,10 +1659,7 @@ static inline bool parse_set_clear_cpuid(char *arg, = bool set) setup_clear_cpu_cap(bit); } /* empty-string, i.e., ""-defined feature flags */ - if (!x86_cap_flags[bit]) - pr_cont(" %d:%d\n", bit >> 5, bit & 31); - else - pr_cont(" %s\n", x86_cap_flags[bit]); + pr_cont(" %s\n", x86_feature_name(bit, name_buf)); =20 taint++; } @@ -1983,6 +1982,27 @@ static void generic_identify(struct cpuinfo_x86 *c) #endif } =20 +/* + * Return the feature "name" if available, otherwise return the + * X86_FEATURE_* numerals to make it easier to identify the feature. + * Callers of this function need to pass a char * buffer of size + * X86_NAMELESS_FEAT_BUFLEN. + */ +const char *x86_feature_name(unsigned int bit, char *buf) +{ + unsigned int word =3D bit >> 5; + const char *name =3D NULL; + + if (word < NCAPINTS) + name =3D x86_cap_flags[bit]; + + if (name) + return name; + + snprintf(buf, X86_NAMELESS_FEAT_BUFLEN, "%u:%u", word, bit & 31); + return buf; +} + /* * This does the hard work of actually picking apart the CPU stuff... */ diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h index 5c7a3a71191a..0ce29ee56442 100644 --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h @@ -91,4 +91,8 @@ static inline bool spectre_v2_in_eibrs_mode(enum spectre_= v2_mitigation mode) mode =3D=3D SPECTRE_V2_EIBRS_LFENCE; } =20 +#define X86_NAMELESS_FEAT_BUFLEN 16 + +const char *x86_feature_name(unsigned int bit, char *buf); + #endif /* ARCH_X86_CPU_H */ diff --git a/arch/x86/kernel/cpu/cpuid-deps.c b/arch/x86/kernel/cpu/cpuid-d= eps.c index 146f6f8b0650..4354c0dd6d66 100644 --- a/arch/x86/kernel/cpu/cpuid-deps.c +++ b/arch/x86/kernel/cpu/cpuid-deps.c @@ -4,6 +4,8 @@ #include #include =20 +#include "cpu.h" + struct cpuid_dep { unsigned int feature; unsigned int depends; @@ -156,24 +158,9 @@ void setup_clear_cpu_cap(unsigned int feature) do_clear_cpu_cap(NULL, feature); } =20 -/* - * Return the feature "name" if available, otherwise return - * the X86_FEATURE_* numerals to make it easier to identify - * the feature. - */ -static const char *x86_feature_name(unsigned int feature, char *buf) -{ - if (x86_cap_flags[feature]) - return x86_cap_flags[feature]; - - snprintf(buf, 16, "%d*32+%2d", feature / 32, feature % 32); - - return buf; -} - void check_cpufeature_deps(struct cpuinfo_x86 *c) { - char feature_buf[16], depends_buf[16]; + char feature_buf[X86_NAMELESS_FEAT_BUFLEN], depends_buf[X86_NAMELESS_FEAT= _BUFLEN]; const struct cpuid_dep *d; =20 for (d =3D cpuid_deps; d->feature; d++) { --=20 2.53.0 From nobody Thu Apr 2 15:36:23 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 From nobody Thu Apr 2 15:36:23 2026 Received: from mail-244122.protonmail.ch (mail-244122.protonmail.ch [109.224.244.122]) (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 4D5A12C11D7 for ; Fri, 27 Mar 2026 15:11:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=109.224.244.122 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774624276; cv=none; b=nn9DFn0FDGkLVS+vz3xZkfAw/5wk9tU36F6Otl1UyqDsDXVFayPLDEUeG7Ul2bxMzNKUgKCqTObKdxBY/sGz8KieMzyV59OcR7apj6GfNxT9y4yEHlMKPR2WBXdRb6Ps3mbYInrw2r4SpNp+OHUOngZoKpC5DBkVcvawx41xqf0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774624276; c=relaxed/simple; bh=wzzalzPxVVKQxnGvWEyChxXh3eeSSgsRnM1yqXEoC80=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Wb6zccXmWUB/nEy86R7pWrW5UjGqxe34VkoG1vCIeKpo3tekOiEfom+7l1fUwj7eip2wNpKM9rrBflW0nOrcNe7oQnOuAJURiTDovECCdEYGUmypZQpYXdCB2o2S4/xO8KRTVc2vM1tEp5+te8ctiaqza8Iaf/V1/fEmTuZZ+08= 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=SePzEZNS; arc=none smtp.client-ip=109.224.244.122 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="SePzEZNS" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774624267; x=1774883467; bh=2t+mCAaBPvVGyZJ5jJNkh3hsQUUyOl8CVa+3ml4O2pQ=; 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=SePzEZNSkyYdG7ew2kyv4jApMZU2qrWHjlmrnmUcK31eie4tj6G7+FdD5PgRjQV7g 2Pm9MflVTCKspCrwjkSiQ9YFdHgtDc+u8eK2M/umOMboEcF2q20U30KEp4iblyGASg +1wajy2417xXlLyLoh+dq7yd0BBIUiwlGzCVeiJqH6s1Bt8olipHJf5wTjTn218ul7 35cdeuiiZ33G0+4ZumHUFKpAwzCSuuYtO78YkF1r6/NPJEotjbcvW2cfdwGjL/VOsN 2nZ7SK/DhqhYfMsBXXP95Kvzh2lt0MtDZtBhAVblwDstfe4gn1GVhsW/1qH7RkvubH af9oLrLsNMagQ== Date: Fri, 27 Mar 2026 15:11:04 +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 4/4] x86/cpu: Clear feature bits whose dependencies were cleared Message-ID: <48fda57397205a062b752e37e63948fa668946f7.1774623092.git.m.wieczorretman@pm.me> In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: 57334ec51a1159fa048a1d7fcdf191d174633637 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_caps_cleared[] is initialized with DISABLED_MASK_INIT, features present in disabled bitmasks are cleared from x86_capability[]. However features that depend on them and are not part of any disabled mask are not cleared by anything. They can trigger the warning in check_cpufeature_deps(), as before both features would show up as enabled even though they weren't. The uncleared features can also still falsely show up in /proc/cpuinfo. Take such cases into account before applying the cpu_caps_cleared[] array. Signed-off-by: Maciej Wieczor-Retman --- Changelog v12: - Move the check from check_cpufeature_deps() to apply_forced_caps(). Redo last paragraph of the patch message. Changelog v11: - Add this patch to the series. arch/x86/include/asm/cpufeature.h | 1 + arch/x86/kernel/cpu/common.c | 2 ++ arch/x86/kernel/cpu/cpuid-deps.c | 14 ++++++++++++++ 3 files changed, 17 insertions(+) diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufe= ature.h index 3ddc1d33399b..e7a62990a9c2 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -77,6 +77,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; =20 extern void setup_clear_cpu_cap(unsigned int bit); extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit); +void clear_feature_disabled_deps(struct cpuinfo_x86 *c); void check_cpufeature_deps(struct cpuinfo_x86 *c); =20 #define setup_force_cpu_cap(bit) do { \ diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 8ad0da7012dd..2e24bdb3acaa 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -955,6 +955,8 @@ static void apply_forced_caps(struct cpuinfo_x86 *c) { int i; =20 + clear_feature_disabled_deps(c); + for (i =3D 0; i < NCAPINTS + NBUGINTS; i++) { c->x86_capability[i] &=3D ~cpu_caps_cleared[i]; c->x86_capability[i] |=3D cpu_caps_set[i]; diff --git a/arch/x86/kernel/cpu/cpuid-deps.c b/arch/x86/kernel/cpu/cpuid-d= eps.c index 4354c0dd6d66..83060c0013c1 100644 --- a/arch/x86/kernel/cpu/cpuid-deps.c +++ b/arch/x86/kernel/cpu/cpuid-deps.c @@ -158,6 +158,20 @@ void setup_clear_cpu_cap(unsigned int feature) do_clear_cpu_cap(NULL, feature); } =20 +/* + * If the dependency was cleared through the disabled bitmasks while the + * feature wasn't it also needs to be cleared. + */ +void clear_feature_disabled_deps(struct cpuinfo_x86 *c) +{ + const struct cpuid_dep *d; + + for (d =3D cpuid_deps; d->feature; d++) { + if (!DISABLED_MASK_BIT_SET(d->feature) && DISABLED_MASK_BIT_SET(d->depen= ds)) + set_bit(d->feature, (unsigned long *)cpu_caps_cleared); + } +} + void check_cpufeature_deps(struct cpuinfo_x86 *c) { char feature_buf[X86_NAMELESS_FEAT_BUFLEN], depends_buf[X86_NAMELESS_FEAT= _BUFLEN]; --=20 2.53.0