# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1232623068 0
# Node ID 9f9ba1a7cc924fbc547e05ea21071becafe5e2c2
# Parent adc3775bb6d8aa1070b8aaaa186a2a98898f9478
x86 ucode: add S3 microcode update
When wakeup from S3, use per cpu microcode image to update cpu
microcode.
Signed-off-by: Liu, Jinsong <jinsong.liu@xxxxxxxxx>
---
xen/arch/x86/acpi/power.c | 1 +
xen/arch/x86/microcode.c | 9 +++++----
xen/arch/x86/microcode_amd.c | 6 ++++++
xen/arch/x86/microcode_intel.c | 9 +++++++++
xen/arch/x86/smpboot.c | 2 ++
xen/include/asm-x86/microcode.h | 1 +
xen/include/asm-x86/processor.h | 1 +
7 files changed, 25 insertions(+), 4 deletions(-)
diff -r adc3775bb6d8 -r 9f9ba1a7cc92 xen/arch/x86/acpi/power.c
--- a/xen/arch/x86/acpi/power.c Thu Jan 22 11:11:39 2009 +0000
+++ b/xen/arch/x86/acpi/power.c Thu Jan 22 11:17:48 2009 +0000
@@ -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 -r adc3775bb6d8 -r 9f9ba1a7cc92 xen/arch/x86/microcode.c
--- a/xen/arch/x86/microcode.c Thu Jan 22 11:11:39 2009 +0000
+++ b/xen/arch/x86/microcode.c Thu Jan 22 11:17:48 2009 +0000
@@ -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 -r adc3775bb6d8 -r 9f9ba1a7cc92 xen/arch/x86/microcode_amd.c
--- a/xen/arch/x86/microcode_amd.c Thu Jan 22 11:11:39 2009 +0000
+++ b/xen/arch/x86/microcode_amd.c Thu Jan 22 11:17:48 2009 +0000
@@ -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 -r adc3775bb6d8 -r 9f9ba1a7cc92 xen/arch/x86/microcode_intel.c
--- a/xen/arch/x86/microcode_intel.c Thu Jan 22 11:11:39 2009 +0000
+++ b/xen/arch/x86/microcode_intel.c Thu Jan 22 11:17:48 2009 +0000
@@ -360,7 +360,16 @@ static int cpu_request_microcode(int cpu
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 -r adc3775bb6d8 -r 9f9ba1a7cc92 xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c Thu Jan 22 11:11:39 2009 +0000
+++ b/xen/arch/x86/smpboot.c Thu Jan 22 11:17:48 2009 +0000
@@ -525,6 +525,8 @@ void __devinit start_secondary(void *unu
/* We can take interrupts now: we're officially "up". */
local_irq_enable();
+ microcode_resume_cpu(cpu);
+
wmb();
startup_cpu_idle_loop();
}
diff -r adc3775bb6d8 -r 9f9ba1a7cc92 xen/include/asm-x86/microcode.h
--- a/xen/include/asm-x86/microcode.h Thu Jan 22 11:11:39 2009 +0000
+++ b/xen/include/asm-x86/microcode.h Thu Jan 22 11:17:48 2009 +0000
@@ -5,6 +5,7 @@ struct ucode_cpu_info;
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 -r adc3775bb6d8 -r 9f9ba1a7cc92 xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h Thu Jan 22 11:11:39 2009 +0000
+++ b/xen/include/asm-x86/processor.h Thu Jan 22 11:17:48 2009 +0000
@@ -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__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|