more sampling fun 1
PATCH 1/2 more sampling fun 1
From: mark gross <[email protected]>
Subject: [PATCH 1/2] Add capability to specify a range of steppings in the
Intel has produced processors with the same CPUID family+model. Code may need to check the stepping when programming model specific behavior.
Add an API to allow easy specification of stepping or range of steppings with a 16 bit bitmask.
Update cpu_vuln_whitelist using this new API.
I implemented this in the way I did to avoid modifying x86_cpu_id as that structure is an exported ABI and any change would impact user mode code using the structure.
Signed-off-by mark gross <[email protected]>
Reviewed-by tony luck <[email protected]>
--- arch/x86/include/asm/cpu_device_id.h | 12 ++++++++++++ arch/x86/kernel/cpu/common.c | 28 ++++++++++++++-------------- arch/x86/kernel/cpu/match.c | 26 ++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 14 deletions(-)
arch/x86/include/asm/cpu_device_id.h +12 -0
@@ -35,7 +35,19 @@ struct x86_cpu_desc { .x86_microcode_rev = (revision), \ } +/* +* Match a range of steppings +*/ + +struct x86_cpu_id_ext { +struct x86_cpu_id id; +__u16 steppings;/* bit map of steppings to match against */ +}; + +#define X86_STEPPING_ANY 0 +extern const struct x86_cpu_id *x86_match_cpu (const struct x86_cpu_id *match); +const struct x86_cpu_id_ext *x86_match_cpu_ext (const struct x86_cpu_id_ext *match);extern bool x86_cpu_has_min_microcode_rev (const struct x86_cpu_desc *table);#endif /* _ASM_X86_CPU_DEVICE_ID */
arch/x86/kernel/cpu/common.c +14 -14
@@ -1008,23 +1008,23 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)#define NO_ITLB_MULTIHIT BIT(7)#define NO_SPECTRE_V2 BIT(8) -#define VULNWL (_vendor, _family, _model, _whitelist) \ - { X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist } +#define VULNWL (_vendor, _family, _model, __stepping, _whitelist) \ + {{ X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist }, __stepping}#define VULNWL_INTEL (model, whitelist) \ - VULNWL(INTEL, 6, INTEL_FAM6_##model, whitelist) + VULNWL(INTEL, 6, INTEL_FAM6_##model, X86_STEPPING_ANY, whitelist)#define VULNWL_AMD (family, whitelist) \ - VULNWL(AMD, family, X86_MODEL_ANY, whitelist) + VULNWL(AMD, family, X86_MODEL_ANY, X86_STEPPING_ANY, whitelist)#define VULNWL_HYGON (family, whitelist) \ - VULNWL(HYGON, family, X86_MODEL_ANY, whitelist) + VULNWL(HYGON, family, X86_MODEL_ANY, X86_STEPPING_ANY, whitelist) -static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { -VULNWL (ANY ,4 ,X86_MODEL_ANY ,NO_SPECULATION ), -VULNWL (CENTAUR ,5 ,X86_MODEL_ANY ,NO_SPECULATION ), -VULNWL (INTEL ,5 ,X86_MODEL_ANY ,NO_SPECULATION ), -VULNWL (NSC ,5 ,X86_MODEL_ANY ,NO_SPECULATION ), +static const struct x86_cpu_id_ext cpu_vuln_whitelist[]__initconst = { +VULNWL (ANY ,4 ,X86_MODEL_ANY ,X86_STEPPING_ANY ,NO_SPECULATION ), +VULNWL (CENTAUR ,5 ,X86_MODEL_ANY ,X86_STEPPING_ANY ,NO_SPECULATION ), +VULNWL (INTEL ,5 ,X86_MODEL_ANY ,X86_STEPPING_ANY ,NO_SPECULATION ), +VULNWL (NSC ,5 ,X86_MODEL_ANY ,X86_STEPPING_ANY ,NO_SPECULATION ),/* Intel Family 6 */ VULNWL_INTEL (ATOM_SALTWELL ,NO_SPECULATION |NO_ITLB_MULTIHIT ),
@@ -1070,16 +1070,16 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {VULNWL_HYGON (X86_FAMILY_ANY ,NO_MELTDOWN |NO_L1TF |NO_MDS |NO_SWAPGS |NO_ITLB_MULTIHIT ),/* Zhaoxin Family 7 */ -VULNWL (CENTAUR ,7 ,X86_MODEL_ANY ,NO_SPECTRE_V2 |NO_SWAPGS ), - VULNWL(ZHAOXIN, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS), +VULNWL (CENTAUR ,7 ,X86_MODEL_ANY ,X86_STEPPING_ANY ,NO_SPECTRE_V2 |NO_SWAPGS ), + VULNWL(ZHAOXIN, 7, X86_MODEL_ANY, X86_STEPPING_ANY, NO_SPECTRE_V2 | NO_SWAPGS), {} };static bool __init cpu_matches (unsigned long which) { -const struct x86_cpu_id *m =x86_match_cpu (cpu_vuln_whitelist); +const struct x86_cpu_id_ext *m =x86_match_cpu_ext (cpu_vuln_whitelist); -return m && !!(m->driver_data & which); +return m && !!(m->id.driver_data & which); }u64 x86_read_arch_cap_msr (void )
arch/x86/kernel/cpu/match.c +26 -0
@@ -49,6 +49,32 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) }EXPORT_SYMBOL (x86_match_cpu); +/* +* Extend x86_match_cpu to support matching a range of steppings. +*/ +const struct x86_cpu_id_ext *x86_match_cpu_ext (const struct x86_cpu_id_ext *match) +{ +const struct x86_cpu_id_ext *m; +struct cpuinfo_x86 *c = &boot_cpu_data; + +for (m = match; m->id.vendor | m->id.family | m->id.model | m->id.feature; m++) { +if (m->id.vendor !=X86_VENDOR_ANY && c->x86_vendor != m->id.vendor) +continue ; +if (m->id.family !=X86_FAMILY_ANY && c->x86 != m->id.family) +continue ; +if (m->id.model !=X86_MODEL_ANY && c->x86_model != m->id.model) +continue ; +if (m->steppings !=X86_STEPPING_ANY && + !(BIT (c->x86_stepping) & m->steppings)) +continue ; +if (m->id.feature !=X86_FEATURE_ANY && !cpu_has (c, m->id.feature)) +continue ; +return m; + } +return NULL ; +} +EXPORT_SYMBOL (x86_match_cpu_ext); +static const struct x86_cpu_desc *x86_match_cpu_with_stepping (const struct x86_cpu_desc *match) {
Signature · 1 line
2.17.1