| From 774c3e2de69911f2baaaaab1b3ef55ea25776a30 Mon Sep 17 00:00:00 2001 |
| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Tue, 17 Oct 2023 23:23:53 +0200 |
| Subject: x86/microcode/amd: Cache builtin/initrd microcode early |
| |
| From: Thomas Gleixner <tglx@linutronix.de> |
| |
| commit a7939f01672034a58ad3fdbce69bb6c665ce0024 upstream |
| |
| There is no reason to scan builtin/initrd microcode on each AP. |
| |
| Cache the builtin/initrd microcode in an early initcall so that the |
| early AP loader can utilize the cache. |
| |
| The existing fs initcall which invoked save_microcode_in_initrd_amd() is |
| still required to maintain the initrd_gone flag. Rename it accordingly. |
| This will be removed once the AP loader code is converted to use the |
| cache. |
| |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> |
| Link: https://lore.kernel.org/r/20231017211723.187566507@linutronix.de |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/x86/kernel/cpu/microcode/amd.c | 8 +++++++- |
| arch/x86/kernel/cpu/microcode/core.c | 26 ++++---------------------- |
| 2 files changed, 11 insertions(+), 23 deletions(-) |
| |
| --- a/arch/x86/kernel/cpu/microcode/amd.c |
| +++ b/arch/x86/kernel/cpu/microcode/amd.c |
| @@ -527,12 +527,17 @@ void load_ucode_amd_early(unsigned int c |
| |
| static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size); |
| |
| -int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax) |
| +static int __init save_microcode_in_initrd(void) |
| { |
| + unsigned int cpuid_1_eax = native_cpuid_eax(1); |
| + struct cpuinfo_x86 *c = &boot_cpu_data; |
| struct cont_desc desc = { 0 }; |
| enum ucode_state ret; |
| struct cpio_data cp; |
| |
| + if (dis_ucode_ldr || c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) |
| + return 0; |
| + |
| find_blobs_in_containers(cpuid_1_eax, &cp); |
| if (!(cp.data && cp.size)) |
| return -EINVAL; |
| @@ -549,6 +554,7 @@ int __init save_microcode_in_initrd_amd( |
| |
| return 0; |
| } |
| +early_initcall(save_microcode_in_initrd); |
| |
| /* |
| * a small, trivial cache of per-family ucode patches |
| --- a/arch/x86/kernel/cpu/microcode/core.c |
| +++ b/arch/x86/kernel/cpu/microcode/core.c |
| @@ -180,30 +180,13 @@ void load_ucode_ap(void) |
| } |
| } |
| |
| -static int __init save_microcode_in_initrd(void) |
| +/* Temporary workaround until find_microcode_in_initrd() is __init */ |
| +static int __init mark_initrd_gone(void) |
| { |
| - struct cpuinfo_x86 *c = &boot_cpu_data; |
| - int ret = -EINVAL; |
| - |
| - if (dis_ucode_ldr) { |
| - ret = 0; |
| - goto out; |
| - } |
| - |
| - switch (c->x86_vendor) { |
| - case X86_VENDOR_AMD: |
| - if (c->x86 >= 0x10) |
| - ret = save_microcode_in_initrd_amd(cpuid_eax(1)); |
| - break; |
| - default: |
| - break; |
| - } |
| - |
| -out: |
| initrd_gone = true; |
| - |
| - return ret; |
| + return 0; |
| } |
| +fs_initcall(mark_initrd_gone); |
| |
| struct cpio_data find_microcode_in_initrd(const char *path) |
| { |
| @@ -621,5 +604,4 @@ static int __init microcode_init(void) |
| return error; |
| |
| } |
| -fs_initcall(save_microcode_in_initrd); |
| late_initcall(microcode_init); |