Skip to content

Commit 080990a

Browse files
committed
x86/microcode: Rework early revisions reporting
The AMD side of the loader issues the microcode revision for each logical thread on the system, which can become really noisy on huge machines. And doing that doesn't make a whole lot of sense - the microcode revision is already in /proc/cpuinfo. So in case one is interested in the theoretical support of mixed silicon steppings on AMD, one can check there. What is also missing on the AMD side - something which people have requested before - is showing the microcode revision the CPU had *before* the early update. So abstract that up in the main code and have the BSP on each vendor provide those revision numbers. Then, dump them only once on driver init. On Intel, do not dump the patch date - it is not needed. Reported-by: Linus Torvalds <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Reviewed-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/r/CAHk-=wg=%[email protected]
1 parent 2e569ad commit 080990a

File tree

4 files changed

+37
-44
lines changed

4 files changed

+37
-44
lines changed

arch/x86/kernel/cpu/microcode/amd.c

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,6 @@ struct cont_desc {
104104
size_t size;
105105
};
106106

107-
static u32 ucode_new_rev;
108-
109107
/*
110108
* Microcode patch container file is prepended to the initrd in cpio
111109
* format. See Documentation/arch/x86/microcode.rst
@@ -442,12 +440,11 @@ static int __apply_microcode_amd(struct microcode_amd *mc)
442440
*
443441
* Returns true if container found (sets @desc), false otherwise.
444442
*/
445-
static bool early_apply_microcode(u32 cpuid_1_eax, void *ucode, size_t size)
443+
static bool early_apply_microcode(u32 cpuid_1_eax, u32 old_rev, void *ucode, size_t size)
446444
{
447445
struct cont_desc desc = { 0 };
448446
struct microcode_amd *mc;
449447
bool ret = false;
450-
u32 rev, dummy;
451448

452449
desc.cpuid_1_eax = cpuid_1_eax;
453450

@@ -457,22 +454,15 @@ static bool early_apply_microcode(u32 cpuid_1_eax, void *ucode, size_t size)
457454
if (!mc)
458455
return ret;
459456

460-
native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
461-
462457
/*
463458
* Allow application of the same revision to pick up SMT-specific
464459
* changes even if the revision of the other SMT thread is already
465460
* up-to-date.
466461
*/
467-
if (rev > mc->hdr.patch_id)
462+
if (old_rev > mc->hdr.patch_id)
468463
return ret;
469464

470-
if (!__apply_microcode_amd(mc)) {
471-
ucode_new_rev = mc->hdr.patch_id;
472-
ret = true;
473-
}
474-
475-
return ret;
465+
return !__apply_microcode_amd(mc);
476466
}
477467

478468
static bool get_builtin_microcode(struct cpio_data *cp, unsigned int family)
@@ -506,9 +496,12 @@ static void __init find_blobs_in_containers(unsigned int cpuid_1_eax, struct cpi
506496
*ret = cp;
507497
}
508498

509-
void __init load_ucode_amd_bsp(unsigned int cpuid_1_eax)
499+
void __init load_ucode_amd_bsp(struct early_load_data *ed, unsigned int cpuid_1_eax)
510500
{
511501
struct cpio_data cp = { };
502+
u32 dummy;
503+
504+
native_rdmsr(MSR_AMD64_PATCH_LEVEL, ed->old_rev, dummy);
512505

513506
/* Needed in load_microcode_amd() */
514507
ucode_cpu_info[0].cpu_sig.sig = cpuid_1_eax;
@@ -517,7 +510,8 @@ void __init load_ucode_amd_bsp(unsigned int cpuid_1_eax)
517510
if (!(cp.data && cp.size))
518511
return;
519512

520-
early_apply_microcode(cpuid_1_eax, cp.data, cp.size);
513+
if (early_apply_microcode(cpuid_1_eax, ed->old_rev, cp.data, cp.size))
514+
native_rdmsr(MSR_AMD64_PATCH_LEVEL, ed->new_rev, dummy);
521515
}
522516

523517
static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size);
@@ -625,10 +619,8 @@ void reload_ucode_amd(unsigned int cpu)
625619
rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
626620

627621
if (rev < mc->hdr.patch_id) {
628-
if (!__apply_microcode_amd(mc)) {
629-
ucode_new_rev = mc->hdr.patch_id;
630-
pr_info("reload patch_level=0x%08x\n", ucode_new_rev);
631-
}
622+
if (!__apply_microcode_amd(mc))
623+
pr_info_once("reload revision: 0x%08x\n", mc->hdr.patch_id);
632624
}
633625
}
634626

@@ -649,8 +641,6 @@ static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig)
649641
if (p && (p->patch_id == csig->rev))
650642
uci->mc = p->data;
651643

652-
pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev);
653-
654644
return 0;
655645
}
656646

@@ -691,8 +681,6 @@ static enum ucode_state apply_microcode_amd(int cpu)
691681
rev = mc_amd->hdr.patch_id;
692682
ret = UCODE_UPDATED;
693683

694-
pr_info("CPU%d: new patch_level=0x%08x\n", cpu, rev);
695-
696684
out:
697685
uci->cpu_sig.rev = rev;
698686
c->microcode = rev;
@@ -935,11 +923,6 @@ struct microcode_ops * __init init_amd_microcode(void)
935923
pr_warn("AMD CPU family 0x%x not supported\n", c->x86);
936924
return NULL;
937925
}
938-
939-
if (ucode_new_rev)
940-
pr_info_once("microcode updated early to new patch_level=0x%08x\n",
941-
ucode_new_rev);
942-
943926
return &microcode_amd_ops;
944927
}
945928

