WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [XEN] Upgrade microcode driver to 1.14a.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [XEN] Upgrade microcode driver to 1.14a.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 27 Jun 2006 16:50:16 +0000
Delivery-date: Tue, 27 Jun 2006 09:52:33 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxxxx
# Node ID bad506bc0c85fc9e52b95392c131ecb0d0e6a706
# Parent  1a52829fd60ed55357edbd08b12b99fddc644a57
[XEN] Upgrade microcode driver to 1.14a.
Based on a patch from Jan Beulich.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/microcode.c |  138 +++++++++++++++++++++++++++--------------------
 1 files changed, 81 insertions(+), 57 deletions(-)

diff -r 1a52829fd60e -r bad506bc0c85 xen/arch/x86/microcode.c
--- a/xen/arch/x86/microcode.c  Tue Jun 27 14:38:58 2006 +0100
+++ b/xen/arch/x86/microcode.c  Tue Jun 27 15:22:55 2006 +0100
@@ -83,9 +83,9 @@
 #include <asm/processor.h>
 
 #define pr_debug(x...) ((void)0)
-#define DECLARE_MUTEX(_m) DEFINE_SPINLOCK(_m)
-#define down(_m) spin_lock(_m)
-#define up(_m) spin_unlock(_m)
+#define DEFINE_MUTEX(_m) DEFINE_SPINLOCK(_m)
+#define mutex_lock(_m) spin_lock(_m)
+#define mutex_unlock(_m) spin_unlock(_m)
 #define vmalloc(_s) xmalloc_bytes(_s)
 #define vfree(_p) xfree(_p)
 
@@ -95,7 +95,10 @@ MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 #endif
 
-#define MICROCODE_VERSION      "1.14"
+static int verbose;
+boolean_param("microcode.verbose", verbose);
+
+#define MICROCODE_VERSION      "1.14a"
 
 #define DEFAULT_UCODE_DATASIZE         (2000)    /* 2000 bytes */
 #define MC_HEADER_SIZE         (sizeof (microcode_header_t))     /* 48 bytes */
@@ -119,21 +122,22 @@ static DEFINE_SPINLOCK(microcode_update_
 static DEFINE_SPINLOCK(microcode_update_lock);
 
 /* no concurrent ->write()s are allowed on /dev/cpu/microcode */
-static DECLARE_MUTEX(microcode_sem);
+static DEFINE_MUTEX(microcode_mutex);
 
 static void __user *user_buffer;       /* user area microcode data buffer */
 static unsigned int user_buffer_size;  /* it's size */
 
 typedef enum mc_error_code {
        MC_SUCCESS      = 0,
-       MC_NOTFOUND     = 1,
-       MC_MARKED       = 2,
-       MC_ALLOCATED    = 3,
+       MC_IGNORED      = 1,
+       MC_NOTFOUND     = 2,
+       MC_MARKED       = 3,
+       MC_ALLOCATED    = 4,
 } mc_error_code_t;
 
 static struct ucode_cpu_info {
        unsigned int sig;
-       unsigned int pf;
+       unsigned int pf, orig_pf;
        unsigned int rev;
        unsigned int cksum;
        mc_error_code_t err;
@@ -163,6 +167,7 @@ static void collect_cpu_info (void *unus
                        rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
                        uci->pf = 1 << ((val[1] >> 18) & 7);
                }
+               uci->orig_pf = uci->pf;
        }
 
        wrmsr(MSR_IA32_UCODE_REV, 0, 0);
@@ -196,23 +201,34 @@ static inline void mark_microcode_update
        pr_debug("   Checksum 0x%x\n", cksum);
 
        if (mc_header->rev < uci->rev) {
-               printk(KERN_ERR "microcode: CPU%d not 'upgrading' to earlier 
revision"
-                      " 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, 
uci->rev);
-               goto out;
+               if (uci->err == MC_NOTFOUND) {
+                       uci->err = MC_IGNORED;
+                       uci->cksum = mc_header->rev;
+               } else if (uci->err == MC_IGNORED && uci->cksum < 
mc_header->rev)
+                       uci->cksum = mc_header->rev;
        } else if (mc_header->rev == uci->rev) {
-               /* notify the caller of success on this cpu */
-               uci->err = MC_SUCCESS;
-               printk(KERN_ERR "microcode: CPU%d already at revision"
-                       " 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, 
uci->rev);
-               goto out;
-       }
-
-       pr_debug("microcode: CPU%d found a matching microcode update with "
-               " revision 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, 
uci->rev);
-       uci->cksum = cksum;
-       uci->pf = pf; /* keep the original mc pf for cksum calculation */
-       uci->err = MC_MARKED; /* found the match */
-out:
+               if (uci->err < MC_MARKED) {
+                       /* notify the caller of success on this cpu */
+                       uci->err = MC_SUCCESS;
+               }
+       } else if (uci->err != MC_ALLOCATED || mc_header->rev > 
uci->mc->hdr.rev) {
+               pr_debug("microcode: CPU%d found a matching microcode update 
with "
+                       " revision 0x%x (current=0x%x)\n", cpu_num, 
mc_header->rev, uci->rev);
+               uci->cksum = cksum;
+               uci->pf = pf; /* keep the original mc pf for cksum calculation 
*/
+               uci->err = MC_MARKED; /* found the match */
+               for_each_online_cpu(cpu_num) {
+                       if (ucode_cpu_info + cpu_num != uci
+                           && ucode_cpu_info[cpu_num].mc == uci->mc) {
+                               uci->mc = NULL;
+                               break;
+                       }
+               }
+               if (uci->mc != NULL) {
+                       vfree(uci->mc);
+                       uci->mc = NULL;
+               }
+       }
        return;
 }
 
