aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xen/arch/x86/acpi/power.c1
-rw-r--r--xen/arch/x86/microcode.c9
-rw-r--r--xen/arch/x86/microcode_amd.c6
-rw-r--r--xen/arch/x86/microcode_intel.c9
-rw-r--r--xen/arch/x86/smpboot.c2
-rw-r--r--xen/include/asm-x86/microcode.h1
-rw-r--r--xen/include/asm-x86/processor.h1
7 files changed, 25 insertions, 4 deletions
diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c
index ccad2ea5ee..fce2163ffc 100644
--- a/xen/arch/x86/acpi/power.c
+++ b/xen/arch/x86/acpi/power.c
@@ -221,6 +221,7 @@ static int enter_state(u32 state)
enable_cpu:
cpufreq_add_cpu(0);
+ microcode_resume_cpu(0);
enable_nonboot_cpus();
thaw_domains();
spin_unlock(&pm_lock);
diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c
index 80526a6103..ebad6ef11d 100644
--- a/xen/arch/x86/microcode.c
+++ b/xen/arch/x86/microcode.c
@@ -86,14 +86,15 @@ int microcode_resume_cpu(int cpu)
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)
diff --git a/xen/arch/x86/microcode_amd.c b/xen/arch/x86/microcode_amd.c
index 730dce0a0b..77053c258d 100644
--- a/xen/arch/x86/microcode_amd.c
+++ b/xen/arch/x86/microcode_amd.c
@@ -318,7 +318,13 @@ out:
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,
diff --git a/xen/arch/x86/microcode_intel.c b/xen/arch/x86/microcode_intel.c
index c93df509ad..7d8657ff2f 100644
--- a/xen/arch/x86/microcode_intel.c
+++ b/xen/arch/x86/microcode_intel.c
@@ -360,7 +360,16 @@ static int cpu_request_microcode(int cpu, const void *buf, size_t size)
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,
diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
index 8eae62196c..a77d406f46 100644
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -525,6 +525,8 @@ void __devinit start_secondary(void *unused)
/* We can take interrupts now: we're officially "up". */
local_irq_enable();
+ microcode_resume_cpu(cpu);
+
wmb();
startup_cpu_idle_loop();
}
diff --git a/xen/include/asm-x86/microcode.h b/xen/include/asm-x86/microcode.h
index 57582cfa91..980da227dc 100644
--- a/xen/include/asm-x86/microcode.h
+++ b/xen/include/asm-x86/microcode.h
@@ -5,6 +5,7 @@ struct cpu_signature;
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);
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index d218e50d4f..d9af37aba2 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -553,6 +553,7 @@ int wrmsr_hypervisor_regs(
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__ */