Skip to content

Commit 05e91e7

Browse files
committed
x86/microcode/AMD: Rip out static buffers
Load straight from the containers (initrd or builtin, for example). There's no need to cache the patch per node. This even simplifies the code a bit with the opportunity for more cleanups later. Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Tested-by: John Allen <john.allen@amd.com> Link: https://lore.kernel.org/r/20230720202813.3269888-1-john.allen@amd.com
1 parent 6eaae19 commit 05e91e7

File tree

3 files changed

+31
-70
lines changed

3 files changed

+31
-70
lines changed

arch/x86/include/asm/microcode_amd.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,11 @@ struct microcode_amd {
4444
#define PATCH_MAX_SIZE (3 * PAGE_SIZE)
4545

4646
#ifdef CONFIG_MICROCODE_AMD
47-
extern void __init load_ucode_amd_bsp(unsigned int family);
48-
extern void load_ucode_amd_ap(unsigned int family);
47+
extern void load_ucode_amd_early(unsigned int cpuid_1_eax);
4948
extern int __init save_microcode_in_initrd_amd(unsigned int family);
5049
void reload_ucode_amd(unsigned int cpu);
5150
#else
52-
static inline void __init load_ucode_amd_bsp(unsigned int family) {}
53-
static inline void load_ucode_amd_ap(unsigned int family) {}
51+
static inline void load_ucode_amd_early(unsigned int cpuid_1_eax) {}
5452
static inline int __init
5553
save_microcode_in_initrd_amd(unsigned int family) { return -EINVAL; }
5654
static inline void reload_ucode_amd(unsigned int cpu) {}

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

Lines changed: 27 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,6 @@ struct cont_desc {
5656

5757
static u32 ucode_new_rev;
5858

59-
/* One blob per node. */
60-
static u8 amd_ucode_patch[MAX_NUMNODES][PATCH_MAX_SIZE];
61-
6259
/*
6360
* Microcode patch container file is prepended to the initrd in cpio
6461
* format. See Documentation/arch/x86/microcode.rst
@@ -415,20 +412,17 @@ static int __apply_microcode_amd(struct microcode_amd *mc)
415412
*
416413
* Returns true if container found (sets @desc), false otherwise.
417414
*/
418-
static bool early_apply_microcode(u32 cpuid_1_eax, void *ucode, size_t size, bool save_patch)
415+
static bool early_apply_microcode(u32 cpuid_1_eax, void *ucode, size_t size)
419416
{
420417
struct cont_desc desc = { 0 };
421-
u8 (*patch)[PATCH_MAX_SIZE];
422418
struct microcode_amd *mc;
423419
u32 rev, dummy, *new_rev;
424420
bool ret = false;
425421

426422
#ifdef CONFIG_X86_32
427423
new_rev = (u32 *)__pa_nodebug(&ucode_new_rev);
428-
patch = (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch);
429424
#else
430425
new_rev = &ucode_new_rev;
431-
patch = &amd_ucode_patch[0];
432426
#endif
433427

434428
desc.cpuid_1_eax = cpuid_1_eax;
@@ -452,9 +446,6 @@ static bool early_apply_microcode(u32 cpuid_1_eax, void *ucode, size_t size, boo
452446
if (!__apply_microcode_amd(mc)) {
453447
*new_rev = mc->hdr.patch_id;
454448
ret = true;
455-
456-
if (save_patch)
457-
memcpy(patch, mc, min_t(u32, desc.psize, PATCH_MAX_SIZE));
458449
}
459450

460451
return ret;
@@ -507,50 +498,20 @@ static void find_blobs_in_containers(unsigned int cpuid_1_eax, struct cpio_data
507498
*ret = cp;
508499
}
509500

510-
void __init load_ucode_amd_bsp(unsigned int cpuid_1_eax)
501+
static void apply_ucode_from_containers(unsigned int cpuid_1_eax)
511502
{
512503
struct cpio_data cp = { };
513504

514505
find_blobs_in_containers(cpuid_1_eax, &cp);
515506
if (!(cp.data && cp.size))
516507
return;
517508

518-
early_apply_microcode(cpuid_1_eax, cp.data, cp.size, true);
509+
early_apply_microcode(cpuid_1_eax, cp.data, cp.size);
519510
}
520511

521-
void load_ucode_amd_ap(unsigned int cpuid_1_eax)
512+
void load_ucode_amd_early(unsigned int cpuid_1_eax)
522513
{
523-
struct microcode_amd *mc;
524-
struct cpio_data cp;
525-
u32 *new_rev, rev, dummy;
526-
527-
if (IS_ENABLED(CONFIG_X86_32)) {
528-
mc = (struct microcode_amd *)__pa_nodebug(amd_ucode_patch);
529-
new_rev = (u32 *)__pa_nodebug(&ucode_new_rev);
530-
} else {
531-
mc = (struct microcode_amd *)amd_ucode_patch;
532-
new_rev = &ucode_new_rev;
533-
}
534-
535-
native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
536-
537-
/*
538-
* Check whether a new patch has been saved already. Also, allow application of
539-
* the same revision in order to pick up SMT-thread-specific configuration even
540-
* if the sibling SMT thread already has an up-to-date revision.
541-
*/
542-
if (*new_rev && rev <= mc->hdr.patch_id) {
543-
if (!__apply_microcode_amd(mc)) {
544-
*new_rev = mc->hdr.patch_id;
545-
return;
546-
}
547-
}
548-
549-
find_blobs_in_containers(cpuid_1_eax, &cp);
550-
if (!(cp.data && cp.size))
551-
return;
552-
553-
early_apply_microcode(cpuid_1_eax, cp.data, cp.size, false);
514+
return apply_ucode_from_containers(cpuid_1_eax);
554515
}
555516

556517
static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size);
@@ -578,23 +539,6 @@ int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax)
578539
return 0;
579540
}
580541

581-
void reload_ucode_amd(unsigned int cpu)
582-
{
583-
u32 rev, dummy __always_unused;
584-
struct microcode_amd *mc;
585-
586-
mc = (struct microcode_amd *)amd_ucode_patch[cpu_to_node(cpu)];
587-
588-
rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
589-
590-
if (rev < mc->hdr.patch_id) {
591-
if (!__apply_microcode_amd(mc)) {
592-
ucode_new_rev = mc->hdr.patch_id;
593-
pr_info("reload patch_level=0x%08x\n", ucode_new_rev);
594-
}
595-
}
596-
}
597-
598542
/*
599543
* a small, trivial cache of per-family ucode patches
600544
*/
@@ -655,6 +599,28 @@ static struct ucode_patch *find_patch(unsigned int cpu)
655599
return cache_find_patch(equiv_id);
656600
}
657601

