Commit 2bbd2904 authored by Aichun Shi's avatar Aichun Shi
Browse files

Revert "x86/microcode: Simplify init path even more"

Intel inclusion
category: feature
feature: Backport Intel In Field Scan(IFS) multi-blob images support
bugzilla: https://gitee.com/openeuler/intel-kernel/issues/I6L337


CVE: N/A
Reference: N/A

Intel-SIG: Revert commit 5071ec24 ("x86/microcode: Simplify init
path even more")

-------------------------------------

This reverts commit 5071ec24.

This revert is to recover old microcode interface /dev/cpu/microcode.

Signed-off-by: default avatarAichun Shi <aichun.shi@intel.com>
parent 0e74f45b
Loading
Loading
Loading
Loading
+104 −16
Original line number Diff line number Diff line
@@ -336,6 +336,60 @@ 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;

@@ -421,7 +475,7 @@ static int __reload_late(void *info)
	 * below.
	 */
	if (cpumask_first(topology_sibling_cpumask(cpu)) == cpu)
		err = microcode_ops->apply_microcode(cpu);
		apply_microcode_local(&err);
	else
		goto wait_for_siblings;

@@ -443,7 +497,7 @@ static int __reload_late(void *info)
	 * revision.
	 */
	if (cpumask_first(topology_sibling_cpumask(cpu)) != cpu)
		err = microcode_ops->apply_microcode(cpu);
		apply_microcode_local(&err);

	return ret;
}
@@ -552,15 +606,51 @@ static void microcode_fini_cpu(int cpu)
		microcode_ops->microcode_fini_cpu(cpu);
}

static enum ucode_state microcode_init_cpu(int 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;

	memset(uci, 0, sizeof(*uci));
	if (uci->valid)
		return UCODE_OK;

	microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig);
	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, &microcode_pdev->dev, refresh_fw);
	if (ustate == UCODE_NEW) {
		pr_debug("CPU%d updated upon init\n", cpu);
		apply_microcode_on_target(cpu);
	}

	return ustate;
}

	return microcode_ops->apply_microcode(cpu);
static enum ucode_state microcode_update_cpu(int cpu)
{
	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;

	/* Refresh CPU microcode revision after resume. */
	collect_cpu_info(cpu);

	if (uci->valid)
		return microcode_resume_cpu(cpu);

	return microcode_init_cpu(cpu, false);
}

/**
@@ -583,9 +673,9 @@ static struct syscore_ops mc_syscore_ops = {

static int mc_cpu_starting(unsigned int cpu)
{
	enum ucode_state err = microcode_ops->apply_microcode(cpu);

	return err == UCODE_ERROR;
	microcode_update_cpu(cpu);
	pr_debug("CPU%d added\n", cpu);
	return 0;
}

static int mc_cpu_online(unsigned int cpu)
@@ -615,13 +705,11 @@ static int mc_cpu_down_prep(unsigned int cpu)
static void setup_online_cpu(struct work_struct *work)
{
	int cpu = smp_processor_id();
	enum ucode_state err;
	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;

	err = microcode_init_cpu(cpu);
	if (err == UCODE_ERROR) {
		pr_err("Error applying microcode on CPU%d\n", cpu);
		return;
	}
	memset(uci, 0, sizeof(*uci));

	microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig);

	mc_cpu_online(cpu);
}