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 + * 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(&microcode_mutex);
   1.114 -	microcode_ops->microcode_fini_cpu(cpu);
   1.115 -	uci->valid = 0;
   1.116 -	spin_unlock(&microcode_mutex);
   1.117 +    spin_lock(&microcode_mutex);
   1.118 +    microcode_ops->microcode_fini_cpu(cpu);
   1.119 +    uci->valid = 0;
   1.120 +    spin_unlock(&microcode_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(&microcode_mutex);
   1.212  
   1.213 -	spin_lock(&microcode_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(&microcode_mutex);
   1.245 +    spin_unlock(&microcode_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(&microcode_update_lock, flags);
   2.278 +    spin_lock_irqsave(&microcode_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(&microcode_update_lock, flags);
   2.302 +    spin_unlock_irqrestore(&microcode_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 = &microcode_amd_ops;
   2.599 -	return 0;
   2.600 +    if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
   2.601 +        microcode_ops = &microcode_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(&microcode_update_lock, flags);
   3.486 +    /* serialize access to the physical write to MSR 0x79 */
   3.487 +    spin_lock_irqsave(&microcode_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(&microcode_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(&microcode_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 = &microcode_intel_ops;
   3.686 -	return 0;
   3.687 +    if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
   3.688 +        microcode_ops = &microcode_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 */