arch/x86/kernel/cpu/microcode/core.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ static u32 final_levels[] = {
7575
0, /* T-101 terminator */
7676
};
7777

78+
struct early_load_data early_data;
79+
7880
/*
7981
* Check the current patch level on this CPU.
8082
*
@@ -153,9 +155,9 @@ void __init load_ucode_bsp(void)
153155
return;
154156

155157
if (intel)
156-
load_ucode_intel_bsp();
158+
load_ucode_intel_bsp(&early_data);
157159
else
158-
load_ucode_amd_bsp(cpuid_1_eax);
160+
load_ucode_amd_bsp(&early_data, cpuid_1_eax);
159161
}
160162

161163
void load_ucode_ap(void)
@@ -826,6 +828,11 @@ static int __init microcode_init(void)
826828
if (!microcode_ops)
827829
return -ENODEV;
828830

831+
pr_info_once("Current revision: 0x%08x\n", (early_data.new_rev ?: early_data.old_rev));
832+
833+
if (early_data.new_rev)
834+
pr_info_once("Updated early from: 0x%08x\n", early_data.old_rev);
835+
829836
microcode_pdev = platform_device_register_simple("microcode", -1, NULL, 0);
830837
if (IS_ERR(microcode_pdev))
831838
return PTR_ERR(microcode_pdev);

arch/x86/kernel/cpu/microcode/intel.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -339,16 +339,9 @@ static enum ucode_state __apply_microcode(struct ucode_cpu_info *uci,
339339
static enum ucode_state apply_microcode_early(struct ucode_cpu_info *uci)
340340
{
341341
struct microcode_intel *mc = uci->mc;
342-
enum ucode_state ret;
343-
u32 cur_rev, date;
342+
u32 cur_rev;
344343

345-
ret = __apply_microcode(uci, mc, &cur_rev);
346-
if (ret == UCODE_UPDATED) {
347-
date = mc->hdr.date;
348-
pr_info_once("updated early: 0x%x -> 0x%x, date = %04x-%02x-%02x\n",
349-
cur_rev, mc->hdr.rev, date & 0xffff, date >> 24, (date >> 16) & 0xff);
350-
}
351-
return ret;
344+
return __apply_microcode(uci, mc, &cur_rev);
352345
}
353346

354347
static __init bool load_builtin_intel_microcode(struct cpio_data *cp)
@@ -413,13 +406,17 @@ static int __init save_builtin_microcode(void)
413406
early_initcall(save_builtin_microcode);
414407

415408
/* Load microcode on BSP from initrd or builtin blobs */
416-
void __init load_ucode_intel_bsp(void)
409+
void __init load_ucode_intel_bsp(struct early_load_data *ed)
417410
{
418411
struct ucode_cpu_info uci;
419412

413+
ed->old_rev = intel_get_microcode_revision();
414+
420415
uci.mc = get_microcode_blob(&uci, false);
421416
if (uci.mc && apply_microcode_early(&uci) == UCODE_UPDATED)
422417
ucode_patch_va = UCODE_BSP_LOADED;
418+
419+
ed->new_rev = uci.cpu_sig.rev;
423420
}
424421

425422
void load_ucode_intel_ap(void)

arch/x86/kernel/cpu/microcode/internal.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ struct microcode_ops {
3737
use_nmi : 1;
3838
};
3939

40+
struct early_load_data {
41+
u32 old_rev;
42+
u32 new_rev;
43+
};
44+
45+
extern struct early_load_data early_data;
4046
extern struct ucode_cpu_info ucode_cpu_info[];
4147
struct cpio_data find_microcode_in_initrd(const char *path);
4248

@@ -92,14 +98,14 @@ extern bool dis_ucode_ldr;
9298
extern bool force_minrev;
9399

94100
#ifdef CONFIG_CPU_SUP_AMD
95-
void load_ucode_amd_bsp(unsigned int family);
101+
void load_ucode_amd_bsp(struct early_load_data *ed, unsigned int family);
96102
void load_ucode_amd_ap(unsigned int family);
97103
int save_microcode_in_initrd_amd(unsigned int family);
98104
void reload_ucode_amd(unsigned int cpu);
99105
struct microcode_ops *init_amd_microcode(void);
100106
void exit_amd_microcode(void);
101107
#else /* CONFIG_CPU_SUP_AMD */
102-
static inline void load_ucode_amd_bsp(unsigned int family) { }
108+
static inline void load_ucode_amd_bsp(struct early_load_data *ed, unsigned int family) { }
103109
static inline void load_ucode_amd_ap(unsigned int family) { }
104110
static inline int save_microcode_in_initrd_amd(unsigned int family) { return -EINVAL; }
105111
static inline void reload_ucode_amd(unsigned int cpu) { }
@@ -108,12 +114,12 @@ static inline void exit_amd_microcode(void) { }
108114
#endif /* !CONFIG_CPU_SUP_AMD */
109115

110116
#ifdef CONFIG_CPU_SUP_INTEL
111-
void load_ucode_intel_bsp(void);
117+
void load_ucode_intel_bsp(struct early_load_data *ed);
112118
void load_ucode_intel_ap(void);
113119
void reload_ucode_intel(void);
114120
struct microcode_ops *init_intel_microcode(void);
115121
#else /* CONFIG_CPU_SUP_INTEL */
116-
static inline void load_ucode_intel_bsp(void) { }
122+
static inline void load_ucode_intel_bsp(struct early_load_data *ed) { }
117123
static inline void load_ucode_intel_ap(void) { }
118124
static inline void reload_ucode_intel(void) { }
119125
static inline struct microcode_ops *init_intel_microcode(void) { return NULL; }

0 commit comments

Comments
 (0)