x86 ucode: microcode logic update
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 22 Jan 2009 11:11:10 +0000 (11:11 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 22 Jan 2009 11:11:10 +0000 (11:11 +0000)
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>
xen/arch/x86/microcode.c
xen/arch/x86/microcode_intel.c

index b6eacda59b51e9a2645cf5c36b3e907d9789573e..80526a61031d7ae3fc54e4638dc9af51525fab0a 100644 (file)
@@ -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);
 
index 4efd67966028af7be6857ed0e2da5be6b5e1da71..8681a6945f525164f7cc51c95181b95e0bca2a52 100644 (file)
@@ -64,6 +64,8 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
     struct cpuinfo_x86 *c = &cpu_data[cpu_num];
     unsigned int val[2];
 
+    BUG_ON(cpu_num != smp_processor_id());
+
     memset(csig, 0, sizeof(*csig));
 
     if ( (c->x86_vendor != X86_VENDOR_INTEL) || (c->x86 < 6) ||