aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/microcode.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-01-22 11:11:10 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-01-22 11:11:10 +0000
commit4a10e13111a0417d4c9f2d4ee2ce65955ef745d5 (patch)
treeab79bc92cfb65ab8c10bf7e29c388b52e421de4d /xen/arch/x86/microcode.c
parentdf29e279e265fbb2195124e31d0003064ecdc126 (diff)
downloadxen-4a10e13111a0417d4c9f2d4ee2ce65955ef745d5.tar.gz
xen-4a10e13111a0417d4c9f2d4ee2ce65955ef745d5.tar.bz2
xen-4a10e13111a0417d4c9f2d4ee2ce65955ef745d5.zip
x86 ucode: microcode logic update
Update microcode logic: 1. separate microcode_fini_cpu() into 2 level to avoid deadlock (when fail at microcode_update_cpu); 2. cancel redundant collect_cpu_info at microcode.c level, use relative function at microcode driver level; 3. separate microcode_resume_cpu from microcode_update_cpu, because it's redundant (should only be called when S3 wakeup) and will block newer microcode update when user update newer microcode.dat from user level Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>
Diffstat (limited to 'xen/arch/x86/microcode.c')
-rw-r--r--xen/arch/x86/microcode.c33
1 files changed, 12 insertions, 21 deletions
diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c
index b6eacda59b..80526a6103 100644
--- a/xen/arch/x86/microcode.c
+++ b/xen/arch/x86/microcode.c
@@ -49,25 +49,22 @@ struct microcode_info {
char buffer[1];
};
-static void microcode_fini_cpu(int cpu)
+static void __microcode_fini_cpu(int cpu)
{
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
- spin_lock(&microcode_mutex);
xfree(uci->mc.mc_valid);
- uci->mc.mc_valid = NULL;
- spin_unlock(&microcode_mutex);
+ memset(uci, 0, sizeof(*uci));
}
-static int collect_cpu_info(int cpu)
+static void microcode_fini_cpu(int cpu)
{
- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
-
- memset(uci, 0, sizeof(*uci));
- return microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig);
+ spin_lock(&microcode_mutex);
+ __microcode_fini_cpu(cpu);
+ spin_unlock(&microcode_mutex);
}
-static int microcode_resume_cpu(int cpu)
+int microcode_resume_cpu(int cpu)
{
int err = 0;
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
@@ -107,17 +104,11 @@ static int microcode_update_cpu(const void *buf, size_t size)
spin_lock(&microcode_mutex);
- /*
- * Check if the system resume is in progress (uci->mc.mc_valid != NULL),
- * otherwise just request a firmware:
- */
- if ( uci->mc.mc_valid ) {
- err = microcode_resume_cpu(cpu);
- } else {
- err = collect_cpu_info(cpu);
- if ( !err )
- err = microcode_ops->cpu_request_microcode(cpu, buf, size);
- }
+ err = microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig);
+ if ( likely(!err) )
+ err = microcode_ops->cpu_request_microcode(cpu, buf, size);
+ else
+ __microcode_fini_cpu(cpu);
spin_unlock(&microcode_mutex);