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