x86/microcode/amd: Use cached microcode for AP load
authorThomas Gleixner <tglx@linutronix.de>
Tue, 17 Oct 2023 21:23:55 +0000 (23:23 +0200)
committerBorislav Petkov (AMD) <bp@alien8.de>
Tue, 24 Oct 2023 13:05:54 +0000 (15:05 +0200)
Now that the microcode cache is initialized before the APs are brought
up, there is no point in scanning builtin/initrd microcode during AP
loading.

Convert the AP loader to utilize the cache, which in turn makes the CPU
hotplug callback which applies the microcode after initrd/builtin is
gone, obsolete as the early loading during late hotplug operations
including the resume path depends now only on 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.243426023@linutronix.de
arch/x86/kernel/cpu/microcode/amd.c
arch/x86/kernel/cpu/microcode/core.c
arch/x86/kernel/cpu/microcode/internal.h

index 6717f0ea9b2f4e349341019c1476addd9a4a8a6f..99aa5a88d668d0c6f754fba58f135cf978d4bb45 100644 (file)
@@ -496,7 +496,7 @@ static bool get_builtin_microcode(struct cpio_data *cp, unsigned int family)
        return false;
 }
 
-static void find_blobs_in_containers(unsigned int cpuid_1_eax, struct cpio_data *ret)
+static void __init find_blobs_in_containers(unsigned int cpuid_1_eax, struct cpio_data *ret)
 {
        struct cpio_data cp;
 
@@ -506,12 +506,12 @@ static void find_blobs_in_containers(unsigned int cpuid_1_eax, struct cpio_data
        *ret = cp;
 }
 
-static void apply_ucode_from_containers(unsigned int cpuid_1_eax)
+void __init load_ucode_amd_bsp(unsigned int cpuid_1_eax)
 {
        struct cpio_data cp = { };
 
        /* Needed in load_microcode_amd() */
-       ucode_cpu_info[smp_processor_id()].cpu_sig.sig = cpuid_1_eax;
+       ucode_cpu_info[0].cpu_sig.sig = cpuid_1_eax;
 
        find_blobs_in_containers(cpuid_1_eax, &cp);
        if (!(cp.data && cp.size))
@@ -520,11 +520,6 @@ static void apply_ucode_from_containers(unsigned int cpuid_1_eax)
        early_apply_microcode(cpuid_1_eax, cp.data, cp.size);
 }
 
-void load_ucode_amd_early(unsigned int cpuid_1_eax)
-{
-       return apply_ucode_from_containers(cpuid_1_eax);
-}
-
 static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size);
 
 static int __init save_microcode_in_initrd(void)
@@ -608,7 +603,6 @@ static struct ucode_patch *find_patch(unsigned int cpu)
        struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
        u16 equiv_id;
 
-
        equiv_id = find_equiv_id(&equiv_table, uci->cpu_sig.sig);
        if (!equiv_id)
                return NULL;
@@ -710,6 +704,14 @@ out:
        return ret;
 }
 
+void load_ucode_amd_ap(unsigned int cpuid_1_eax)
+{
+       unsigned int cpu = smp_processor_id();
+
+       ucode_cpu_info[cpu].cpu_sig.sig = cpuid_1_eax;
+       apply_microcode_amd(cpu);
+}
+
 static size_t install_equiv_cpu_table(const u8 *buf, size_t buf_size)
 {
        u32 equiv_tbl_len;
index 3d769ff1a1cade7cac114d3e80692924b3bcf715..15c50420da0b4a5e24aa0a3865bb21ff3cc2342f 100644 (file)
@@ -154,7 +154,7 @@ void __init load_ucode_bsp(void)
        if (intel)
                load_ucode_intel_bsp();
        else
-               load_ucode_amd_early(cpuid_1_eax);
+               load_ucode_amd_bsp(cpuid_1_eax);
 }
 
 void load_ucode_ap(void)
@@ -173,7 +173,7 @@ void load_ucode_ap(void)
                break;
        case X86_VENDOR_AMD:
                if (x86_family(cpuid_1_eax) >= 0x10)
-                       load_ucode_amd_early(cpuid_1_eax);
+                       load_ucode_amd_ap(cpuid_1_eax);
                break;
        default:
                break;
@@ -494,15 +494,6 @@ static struct syscore_ops mc_syscore_ops = {
        .resume = microcode_bsp_resume,
 };
 
-static int mc_cpu_starting(unsigned int cpu)
-{
-       enum ucode_state err = microcode_ops->apply_microcode(cpu);
-
-       pr_debug("%s: CPU%d, err: %d\n", __func__, cpu, err);
-
-       return err == UCODE_ERROR;
-}
-
 static int mc_cpu_online(unsigned int cpu)
 {
        struct device *dev = get_cpu_device(cpu);
@@ -590,8 +581,6 @@ static int __init microcode_init(void)
        schedule_on_each_cpu(setup_online_cpu);
 
        register_syscore_ops(&mc_syscore_ops);
-       cpuhp_setup_state_nocalls(CPUHP_AP_MICROCODE_LOADER, "x86/microcode:starting",
-                                 mc_cpu_starting, NULL);
        cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "x86/microcode:online",
                                  mc_cpu_online, mc_cpu_down_prep);
 
index 32f6ad593ef997568761aa6e1054db4a5f58b867..89fbf749dcc6b5805e4b26a85e2fcc340e5faed8 100644 (file)
@@ -91,7 +91,6 @@ extern bool initrd_gone;
 #ifdef CONFIG_CPU_SUP_AMD
 void load_ucode_amd_bsp(unsigned int family);
 void load_ucode_amd_ap(unsigned int family);
-void load_ucode_amd_early(unsigned int cpuid_1_eax);
 int save_microcode_in_initrd_amd(unsigned int family);
 void reload_ucode_amd(unsigned int cpu);
 struct microcode_ops *init_amd_microcode(void);
@@ -99,7 +98,6 @@ void exit_amd_microcode(void);
 #else /* CONFIG_CPU_SUP_AMD */
 static inline void load_ucode_amd_bsp(unsigned int family) { }
 static inline void load_ucode_amd_ap(unsigned int family) { }
-static inline void load_ucode_amd_early(unsigned int family) { }
 static inline int save_microcode_in_initrd_amd(unsigned int family) { return -EINVAL; }
 static inline void reload_ucode_amd(unsigned int cpu) { }
 static inline struct microcode_ops *init_amd_microcode(void) { return NULL; }