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

Configure Feed

Select the types of activity you want to include in your feed.

x86/cpufeature: Add facility to check for min microcode revisions

For bug workarounds or checks, it is useful to check for specific
microcode revisions.

Add a new generic function to match the CPU with stepping.
Add the other function to check the min microcode revisions for
the matched CPU.

A new table format is introduced to facilitate the quirk to
fill the related information.

This does not change the existing x86_cpu_id because it's an ABI
shared with modules, and also has quite different requirements,
as in no wildcards, but everything has to be matched exactly.

Originally-by: Andi Kleen <ak@linux.intel.com>
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Borislav Petkov <bp@alien8.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: eranian@google.com
Link: https://lkml.kernel.org/r/1549319013-4522-1-git-send-email-kan.liang@linux.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Kan Liang and committed by
Ingo Molnar
0f42b790 02371991

+59
+28
arch/x86/include/asm/cpu_device_id.h
··· 11 11 12 12 extern const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match); 13 13 14 + /* 15 + * Match specific microcode revisions. 16 + * 17 + * vendor/family/model/stepping must be all set. 18 + * 19 + * Only checks against the boot CPU. When mixed-stepping configs are 20 + * valid for a CPU model, add a quirk for every valid stepping and 21 + * do the fine-tuning in the quirk handler. 22 + */ 23 + 24 + struct x86_cpu_desc { 25 + __u8 x86_family; 26 + __u8 x86_vendor; 27 + __u8 x86_model; 28 + __u8 x86_stepping; 29 + __u32 x86_microcode_rev; 30 + }; 31 + 32 + #define INTEL_CPU_DESC(mod, step, rev) { \ 33 + .x86_family = 6, \ 34 + .x86_vendor = X86_VENDOR_INTEL, \ 35 + .x86_model = mod, \ 36 + .x86_stepping = step, \ 37 + .x86_microcode_rev = rev, \ 38 + } 39 + 40 + extern bool x86_cpu_has_min_microcode_rev(const struct x86_cpu_desc *table); 41 + 14 42 #endif
+31
arch/x86/kernel/cpu/match.c
··· 48 48 return NULL; 49 49 } 50 50 EXPORT_SYMBOL(x86_match_cpu); 51 + 52 + static const struct x86_cpu_desc * 53 + x86_match_cpu_with_stepping(const struct x86_cpu_desc *match) 54 + { 55 + struct cpuinfo_x86 *c = &boot_cpu_data; 56 + const struct x86_cpu_desc *m; 57 + 58 + for (m = match; m->x86_family | m->x86_model; m++) { 59 + if (c->x86_vendor != m->x86_vendor) 60 + continue; 61 + if (c->x86 != m->x86_family) 62 + continue; 63 + if (c->x86_model != m->x86_model) 64 + continue; 65 + if (c->x86_stepping != m->x86_stepping) 66 + continue; 67 + return m; 68 + } 69 + return NULL; 70 + } 71 + 72 + bool x86_cpu_has_min_microcode_rev(const struct x86_cpu_desc *table) 73 + { 74 + const struct x86_cpu_desc *res = x86_match_cpu_with_stepping(table); 75 + 76 + if (!res || res->x86_microcode_rev > boot_cpu_data.microcode) 77 + return false; 78 + 79 + return true; 80 + } 81 + EXPORT_SYMBOL_GPL(x86_cpu_has_min_microcode_rev);