enable_cpu:
cpufreq_add_cpu(0);
+ microcode_resume_cpu(0);
enable_nonboot_cpus();
thaw_domains();
spin_unlock(&pm_lock);
return err;
}
- if ( memcmp(&nsig, &uci->cpu_sig, sizeof(nsig)) )
+ if ( microcode_ops->microcode_resume_match(cpu, &nsig) )
+ {
+ return microcode_ops->apply_microcode(cpu);
+ }
+ else
{
microcode_fini_cpu(cpu);
- /* Should we look for a new ucode here? */
return -EIO;
}
-
- return microcode_ops->apply_microcode(cpu);
}
static int microcode_update_cpu(const void *buf, size_t size)
return error;
}
+static int microcode_resume_match(int cpu, struct cpu_signature *nsig)
+{
+ return 0;
+}
+
static struct microcode_ops microcode_amd_ops = {
+ .microcode_resume_match = microcode_resume_match,
.cpu_request_microcode = cpu_request_microcode,
.collect_cpu_info = collect_cpu_info,
.apply_microcode = apply_microcode,
return error;
}
+static int microcode_resume_match(int cpu, struct cpu_signature *nsig)
+{
+ struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
+
+ return (sigmatch(nsig->sig, uci->cpu_sig.sig, nsig->pf, uci->cpu_sig.pf) &&
+ (uci->cpu_sig.rev > nsig->rev));
+}
+
static struct microcode_ops microcode_intel_ops = {
+ .microcode_resume_match = microcode_resume_match,
.cpu_request_microcode = cpu_request_microcode,
.collect_cpu_info = collect_cpu_info,
.apply_microcode = apply_microcode,
/* We can take interrupts now: we're officially "up". */
local_irq_enable();
+ microcode_resume_cpu(cpu);
+
wmb();
startup_cpu_idle_loop();
}
struct ucode_cpu_info;
struct microcode_ops {
+ int (*microcode_resume_match)(int cpu, struct cpu_signature *nsig);
int (*cpu_request_microcode)(int cpu, const void *buf, size_t size);
int (*collect_cpu_info)(int cpu, struct cpu_signature *csig);
int (*apply_microcode)(int cpu);
uint32_t idx, uint32_t eax, uint32_t edx);
int microcode_update(XEN_GUEST_HANDLE(const_void), unsigned long len);
+int microcode_resume_cpu(int cpu);
#endif /* !__ASSEMBLY__ */