x86/mce: Fix thermal throttling reporting after kexec
[linux-2.6-block.git] / arch / x86 / kernel / cpu / microcode / intel.c
CommitLineData
1da177e4 1/*
6b44e72a 2 * Intel CPU Microcode Update Driver for Linux
1da177e4 3 *
6b44e72a
BP
4 * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
5 * 2006 Shaohua Li <shaohua.li@intel.com>
1da177e4 6 *
6b44e72a
BP
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
1da177e4 11 */
f58e1f53
JP
12
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
4bae1967 15#include <linux/firmware.h>
4bae1967 16#include <linux/uaccess.h>
4bae1967
IM
17#include <linux/kernel.h>
18#include <linux/module.h>
871b72dd 19#include <linux/vmalloc.h>
1da177e4 20
9cd4d78e 21#include <asm/microcode_intel.h>
4bae1967
IM
22#include <asm/processor.h>
23#include <asm/msr.h>
1da177e4 24
3e135d88 25MODULE_DESCRIPTION("Microcode Update Driver");
69688262 26MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
1da177e4
LT
27MODULE_LICENSE("GPL");
28
d45de409 29static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
1da177e4 30{
92cb7612 31 struct cpuinfo_x86 *c = &cpu_data(cpu_num);
1da177e4
LT
32 unsigned int val[2];
33
d45de409 34 memset(csig, 0, sizeof(*csig));
1da177e4 35
d45de409 36 csig->sig = cpuid_eax(0x00000001);
9a3110bf
SL
37
38 if ((c->x86_model >= 5) || (c->x86 > 6)) {
39 /* get processor flags from MSR 0x17 */
40 rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
d45de409 41 csig->pf = 1 << ((val[1] >> 18) & 7);
1da177e4
LT
42 }
43
506ed6b5 44 csig->rev = c->microcode;
f58e1f53
JP
45 pr_info("CPU%d sig=0x%x, pf=0x%x, revision=0x%x\n",
46 cpu_num, csig->sig, csig->pf, csig->rev);
d45de409
DA
47
48 return 0;
1da177e4
LT
49}
50
9a3110bf
SL
51/*
52 * return 0 - no update found
53 * return 1 - found update
9a3110bf 54 */
9cd4d78e 55static int get_matching_mc(struct microcode_intel *mc_intel, int cpu)
9a3110bf 56{
9cd4d78e
FY
57 struct cpu_signature cpu_sig;
58 unsigned int csig, cpf, crev;
9a3110bf 59
9cd4d78e 60 collect_cpu_info(cpu, &cpu_sig);
a0a29b62 61
9cd4d78e
FY
62 csig = cpu_sig.sig;
63 cpf = cpu_sig.pf;
64 crev = cpu_sig.rev;
9a3110bf 65
8de3eafc 66 return has_newer_microcode(mc_intel, csig, cpf, crev);
1da177e4
LT
67}
68
532ed374 69static int apply_microcode_intel(int cpu)
1da177e4 70{
4bae1967
IM
71 struct microcode_intel *mc_intel;
72 struct ucode_cpu_info *uci;
1da177e4 73 unsigned int val[2];
506ed6b5
AK
74 int cpu_num = raw_smp_processor_id();
75 struct cpuinfo_x86 *c = &cpu_data(cpu_num);
4bae1967 76
4bae1967
IM
77 uci = ucode_cpu_info + cpu;
78 mc_intel = uci->mc;
1da177e4 79
9a3110bf
SL
80 /* We should bind the task to the CPU */
81 BUG_ON(cpu_num != cpu);
82
18dbc916 83 if (mc_intel == NULL)
871b72dd 84 return 0;
1da177e4 85
9cd4d78e
FY
86 /*
87 * Microcode on this CPU could be updated earlier. Only apply the
88 * microcode patch in mc_intel when it is newer than the one on this
89 * CPU.
90 */
91 if (get_matching_mc(mc_intel, cpu) == 0)
92 return 0;
93
1da177e4
LT
94 /* write microcode via MSR 0x79 */
95 wrmsr(MSR_IA32_UCODE_WRITE,
18dbc916
DA
96 (unsigned long) mc_intel->bits,
97 (unsigned long) mc_intel->bits >> 16 >> 16);
1da177e4
LT
98 wrmsr(MSR_IA32_UCODE_REV, 0, 0);
99
506ed6b5 100 /* As documented in the SDM: Do a CPUID 1 here */
487472bc 101 sync_core();
245067d1 102
1da177e4
LT
103 /* get the current revision from MSR 0x8B */
104 rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
105
18dbc916 106 if (val[1] != mc_intel->hdr.rev) {
f58e1f53
JP
107 pr_err("CPU%d update to revision 0x%x failed\n",
108 cpu_num, mc_intel->hdr.rev);
871b72dd 109 return -1;
9a3110bf 110 }
3235dc3f 111 pr_info("CPU%d updated to revision 0x%x, date = %04x-%02x-%02x\n",
871b72dd 112 cpu_num, val[1],
18dbc916
DA
113 mc_intel->hdr.date & 0xffff,
114 mc_intel->hdr.date >> 24,
115 (mc_intel->hdr.date >> 16) & 0xff);
4bae1967 116
d45de409 117 uci->cpu_sig.rev = val[1];
506ed6b5 118 c->microcode = val[1];
871b72dd
DA
119
120 return 0;
1da177e4
LT
121}
122
871b72dd
DA
123static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
124 int (*get_ucode_data)(void *, const void *, size_t))
9a3110bf 125{
a0a29b62 126 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
938179b4 127 u8 *ucode_ptr = data, *new_mc = NULL, *mc = NULL;
a0a29b62
DA
128 int new_rev = uci->cpu_sig.rev;
129 unsigned int leftover = size;
871b72dd 130 enum ucode_state state = UCODE_OK;
938179b4 131 unsigned int curr_mc_size = 0;
9cd4d78e 132 unsigned int csig, cpf;
9a3110bf 133
a0a29b62
DA
134 while (leftover) {
135 struct microcode_header_intel mc_header;
136 unsigned int mc_size;
9a3110bf 137
35a9ff4e
QC
138 if (leftover < sizeof(mc_header)) {
139 pr_err("error! Truncated header in microcode data file\n");
140 break;
141 }
142
a0a29b62
DA
143 if (get_ucode_data(&mc_header, ucode_ptr, sizeof(mc_header)))
144 break;
a30a6a2c 145
a0a29b62
DA
146 mc_size = get_totalsize(&mc_header);
147 if (!mc_size || mc_size > leftover) {
f58e1f53 148 pr_err("error! Bad data in microcode data file\n");
a0a29b62
DA
149 break;
150 }
a30a6a2c 151
938179b4
DS
152 /* For performance reasons, reuse mc area when possible */
153 if (!mc || mc_size > curr_mc_size) {
5cdd2de0 154 vfree(mc);
938179b4
DS
155 mc = vmalloc(mc_size);
156 if (!mc)
157 break;
158 curr_mc_size = mc_size;
159 }
a0a29b62
DA
160
161 if (get_ucode_data(mc, ucode_ptr, mc_size) ||
9cd4d78e 162 microcode_sanity_check(mc, 1) < 0) {
a0a29b62
DA
163 break;
164 }
165
9cd4d78e
FY
166 csig = uci->cpu_sig.sig;
167 cpf = uci->cpu_sig.pf;
8de3eafc 168 if (has_newer_microcode(mc, csig, cpf, new_rev)) {
5cdd2de0 169 vfree(new_mc);
a0a29b62
DA
170 new_rev = mc_header.rev;
171 new_mc = mc;
938179b4
DS
172 mc = NULL; /* trigger new vmalloc */
173 }
a0a29b62
DA
174
175 ucode_ptr += mc_size;
176 leftover -= mc_size;
a30a6a2c
SL
177 }
178
5cdd2de0 179 vfree(mc);
938179b4 180
871b72dd 181 if (leftover) {
5cdd2de0 182 vfree(new_mc);
871b72dd 183 state = UCODE_ERROR;
4bae1967 184 goto out;
871b72dd 185 }
4bae1967 186
871b72dd
DA
187 if (!new_mc) {
188 state = UCODE_NFOUND;
4bae1967 189 goto out;
a30a6a2c 190 }
a0a29b62 191
5cdd2de0 192 vfree(uci->mc);
4bae1967
IM
193 uci->mc = (struct microcode_intel *)new_mc;
194
9cd4d78e
FY
195 /*
196 * If early loading microcode is supported, save this mc into
197 * permanent memory. So it will be loaded early when a CPU is hot added
198 * or resumes.
199 */
200 save_mc_for_early(new_mc);
201
f58e1f53
JP
202 pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",
203 cpu, new_rev, uci->cpu_sig.rev);
871b72dd
DA
204out:
205 return state;
a30a6a2c
SL
206}
207
a0a29b62
DA
208static int get_ucode_fw(void *to, const void *from, size_t n)
209{
210 memcpy(to, from, n);
211 return 0;
212}
a30a6a2c 213
48e30685
BP
214static enum ucode_state request_microcode_fw(int cpu, struct device *device,
215 bool refresh_fw)
a30a6a2c
SL
216{
217 char name[30];
92cb7612 218 struct cpuinfo_x86 *c = &cpu_data(cpu);
a30a6a2c 219 const struct firmware *firmware;
871b72dd 220 enum ucode_state ret;
a30a6a2c 221
3e135d88 222 sprintf(name, "intel-ucode/%02x-%02x-%02x",
a30a6a2c 223 c->x86, c->x86_model, c->x86_mask);
871b72dd 224
75da02b2 225 if (request_firmware_direct(&firmware, name, device)) {
f58e1f53 226 pr_debug("data file %s load failed\n", name);
871b72dd 227 return UCODE_NFOUND;
a30a6a2c 228 }
a0a29b62 229
dd3feda7
JSR
230 ret = generic_load_microcode(cpu, (void *)firmware->data,
231 firmware->size, &get_ucode_fw);
a0a29b62 232
a30a6a2c
SL
233 release_firmware(firmware);
234
a0a29b62
DA
235 return ret;
236}
237
238static int get_ucode_user(void *to, const void *from, size_t n)
239{
240 return copy_from_user(to, from, n);
241}
242
871b72dd
DA
243static enum ucode_state
244request_microcode_user(int cpu, const void __user *buf, size_t size)
a0a29b62 245{
dd3feda7 246 return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user);
a30a6a2c
SL
247}
248
8d86f390 249static void microcode_fini_cpu(int cpu)
a30a6a2c
SL
250{
251 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
252
18dbc916
DA
253 vfree(uci->mc);
254 uci->mc = NULL;
a30a6a2c 255}
8d86f390 256
4db646b1 257static struct microcode_ops microcode_intel_ops = {
a0a29b62
DA
258 .request_microcode_user = request_microcode_user,
259 .request_microcode_fw = request_microcode_fw,
8d86f390 260 .collect_cpu_info = collect_cpu_info,
532ed374 261 .apply_microcode = apply_microcode_intel,
8d86f390
PO
262 .microcode_fini_cpu = microcode_fini_cpu,
263};
264
18dbc916 265struct microcode_ops * __init init_intel_microcode(void)
8d86f390 266{
7164b3f5
SB
267 struct cpuinfo_x86 *c = &cpu_data(0);
268
269 if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
270 cpu_has(c, X86_FEATURE_IA64)) {
271 pr_err("Intel CPU family 0x%x not supported\n", c->x86);
272 return NULL;
273 }
274
18dbc916 275 return &microcode_intel_ops;
8d86f390
PO
276}
277