602+
void reload_ucode_amd(unsigned int cpu)
603+
{
604+
u32 rev, dummy __always_unused;
605+
struct microcode_amd *mc;
606+
struct ucode_patch *p;
607+
608+
p = find_patch(cpu);
609+
if (!p)
610+
return;
611+
612+
mc = p->data;
613+
614+
rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
615+
616+
if (rev < mc->hdr.patch_id) {
617+
if (!__apply_microcode_amd(mc)) {
618+
ucode_new_rev = mc->hdr.patch_id;
619+
pr_info("reload patch_level=0x%08x\n", ucode_new_rev);
620+
}
621+
}
622+
}
623+
658624
static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig)
659625
{
660626
struct cpuinfo_x86 *c = &cpu_data(cpu);
@@ -875,9 +841,6 @@ static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t siz
875841
continue;
876842

877843
ret = UCODE_NEW;
878-
879-
memset(&amd_ucode_patch[nid], 0, PATCH_MAX_SIZE);
880-
memcpy(&amd_ucode_patch[nid], p->data, min_t(u32, p->size, PATCH_MAX_SIZE));
881844
}
882845

883846
return ret;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ void __init load_ucode_bsp(void)
172172
if (intel)
173173
load_ucode_intel_bsp();
174174
else
175-
load_ucode_amd_bsp(cpuid_1_eax);
175+
load_ucode_amd_early(cpuid_1_eax);
176176
}
177177

178178
static bool check_loader_disabled_ap(void)
@@ -200,7 +200,7 @@ void load_ucode_ap(void)
200200
break;
201201
case X86_VENDOR_AMD:
202202
if (x86_family(cpuid_1_eax) >= 0x10)
203-
load_ucode_amd_ap(cpuid_1_eax);
203+
load_ucode_amd_early(cpuid_1_eax);
204204
break;
205205
default:
206206
break;

0 commit comments

Comments
 (0)