ia64/xen-unstable
changeset 18497:087b8b29b6b2
x86, microcode: Clean up for Xen coding style, and disable for now
(until allocations in irq context are fixed).
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
(until allocations in irq context are fixed).
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Tue Sep 16 11:26:19 2008 +0100 (2008-09-16) |
parents | 087008dfb005 |
children | f03b0cc33576 |
files | xen/arch/x86/microcode.c xen/arch/x86/microcode_amd.c xen/arch/x86/microcode_intel.c xen/include/asm-x86/microcode.h |
line diff
1.1 --- a/xen/arch/x86/microcode.c Mon Sep 15 17:10:43 2008 +0100 1.2 +++ b/xen/arch/x86/microcode.c Tue Sep 16 11:26:19 2008 +0100 1.3 @@ -1,73 +1,24 @@ 1.4 /* 1.5 - * Intel CPU Microcode Update Driver for Linux 1.6 - * 1.7 - * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk> 1.8 - * 2006 Shaohua Li <shaohua.li@intel.com> * 1.9 - * This driver allows to upgrade microcode on Intel processors 1.10 - * belonging to IA-32 family - PentiumPro, Pentium II, 1.11 - * Pentium III, Xeon, Pentium 4, etc. 1.12 + * Intel CPU Microcode Update Driver for Linux 1.13 * 1.14 - * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture 1.15 - * Software Developer's Manual 1.16 - * Order Number 253668 or free download from: 1.17 - * 1.18 - * http://developer.intel.com/design/pentium4/manuals/253668.htm 1.19 - * 1.20 - * For more information, go to http://www.urbanmyth.org/microcode 1.21 - * 1.22 - * This program is free software; you can redistribute it and/or 1.23 - * modify it under the terms of the GNU General Public License 1.24 - * as published by the Free Software Foundation; either version 1.25 - * 2 of the License, or (at your option) any later version. 1.26 + * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk> 1.27 + * 2006 Shaohua Li <shaohua.li@intel.com> * 1.28 + * This driver allows to upgrade microcode on Intel processors 1.29 + * belonging to IA-32 family - PentiumPro, Pentium II, 1.30 + * Pentium III, Xeon, Pentium 4, etc. 1.31 * 1.32 - * 1.0 16 Feb 2000, Tigran Aivazian <tigran@sco.com> 1.33 - * Initial release. 1.34 - * 1.01 18 Feb 2000, Tigran Aivazian <tigran@sco.com> 1.35 - * Added read() support + cleanups. 1.36 - * 1.02 21 Feb 2000, Tigran Aivazian <tigran@sco.com> 1.37 - * Added 'device trimming' support. open(O_WRONLY) zeroes 1.38 - * and frees the saved copy of applied microcode. 1.39 - * 1.03 29 Feb 2000, Tigran Aivazian <tigran@sco.com> 1.40 - * Made to use devfs (/dev/cpu/microcode) + cleanups. 1.41 - * 1.04 06 Jun 2000, Simon Trimmer <simon@veritas.com> 1.42 - * Added misc device support (now uses both devfs and misc). 1.43 - * Added MICROCODE_IOCFREE ioctl to clear memory. 1.44 - * 1.05 09 Jun 2000, Simon Trimmer <simon@veritas.com> 1.45 - * Messages for error cases (non Intel & no suitable microcode). 1.46 - * 1.06 03 Aug 2000, Tigran Aivazian <tigran@veritas.com> 1.47 - * Removed ->release(). Removed exclusive open and status bitmap. 1.48 - * Added microcode_rwsem to serialize read()/write()/ioctl(). 1.49 - * Removed global kernel lock usage. 1.50 - * 1.07 07 Sep 2000, Tigran Aivazian <tigran@veritas.com> 1.51 - * Write 0 to 0x8B msr and then cpuid before reading revision, 1.52 - * so that it works even if there were no update done by the 1.53 - * BIOS. Otherwise, reading from 0x8B gives junk (which happened 1.54 - * to be 0 on my machine which is why it worked even when I 1.55 - * disabled update by the BIOS) 1.56 - * Thanks to Eric W. Biederman <ebiederman@lnxi.com> for the fix. 1.57 - * 1.08 11 Dec 2000, Richard Schaal <richard.schaal@intel.com> and 1.58 - * Tigran Aivazian <tigran@veritas.com> 1.59 - * Intel Pentium 4 processor support and bugfixes. 1.60 - * 1.09 30 Oct 2001, Tigran Aivazian <tigran@veritas.com> 1.61 - * Bugfix for HT (Hyper-Threading) enabled processors 1.62 - * whereby processor resources are shared by all logical processors 1.63 - * in a single CPU package. 1.64 - * 1.10 28 Feb 2002 Asit K Mallick <asit.k.mallick@intel.com> and 1.65 - * Tigran Aivazian <tigran@veritas.com>, 1.66 - * Serialize updates as required on HT processors due to 1.67 - * speculative nature of implementation. 1.68 - * 1.11 22 Mar 2002 Tigran Aivazian <tigran@veritas.com> 1.69 - * Fix the panic when writing zero-length microcode chunk. 1.70 - * 1.12 29 Sep 2003 Nitin Kamble <nitin.a.kamble@intel.com>, 1.71 - * Jun Nakajima <jun.nakajima@intel.com> 1.72 - * Support for the microcode updates in the new format. 1.73 - * 1.13 10 Oct 2003 Tigran Aivazian <tigran@veritas.com> 1.74 - * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl 1.75 - * because we no longer hold a copy of applied microcode 1.76 - * in kernel memory. 1.77 - * 1.14 25 Jun 2004 Tigran Aivazian <tigran@veritas.com> 1.78 - * Fix sigmatch() macro to handle old CPUs with pf == 0. 1.79 - * Thanks to Stuart Swales for pointing out this bug. 1.80 + * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture 1.81 + * Software Developer's Manual 1.82 + * Order Number 253668 or free download from: 1.83 + * 1.84 + * http://developer.intel.com/design/pentium4/manuals/253668.htm 1.85 + * 1.86 + * For more information, go to http://www.urbanmyth.org/microcode 1.87 + * 1.88 + * This program is free software; you can redistribute it and/or 1.89 + * modify it under the terms of the GNU General Public License 1.90 + * as published by the Free Software Foundation; either version 1.91 + * 2 of the License, or (at your option) any later version. 1.92 */ 1.93 1.94 #include <xen/config.h> 1.95 @@ -95,8 +46,8 @@ static DEFINE_SPINLOCK(microcode_mutex); 1.96 struct ucode_cpu_info ucode_cpu_info[NR_CPUS]; 1.97 1.98 struct microcode_buffer { 1.99 - void *buf; 1.100 - size_t size; 1.101 + void *buf; 1.102 + size_t size; 1.103 }; 1.104 1.105 static struct microcode_buffer microcode_buffer; 1.106 @@ -104,164 +55,157 @@ static bool_t microcode_error; 1.107 1.108 static void microcode_fini_cpu(int cpu) 1.109 { 1.110 - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 1.111 + struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 1.112 1.113 - spin_lock(µcode_mutex); 1.114 - microcode_ops->microcode_fini_cpu(cpu); 1.115 - uci->valid = 0; 1.116 - spin_unlock(µcode_mutex); 1.117 + spin_lock(µcode_mutex); 1.118 + microcode_ops->microcode_fini_cpu(cpu); 1.119 + uci->valid = 0; 1.120 + spin_unlock(µcode_mutex); 1.121 } 1.122 1.123 static int collect_cpu_info(int cpu) 1.124 { 1.125 - int err = 0; 1.126 - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 1.127 + int err = 0; 1.128 + struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 1.129 1.130 - memset(uci, 0, sizeof(*uci)); 1.131 - err = microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); 1.132 - if (!err) 1.133 - uci->valid = 1; 1.134 + memset(uci, 0, sizeof(*uci)); 1.135 + err = microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); 1.136 + if ( !err ) 1.137 + uci->valid = 1; 1.138 1.139 - return err; 1.140 + return err; 1.141 } 1.142 1.143 static int microcode_resume_cpu(int cpu) 1.144 { 1.145 - int err = 0; 1.146 - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 1.147 - struct cpu_signature nsig; 1.148 + int err = 0; 1.149 + struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 1.150 + struct cpu_signature nsig; 1.151 1.152 - gdprintk(XENLOG_INFO, "microcode: CPU%d resumed\n", cpu); 1.153 + gdprintk(XENLOG_INFO, "microcode: CPU%d resumed\n", cpu); 1.154 1.155 - if (!uci->mc.valid_mc) 1.156 - return -EIO; 1.157 + if ( !uci->mc.valid_mc ) 1.158 + return -EIO; 1.159 1.160 - /* 1.161 - * Let's verify that the 'cached' ucode does belong 1.162 - * to this cpu (a bit of paranoia): 1.163 - */ 1.164 - err = microcode_ops->collect_cpu_info(cpu, &nsig); 1.165 - if (err) { 1.166 - microcode_fini_cpu(cpu); 1.167 - return err; 1.168 - } 1.169 + /* 1.170 + * Let's verify that the 'cached' ucode does belong 1.171 + * to this cpu (a bit of paranoia): 1.172 + */ 1.173 + err = microcode_ops->collect_cpu_info(cpu, &nsig); 1.174 + if ( err ) 1.175 + { 1.176 + microcode_fini_cpu(cpu); 1.177 + return err; 1.178 + } 1.179 1.180 - if (memcmp(&nsig, &uci->cpu_sig, sizeof(nsig))) { 1.181 - microcode_fini_cpu(cpu); 1.182 - /* Should we look for a new ucode here? */ 1.183 - return -EIO; 1.184 - } 1.185 + if ( memcmp(&nsig, &uci->cpu_sig, sizeof(nsig)) ) 1.186 + { 1.187 + microcode_fini_cpu(cpu); 1.188 + /* Should we look for a new ucode here? */ 1.189 + return -EIO; 1.190 + } 1.191 1.192 - err = microcode_ops->apply_microcode(cpu); 1.193 + err = microcode_ops->apply_microcode(cpu); 1.194 1.195 - return err; 1.196 + return err; 1.197 } 1.198 1.199 static int microcode_update_cpu(int cpu, const void *buf, size_t size) 1.200 { 1.201 - int err = 0; 1.202 - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 1.203 + int err = 0; 1.204 + struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 1.205 1.206 - /* We should bind the task to the CPU */ 1.207 - BUG_ON(raw_smp_processor_id() != cpu); 1.208 + /* We should bind the task to the CPU */ 1.209 + BUG_ON(raw_smp_processor_id() != cpu); 1.210 + 1.211 + spin_lock(µcode_mutex); 1.212 1.213 - spin_lock(µcode_mutex); 1.214 - /* 1.215 - * Check if the system resume is in progress (uci->valid != NULL), 1.216 - * otherwise just request a firmware: 1.217 - */ 1.218 - if (uci->valid) { 1.219 - err = microcode_resume_cpu(cpu); 1.220 - } else { 1.221 - err = collect_cpu_info(cpu); 1.222 - if (err) 1.223 - goto out; 1.224 - if (uci->valid) { 1.225 - err = microcode_ops->cpu_request_microcode(cpu, buf, size); 1.226 - } 1.227 - } 1.228 + /* 1.229 + * Check if the system resume is in progress (uci->valid != NULL), 1.230 + * otherwise just request a firmware: 1.231 + */ 1.232 + if ( uci->valid ) 1.233 + { 1.234 + err = microcode_resume_cpu(cpu); 1.235 + } 1.236 + else 1.237 + { 1.238 + err = collect_cpu_info(cpu); 1.239 + if ( !err && uci->valid ) 1.240 + err = microcode_ops->cpu_request_microcode(cpu, buf, size); 1.241 + } 1.242 1.243 -out: 1.244 - spin_unlock(µcode_mutex); 1.245 + spin_unlock(µcode_mutex); 1.246 1.247 - return err; 1.248 + return err; 1.249 } 1.250 1.251 static void do_microcode_update_one(void *info) 1.252 { 1.253 - int error = 0; 1.254 + int error; 1.255 1.256 - error = microcode_update_cpu(smp_processor_id(), 1.257 - microcode_buffer.buf, microcode_buffer.size); 1.258 + error = microcode_update_cpu( 1.259 + smp_processor_id(), microcode_buffer.buf, microcode_buffer.size); 1.260 1.261 - if (error) 1.262 - microcode_error = error; 1.263 + if ( error ) 1.264 + microcode_error = error; 1.265 } 1.266 1.267 static int do_microcode_update(void) 1.268 { 1.269 - int error = 0; 1.270 + int error = 0; 1.271 1.272 - microcode_error = 0; 1.273 + microcode_error = 0; 1.274 1.275 - if (on_each_cpu(do_microcode_update_one, NULL, 1, 1) != 0) { 1.276 - printk(KERN_ERR "microcode: Error! Could not run on all processors\n"); 1.277 - error = -EIO; 1.278 - goto out; 1.279 - } 1.280 + if ( on_each_cpu(do_microcode_update_one, NULL, 1, 1) != 0 ) 1.281 + { 1.282 + printk(KERN_ERR "microcode: Error! Could not run on all processors\n"); 1.283 + error = -EIO; 1.284 + goto out; 1.285 + } 1.286 1.287 - if (microcode_error) { 1.288 - error = microcode_error; 1.289 - goto out; 1.290 - } 1.291 + if ( microcode_error ) 1.292 + { 1.293 + error = microcode_error; 1.294 + goto out; 1.295 + } 1.296 1.297 -out: 1.298 - return error; 1.299 + out: 1.300 + return error; 1.301 } 1.302 1.303 int microcode_update(XEN_GUEST_HANDLE(const_void) buf, unsigned long len) 1.304 { 1.305 - int ret; 1.306 - struct cpuinfo_x86 *c = &boot_cpu_data; 1.307 + int ret; 1.308 1.309 - if (len != (typeof(microcode_buffer.size))len) { 1.310 - printk(KERN_ERR "microcode: too much data\n"); 1.311 - return -E2BIG; 1.312 - } 1.313 + /* XXX FIXME: No allocations in interrupt context. */ 1.314 + return -EINVAL; 1.315 1.316 - switch (c->x86_vendor) { 1.317 - case X86_VENDOR_AMD: 1.318 - ret = microcode_init_amd(c); 1.319 - break; 1.320 + if ( len != (typeof(microcode_buffer.size))len ) 1.321 + { 1.322 + printk(KERN_ERR "microcode: too much data\n"); 1.323 + return -E2BIG; 1.324 + } 1.325 1.326 - case X86_VENDOR_INTEL: 1.327 - ret = microcode_init_intel(c); 1.328 - break; 1.329 - default: 1.330 - printk(KERN_ERR "microcode: CPU vendor not supported\n"); 1.331 - ret = -EINVAL; 1.332 - break; 1.333 - } 1.334 + if (microcode_ops == NULL) 1.335 + return -EINVAL; 1.336 1.337 - if (ret != 0) 1.338 - return ret; 1.339 + microcode_buffer.buf = xmalloc_array(uint8_t, len); 1.340 + if ( microcode_buffer.buf == NULL ) 1.341 + return -ENOMEM; 1.342 1.343 - microcode_buffer.buf = xmalloc_array(uint8_t, len); 1.344 - if (!microcode_buffer.buf) 1.345 - return -ENOMEM; 1.346 - 1.347 - ret = copy_from_guest(microcode_buffer.buf, buf, len); 1.348 - if (ret != 0) 1.349 - return ret; 1.350 + ret = copy_from_guest(microcode_buffer.buf, buf, len); 1.351 + if ( ret != 0 ) 1.352 + return ret; 1.353 1.354 - microcode_buffer.size = len; 1.355 - wmb(); 1.356 + microcode_buffer.size = len; 1.357 + wmb(); 1.358 1.359 - ret = do_microcode_update(); 1.360 + ret = do_microcode_update(); 1.361 1.362 - xfree(microcode_buffer.buf); 1.363 - microcode_buffer.buf = NULL; 1.364 - microcode_buffer.size = 0; 1.365 + xfree(microcode_buffer.buf); 1.366 + microcode_buffer.buf = NULL; 1.367 + microcode_buffer.size = 0; 1.368 1.369 - return ret; 1.370 + return ret; 1.371 }
2.1 --- a/xen/arch/x86/microcode_amd.c Mon Sep 15 17:10:43 2008 +0100 2.2 +++ b/xen/arch/x86/microcode_amd.c Tue Sep 16 11:26:19 2008 +0100 2.3 @@ -12,7 +12,7 @@ 2.4 * 2.5 * Licensed unter the terms of the GNU General Public 2.6 * License version 2. See file COPYING for details. 2.7 -*/ 2.8 + */ 2.9 2.10 #include <xen/config.h> 2.11 #include <xen/lib.h> 2.12 @@ -27,28 +27,21 @@ 2.13 #include <asm/processor.h> 2.14 #include <asm/microcode.h> 2.15 2.16 - 2.17 #define pr_debug(x...) ((void)0) 2.18 -#define DEFINE_MUTEX(_m) DEFINE_SPINLOCK(_m) 2.19 -#define mutex_lock(_m) spin_lock(_m) 2.20 -#define mutex_unlock(_m) spin_unlock(_m) 2.21 -#define vmalloc(_s) xmalloc_bytes(_s) 2.22 -#define vfree(_p) xfree(_p) 2.23 - 2.24 2.25 #define UCODE_MAGIC 0x00414d44 2.26 #define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000 2.27 #define UCODE_UCODE_TYPE 0x00000001 2.28 2.29 #define UCODE_MAX_SIZE (2048) 2.30 -#define DEFAULT_UCODE_DATASIZE (896) 2.31 -#define MC_HEADER_SIZE (sizeof(struct microcode_header_amd)) 2.32 +#define DEFAULT_UCODE_DATASIZE (896) 2.33 +#define MC_HEADER_SIZE (sizeof(struct microcode_header_amd)) 2.34 #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) 2.35 -#define DWSIZE (sizeof(uint32_t)) 2.36 +#define DWSIZE (sizeof(uint32_t)) 2.37 /* For now we support a fixed ucode total size only */ 2.38 #define get_totalsize(mc) \ 2.39 - ((((struct microcode_amd *)mc)->hdr.mc_patch_data_len * 28) \ 2.40 - + MC_HEADER_SIZE) 2.41 + ((((struct microcode_amd *)mc)->hdr.mc_patch_data_len * 28) \ 2.42 + + MC_HEADER_SIZE) 2.43 2.44 /* serialize access to the physical write */ 2.45 static DEFINE_SPINLOCK(microcode_update_lock); 2.46 @@ -57,309 +50,330 @@ struct equiv_cpu_entry *equiv_cpu_table; 2.47 2.48 static long install_equiv_cpu_table(const void *, uint32_t, long); 2.49 2.50 -static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) 2.51 +static int collect_cpu_info(int cpu, struct cpu_signature *csig) 2.52 { 2.53 - struct cpuinfo_x86 *c = &cpu_data[cpu]; 2.54 + struct cpuinfo_x86 *c = &cpu_data[cpu]; 2.55 2.56 - memset(csig, 0, sizeof(*csig)); 2.57 + memset(csig, 0, sizeof(*csig)); 2.58 2.59 - if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) { 2.60 - printk(KERN_ERR "microcode: CPU%d not a capable AMD processor\n", 2.61 - cpu); 2.62 - return -1; 2.63 - } 2.64 + if ( (c->x86_vendor != X86_VENDOR_AMD) || (c->x86 < 0x10) ) 2.65 + { 2.66 + printk(KERN_ERR "microcode: CPU%d not a capable AMD processor\n", 2.67 + cpu); 2.68 + return -1; 2.69 + } 2.70 2.71 - asm volatile("movl %1, %%ecx; rdmsr" 2.72 - : "=a" (csig->rev) 2.73 - : "i" (MSR_AMD_PATCHLEVEL) : "ecx"); 2.74 + asm volatile("movl %1, %%ecx; rdmsr" 2.75 + : "=a" (csig->rev) 2.76 + : "i" (MSR_AMD_PATCHLEVEL) : "ecx"); 2.77 2.78 - printk(KERN_INFO "microcode: collect_cpu_info_amd : patch_id=0x%x\n", 2.79 - csig->rev); 2.80 + printk(KERN_INFO "microcode: collect_cpu_info: patch_id=0x%x\n", 2.81 + csig->rev); 2.82 2.83 - return 0; 2.84 + return 0; 2.85 } 2.86 2.87 -static int get_matching_microcode_amd(void *mc, int cpu) 2.88 +static int get_matching_microcode(void *mc, int cpu) 2.89 { 2.90 - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 2.91 - struct microcode_header_amd *mc_header = mc; 2.92 - unsigned long total_size = get_totalsize(mc_header); 2.93 - void *new_mc; 2.94 - unsigned int current_cpu_id; 2.95 - unsigned int equiv_cpu_id = 0x00; 2.96 - unsigned int i = 0; 2.97 + struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 2.98 + struct microcode_header_amd *mc_header = mc; 2.99 + unsigned long total_size = get_totalsize(mc_header); 2.100 + void *new_mc; 2.101 + unsigned int current_cpu_id; 2.102 + unsigned int equiv_cpu_id = 0x00; 2.103 + unsigned int i = 0; 2.104 2.105 - /* We should bind the task to the CPU */ 2.106 - BUG_ON(cpu != raw_smp_processor_id()); 2.107 + /* We should bind the task to the CPU */ 2.108 + BUG_ON(cpu != raw_smp_processor_id()); 2.109 2.110 - /* This is a tricky part. We might be called from a write operation 2.111 - * to the device file instead of the usual process of firmware 2.112 - * loading. This routine needs to be able to distinguish both 2.113 - * cases. This is done by checking if there already is a equivalent 2.114 - * CPU table installed. If not, we're written through 2.115 - * /dev/cpu/microcode. 2.116 - * Since we ignore all checks. The error case in which going through 2.117 - * firmware loading and that table is not loaded has already been 2.118 - * checked earlier. 2.119 - */ 2.120 - if (equiv_cpu_table == NULL) { 2.121 - printk(KERN_INFO "microcode: CPU%d microcode update with " 2.122 - "version 0x%x (current=0x%x)\n", 2.123 - cpu, mc_header->patch_id, uci->cpu_sig.rev); 2.124 - goto out; 2.125 - } 2.126 + /* This is a tricky part. We might be called from a write operation 2.127 + * to the device file instead of the usual process of firmware 2.128 + * loading. This routine needs to be able to distinguish both 2.129 + * cases. This is done by checking if there already is a equivalent 2.130 + * CPU table installed. If not, we're written through 2.131 + * /dev/cpu/microcode. 2.132 + * Since we ignore all checks. The error case in which going through 2.133 + * firmware loading and that table is not loaded has already been 2.134 + * checked earlier. 2.135 + */ 2.136 + if ( equiv_cpu_table == NULL ) 2.137 + { 2.138 + printk(KERN_INFO "microcode: CPU%d microcode update with " 2.139 + "version 0x%x (current=0x%x)\n", 2.140 + cpu, mc_header->patch_id, uci->cpu_sig.rev); 2.141 + goto out; 2.142 + } 2.143 2.144 - current_cpu_id = cpuid_eax(0x00000001); 2.145 + current_cpu_id = cpuid_eax(0x00000001); 2.146 2.147 - while (equiv_cpu_table[i].installed_cpu != 0) { 2.148 - if (current_cpu_id == equiv_cpu_table[i].installed_cpu) { 2.149 - equiv_cpu_id = equiv_cpu_table[i].equiv_cpu; 2.150 - break; 2.151 - } 2.152 - i++; 2.153 - } 2.154 + while ( equiv_cpu_table[i].installed_cpu != 0 ) 2.155 + { 2.156 + if ( current_cpu_id == equiv_cpu_table[i].installed_cpu ) 2.157 + { 2.158 + equiv_cpu_id = equiv_cpu_table[i].equiv_cpu; 2.159 + break; 2.160 + } 2.161 + i++; 2.162 + } 2.163 2.164 - if (!equiv_cpu_id) { 2.165 - printk(KERN_ERR "microcode: CPU%d cpu_id " 2.166 - "not found in equivalent cpu table \n", cpu); 2.167 - return 0; 2.168 - } 2.169 + if ( !equiv_cpu_id ) 2.170 + { 2.171 + printk(KERN_ERR "microcode: CPU%d cpu_id " 2.172 + "not found in equivalent cpu table \n", cpu); 2.173 + return 0; 2.174 + } 2.175 2.176 - if ((mc_header->processor_rev_id[0]) != (equiv_cpu_id & 0xff)) { 2.177 - printk(KERN_INFO 2.178 - "microcode: CPU%d patch does not match " 2.179 - "(patch is %x, cpu extended is %x) \n", 2.180 - cpu, mc_header->processor_rev_id[0], 2.181 - (equiv_cpu_id & 0xff)); 2.182 - return 0; 2.183 - } 2.184 - 2.185 - if ((mc_header->processor_rev_id[1]) != ((equiv_cpu_id >> 16) & 0xff)) { 2.186 - printk(KERN_INFO "microcode: CPU%d patch does not match " 2.187 - "(patch is %x, cpu base id is %x) \n", 2.188 - cpu, mc_header->processor_rev_id[1], 2.189 - ((equiv_cpu_id >> 16) & 0xff)); 2.190 + if ( (mc_header->processor_rev_id[0]) != (equiv_cpu_id & 0xff) ) 2.191 + { 2.192 + printk(KERN_INFO 2.193 + "microcode: CPU%d patch does not match " 2.194 + "(patch is %x, cpu extended is %x) \n", 2.195 + cpu, mc_header->processor_rev_id[0], 2.196 + (equiv_cpu_id & 0xff)); 2.197 + return 0; 2.198 + } 2.199 2.200 - return 0; 2.201 - } 2.202 + if ( (mc_header->processor_rev_id[1]) != ((equiv_cpu_id >> 16) & 0xff) ) 2.203 + { 2.204 + printk(KERN_INFO "microcode: CPU%d patch does not match " 2.205 + "(patch is %x, cpu base id is %x) \n", 2.206 + cpu, mc_header->processor_rev_id[1], 2.207 + ((equiv_cpu_id >> 16) & 0xff)); 2.208 + return 0; 2.209 + } 2.210 2.211 - if (mc_header->patch_id <= uci->cpu_sig.rev) 2.212 - return 0; 2.213 + if ( mc_header->patch_id <= uci->cpu_sig.rev ) 2.214 + return 0; 2.215 2.216 - printk(KERN_INFO "microcode: CPU%d found a matching microcode " 2.217 - "update with version 0x%x (current=0x%x)\n", 2.218 - cpu, mc_header->patch_id, uci->cpu_sig.rev); 2.219 + printk(KERN_INFO "microcode: CPU%d found a matching microcode " 2.220 + "update with version 0x%x (current=0x%x)\n", 2.221 + cpu, mc_header->patch_id, uci->cpu_sig.rev); 2.222 2.223 -out: 2.224 - new_mc = vmalloc(UCODE_MAX_SIZE); 2.225 - if (!new_mc) { 2.226 - printk(KERN_ERR "microcode: error, can't allocate memory\n"); 2.227 - return -ENOMEM; 2.228 - } 2.229 - memset(new_mc, 0, UCODE_MAX_SIZE); 2.230 + out: 2.231 + new_mc = xmalloc_bytes(UCODE_MAX_SIZE); 2.232 + if ( new_mc == NULL ) 2.233 + { 2.234 + printk(KERN_ERR "microcode: error, can't allocate memory\n"); 2.235 + return -ENOMEM; 2.236 + } 2.237 + memset(new_mc, 0, UCODE_MAX_SIZE); 2.238 2.239 - /* free previous update file */ 2.240 - vfree(uci->mc.mc_amd); 2.241 + /* free previous update file */ 2.242 + xfree(uci->mc.mc_amd); 2.243 2.244 - memcpy(new_mc, mc, total_size); 2.245 + memcpy(new_mc, mc, total_size); 2.246 2.247 - uci->mc.mc_amd = new_mc; 2.248 - return 1; 2.249 + uci->mc.mc_amd = new_mc; 2.250 + return 1; 2.251 } 2.252 2.253 -static int apply_microcode_amd(int cpu) 2.254 +static int apply_microcode(int cpu) 2.255 { 2.256 - unsigned long flags; 2.257 - uint32_t eax, edx, rev; 2.258 - int cpu_num = raw_smp_processor_id(); 2.259 - struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 2.260 - uint64_t addr; 2.261 + unsigned long flags; 2.262 + uint32_t eax, edx, rev; 2.263 + int cpu_num = raw_smp_processor_id(); 2.264 + struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 2.265 + uint64_t addr; 2.266 2.267 - /* We should bind the task to the CPU */ 2.268 - BUG_ON(cpu_num != cpu); 2.269 + /* We should bind the task to the CPU */ 2.270 + BUG_ON(cpu_num != cpu); 2.271 2.272 - if (uci->mc.mc_amd == NULL) 2.273 - return -EINVAL; 2.274 + if ( uci->mc.mc_amd == NULL ) 2.275 + return -EINVAL; 2.276 2.277 - spin_lock_irqsave(µcode_update_lock, flags); 2.278 + spin_lock_irqsave(µcode_update_lock, flags); 2.279 2.280 - addr = (unsigned long)&uci->mc.mc_amd->hdr.data_code; 2.281 - edx = (uint32_t)(addr >> 32); 2.282 - eax = (uint32_t)addr; 2.283 + addr = (unsigned long)&uci->mc.mc_amd->hdr.data_code; 2.284 + edx = (uint32_t)(addr >> 32); 2.285 + eax = (uint32_t)addr; 2.286 2.287 - asm volatile("movl %0, %%ecx; wrmsr" : 2.288 - : "i" (MSR_AMD_PATCHLOADER), "a" (eax), "d" (edx) : "ecx"); 2.289 + asm volatile("movl %0, %%ecx; wrmsr" : 2.290 + : "i" (MSR_AMD_PATCHLOADER), "a" (eax), "d" (edx) : "ecx"); 2.291 2.292 - /* get patch id after patching */ 2.293 - asm volatile("movl %1, %%ecx; rdmsr" 2.294 - : "=a" (rev) 2.295 - : "i" (MSR_AMD_PATCHLEVEL) : "ecx"); 2.296 + /* get patch id after patching */ 2.297 + asm volatile("movl %1, %%ecx; rdmsr" 2.298 + : "=a" (rev) 2.299 + : "i" (MSR_AMD_PATCHLEVEL) : "ecx"); 2.300 2.301 - spin_unlock_irqrestore(µcode_update_lock, flags); 2.302 + spin_unlock_irqrestore(µcode_update_lock, flags); 2.303 2.304 - /* check current patch id and patch's id for match */ 2.305 - if (rev != uci->mc.mc_amd->hdr.patch_id) { 2.306 - printk(KERN_ERR "microcode: CPU%d update from revision " 2.307 - "0x%x to 0x%x failed\n", cpu_num, 2.308 - uci->mc.mc_amd->hdr.patch_id, rev); 2.309 - return -EIO; 2.310 - } 2.311 + /* check current patch id and patch's id for match */ 2.312 + if ( rev != uci->mc.mc_amd->hdr.patch_id ) 2.313 + { 2.314 + printk(KERN_ERR "microcode: CPU%d update from revision " 2.315 + "0x%x to 0x%x failed\n", cpu_num, 2.316 + uci->mc.mc_amd->hdr.patch_id, rev); 2.317 + return -EIO; 2.318 + } 2.319 2.320 - printk("microcode: CPU%d updated from revision " 2.321 - "0x%x to 0x%x \n", 2.322 - cpu_num, uci->cpu_sig.rev, uci->mc.mc_amd->hdr.patch_id); 2.323 + printk("microcode: CPU%d updated from revision " 2.324 + "0x%x to 0x%x \n", 2.325 + cpu_num, uci->cpu_sig.rev, uci->mc.mc_amd->hdr.patch_id); 2.326 2.327 - uci->cpu_sig.rev = rev; 2.328 + uci->cpu_sig.rev = rev; 2.329 2.330 - return 0; 2.331 + return 0; 2.332 } 2.333 2.334 static long get_next_ucode_from_buffer_amd(void **mc, const void *buf, 2.335 - unsigned long size, long offset) 2.336 + unsigned long size, long offset) 2.337 { 2.338 - struct microcode_header_amd *mc_header; 2.339 - unsigned long total_size; 2.340 - const uint8_t *buf_pos = buf; 2.341 + struct microcode_header_amd *mc_header; 2.342 + unsigned long total_size; 2.343 + const uint8_t *buf_pos = buf; 2.344 + 2.345 + /* No more data */ 2.346 + if ( offset >= size ) 2.347 + return 0; 2.348 2.349 - /* No more data */ 2.350 - if (offset >= size) 2.351 - return 0; 2.352 + if ( buf_pos[offset] != UCODE_UCODE_TYPE ) 2.353 + { 2.354 + printk(KERN_ERR "microcode: error! " 2.355 + "Wrong microcode payload type field\n"); 2.356 + return -EINVAL; 2.357 + } 2.358 2.359 - if (buf_pos[offset] != UCODE_UCODE_TYPE) { 2.360 - printk(KERN_ERR "microcode: error! " 2.361 - "Wrong microcode payload type field\n"); 2.362 - return -EINVAL; 2.363 - } 2.364 + mc_header = (struct microcode_header_amd *)(&buf_pos[offset+8]); 2.365 2.366 - mc_header = (struct microcode_header_amd *)(&buf_pos[offset+8]); 2.367 + total_size = (unsigned long) (buf_pos[offset+4] + 2.368 + (buf_pos[offset+5] << 8)); 2.369 2.370 - total_size = (unsigned long) (buf_pos[offset+4] + 2.371 - (buf_pos[offset+5] << 8)); 2.372 + printk(KERN_INFO "microcode: size %lu, total_size %lu, offset %ld\n", 2.373 + size, total_size, offset); 2.374 2.375 - printk(KERN_INFO "microcode: size %lu, total_size %lu, offset %ld\n", 2.376 - size, total_size, offset); 2.377 - 2.378 - if (offset + total_size > size) { 2.379 - printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); 2.380 - return -EINVAL; 2.381 - } 2.382 + if ( (offset + total_size) > size ) 2.383 + { 2.384 + printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); 2.385 + return -EINVAL; 2.386 + } 2.387 2.388 - *mc = vmalloc(UCODE_MAX_SIZE); 2.389 - if (!*mc) { 2.390 - printk(KERN_ERR "microcode: error! " 2.391 - "Can not allocate memory for microcode patch\n"); 2.392 - return -ENOMEM; 2.393 - } 2.394 + *mc = xmalloc_bytes(UCODE_MAX_SIZE); 2.395 + if ( *mc == NULL ) 2.396 + { 2.397 + printk(KERN_ERR "microcode: error! " 2.398 + "Can not allocate memory for microcode patch\n"); 2.399 + return -ENOMEM; 2.400 + } 2.401 2.402 - memset(*mc, 0, UCODE_MAX_SIZE); 2.403 - memcpy(*mc, (const void *)(buf + offset + 8), total_size); 2.404 + memset(*mc, 0, UCODE_MAX_SIZE); 2.405 + memcpy(*mc, (const void *)(buf + offset + 8), total_size); 2.406 2.407 - return offset + total_size + 8; 2.408 + return offset + total_size + 8; 2.409 } 2.410 2.411 static long install_equiv_cpu_table(const void *buf, 2.412 - uint32_t size, long offset) 2.413 + uint32_t size, long offset) 2.414 { 2.415 - const uint32_t *buf_pos = buf; 2.416 + const uint32_t *buf_pos = buf; 2.417 2.418 - /* No more data */ 2.419 - if (offset >= size) 2.420 - return 0; 2.421 + /* No more data */ 2.422 + if ( offset >= size ) 2.423 + return 0; 2.424 2.425 - if (buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE) { 2.426 - printk(KERN_ERR "microcode: error! " 2.427 - "Wrong microcode equivalnet cpu table type field\n"); 2.428 - return 0; 2.429 - } 2.430 + if ( buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE ) 2.431 + { 2.432 + printk(KERN_ERR "microcode: error! " 2.433 + "Wrong microcode equivalnet cpu table type field\n"); 2.434 + return 0; 2.435 + } 2.436 2.437 - if (size == 0) { 2.438 - printk(KERN_ERR "microcode: error! " 2.439 - "Wrong microcode equivalnet cpu table length\n"); 2.440 - return 0; 2.441 - } 2.442 + if ( size == 0 ) 2.443 + { 2.444 + printk(KERN_ERR "microcode: error! " 2.445 + "Wrong microcode equivalnet cpu table length\n"); 2.446 + return 0; 2.447 + } 2.448 2.449 - equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size); 2.450 - if (!equiv_cpu_table) { 2.451 - printk(KERN_ERR "microcode: error, can't allocate memory for equiv CPU table\n"); 2.452 - return 0; 2.453 - } 2.454 + equiv_cpu_table = xmalloc_bytes(size); 2.455 + if ( equiv_cpu_table == NULL ) 2.456 + { 2.457 + printk(KERN_ERR "microcode: error, can't allocate " 2.458 + "memory for equiv CPU table\n"); 2.459 + return 0; 2.460 + } 2.461 2.462 - memset(equiv_cpu_table, 0, size); 2.463 - memcpy(equiv_cpu_table, (const void *)&buf_pos[3], size); 2.464 + memset(equiv_cpu_table, 0, size); 2.465 + memcpy(equiv_cpu_table, (const void *)&buf_pos[3], size); 2.466 2.467 - return size + 12; /* add header length */ 2.468 + return size + 12; /* add header length */ 2.469 } 2.470 2.471 -static int cpu_request_microcode_amd(int cpu, const void *buf, 2.472 - size_t size) 2.473 +static int cpu_request_microcode(int cpu, const void *buf, size_t size) 2.474 { 2.475 - const uint32_t *buf_pos; 2.476 - long offset = 0; 2.477 - int error = 0; 2.478 - void *mc; 2.479 + const uint32_t *buf_pos; 2.480 + long offset = 0; 2.481 + int error = 0; 2.482 + void *mc; 2.483 2.484 - /* We should bind the task to the CPU */ 2.485 - BUG_ON(cpu != raw_smp_processor_id()); 2.486 + /* We should bind the task to the CPU */ 2.487 + BUG_ON(cpu != raw_smp_processor_id()); 2.488 + 2.489 + buf_pos = (const uint32_t *)buf; 2.490 2.491 - buf_pos = (const uint32_t *)buf; 2.492 + if ( buf_pos[0] != UCODE_MAGIC ) 2.493 + { 2.494 + printk(KERN_ERR "microcode: error! Wrong " 2.495 + "microcode patch file magic\n"); 2.496 + return -EINVAL; 2.497 + } 2.498 2.499 - if (buf_pos[0] != UCODE_MAGIC) { 2.500 - printk(KERN_ERR "microcode: error! Wrong microcode patch file magic\n"); 2.501 - return -EINVAL; 2.502 - } 2.503 - 2.504 - offset = install_equiv_cpu_table(buf, (uint32_t)(buf_pos[2]), offset); 2.505 - if (!offset) { 2.506 - printk(KERN_ERR "microcode: installing equivalent cpu table failed\n"); 2.507 - return -EINVAL; 2.508 - } 2.509 + offset = install_equiv_cpu_table(buf, (uint32_t)(buf_pos[2]), offset); 2.510 + if ( !offset ) 2.511 + { 2.512 + printk(KERN_ERR "microcode: installing equivalent cpu table failed\n"); 2.513 + return -EINVAL; 2.514 + } 2.515 2.516 - while ((offset = 2.517 - get_next_ucode_from_buffer_amd(&mc, buf, size, offset)) > 0) { 2.518 - error = get_matching_microcode_amd(mc, cpu); 2.519 - if (error < 0) 2.520 - break; 2.521 - /* 2.522 - * It's possible the data file has multiple matching ucode, 2.523 - * lets keep searching till the latest version 2.524 - */ 2.525 - if (error == 1) { 2.526 - apply_microcode_amd(cpu); 2.527 - error = 0; 2.528 - } 2.529 - vfree(mc); 2.530 - } 2.531 - if (offset > 0) { 2.532 - vfree(mc); 2.533 - vfree(equiv_cpu_table); 2.534 - equiv_cpu_table = NULL; 2.535 - } 2.536 - if (offset < 0) 2.537 - error = offset; 2.538 + while ( (offset = 2.539 + get_next_ucode_from_buffer_amd(&mc, buf, size, offset)) > 0 ) 2.540 + { 2.541 + error = get_matching_microcode(mc, cpu); 2.542 + if ( error < 0 ) 2.543 + break; 2.544 + /* 2.545 + * It's possible the data file has multiple matching ucode, 2.546 + * lets keep searching till the latest version 2.547 + */ 2.548 + if ( error == 1 ) 2.549 + { 2.550 + apply_microcode(cpu); 2.551 + error = 0; 2.552 + } 2.553 + xfree(mc); 2.554 + } 2.555 + if ( offset > 0 ) 2.556 + { 2.557 + xfree(mc); 2.558 + xfree(equiv_cpu_table); 2.559 + equiv_cpu_table = NULL; 2.560 + } 2.561 + if ( offset < 0 ) 2.562 + error = offset; 2.563 2.564 - return error; 2.565 + return error; 2.566 } 2.567 2.568 -static void microcode_fini_cpu_amd(int cpu) 2.569 +static void microcode_fini_cpu(int cpu) 2.570 { 2.571 - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 2.572 + struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 2.573 2.574 - vfree(uci->mc.mc_amd); 2.575 - uci->mc.mc_amd = NULL; 2.576 + xfree(uci->mc.mc_amd); 2.577 + uci->mc.mc_amd = NULL; 2.578 } 2.579 2.580 static struct microcode_ops microcode_amd_ops = { 2.581 - .get_matching_microcode = get_matching_microcode_amd, 2.582 - .microcode_sanity_check = NULL, 2.583 - .cpu_request_microcode = cpu_request_microcode_amd, 2.584 - .collect_cpu_info = collect_cpu_info_amd, 2.585 - .apply_microcode = apply_microcode_amd, 2.586 - .microcode_fini_cpu = microcode_fini_cpu_amd, 2.587 + .get_matching_microcode = get_matching_microcode, 2.588 + .microcode_sanity_check = NULL, 2.589 + .cpu_request_microcode = cpu_request_microcode, 2.590 + .collect_cpu_info = collect_cpu_info, 2.591 + .apply_microcode = apply_microcode, 2.592 + .microcode_fini_cpu = microcode_fini_cpu, 2.593 }; 2.594 2.595 -int microcode_init_amd(struct cpuinfo_x86 *c) 2.596 +static __init int microcode_init_amd(void) 2.597 { 2.598 - microcode_ops = µcode_amd_ops; 2.599 - return 0; 2.600 + if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD ) 2.601 + microcode_ops = µcode_amd_ops; 2.602 + return 0; 2.603 } 2.604 - 2.605 +__initcall(microcode_init_amd);
3.1 --- a/xen/arch/x86/microcode_intel.c Mon Sep 15 17:10:43 2008 +0100 3.2 +++ b/xen/arch/x86/microcode_intel.c Tue Sep 16 11:26:19 2008 +0100 3.3 @@ -1,73 +1,24 @@ 3.4 /* 3.5 - * Intel CPU Microcode Update Driver for Linux 3.6 - * 3.7 - * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk> 3.8 - * 2006 Shaohua Li <shaohua.li@intel.com> * 3.9 - * This driver allows to upgrade microcode on Intel processors 3.10 - * belonging to IA-32 family - PentiumPro, Pentium II, 3.11 - * Pentium III, Xeon, Pentium 4, etc. 3.12 + * Intel CPU Microcode Update Driver for Linux 3.13 * 3.14 - * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture 3.15 - * Software Developer's Manual 3.16 - * Order Number 253668 or free download from: 3.17 - * 3.18 - * http://developer.intel.com/design/pentium4/manuals/253668.htm 3.19 - * 3.20 - * For more information, go to http://www.urbanmyth.org/microcode 3.21 - * 3.22 - * This program is free software; you can redistribute it and/or 3.23 - * modify it under the terms of the GNU General Public License 3.24 - * as published by the Free Software Foundation; either version 3.25 - * 2 of the License, or (at your option) any later version. 3.26 + * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk> 3.27 + * 2006 Shaohua Li <shaohua.li@intel.com> * 3.28 + * This driver allows to upgrade microcode on Intel processors 3.29 + * belonging to IA-32 family - PentiumPro, Pentium II, 3.30 + * Pentium III, Xeon, Pentium 4, etc. 3.31 * 3.32 - * 1.0 16 Feb 2000, Tigran Aivazian <tigran@sco.com> 3.33 - * Initial release. 3.34 - * 1.01 18 Feb 2000, Tigran Aivazian <tigran@sco.com> 3.35 - * Added read() support + cleanups. 3.36 - * 1.02 21 Feb 2000, Tigran Aivazian <tigran@sco.com> 3.37 - * Added 'device trimming' support. open(O_WRONLY) zeroes 3.38 - * and frees the saved copy of applied microcode. 3.39 - * 1.03 29 Feb 2000, Tigran Aivazian <tigran@sco.com> 3.40 - * Made to use devfs (/dev/cpu/microcode) + cleanups. 3.41 - * 1.04 06 Jun 2000, Simon Trimmer <simon@veritas.com> 3.42 - * Added misc device support (now uses both devfs and misc). 3.43 - * Added MICROCODE_IOCFREE ioctl to clear memory. 3.44 - * 1.05 09 Jun 2000, Simon Trimmer <simon@veritas.com> 3.45 - * Messages for error cases (non Intel & no suitable microcode). 3.46 - * 1.06 03 Aug 2000, Tigran Aivazian <tigran@veritas.com> 3.47 - * Removed ->release(). Removed exclusive open and status bitmap. 3.48 - * Added microcode_rwsem to serialize read()/write()/ioctl(). 3.49 - * Removed global kernel lock usage. 3.50 - * 1.07 07 Sep 2000, Tigran Aivazian <tigran@veritas.com> 3.51 - * Write 0 to 0x8B msr and then cpuid before reading revision, 3.52 - * so that it works even if there were no update done by the 3.53 - * BIOS. Otherwise, reading from 0x8B gives junk (which happened 3.54 - * to be 0 on my machine which is why it worked even when I 3.55 - * disabled update by the BIOS) 3.56 - * Thanks to Eric W. Biederman <ebiederman@lnxi.com> for the fix. 3.57 - * 1.08 11 Dec 2000, Richard Schaal <richard.schaal@intel.com> and 3.58 - * Tigran Aivazian <tigran@veritas.com> 3.59 - * Intel Pentium 4 processor support and bugfixes. 3.60 - * 1.09 30 Oct 2001, Tigran Aivazian <tigran@veritas.com> 3.61 - * Bugfix for HT (Hyper-Threading) enabled processors 3.62 - * whereby processor resources are shared by all logical processors 3.63 - * in a single CPU package. 3.64 - * 1.10 28 Feb 2002 Asit K Mallick <asit.k.mallick@intel.com> and 3.65 - * Tigran Aivazian <tigran@veritas.com>, 3.66 - * Serialize updates as required on HT processors due to 3.67 - * speculative nature of implementation. 3.68 - * 1.11 22 Mar 2002 Tigran Aivazian <tigran@veritas.com> 3.69 - * Fix the panic when writing zero-length microcode chunk. 3.70 - * 1.12 29 Sep 2003 Nitin Kamble <nitin.a.kamble@intel.com>, 3.71 - * Jun Nakajima <jun.nakajima@intel.com> 3.72 - * Support for the microcode updates in the new format. 3.73 - * 1.13 10 Oct 2003 Tigran Aivazian <tigran@veritas.com> 3.74 - * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl 3.75 - * because we no longer hold a copy of applied microcode 3.76 - * in kernel memory. 3.77 - * 1.14 25 Jun 2004 Tigran Aivazian <tigran@veritas.com> 3.78 - * Fix sigmatch() macro to handle old CPUs with pf == 0. 3.79 - * Thanks to Stuart Swales for pointing out this bug. 3.80 + * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture 3.81 + * Software Developer's Manual 3.82 + * Order Number 253668 or free download from: 3.83 + * 3.84 + * http://developer.intel.com/design/pentium4/manuals/253668.htm 3.85 + * 3.86 + * For more information, go to http://www.urbanmyth.org/microcode 3.87 + * 3.88 + * This program is free software; you can redistribute it and/or 3.89 + * modify it under the terms of the GNU General Public License 3.90 + * as published by the Free Software Foundation; either version 3.91 + * 2 of the License, or (at your option) any later version. 3.92 */ 3.93 3.94 #include <xen/config.h> 3.95 @@ -84,35 +35,24 @@ 3.96 #include <asm/microcode.h> 3.97 3.98 #define pr_debug(x...) ((void)0) 3.99 -#define DEFINE_MUTEX(_m) DEFINE_SPINLOCK(_m) 3.100 -#define mutex_lock(_m) spin_lock(_m) 3.101 -#define mutex_unlock(_m) spin_unlock(_m) 3.102 -#define vmalloc(_s) xmalloc_bytes(_s) 3.103 -#define vfree(_p) xfree(_p) 3.104 3.105 -#if 0 3.106 -MODULE_DESCRIPTION("Microcode Update Driver"); 3.107 -MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); 3.108 -MODULE_LICENSE("GPL"); 3.109 -#endif 3.110 - 3.111 -#define DEFAULT_UCODE_DATASIZE (2000) 3.112 -#define MC_HEADER_SIZE (sizeof(struct microcode_header_intel)) 3.113 +#define DEFAULT_UCODE_DATASIZE (2000) 3.114 +#define MC_HEADER_SIZE (sizeof(struct microcode_header_intel)) 3.115 #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) 3.116 -#define EXT_HEADER_SIZE (sizeof(struct extended_sigtable)) 3.117 -#define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature)) 3.118 -#define DWSIZE (sizeof(u32)) 3.119 +#define EXT_HEADER_SIZE (sizeof(struct extended_sigtable)) 3.120 +#define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature)) 3.121 +#define DWSIZE (sizeof(u32)) 3.122 #define get_totalsize(mc) \ 3.123 - (((struct microcode_intel *)mc)->hdr.totalsize ? \ 3.124 - ((struct microcode_intel *)mc)->hdr.totalsize : \ 3.125 - DEFAULT_UCODE_TOTALSIZE) 3.126 + (((struct microcode_intel *)mc)->hdr.totalsize ? \ 3.127 + ((struct microcode_intel *)mc)->hdr.totalsize : \ 3.128 + DEFAULT_UCODE_TOTALSIZE) 3.129 3.130 #define get_datasize(mc) \ 3.131 - (((struct microcode_intel *)mc)->hdr.datasize ? \ 3.132 - ((struct microcode_intel *)mc)->hdr.datasize : DEFAULT_UCODE_DATASIZE) 3.133 + (((struct microcode_intel *)mc)->hdr.datasize ? \ 3.134 + ((struct microcode_intel *)mc)->hdr.datasize : DEFAULT_UCODE_DATASIZE) 3.135 3.136 #define sigmatch(s1, s2, p1, p2) \ 3.137 - (((s1) == (s2)) && (((p1) & (p2)) || (((p1) == 0) && ((p2) == 0)))) 3.138 + (((s1) == (s2)) && (((p1) & (p2)) || (((p1) == 0) && ((p2) == 0)))) 3.139 3.140 #define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE) 3.141 3.142 @@ -121,125 +61,135 @@ static DEFINE_SPINLOCK(microcode_update_ 3.143 3.144 static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) 3.145 { 3.146 - struct cpuinfo_x86 *c = &cpu_data[cpu_num]; 3.147 - unsigned int val[2]; 3.148 + struct cpuinfo_x86 *c = &cpu_data[cpu_num]; 3.149 + unsigned int val[2]; 3.150 3.151 - memset(csig, 0, sizeof(*csig)); 3.152 + memset(csig, 0, sizeof(*csig)); 3.153 3.154 - if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || 3.155 - cpu_has(c, X86_FEATURE_IA64)) { 3.156 - printk(KERN_ERR "microcode: CPU%d not a capable Intel " 3.157 - "processor\n", cpu_num); 3.158 - return -1; 3.159 - } 3.160 + if ( (c->x86_vendor != X86_VENDOR_INTEL) || (c->x86 < 6) || 3.161 + cpu_has(c, X86_FEATURE_IA64) ) 3.162 + { 3.163 + printk(KERN_ERR "microcode: CPU%d not a capable Intel " 3.164 + "processor\n", cpu_num); 3.165 + return -1; 3.166 + } 3.167 3.168 - csig->sig = cpuid_eax(0x00000001); 3.169 + csig->sig = cpuid_eax(0x00000001); 3.170 3.171 - if ((c->x86_model >= 5) || (c->x86 > 6)) { 3.172 - /* get processor flags from MSR 0x17 */ 3.173 - rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); 3.174 - csig->pf = 1 << ((val[1] >> 18) & 7); 3.175 - } 3.176 + if ( (c->x86_model >= 5) || (c->x86 > 6) ) 3.177 + { 3.178 + /* get processor flags from MSR 0x17 */ 3.179 + rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); 3.180 + csig->pf = 1 << ((val[1] >> 18) & 7); 3.181 + } 3.182 3.183 - wrmsr(MSR_IA32_UCODE_REV, 0, 0); 3.184 - /* see notes above for revision 1.07. Apparent chip bug */ 3.185 - sync_core(); 3.186 - /* get the current revision from MSR 0x8B */ 3.187 - rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev); 3.188 - pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n", 3.189 - csig->sig, csig->pf, csig->rev); 3.190 + wrmsr(MSR_IA32_UCODE_REV, 0, 0); 3.191 + /* see notes above for revision 1.07. Apparent chip bug */ 3.192 + sync_core(); 3.193 + /* get the current revision from MSR 0x8B */ 3.194 + rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev); 3.195 + pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n", 3.196 + csig->sig, csig->pf, csig->rev); 3.197 3.198 - return 0; 3.199 + return 0; 3.200 } 3.201 3.202 -static inline int microcode_update_match(int cpu_num, 3.203 - struct microcode_header_intel *mc_header, int sig, int pf) 3.204 +static inline int microcode_update_match( 3.205 + int cpu_num, struct microcode_header_intel *mc_header, int sig, int pf) 3.206 { 3.207 - struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 3.208 + struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 3.209 3.210 - if (!sigmatch(sig, uci->cpu_sig.sig, pf, uci->cpu_sig.pf) 3.211 - || mc_header->rev <= uci->cpu_sig.rev) 3.212 - return 0; 3.213 - return 1; 3.214 + return (sigmatch(sig, uci->cpu_sig.sig, pf, uci->cpu_sig.pf) && 3.215 + (mc_header->rev > uci->cpu_sig.rev)); 3.216 } 3.217 3.218 static int microcode_sanity_check(void *mc) 3.219 { 3.220 - struct microcode_header_intel *mc_header = mc; 3.221 - struct extended_sigtable *ext_header = NULL; 3.222 - struct extended_signature *ext_sig; 3.223 - unsigned long total_size, data_size, ext_table_size; 3.224 - int sum, orig_sum, ext_sigcount = 0, i; 3.225 + struct microcode_header_intel *mc_header = mc; 3.226 + struct extended_sigtable *ext_header = NULL; 3.227 + struct extended_signature *ext_sig; 3.228 + unsigned long total_size, data_size, ext_table_size; 3.229 + int sum, orig_sum, ext_sigcount = 0, i; 3.230 3.231 - total_size = get_totalsize(mc_header); 3.232 - data_size = get_datasize(mc_header); 3.233 - if (data_size + MC_HEADER_SIZE > total_size) { 3.234 - printk(KERN_ERR "microcode: error! " 3.235 - "Bad data size in microcode data file\n"); 3.236 - return -EINVAL; 3.237 - } 3.238 + total_size = get_totalsize(mc_header); 3.239 + data_size = get_datasize(mc_header); 3.240 + if ( (data_size + MC_HEADER_SIZE) > total_size ) 3.241 + { 3.242 + printk(KERN_ERR "microcode: error! " 3.243 + "Bad data size in microcode data file\n"); 3.244 + return -EINVAL; 3.245 + } 3.246 3.247 - if (mc_header->ldrver != 1 || mc_header->hdrver != 1) { 3.248 - printk(KERN_ERR "microcode: error! " 3.249 - "Unknown microcode update format\n"); 3.250 - return -EINVAL; 3.251 - } 3.252 - ext_table_size = total_size - (MC_HEADER_SIZE + data_size); 3.253 - if (ext_table_size) { 3.254 - if ((ext_table_size < EXT_HEADER_SIZE) 3.255 - || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) { 3.256 - printk(KERN_ERR "microcode: error! " 3.257 - "Small exttable size in microcode data file\n"); 3.258 - return -EINVAL; 3.259 - } 3.260 - ext_header = mc + MC_HEADER_SIZE + data_size; 3.261 - if (ext_table_size != exttable_size(ext_header)) { 3.262 - printk(KERN_ERR "microcode: error! " 3.263 - "Bad exttable size in microcode data file\n"); 3.264 - return -EFAULT; 3.265 - } 3.266 - ext_sigcount = ext_header->count; 3.267 - } 3.268 + if ( (mc_header->ldrver != 1) || (mc_header->hdrver != 1) ) 3.269 + { 3.270 + printk(KERN_ERR "microcode: error! " 3.271 + "Unknown microcode update format\n"); 3.272 + return -EINVAL; 3.273 + } 3.274 + ext_table_size = total_size - (MC_HEADER_SIZE + data_size); 3.275 + if ( ext_table_size ) 3.276 + { 3.277 + if ( (ext_table_size < EXT_HEADER_SIZE) || 3.278 + ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE) ) 3.279 + { 3.280 + printk(KERN_ERR "microcode: error! " 3.281 + "Small exttable size in microcode data file\n"); 3.282 + return -EINVAL; 3.283 + } 3.284 + ext_header = mc + MC_HEADER_SIZE + data_size; 3.285 + if ( ext_table_size != exttable_size(ext_header) ) 3.286 + { 3.287 + printk(KERN_ERR "microcode: error! " 3.288 + "Bad exttable size in microcode data file\n"); 3.289 + return -EFAULT; 3.290 + } 3.291 + ext_sigcount = ext_header->count; 3.292 + } 3.293 3.294 - /* check extended table checksum */ 3.295 - if (ext_table_size) { 3.296 - int ext_table_sum = 0; 3.297 - int *ext_tablep = (int *)ext_header; 3.298 + /* check extended table checksum */ 3.299 + if ( ext_table_size ) 3.300 + { 3.301 + int ext_table_sum = 0; 3.302 + int *ext_tablep = (int *)ext_header; 3.303 3.304 - i = ext_table_size / DWSIZE; 3.305 - while (i--) 3.306 - ext_table_sum += ext_tablep[i]; 3.307 - if (ext_table_sum) { 3.308 - printk(KERN_WARNING "microcode: aborting, " 3.309 - "bad extended signature table checksum\n"); 3.310 - return -EINVAL; 3.311 - } 3.312 - } 3.313 + i = ext_table_size / DWSIZE; 3.314 + while ( i-- ) 3.315 + ext_table_sum += ext_tablep[i]; 3.316 + if ( ext_table_sum ) 3.317 + { 3.318 + printk(KERN_WARNING "microcode: aborting, " 3.319 + "bad extended signature table checksum\n"); 3.320 + return -EINVAL; 3.321 + } 3.322 + } 3.323 3.324 - /* calculate the checksum */ 3.325 - orig_sum = 0; 3.326 - i = (MC_HEADER_SIZE + data_size) / DWSIZE; 3.327 - while (i--) 3.328 - orig_sum += ((int *)mc)[i]; 3.329 - if (orig_sum) { 3.330 - printk(KERN_ERR "microcode: aborting, bad checksum\n"); 3.331 - return -EINVAL; 3.332 - } 3.333 - if (!ext_table_size) 3.334 - return 0; 3.335 - /* check extended signature checksum */ 3.336 - for (i = 0; i < ext_sigcount; i++) { 3.337 - ext_sig = (void *)ext_header + EXT_HEADER_SIZE + 3.338 - EXT_SIGNATURE_SIZE * i; 3.339 - sum = orig_sum 3.340 - - (mc_header->sig + mc_header->pf + mc_header->cksum) 3.341 - + (ext_sig->sig + ext_sig->pf + ext_sig->cksum); 3.342 - if (sum) { 3.343 - printk(KERN_ERR "microcode: aborting, bad checksum\n"); 3.344 - return -EINVAL; 3.345 - } 3.346 - } 3.347 - return 0; 3.348 + /* calculate the checksum */ 3.349 + orig_sum = 0; 3.350 + i = (MC_HEADER_SIZE + data_size) / DWSIZE; 3.351 + while ( i-- ) 3.352 + orig_sum += ((int *)mc)[i]; 3.353 + if ( orig_sum ) 3.354 + { 3.355 + printk(KERN_ERR "microcode: aborting, bad checksum\n"); 3.356 + return -EINVAL; 3.357 + } 3.358 + if ( !ext_table_size ) 3.359 + return 0; 3.360 + /* check extended signature checksum */ 3.361 + for ( i = 0; i < ext_sigcount; i++ ) 3.362 + { 3.363 + ext_sig = (void *)ext_header + EXT_HEADER_SIZE + 3.364 + EXT_SIGNATURE_SIZE * i; 3.365 + sum = orig_sum 3.366 + - (mc_header->sig + mc_header->pf + mc_header->cksum) 3.367 + + (ext_sig->sig + ext_sig->pf + ext_sig->cksum); 3.368 + if ( sum ) 3.369 + { 3.370 + printk(KERN_ERR "microcode: aborting, bad checksum\n"); 3.371 + return -EINVAL; 3.372 + } 3.373 + } 3.374 + return 0; 3.375 } 3.376 3.377 /* 3.378 @@ -249,118 +199,123 @@ static int microcode_sanity_check(void * 3.379 */ 3.380 static int get_matching_microcode(void *mc, int cpu) 3.381 { 3.382 - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 3.383 - struct microcode_header_intel *mc_header = mc; 3.384 - struct extended_sigtable *ext_header; 3.385 - unsigned long total_size = get_totalsize(mc_header); 3.386 - int ext_sigcount, i; 3.387 - struct extended_signature *ext_sig; 3.388 - void *new_mc; 3.389 + struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 3.390 + struct microcode_header_intel *mc_header = mc; 3.391 + struct extended_sigtable *ext_header; 3.392 + unsigned long total_size = get_totalsize(mc_header); 3.393 + int ext_sigcount, i; 3.394 + struct extended_signature *ext_sig; 3.395 + void *new_mc; 3.396 3.397 - if (microcode_update_match(cpu, mc_header, 3.398 - mc_header->sig, mc_header->pf)) 3.399 - goto find; 3.400 + if ( microcode_update_match(cpu, mc_header, 3.401 + mc_header->sig, mc_header->pf) ) 3.402 + goto find; 3.403 3.404 - if (total_size <= get_datasize(mc_header) + MC_HEADER_SIZE) 3.405 - return 0; 3.406 + if ( total_size <= (get_datasize(mc_header) + MC_HEADER_SIZE) ) 3.407 + return 0; 3.408 3.409 - ext_header = mc + get_datasize(mc_header) + MC_HEADER_SIZE; 3.410 - ext_sigcount = ext_header->count; 3.411 - ext_sig = (void *)ext_header + EXT_HEADER_SIZE; 3.412 - for (i = 0; i < ext_sigcount; i++) { 3.413 - if (microcode_update_match(cpu, mc_header, 3.414 - ext_sig->sig, ext_sig->pf)) 3.415 - goto find; 3.416 - ext_sig++; 3.417 - } 3.418 - return 0; 3.419 -find: 3.420 - pr_debug("microcode: CPU%d found a matching microcode update with" 3.421 - " version 0x%x (current=0x%x)\n", 3.422 - cpu, mc_header->rev, uci->cpu_sig.rev); 3.423 - new_mc = vmalloc(total_size); 3.424 - if (!new_mc) { 3.425 - printk(KERN_ERR "microcode: error! Can not allocate memory\n"); 3.426 - return -ENOMEM; 3.427 - } 3.428 + ext_header = mc + get_datasize(mc_header) + MC_HEADER_SIZE; 3.429 + ext_sigcount = ext_header->count; 3.430 + ext_sig = (void *)ext_header + EXT_HEADER_SIZE; 3.431 + for ( i = 0; i < ext_sigcount; i++ ) 3.432 + { 3.433 + if ( microcode_update_match(cpu, mc_header, 3.434 + ext_sig->sig, ext_sig->pf) ) 3.435 + goto find; 3.436 + ext_sig++; 3.437 + } 3.438 + return 0; 3.439 + find: 3.440 + pr_debug("microcode: CPU%d found a matching microcode update with" 3.441 + " version 0x%x (current=0x%x)\n", 3.442 + cpu, mc_header->rev, uci->cpu_sig.rev); 3.443 + new_mc = xmalloc_bytes(total_size); 3.444 + if ( new_mc == NULL ) 3.445 + { 3.446 + printk(KERN_ERR "microcode: error! Can not allocate memory\n"); 3.447 + return -ENOMEM; 3.448 + } 3.449 3.450 - /* free previous update file */ 3.451 - vfree(uci->mc.mc_intel); 3.452 + /* free previous update file */ 3.453 + xfree(uci->mc.mc_intel); 3.454 3.455 - memcpy(new_mc, mc, total_size); 3.456 - uci->mc.mc_intel = new_mc; 3.457 - return 1; 3.458 + memcpy(new_mc, mc, total_size); 3.459 + uci->mc.mc_intel = new_mc; 3.460 + return 1; 3.461 } 3.462 3.463 static int apply_microcode(int cpu) 3.464 { 3.465 - unsigned long flags; 3.466 - unsigned int val[2]; 3.467 - int cpu_num = raw_smp_processor_id(); 3.468 - struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 3.469 + unsigned long flags; 3.470 + unsigned int val[2]; 3.471 + int cpu_num = raw_smp_processor_id(); 3.472 + struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 3.473 3.474 - /* We should bind the task to the CPU */ 3.475 - BUG_ON(cpu_num != cpu); 3.476 + /* We should bind the task to the CPU */ 3.477 + BUG_ON(cpu_num != cpu); 3.478 3.479 - if (uci->mc.mc_intel == NULL) 3.480 - return -EINVAL; 3.481 + if ( uci->mc.mc_intel == NULL ) 3.482 + return -EINVAL; 3.483 3.484 - /* serialize access to the physical write to MSR 0x79 */ 3.485 - spin_lock_irqsave(µcode_update_lock, flags); 3.486 + /* serialize access to the physical write to MSR 0x79 */ 3.487 + spin_lock_irqsave(µcode_update_lock, flags); 3.488 3.489 - /* write microcode via MSR 0x79 */ 3.490 - wrmsr(MSR_IA32_UCODE_WRITE, 3.491 - (unsigned long) uci->mc.mc_intel->bits, 3.492 - (unsigned long) uci->mc.mc_intel->bits >> 16 >> 16); 3.493 - wrmsr(MSR_IA32_UCODE_REV, 0, 0); 3.494 + /* write microcode via MSR 0x79 */ 3.495 + wrmsr(MSR_IA32_UCODE_WRITE, 3.496 + (unsigned long) uci->mc.mc_intel->bits, 3.497 + (unsigned long) uci->mc.mc_intel->bits >> 16 >> 16); 3.498 + wrmsr(MSR_IA32_UCODE_REV, 0, 0); 3.499 3.500 - /* see notes above for revision 1.07. Apparent chip bug */ 3.501 - sync_core(); 3.502 + /* see notes above for revision 1.07. Apparent chip bug */ 3.503 + sync_core(); 3.504 3.505 - /* get the current revision from MSR 0x8B */ 3.506 - rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); 3.507 + /* get the current revision from MSR 0x8B */ 3.508 + rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); 3.509 3.510 - spin_unlock_irqrestore(µcode_update_lock, flags); 3.511 - if (val[1] != uci->mc.mc_intel->hdr.rev) { 3.512 - printk(KERN_ERR "microcode: CPU%d update from revision " 3.513 - "0x%x to 0x%x failed\n", cpu_num, uci->cpu_sig.rev, val[1]); 3.514 - return -EIO; 3.515 - } 3.516 - printk(KERN_INFO "microcode: CPU%d updated from revision " 3.517 - "0x%x to 0x%x, date = %04x-%02x-%02x \n", 3.518 - cpu_num, uci->cpu_sig.rev, val[1], 3.519 - uci->mc.mc_intel->hdr.date & 0xffff, 3.520 - uci->mc.mc_intel->hdr.date >> 24, 3.521 - (uci->mc.mc_intel->hdr.date >> 16) & 0xff); 3.522 - uci->cpu_sig.rev = val[1]; 3.523 + spin_unlock_irqrestore(µcode_update_lock, flags); 3.524 + if ( val[1] != uci->mc.mc_intel->hdr.rev ) 3.525 + { 3.526 + printk(KERN_ERR "microcode: CPU%d update from revision " 3.527 + "0x%x to 0x%x failed\n", cpu_num, uci->cpu_sig.rev, val[1]); 3.528 + return -EIO; 3.529 + } 3.530 + printk(KERN_INFO "microcode: CPU%d updated from revision " 3.531 + "0x%x to 0x%x, date = %04x-%02x-%02x \n", 3.532 + cpu_num, uci->cpu_sig.rev, val[1], 3.533 + uci->mc.mc_intel->hdr.date & 0xffff, 3.534 + uci->mc.mc_intel->hdr.date >> 24, 3.535 + (uci->mc.mc_intel->hdr.date >> 16) & 0xff); 3.536 + uci->cpu_sig.rev = val[1]; 3.537 3.538 - return 0; 3.539 + return 0; 3.540 } 3.541 3.542 static long get_next_ucode_from_buffer(void **mc, const u8 *buf, 3.543 - unsigned long size, long offset) 3.544 + unsigned long size, long offset) 3.545 { 3.546 - struct microcode_header_intel *mc_header; 3.547 - unsigned long total_size; 3.548 + struct microcode_header_intel *mc_header; 3.549 + unsigned long total_size; 3.550 3.551 - /* No more data */ 3.552 - if (offset >= size) 3.553 - return 0; 3.554 - mc_header = (struct microcode_header_intel *)(buf + offset); 3.555 - total_size = get_totalsize(mc_header); 3.556 + /* No more data */ 3.557 + if ( offset >= size ) 3.558 + return 0; 3.559 + mc_header = (struct microcode_header_intel *)(buf + offset); 3.560 + total_size = get_totalsize(mc_header); 3.561 3.562 - if (offset + total_size > size) { 3.563 - printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); 3.564 - return -EINVAL; 3.565 - } 3.566 + if ( (offset + total_size) > size ) 3.567 + { 3.568 + printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); 3.569 + return -EINVAL; 3.570 + } 3.571 3.572 - *mc = vmalloc(total_size); 3.573 - if (!*mc) { 3.574 - printk(KERN_ERR "microcode: error! Can not allocate memory\n"); 3.575 - return -ENOMEM; 3.576 - } 3.577 - memcpy(*mc, (const void *)(buf + offset), total_size); 3.578 - return offset + total_size; 3.579 + *mc = xmalloc_bytes(total_size); 3.580 + if ( *mc == NULL ) 3.581 + { 3.582 + printk(KERN_ERR "microcode: error! Can not allocate memory\n"); 3.583 + return -ENOMEM; 3.584 + } 3.585 + memcpy(*mc, (const void *)(buf + offset), total_size); 3.586 + return offset + total_size; 3.587 } 3.588 3.589 /* fake device for request_firmware */ 3.590 @@ -368,58 +323,61 @@ extern struct platform_device *microcode 3.591 3.592 static int cpu_request_microcode(int cpu, const void *buf, size_t size) 3.593 { 3.594 - long offset = 0; 3.595 - int error = 0; 3.596 - void *mc; 3.597 + long offset = 0; 3.598 + int error = 0; 3.599 + void *mc; 3.600 3.601 - /* We should bind the task to the CPU */ 3.602 - BUG_ON(cpu != raw_smp_processor_id()); 3.603 + /* We should bind the task to the CPU */ 3.604 + BUG_ON(cpu != raw_smp_processor_id()); 3.605 3.606 - while ((offset = get_next_ucode_from_buffer(&mc, buf, size, offset)) 3.607 - > 0) { 3.608 - error = microcode_sanity_check(mc); 3.609 - if (error) 3.610 - break; 3.611 - error = get_matching_microcode(mc, cpu); 3.612 - if (error < 0) 3.613 - break; 3.614 - /* 3.615 - * It's possible the data file has multiple matching ucode, 3.616 - * lets keep searching till the latest version 3.617 - */ 3.618 - if (error == 1) { 3.619 - apply_microcode(cpu); 3.620 - error = 0; 3.621 - } 3.622 - vfree(mc); 3.623 - } 3.624 - if (offset > 0) 3.625 - vfree(mc); 3.626 - if (offset < 0) 3.627 - error = offset; 3.628 + while ( (offset = get_next_ucode_from_buffer(&mc, buf, size, offset)) > 0 ) 3.629 + { 3.630 + error = microcode_sanity_check(mc); 3.631 + if ( error ) 3.632 + break; 3.633 + error = get_matching_microcode(mc, cpu); 3.634 + if ( error < 0 ) 3.635 + break; 3.636 + /* 3.637 + * It's possible the data file has multiple matching ucode, 3.638 + * lets keep searching till the latest version 3.639 + */ 3.640 + if ( error == 1 ) 3.641 + { 3.642 + apply_microcode(cpu); 3.643 + error = 0; 3.644 + } 3.645 + xfree(mc); 3.646 + } 3.647 + if ( offset > 0 ) 3.648 + xfree(mc); 3.649 + if ( offset < 0 ) 3.650 + error = offset; 3.651 3.652 - return error; 3.653 + return error; 3.654 } 3.655 3.656 static void microcode_fini_cpu(int cpu) 3.657 { 3.658 - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 3.659 + struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 3.660 3.661 - vfree(uci->mc.mc_intel); 3.662 - uci->mc.mc_intel = NULL; 3.663 + xfree(uci->mc.mc_intel); 3.664 + uci->mc.mc_intel = NULL; 3.665 } 3.666 3.667 static struct microcode_ops microcode_intel_ops = { 3.668 - .get_matching_microcode = get_matching_microcode, 3.669 - .microcode_sanity_check = microcode_sanity_check, 3.670 - .cpu_request_microcode = cpu_request_microcode, 3.671 - .collect_cpu_info = collect_cpu_info, 3.672 - .apply_microcode = apply_microcode, 3.673 - .microcode_fini_cpu = microcode_fini_cpu, 3.674 + .get_matching_microcode = get_matching_microcode, 3.675 + .microcode_sanity_check = microcode_sanity_check, 3.676 + .cpu_request_microcode = cpu_request_microcode, 3.677 + .collect_cpu_info = collect_cpu_info, 3.678 + .apply_microcode = apply_microcode, 3.679 + .microcode_fini_cpu = microcode_fini_cpu, 3.680 }; 3.681 3.682 -int microcode_init_intel(struct cpuinfo_x86 *c) 3.683 +static __init int microcode_init_intel(void) 3.684 { 3.685 - microcode_ops = µcode_intel_ops; 3.686 - return 0; 3.687 + if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ) 3.688 + microcode_ops = µcode_intel_ops; 3.689 + return 0; 3.690 } 3.691 +__initcall(microcode_init_intel);
4.1 --- a/xen/include/asm-x86/microcode.h Mon Sep 15 17:10:43 2008 +0100 4.2 +++ b/xen/include/asm-x86/microcode.h Tue Sep 16 11:26:19 2008 +0100 4.3 @@ -90,11 +90,8 @@ struct ucode_cpu_info { 4.4 void *valid_mc; 4.5 } mc; 4.6 }; 4.7 + 4.8 extern struct ucode_cpu_info ucode_cpu_info[]; 4.9 - 4.10 extern const struct microcode_ops *microcode_ops; 4.11 4.12 -int microcode_init_amd(struct cpuinfo_x86 *c); 4.13 -int microcode_init_intel(struct cpuinfo_x86 *c); 4.14 - 4.15 #endif /* ASM_X86__MICROCODE_H */