forked from rpms/kernel
213 lines
5.5 KiB
Diff
213 lines
5.5 KiB
Diff
From 1a37aa866d76aaab6901bb331ea1be202ccad636 Mon Sep 17 00:00:00 2001
|
|
From: Borislav Petkov <bp@suse.de>
|
|
Date: Wed, 19 Oct 2022 19:07:30 +0200
|
|
Subject: [PATCH 10/36] x86/microcode: Simplify init path even more
|
|
|
|
Get rid of all the IPI-sending functions and their wrappers and use
|
|
those which are supposed to be called on each CPU.
|
|
|
|
Thus:
|
|
|
|
- microcode_init_cpu() gets called on each CPU on init, applying any new
|
|
microcode that the driver might've found on the filesystem.
|
|
|
|
- mc_cpu_starting() simply tries to apply cached microcode as this is
|
|
the cpuhp starting callback which gets called on CPU resume too.
|
|
|
|
Even if the driver init function is a late initcall, there is no
|
|
filesystem by then (not even a hdd driver has been loaded yet) so a new
|
|
firmware load attempt cannot simply be done.
|
|
|
|
It is pointless anyway - for that there's late loading if one really
|
|
needs it.
|
|
|
|
Signed-off-by: Borislav Petkov <bp@suse.de>
|
|
Reviewed-by: Ashok Raj <ashok.raj@intel.com>
|
|
Link: https://lore.kernel.org/r/20221028142638.28498-3-bp@alien8.de
|
|
(cherry picked from commit 2071c0aeda228107bf1b9e870b6187c90fbeef1d)
|
|
Signed-off-by: Mridula Shastry <mridula.c.shastry@oracle.com>
|
|
Reviewed-by: Todd Vierling <todd.vierling@oracle.com>
|
|
---
|
|
arch/x86/kernel/cpu/microcode/core.c | 120 ++++-----------------------
|
|
1 file changed, 16 insertions(+), 104 deletions(-)
|
|
|
|
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
|
|
index 8a7fc5d8db6e..50321a43da01 100644
|
|
--- a/arch/x86/kernel/cpu/microcode/core.c
|
|
+++ b/arch/x86/kernel/cpu/microcode/core.c
|
|
@@ -338,60 +338,6 @@ void reload_early_microcode(void)
|
|
}
|
|
}
|
|
|
|
-static void collect_cpu_info_local(void *arg)
|
|
-{
|
|
- struct cpu_info_ctx *ctx = arg;
|
|
-
|
|
- ctx->err = microcode_ops->collect_cpu_info(smp_processor_id(),
|
|
- ctx->cpu_sig);
|
|
-}
|
|
-
|
|
-static int collect_cpu_info_on_target(int cpu, struct cpu_signature *cpu_sig)
|
|
-{
|
|
- struct cpu_info_ctx ctx = { .cpu_sig = cpu_sig, .err = 0 };
|
|
- int ret;
|
|
-
|
|
- ret = smp_call_function_single(cpu, collect_cpu_info_local, &ctx, 1);
|
|
- if (!ret)
|
|
- ret = ctx.err;
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static int collect_cpu_info(int cpu)
|
|
-{
|
|
- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
|
|
- int ret;
|
|
-
|
|
- memset(uci, 0, sizeof(*uci));
|
|
-
|
|
- ret = collect_cpu_info_on_target(cpu, &uci->cpu_sig);
|
|
- if (!ret)
|
|
- uci->valid = 1;
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static void apply_microcode_local(void *arg)
|
|
-{
|
|
- enum ucode_state *err = arg;
|
|
-
|
|
- *err = microcode_ops->apply_microcode(smp_processor_id());
|
|
-}
|
|
-
|
|
-static int apply_microcode_on_target(int cpu)
|
|
-{
|
|
- enum ucode_state err;
|
|
- int ret;
|
|
-
|
|
- ret = smp_call_function_single(cpu, apply_microcode_local, &err, 1);
|
|
- if (!ret) {
|
|
- if (err == UCODE_ERROR)
|
|
- ret = 1;
|
|
- }
|
|
- return ret;
|
|
-}
|
|
-
|
|
/* fake device for request_firmware */
|
|
static struct platform_device *microcode_pdev;
|
|
|
|
@@ -478,7 +424,7 @@ static int __reload_late(void *info)
|
|
* below.
|
|
*/
|
|
if (cpumask_first(topology_sibling_cpumask(cpu)) == cpu)
|
|
- apply_microcode_local(&err);
|
|
+ err = microcode_ops->apply_microcode(cpu);
|
|
else
|
|
goto wait_for_siblings;
|
|
|
|
@@ -500,7 +446,7 @@ wait_for_siblings:
|
|
* revision.
|
|
*/
|
|
if (cpumask_first(topology_sibling_cpumask(cpu)) != cpu)
|
|
- apply_microcode_local(&err);
|
|
+ err = microcode_ops->apply_microcode(cpu);
|
|
|
|
return ret;
|
|
}
|
|
@@ -609,51 +555,15 @@ static void microcode_fini_cpu(int cpu)
|
|
microcode_ops->microcode_fini_cpu(cpu);
|
|
}
|
|
|
|
-static enum ucode_state microcode_resume_cpu(int cpu)
|
|
-{
|
|
- if (apply_microcode_on_target(cpu))
|
|
- return UCODE_ERROR;
|
|
-
|
|
- pr_debug("CPU%d updated upon resume\n", cpu);
|
|
-
|
|
- return UCODE_OK;
|
|
-}
|
|
-
|
|
-static enum ucode_state microcode_init_cpu(int cpu, bool refresh_fw)
|
|
-{
|
|
- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
|
|
- enum ucode_state ustate;
|
|
-
|
|
- if (uci->valid)
|
|
- return UCODE_OK;
|
|
-
|
|
- if (collect_cpu_info(cpu))
|
|
- return UCODE_ERROR;
|
|
-
|
|
- /* --dimm. Trigger a delayed update? */
|
|
- if (system_state != SYSTEM_RUNNING)
|
|
- return UCODE_NFOUND;
|
|
-
|
|
- ustate = microcode_ops->request_microcode_fw(cpu, µcode_pdev->dev, refresh_fw);
|
|
- if (ustate == UCODE_NEW) {
|
|
- pr_debug("CPU%d updated upon init\n", cpu);
|
|
- apply_microcode_on_target(cpu);
|
|
- }
|
|
-
|
|
- return ustate;
|
|
-}
|
|
-
|
|
-static enum ucode_state microcode_update_cpu(int cpu)
|
|
+static enum ucode_state microcode_init_cpu(int cpu)
|
|
{
|
|
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
|
|
|
|
- /* Refresh CPU microcode revision after resume. */
|
|
- collect_cpu_info(cpu);
|
|
+ memset(uci, 0, sizeof(*uci));
|
|
|
|
- if (uci->valid)
|
|
- return microcode_resume_cpu(cpu);
|
|
+ microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig);
|
|
|
|
- return microcode_init_cpu(cpu, false);
|
|
+ return microcode_ops->apply_microcode(cpu);
|
|
}
|
|
|
|
/**
|
|
@@ -671,14 +581,14 @@ void microcode_bsp_resume(void)
|
|
}
|
|
|
|
static struct syscore_ops mc_syscore_ops = {
|
|
- .resume = microcode_bsp_resume,
|
|
+ .resume = microcode_bsp_resume,
|
|
};
|
|
|
|
static int mc_cpu_starting(unsigned int cpu)
|
|
{
|
|
- microcode_update_cpu(cpu);
|
|
- pr_debug("CPU%d added\n", cpu);
|
|
- return 0;
|
|
+ enum ucode_state err = microcode_ops->apply_microcode(cpu);
|
|
+
|
|
+ return err == UCODE_ERROR;
|
|
}
|
|
|
|
static int mc_cpu_online(unsigned int cpu)
|
|
@@ -708,11 +618,13 @@ static int mc_cpu_down_prep(unsigned int cpu)
|
|
static void setup_online_cpu(struct work_struct *work)
|
|
{
|
|
int cpu = smp_processor_id();
|
|
- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
|
|
-
|
|
- memset(uci, 0, sizeof(*uci));
|
|
+ enum ucode_state err;
|
|
|
|
- microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig);
|
|
+ err = microcode_init_cpu(cpu);
|
|
+ if (err == UCODE_ERROR) {
|
|
+ pr_err("Error applying microcode on CPU%d\n", cpu);
|
|
+ return;
|
|
+ }
|
|
|
|
mc_cpu_online(cpu);
|
|
}
|
|
--
|
|
2.39.3
|
|
|