Loading arch/x86/include/asm/cpu_device_id.h +28 −0 Original line number Diff line number Diff line Loading @@ -11,4 +11,32 @@ extern const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match); /* * Match specific microcode revisions. * * vendor/family/model/stepping must be all set. * * Only checks against the boot CPU. When mixed-stepping configs are * valid for a CPU model, add a quirk for every valid stepping and * do the fine-tuning in the quirk handler. */ struct x86_cpu_desc { __u8 x86_family; __u8 x86_vendor; __u8 x86_model; __u8 x86_stepping; __u32 x86_microcode_rev; }; #define INTEL_CPU_DESC(mod, step, rev) { \ .x86_family = 6, \ .x86_vendor = X86_VENDOR_INTEL, \ .x86_model = mod, \ .x86_stepping = step, \ .x86_microcode_rev = rev, \ } extern bool x86_cpu_has_min_microcode_rev(const struct x86_cpu_desc *table); #endif arch/x86/kernel/cpu/amd.c +3 −5 Original line number Diff line number Diff line Loading @@ -819,11 +819,9 @@ static void init_amd_bd(struct cpuinfo_x86 *c) static void init_amd_zn(struct cpuinfo_x86 *c) { set_cpu_cap(c, X86_FEATURE_ZEN); /* * Fix erratum 1076: CPB feature bit not being set in CPUID. It affects * all up to and including B1. */ if (c->x86_model <= 1 && c->x86_stepping <= 1) /* Fix erratum 1076: CPB feature bit not being set in CPUID. */ if (!cpu_has(c, X86_FEATURE_CPB)) set_cpu_cap(c, X86_FEATURE_CPB); } Loading arch/x86/kernel/cpu/match.c +31 −0 Original line number Diff line number Diff line Loading @@ -48,3 +48,34 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) return NULL; } EXPORT_SYMBOL(x86_match_cpu); static const struct x86_cpu_desc * x86_match_cpu_with_stepping(const struct x86_cpu_desc *match) { struct cpuinfo_x86 *c = &boot_cpu_data; const struct x86_cpu_desc *m; for (m = match; m->x86_family | m->x86_model; m++) { if (c->x86_vendor != m->x86_vendor) continue; if (c->x86 != m->x86_family) continue; if (c->x86_model != m->x86_model) continue; if (c->x86_stepping != m->x86_stepping) continue; return m; } return NULL; } bool x86_cpu_has_min_microcode_rev(const struct x86_cpu_desc *table) { const struct x86_cpu_desc *res = x86_match_cpu_with_stepping(table); if (!res || res->x86_microcode_rev > boot_cpu_data.microcode) return false; return true; } EXPORT_SYMBOL_GPL(x86_cpu_has_min_microcode_rev); Loading
arch/x86/include/asm/cpu_device_id.h +28 −0 Original line number Diff line number Diff line Loading @@ -11,4 +11,32 @@ extern const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match); /* * Match specific microcode revisions. * * vendor/family/model/stepping must be all set. * * Only checks against the boot CPU. When mixed-stepping configs are * valid for a CPU model, add a quirk for every valid stepping and * do the fine-tuning in the quirk handler. */ struct x86_cpu_desc { __u8 x86_family; __u8 x86_vendor; __u8 x86_model; __u8 x86_stepping; __u32 x86_microcode_rev; }; #define INTEL_CPU_DESC(mod, step, rev) { \ .x86_family = 6, \ .x86_vendor = X86_VENDOR_INTEL, \ .x86_model = mod, \ .x86_stepping = step, \ .x86_microcode_rev = rev, \ } extern bool x86_cpu_has_min_microcode_rev(const struct x86_cpu_desc *table); #endif
arch/x86/kernel/cpu/amd.c +3 −5 Original line number Diff line number Diff line Loading @@ -819,11 +819,9 @@ static void init_amd_bd(struct cpuinfo_x86 *c) static void init_amd_zn(struct cpuinfo_x86 *c) { set_cpu_cap(c, X86_FEATURE_ZEN); /* * Fix erratum 1076: CPB feature bit not being set in CPUID. It affects * all up to and including B1. */ if (c->x86_model <= 1 && c->x86_stepping <= 1) /* Fix erratum 1076: CPB feature bit not being set in CPUID. */ if (!cpu_has(c, X86_FEATURE_CPB)) set_cpu_cap(c, X86_FEATURE_CPB); } Loading
arch/x86/kernel/cpu/match.c +31 −0 Original line number Diff line number Diff line Loading @@ -48,3 +48,34 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) return NULL; } EXPORT_SYMBOL(x86_match_cpu); static const struct x86_cpu_desc * x86_match_cpu_with_stepping(const struct x86_cpu_desc *match) { struct cpuinfo_x86 *c = &boot_cpu_data; const struct x86_cpu_desc *m; for (m = match; m->x86_family | m->x86_model; m++) { if (c->x86_vendor != m->x86_vendor) continue; if (c->x86 != m->x86_family) continue; if (c->x86_model != m->x86_model) continue; if (c->x86_stepping != m->x86_stepping) continue; return m; } return NULL; } bool x86_cpu_has_min_microcode_rev(const struct x86_cpu_desc *table) { const struct x86_cpu_desc *res = x86_match_cpu_with_stepping(table); if (!res || res->x86_microcode_rev > boot_cpu_data.microcode) return false; return true; } EXPORT_SYMBOL_GPL(x86_cpu_has_min_microcode_rev);