Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/cpu: Add cpu_type to struct x86_cpu_id

In addition to matching vendor/family/model/feature, for hybrid variants it is
required to also match cpu-type. For example, some CPU vulnerabilities like
RFDS only affect a specific cpu-type.

To be able to also match CPUs based on their type, add a new field "type" to
struct x86_cpu_id which is used by the CPU-matching tables. Introduce
X86_CPU_TYPE_ANY for the cases that don't care about the cpu-type.

[ bp: Massage commit message. ]

Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
Link: https://lore.kernel.org/r/20250311-add-cpu-type-v8-3-e8514dcaaff2@linux.intel.com

authored by

Pawan Gupta and committed by
Ingo Molnar
00d7fc04 c3390406

+25 -9
+23 -9
arch/x86/include/asm/cpu_device_id.h
··· 74 74 * into another macro at the usage site for good reasons, then please 75 75 * start this local macro with X86_MATCH to allow easy grepping. 76 76 */ 77 - #define X86_MATCH_CPU(_vendor, _family, _model, _steppings, _feature, _data) { \ 77 + #define X86_MATCH_CPU(_vendor, _family, _model, _steppings, _feature, _type, _data) { \ 78 78 .vendor = _vendor, \ 79 79 .family = _family, \ 80 80 .model = _model, \ 81 81 .steppings = _steppings, \ 82 82 .feature = _feature, \ 83 83 .flags = X86_CPU_ID_FLAG_ENTRY_VALID, \ 84 + .type = _type, \ 84 85 .driver_data = (unsigned long) _data \ 85 86 } 86 87 ··· 97 96 */ 98 97 #define X86_MATCH_VENDOR_FAM_FEATURE(vendor, family, feature, data) \ 99 98 X86_MATCH_CPU(X86_VENDOR_##vendor, family, X86_MODEL_ANY, \ 100 - X86_STEPPING_ANY, feature, data) 99 + X86_STEPPING_ANY, feature, X86_CPU_TYPE_ANY, data) 101 100 102 101 /** 103 102 * X86_MATCH_VENDOR_FEATURE - Macro for matching vendor and CPU feature ··· 110 109 */ 111 110 #define X86_MATCH_VENDOR_FEATURE(vendor, feature, data) \ 112 111 X86_MATCH_CPU(X86_VENDOR_##vendor, X86_FAMILY_ANY, X86_MODEL_ANY, \ 113 - X86_STEPPING_ANY, feature, data) 112 + X86_STEPPING_ANY, feature, X86_CPU_TYPE_ANY, data) 114 113 115 114 /** 116 115 * X86_MATCH_FEATURE - Macro for matching a CPU feature ··· 121 120 */ 122 121 #define X86_MATCH_FEATURE(feature, data) \ 123 122 X86_MATCH_CPU(X86_VENDOR_ANY, X86_FAMILY_ANY, X86_MODEL_ANY, \ 124 - X86_STEPPING_ANY, feature, data) 123 + X86_STEPPING_ANY, feature, X86_CPU_TYPE_ANY, data) 125 124 126 125 /** 127 126 * X86_MATCH_VENDOR_FAM_MODEL - Match vendor, family and model ··· 135 134 */ 136 135 #define X86_MATCH_VENDOR_FAM_MODEL(vendor, family, model, data) \ 137 136 X86_MATCH_CPU(X86_VENDOR_##vendor, family, model, X86_STEPPING_ANY, \ 138 - X86_FEATURE_ANY, data) 137 + X86_FEATURE_ANY, X86_CPU_TYPE_ANY, data) 139 138 140 139 /** 141 140 * X86_MATCH_VENDOR_FAM - Match vendor and family ··· 148 147 */ 149 148 #define X86_MATCH_VENDOR_FAM(vendor, family, data) \ 150 149 X86_MATCH_CPU(X86_VENDOR_##vendor, family, X86_MODEL_ANY, \ 151 - X86_STEPPING_ANY, X86_FEATURE_ANY, data) 150 + X86_STEPPING_ANY, X86_FEATURE_ANY, X86_CPU_TYPE_ANY, data) 152 151 153 152 /** 154 153 * X86_MATCH_VFM - Match encoded vendor/family/model ··· 159 158 */ 160 159 #define X86_MATCH_VFM(vfm, data) \ 161 160 X86_MATCH_CPU(VFM_VENDOR(vfm), VFM_FAMILY(vfm), VFM_MODEL(vfm), \ 162 - X86_STEPPING_ANY, X86_FEATURE_ANY, data) 161 + X86_STEPPING_ANY, X86_FEATURE_ANY, X86_CPU_TYPE_ANY, data) 163 162 164 163 #define __X86_STEPPINGS(mins, maxs) GENMASK(maxs, mins) 165 164 /** ··· 174 173 */ 175 174 #define X86_MATCH_VFM_STEPS(vfm, min_step, max_step, data) \ 176 175 X86_MATCH_CPU(VFM_VENDOR(vfm), VFM_FAMILY(vfm), VFM_MODEL(vfm), \ 177 - __X86_STEPPINGS(min_step, max_step), X86_FEATURE_ANY, data) 176 + __X86_STEPPINGS(min_step, max_step), X86_FEATURE_ANY, \ 177 + X86_CPU_TYPE_ANY, data) 178 178 179 179 /** 180 180 * X86_MATCH_VFM_FEATURE - Match encoded vendor/family/model/feature ··· 187 185 */ 188 186 #define X86_MATCH_VFM_FEATURE(vfm, feature, data) \ 189 187 X86_MATCH_CPU(VFM_VENDOR(vfm), VFM_FAMILY(vfm), VFM_MODEL(vfm), \ 190 - X86_STEPPING_ANY, feature, data) 188 + X86_STEPPING_ANY, feature, X86_CPU_TYPE_ANY, data) 189 + 190 + /** 191 + * X86_MATCH_VFM_CPU_TYPE - Match encoded vendor/family/model/type 192 + * @vfm: Encoded 8-bits each for vendor, family, model 193 + * @type: CPU type e.g. P-core, E-core 194 + * @data: Driver specific data or NULL. The internal storage 195 + * format is unsigned long. The supplied value, pointer 196 + * etc. is cast to unsigned long internally. 197 + */ 198 + #define X86_MATCH_VFM_CPU_TYPE(vfm, type, data) \ 199 + X86_MATCH_CPU(VFM_VENDOR(vfm), VFM_FAMILY(vfm), VFM_MODEL(vfm), \ 200 + X86_STEPPING_ANY, X86_FEATURE_ANY, type, data) 191 201 192 202 extern const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match); 193 203 extern bool x86_match_min_microcode_rev(const struct x86_cpu_id *table);
+2
include/linux/mod_devicetable.h
··· 692 692 __u16 feature; /* bit index */ 693 693 /* Solely for kernel-internal use: DO NOT EXPORT to userspace! */ 694 694 __u16 flags; 695 + __u8 type; 695 696 kernel_ulong_t driver_data; 696 697 }; 697 698 ··· 704 703 #define X86_STEP_MIN 0 705 704 #define X86_STEP_MAX 0xf 706 705 #define X86_FEATURE_ANY 0 /* Same as FPU, you can't test for that */ 706 + #define X86_CPU_TYPE_ANY 0 707 707 708 708 /* 709 709 * Generic table type for matching CPU features.