@@ -251,13 +267,11 @@ static int find_matching_ucodes (void)
                        error = -EINVAL;
                        goto out;
                }
-               
-               for (cpu_num = 0; cpu_num < num_online_cpus(); cpu_num++) {
+
+               for_each_online_cpu(cpu_num) {
                        struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
-                       if (uci->err != MC_NOTFOUND) /* already found a match 
or not an online cpu*/
-                               continue;
-
-                       if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, 
uci->pf))
+
+                       if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, 
uci->orig_pf))
                                mark_microcode_update(cpu_num, &mc_header, 
mc_header.sig, mc_header.pf, mc_header.cksum);
                }
 
@@ -294,18 +308,19 @@ static int find_matching_ucodes (void)
                                        error = -EFAULT;
                                        goto out;
                                }
-                               for (cpu_num = 0; cpu_num < num_online_cpus(); 
cpu_num++) {
+                               for_each_online_cpu(cpu_num) {
                                        struct ucode_cpu_info *uci = 
ucode_cpu_info + cpu_num;
-                                       if (uci->err != MC_NOTFOUND) /* already 
found a match or not an online cpu*/
-                                               continue;
-                                       if (sigmatch(ext_sig.sig, uci->sig, 
ext_sig.pf, uci->pf)) {
+
+                                       if (sigmatch(ext_sig.sig, uci->sig, 
ext_sig.pf, uci->orig_pf)) {
                                                mark_microcode_update(cpu_num, 
&mc_header, ext_sig.sig, ext_sig.pf, ext_sig.cksum);
                                        }
                                }
                        }
                }
                /* now check if any cpu has matched */
-               for (cpu_num = 0, allocated_flag = 0, sum = 0; cpu_num < 
num_online_cpus(); cpu_num++) {
+               allocated_flag = 0;
+               sum = 0;
+               for_each_online_cpu(cpu_num) {
                        if (ucode_cpu_info[cpu_num].err == MC_MARKED) { 
                                struct ucode_cpu_info *uci = ucode_cpu_info + 
cpu_num;
                                if (!allocated_flag) {
@@ -367,7 +382,13 @@ static void do_update_one (void * unused
        struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
 
        if (uci->mc == NULL) {
-               printk(KERN_INFO "microcode: No new microcode data for 
CPU%d\n", cpu_num);
+               if (verbose) {
+                       if (uci->err == MC_SUCCESS)
+                               printk(KERN_INFO "microcode: CPU%d already at 
revision 0x%x\n",
+                                       cpu_num, uci->rev);
+                       else
+                               printk(KERN_INFO "microcode: No new microcode 
data for CPU%d\n", cpu_num);
+               }
                return;
        }
 
@@ -416,16 +437,19 @@ static int do_microcode_update (void)
        }
 
 out_free:
-       for (i = 0; i < num_online_cpus(); i++) {
+       for_each_online_cpu(i) {
                if (ucode_cpu_info[i].mc) {
                        int j;
                        void *tmp = ucode_cpu_info[i].mc;
                        vfree(tmp);
-                       for (j = i; j < num_online_cpus(); j++) {
+                       for_each_online_cpu(j) {
                                if (ucode_cpu_info[j].mc == tmp)
                                        ucode_cpu_info[j].mc = NULL;
                        }
                }
+               if (ucode_cpu_info[i].err == MC_IGNORED && verbose)
+                       printk(KERN_WARNING "microcode: CPU%d not 'upgrading' 
to earlier revision"
+                              " 0x%x (current=0x%x)\n", i, 
ucode_cpu_info[i].cksum, ucode_cpu_info[i].rev);
        }
 out:
        return error;
@@ -433,21 +457,21 @@ out:
 
 int microcode_update(void *buf, unsigned long len)
 {
-    int ret;
-
-    if (len < DEFAULT_UCODE_TOTALSIZE) {
-        printk(KERN_ERR "microcode: not enough data\n"); 
-        return -EINVAL;
-    }
-
-    down(&microcode_sem);
-    
-    user_buffer = (void __user *) buf;
-    user_buffer_size = (int) len;
-    
-    ret = do_microcode_update();
-    
-    up(&microcode_sem);
-    
-    return ret;
-}
+       int ret;
+
+       if (len < DEFAULT_UCODE_TOTALSIZE) {
+               printk(KERN_ERR "microcode: not enough data\n"); 
+               return -EINVAL;
+       }
+
+       mutex_lock(&microcode_mutex);
+
+       user_buffer = (void __user *) buf;
+       user_buffer_size = (int) len;
+
+       ret = do_microcode_update();
+
+       mutex_unlock(&microcode_mutex);
+
+       return ret;
+}

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [XEN] Upgrade microcode driver to 1.14a., Xen patchbot-unstable <=