aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-03-15 13:39:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-15 13:39:22 -0400
commit9cf8d6360c1589a97a98313729ed9e5db187f80b (patch)
tree6724fb3915f5343800460d98d31528e09a445028
parentecc026bff6e8444c6b50dcde192e7acdaf42bf82 (diff)
parent4ace2e7a48ab426eaa9745ace4c50c6a7adb3992 (diff)
Merge branch 'x86-microcode-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 microcode updates from Ingo Molnar: "The biggest change in this cycle was the separation of the microcode loading mechanism from the initrd code plus the support of built-in microcode images. There were also lots cleanups and general restructuring (by Borislav Petkov)" * 'x86-microcode-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (24 commits) x86/microcode/intel: Drop orig_sum from ext signature checksum x86/microcode/intel: Improve microcode sanity-checking error messages x86/microcode/intel: Merge two consecutive if-statements x86/microcode/intel: Get rid of DWSIZE x86/microcode/intel: Change checksum variables to u32 x86/microcode: Use kmemdup() rather than duplicating its implementation x86/microcode: Remove unnecessary paravirt_enabled check x86/microcode: Document builtin microcode loading method x86/microcode/AMD: Issue microcode updated message later x86/microcode/intel: Cleanup get_matching_model_microcode() x86/microcode/intel: Remove unused arg of get_matching_model_microcode() x86/microcode/intel: Rename mc_saved_in_initrd x86/microcode/intel: Use *wrmsrl variants x86/microcode/intel: Cleanup apply_microcode_intel() x86/microcode/intel: Move the BUG_ON up and turn it into WARN_ON x86/microcode/intel: Rename mc_intel variable to mc x86/microcode/intel: Rename mc_saved_count to num_saved x86/microcode/intel: Rename local variables of type struct mc_saved_data x86/microcode/AMD: Drop redundant printk prefix x86/microcode: Issue update message only once ...
-rw-r--r--Documentation/x86/early-microcode.txt25
-rw-r--r--arch/x86/Kconfig27
-rw-r--r--arch/x86/include/asm/microcode.h26
-rw-r--r--arch/x86/include/asm/microcode_intel.h1
-rw-r--r--arch/x86/kernel/cpu/microcode/amd.c15
-rw-r--r--arch/x86/kernel/cpu/microcode/core.c19
-rw-r--r--arch/x86/kernel/cpu/microcode/intel.c285
-rw-r--r--arch/x86/kernel/cpu/microcode/intel_lib.c58
8 files changed, 253 insertions, 203 deletions
diff --git a/Documentation/x86/early-microcode.txt b/Documentation/x86/early-microcode.txt
index d62bea6796da..c956d99cf1de 100644
--- a/Documentation/x86/early-microcode.txt
+++ b/Documentation/x86/early-microcode.txt
@@ -40,3 +40,28 @@ cp ../microcode.bin kernel/x86/microcode/GenuineIntel.bin (or AuthenticAMD.bin)
40find . | cpio -o -H newc >../ucode.cpio 40find . | cpio -o -H newc >../ucode.cpio
41cd .. 41cd ..
42cat ucode.cpio /boot/initrd-3.5.0.img >/boot/initrd-3.5.0.ucode.img 42cat ucode.cpio /boot/initrd-3.5.0.img >/boot/initrd-3.5.0.ucode.img
43
44Builtin microcode
45=================
46
47We can also load builtin microcode supplied through the regular firmware
48builtin method CONFIG_FIRMWARE_IN_KERNEL. Here's an example:
49
50CONFIG_FIRMWARE_IN_KERNEL=y
51CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin"
52CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware"
53
54This basically means, you have the following tree structure locally:
55
56/lib/firmware/
57|-- amd-ucode
58...
59| |-- microcode_amd_fam15h.bin
60...
61|-- intel-ucode
62...
63| |-- 06-3a-09
64...
65
66so that the build system can find those files and integrate them into
67the final kernel image. The early loader finds them and applies them.
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index b1051057e5b0..8f2e6659281b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1163,22 +1163,23 @@ config MICROCODE
1163 bool "CPU microcode loading support" 1163 bool "CPU microcode loading support"
1164 default y 1164 default y
1165 depends on CPU_SUP_AMD || CPU_SUP_INTEL 1165 depends on CPU_SUP_AMD || CPU_SUP_INTEL
1166 depends on BLK_DEV_INITRD
1167 select FW_LOADER 1166 select FW_LOADER
1168 ---help--- 1167 ---help---
1169
1170 If you say Y here, you will be able to update the microcode on 1168 If you say Y here, you will be able to update the microcode on
1171 certain Intel and AMD processors. The Intel support is for the 1169 Intel and AMD processors. The Intel support is for the IA32 family,
1172 IA32 family, e.g. Pentium Pro, Pentium II, Pentium III, Pentium 4, 1170 e.g. Pentium Pro, Pentium II, Pentium III, Pentium 4, Xeon etc. The
1173 Xeon etc. The AMD support is for families 0x10 and later. You will 1171 AMD support is for families 0x10 and later. You will obviously need
1174 obviously need the actual microcode binary data itself which is not 1172 the actual microcode binary data itself which is not shipped with
1175 shipped with the Linux kernel. 1173 the Linux kernel.
1176 1174
1177 This option selects the general module only, you need to select 1175 The preferred method to load microcode from a detached initrd is described
1178 at least one vendor specific module as well. 1176 in Documentation/x86/early-microcode.txt. For that you need to enable
1179 1177 CONFIG_BLK_DEV_INITRD in order for the loader to be able to scan the
1180 To compile this driver as a module, choose M here: the module 1178 initrd for microcode blobs.
1181 will be called microcode. 1179
1180 In addition, you can build-in the microcode into the kernel. For that you
1181 need to enable FIRMWARE_IN_KERNEL and add the vendor-supplied microcode
1182 to the CONFIG_EXTRA_FIRMWARE config option.
1182 1183
1183config MICROCODE_INTEL 1184config MICROCODE_INTEL
1184 bool "Intel microcode loading support" 1185 bool "Intel microcode loading support"
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index 1e1b07a5a738..9d3a96c4da78 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -3,6 +3,7 @@
3 3
4#include <asm/cpu.h> 4#include <asm/cpu.h>
5#include <linux/earlycpio.h> 5#include <linux/earlycpio.h>
6#include <linux/initrd.h>
6 7
7#define native_rdmsr(msr, val1, val2) \ 8#define native_rdmsr(msr, val1, val2) \
8do { \ 9do { \
@@ -143,4 +144,29 @@ static inline void reload_early_microcode(void) { }
143static inline bool 144static inline bool
144get_builtin_firmware(struct cpio_data *cd, const char *name) { return false; } 145get_builtin_firmware(struct cpio_data *cd, const char *name) { return false; }
145#endif 146#endif
147
148static inline unsigned long get_initrd_start(void)
149{
150#ifdef CONFIG_BLK_DEV_INITRD
151 return initrd_start;
152#else
153 return 0;
154#endif
155}
156
157static inline unsigned long get_initrd_start_addr(void)
158{
159#ifdef CONFIG_BLK_DEV_INITRD
160#ifdef CONFIG_X86_32
161 unsigned long *initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start);
162
163 return (unsigned long)__pa_nodebug(*initrd_start_p);
164#else
165 return get_initrd_start();
166#endif
167#else /* CONFIG_BLK_DEV_INITRD */
168 return 0;
169#endif
170}
171
146#endif /* _ASM_X86_MICROCODE_H */ 172#endif /* _ASM_X86_MICROCODE_H */
diff --git a/arch/x86/include/asm/microcode_intel.h b/arch/x86/include/asm/microcode_intel.h
index 8559b0102ea1..603417f8dd6c 100644
--- a/arch/x86/include/asm/microcode_intel.h
+++ b/arch/x86/include/asm/microcode_intel.h
@@ -40,7 +40,6 @@ struct extended_sigtable {
40#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) 40#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE)
41#define EXT_HEADER_SIZE (sizeof(struct extended_sigtable)) 41#define EXT_HEADER_SIZE (sizeof(struct extended_sigtable))
42#define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature)) 42#define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature))
43#define DWSIZE (sizeof(u32))
44 43
45#define get_totalsize(mc) \ 44#define get_totalsize(mc) \
46 (((struct microcode_intel *)mc)->hdr.datasize ? \ 45 (((struct microcode_intel *)mc)->hdr.datasize ? \
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 75d3aab5f7b2..8581963894c7 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -431,10 +431,6 @@ int __init save_microcode_in_initrd_amd(void)
431 else 431 else
432 container = cont_va; 432 container = cont_va;
433 433
434 if (ucode_new_rev)
435 pr_info("microcode: updated early to new patch_level=0x%08x\n",
436 ucode_new_rev);
437
438 eax = cpuid_eax(0x00000001); 434 eax = cpuid_eax(0x00000001);
439 eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); 435 eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff);
440 436
@@ -469,8 +465,7 @@ void reload_ucode_amd(void)
469 if (mc && rev < mc->hdr.patch_id) { 465 if (mc && rev < mc->hdr.patch_id) {
470 if (!__apply_microcode_amd(mc)) { 466 if (!__apply_microcode_amd(mc)) {
471 ucode_new_rev = mc->hdr.patch_id; 467 ucode_new_rev = mc->hdr.patch_id;
472 pr_info("microcode: reload patch_level=0x%08x\n", 468 pr_info("reload patch_level=0x%08x\n", ucode_new_rev);
473 ucode_new_rev);
474 } 469 }
475 } 470 }
476} 471}
@@ -793,15 +788,13 @@ static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover)
793 return -EINVAL; 788 return -EINVAL;
794 } 789 }
795 790
796 patch->data = kzalloc(patch_size, GFP_KERNEL); 791 patch->data = kmemdup(fw + SECTION_HDR_SIZE, patch_size, GFP_KERNEL);
797 if (!patch->data) { 792 if (!patch->data) {
798 pr_err("Patch data allocation failure.\n"); 793 pr_err("Patch data allocation failure.\n");
799 kfree(patch); 794 kfree(patch);
800 return -EINVAL; 795 return -EINVAL;
801 } 796 }
802 797
803 /* All looks ok, copy patch... */
804 memcpy(patch->data, fw + SECTION_HDR_SIZE, patch_size);
805 INIT_LIST_HEAD(&patch->plist); 798 INIT_LIST_HEAD(&patch->plist);
806 patch->patch_id = mc_hdr->patch_id; 799 patch->patch_id = mc_hdr->patch_id;
807 patch->equiv_cpu = proc_id; 800 patch->equiv_cpu = proc_id;
@@ -957,6 +950,10 @@ struct microcode_ops * __init init_amd_microcode(void)
957 return NULL; 950 return NULL;
958 } 951 }
959 952
953 if (ucode_new_rev)
954 pr_info_once("microcode updated early to new patch_level=0x%08x\n",
955 ucode_new_rev);
956
960 return &microcode_amd_ops; 957 return &microcode_amd_ops;
961} 958}
962 959
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index faec7120c508..ac360bfbbdb6 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -43,16 +43,8 @@
43#define MICROCODE_VERSION "2.01" 43#define MICROCODE_VERSION "2.01"
44 44
45static struct microcode_ops *microcode_ops; 45static struct microcode_ops *microcode_ops;
46
47static bool dis_ucode_ldr; 46static bool dis_ucode_ldr;
48 47
49static int __init disable_loader(char *str)
50{
51 dis_ucode_ldr = true;
52 return 1;
53}
54__setup("dis_ucode_ldr", disable_loader);
55
56/* 48/*
57 * Synchronization. 49 * Synchronization.
58 * 50 *
@@ -81,15 +73,16 @@ struct cpu_info_ctx {
81 73
82static bool __init check_loader_disabled_bsp(void) 74static bool __init check_loader_disabled_bsp(void)
83{ 75{
76 static const char *__dis_opt_str = "dis_ucode_ldr";
77
84#ifdef CONFIG_X86_32 78#ifdef CONFIG_X86_32
85 const char *cmdline = (const char *)__pa_nodebug(boot_command_line); 79 const char *cmdline = (const char *)__pa_nodebug(boot_command_line);
86 const char *opt = "dis_ucode_ldr"; 80 const char *option = (const char *)__pa_nodebug(__dis_opt_str);
87 const char *option = (const char *)__pa_nodebug(opt);
88 bool *res = (bool *)__pa_nodebug(&dis_ucode_ldr); 81 bool *res = (bool *)__pa_nodebug(&dis_ucode_ldr);
89 82
90#else /* CONFIG_X86_64 */ 83#else /* CONFIG_X86_64 */
91 const char *cmdline = boot_command_line; 84 const char *cmdline = boot_command_line;
92 const char *option = "dis_ucode_ldr"; 85 const char *option = __dis_opt_str;
93 bool *res = &dis_ucode_ldr; 86 bool *res = &dis_ucode_ldr;
94#endif 87#endif
95 88
@@ -479,7 +472,7 @@ static enum ucode_state microcode_init_cpu(int cpu, bool refresh_fw)
479 enum ucode_state ustate; 472 enum ucode_state ustate;
480 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 473 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
481 474
482 if (uci && uci->valid) 475 if (uci->valid)
483 return UCODE_OK; 476 return UCODE_OK;
484 477
485 if (collect_cpu_info(cpu)) 478 if (collect_cpu_info(cpu))
@@ -630,7 +623,7 @@ int __init microcode_init(void)
630 struct cpuinfo_x86 *c = &boot_cpu_data; 623 struct cpuinfo_x86 *c = &boot_cpu_data;
631 int error; 624 int error;
632 625
633 if (paravirt_enabled() || dis_ucode_ldr) 626 if (dis_ucode_ldr)
634 return -EINVAL; 627 return -EINVAL;
635 628
636 if (c->x86_vendor == X86_VENDOR_INTEL) 629 if (c->x86_vendor == X86_VENDOR_INTEL)
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index ee81c544ee0d..cbb3cf09b065 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -39,9 +39,15 @@
39#include <asm/setup.h> 39#include <asm/setup.h>
40#include <asm/msr.h> 40#include <asm/msr.h>
41 41
42static unsigned long mc_saved_in_initrd[MAX_UCODE_COUNT]; 42/*
43 * Temporary microcode blobs pointers storage. We note here the pointers to
44 * microcode blobs we've got from whatever storage (detached initrd, builtin).
45 * Later on, we put those into final storage mc_saved_data.mc_saved.
46 */
47static unsigned long mc_tmp_ptrs[MAX_UCODE_COUNT];
48
43static struct mc_saved_data { 49static struct mc_saved_data {
44 unsigned int mc_saved_count; 50 unsigned int num_saved;
45 struct microcode_intel **mc_saved; 51 struct microcode_intel **mc_saved;
46} mc_saved_data; 52} mc_saved_data;
47 53
@@ -78,53 +84,50 @@ load_microcode_early(struct microcode_intel **saved,
78} 84}
79 85
80static inline void 86static inline void
81copy_initrd_ptrs(struct microcode_intel **mc_saved, unsigned long *initrd, 87copy_ptrs(struct microcode_intel **mc_saved, unsigned long *mc_ptrs,
82 unsigned long off, int num_saved) 88 unsigned long off, int num_saved)
83{ 89{
84 int i; 90 int i;
85 91
86 for (i = 0; i < num_saved; i++) 92 for (i = 0; i < num_saved; i++)
87 mc_saved[i] = (struct microcode_intel *)(initrd[i] + off); 93 mc_saved[i] = (struct microcode_intel *)(mc_ptrs[i] + off);
88} 94}
89 95
90#ifdef CONFIG_X86_32 96#ifdef CONFIG_X86_32
91static void 97static void
92microcode_phys(struct microcode_intel **mc_saved_tmp, 98microcode_phys(struct microcode_intel **mc_saved_tmp, struct mc_saved_data *mcs)
93 struct mc_saved_data *mc_saved_data)
94{ 99{
95 int i; 100 int i;
96 struct microcode_intel ***mc_saved; 101 struct microcode_intel ***mc_saved;
97 102
98 mc_saved = (struct microcode_intel ***) 103 mc_saved = (struct microcode_intel ***)__pa_nodebug(&mcs->mc_saved);
99 __pa_nodebug(&mc_saved_data->mc_saved); 104
100 for (i = 0; i < mc_saved_data->mc_saved_count; i++) { 105 for (i = 0; i < mcs->num_saved; i++) {
101 struct microcode_intel *p; 106 struct microcode_intel *p;
102 107
103 p = *(struct microcode_intel **) 108 p = *(struct microcode_intel **)__pa_nodebug(mcs->mc_saved + i);
104 __pa_nodebug(mc_saved_data->mc_saved + i);
105 mc_saved_tmp[i] = (struct microcode_intel *)__pa_nodebug(p); 109 mc_saved_tmp[i] = (struct microcode_intel *)__pa_nodebug(p);
106 } 110 }
107} 111}
108#endif 112#endif
109 113
110static enum ucode_state 114static enum ucode_state
111load_microcode(struct mc_saved_data *mc_saved_data, unsigned long *initrd, 115load_microcode(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
112 unsigned long initrd_start, struct ucode_cpu_info *uci) 116 unsigned long offset, struct ucode_cpu_info *uci)
113{ 117{
114 struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT]; 118 struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
115 unsigned int count = mc_saved_data->mc_saved_count; 119 unsigned int count = mcs->num_saved;
116 120
117 if (!mc_saved_data->mc_saved) { 121 if (!mcs->mc_saved) {
118 copy_initrd_ptrs(mc_saved_tmp, initrd, initrd_start, count); 122 copy_ptrs(mc_saved_tmp, mc_ptrs, offset, count);
119 123
120 return load_microcode_early(mc_saved_tmp, count, uci); 124 return load_microcode_early(mc_saved_tmp, count, uci);
121 } else { 125 } else {
122#ifdef CONFIG_X86_32 126#ifdef CONFIG_X86_32
123 microcode_phys(mc_saved_tmp, mc_saved_data); 127 microcode_phys(mc_saved_tmp, mcs);
124 return load_microcode_early(mc_saved_tmp, count, uci); 128 return load_microcode_early(mc_saved_tmp, count, uci);
125#else 129#else
126 return load_microcode_early(mc_saved_data->mc_saved, 130 return load_microcode_early(mcs->mc_saved, count, uci);
127 count, uci);
128#endif 131#endif
129 } 132 }
130} 133}
@@ -175,25 +178,25 @@ matching_model_microcode(struct microcode_header_intel *mc_header,
175} 178}
176 179
177static int 180static int
178save_microcode(struct mc_saved_data *mc_saved_data, 181save_microcode(struct mc_saved_data *mcs,
179 struct microcode_intel **mc_saved_src, 182 struct microcode_intel **mc_saved_src,
180 unsigned int mc_saved_count) 183 unsigned int num_saved)
181{ 184{
182 int i, j; 185 int i, j;
183 struct microcode_intel **saved_ptr; 186 struct microcode_intel **saved_ptr;
184 int ret; 187 int ret;
185 188
186 if (!mc_saved_count) 189 if (!num_saved)
187 return -EINVAL; 190 return -EINVAL;
188 191
189 /* 192 /*
190 * Copy new microcode data. 193 * Copy new microcode data.
191 */ 194 */
192 saved_ptr = kcalloc(mc_saved_count, sizeof(struct microcode_intel *), GFP_KERNEL); 195 saved_ptr = kcalloc(num_saved, sizeof(struct microcode_intel *), GFP_KERNEL);
193 if (!saved_ptr) 196 if (!saved_ptr)
194 return -ENOMEM; 197 return -ENOMEM;
195 198
196 for (i = 0; i < mc_saved_count; i++) { 199 for (i = 0; i < num_saved; i++) {
197 struct microcode_header_intel *mc_hdr; 200 struct microcode_header_intel *mc_hdr;
198 struct microcode_intel *mc; 201 struct microcode_intel *mc;
199 unsigned long size; 202 unsigned long size;
@@ -207,20 +210,18 @@ save_microcode(struct mc_saved_data *mc_saved_data,
207 mc_hdr = &mc->hdr; 210 mc_hdr = &mc->hdr;
208 size = get_totalsize(mc_hdr); 211 size = get_totalsize(mc_hdr);
209 212
210 saved_ptr[i] = kmalloc(size, GFP_KERNEL); 213 saved_ptr[i] = kmemdup(mc, size, GFP_KERNEL);
211 if (!saved_ptr[i]) { 214 if (!saved_ptr[i]) {
212 ret = -ENOMEM; 215 ret = -ENOMEM;
213 goto err; 216 goto err;
214 } 217 }
215
216 memcpy(saved_ptr[i], mc, size);
217 } 218 }
218 219
219 /* 220 /*
220 * Point to newly saved microcode. 221 * Point to newly saved microcode.
221 */ 222 */
222 mc_saved_data->mc_saved = saved_ptr; 223 mcs->mc_saved = saved_ptr;
223 mc_saved_data->mc_saved_count = mc_saved_count; 224 mcs->num_saved = num_saved;
224 225
225 return 0; 226 return 0;
226 227
@@ -284,22 +285,20 @@ static unsigned int _save_mc(struct microcode_intel **mc_saved,
284 * BSP can stay in the platform. 285 * BSP can stay in the platform.
285 */ 286 */
286static enum ucode_state __init 287static enum ucode_state __init
287get_matching_model_microcode(int cpu, unsigned long start, 288get_matching_model_microcode(unsigned long start, void *data, size_t size,
288 void *data, size_t size, 289 struct mc_saved_data *mcs, unsigned long *mc_ptrs,
289 struct mc_saved_data *mc_saved_data,
290 unsigned long *mc_saved_in_initrd,
291 struct ucode_cpu_info *uci) 290 struct ucode_cpu_info *uci)
292{ 291{
293 u8 *ucode_ptr = data; 292 struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
294 unsigned int leftover = size; 293 struct microcode_header_intel *mc_header;
294 unsigned int num_saved = mcs->num_saved;
295 enum ucode_state state = UCODE_OK; 295 enum ucode_state state = UCODE_OK;
296 unsigned int leftover = size;
297 u8 *ucode_ptr = data;
296 unsigned int mc_size; 298 unsigned int mc_size;
297 struct microcode_header_intel *mc_header;
298 struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
299 unsigned int mc_saved_count = mc_saved_data->mc_saved_count;
300 int i; 299 int i;
301 300
302 while (leftover && mc_saved_count < ARRAY_SIZE(mc_saved_tmp)) { 301 while (leftover && num_saved < ARRAY_SIZE(mc_saved_tmp)) {
303 302
304 if (leftover < sizeof(mc_header)) 303 if (leftover < sizeof(mc_header))
305 break; 304 break;
@@ -318,32 +317,31 @@ get_matching_model_microcode(int cpu, unsigned long start,
318 * the platform, we need to find and save microcode patches 317 * the platform, we need to find and save microcode patches
319 * with the same family and model as the BSP. 318 * with the same family and model as the BSP.
320 */ 319 */
321 if (matching_model_microcode(mc_header, uci->cpu_sig.sig) != 320 if (matching_model_microcode(mc_header, uci->cpu_sig.sig) != UCODE_OK) {
322 UCODE_OK) {
323 ucode_ptr += mc_size; 321 ucode_ptr += mc_size;
324 continue; 322 continue;
325 } 323 }
326 324
327 mc_saved_count = _save_mc(mc_saved_tmp, ucode_ptr, mc_saved_count); 325 num_saved = _save_mc(mc_saved_tmp, ucode_ptr, num_saved);
328 326
329 ucode_ptr += mc_size; 327 ucode_ptr += mc_size;
330 } 328 }
331 329
332 if (leftover) { 330 if (leftover) {
333 state = UCODE_ERROR; 331 state = UCODE_ERROR;
334 goto out; 332 return state;
335 } 333 }
336 334
337 if (mc_saved_count == 0) { 335 if (!num_saved) {
338 state = UCODE_NFOUND; 336 state = UCODE_NFOUND;
339 goto out; 337 return state;
340 } 338 }
341 339
342 for (i = 0; i < mc_saved_count; i++) 340 for (i = 0; i < num_saved; i++)
343 mc_saved_in_initrd[i] = (unsigned long)mc_saved_tmp[i] - start; 341 mc_ptrs[i] = (unsigned long)mc_saved_tmp[i] - start;
342
343 mcs->num_saved = num_saved;
344 344
345 mc_saved_data->mc_saved_count = mc_saved_count;
346out:
347 return state; 345 return state;
348} 346}
349 347
@@ -373,7 +371,7 @@ static int collect_cpu_info_early(struct ucode_cpu_info *uci)
373 native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); 371 native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
374 csig.pf = 1 << ((val[1] >> 18) & 7); 372 csig.pf = 1 << ((val[1] >> 18) & 7);
375 } 373 }
376 native_wrmsr(MSR_IA32_UCODE_REV, 0, 0); 374 native_wrmsrl(MSR_IA32_UCODE_REV, 0);
377 375
378 /* As documented in the SDM: Do a CPUID 1 here */ 376 /* As documented in the SDM: Do a CPUID 1 here */
379 sync_core(); 377 sync_core();
@@ -396,11 +394,11 @@ static void show_saved_mc(void)
396 unsigned int sig, pf, rev, total_size, data_size, date; 394 unsigned int sig, pf, rev, total_size, data_size, date;
397 struct ucode_cpu_info uci; 395 struct ucode_cpu_info uci;
398 396
399 if (mc_saved_data.mc_saved_count == 0) { 397 if (!mc_saved_data.num_saved) {
400 pr_debug("no microcode data saved.\n"); 398 pr_debug("no microcode data saved.\n");
401 return; 399 return;
402 } 400 }
403 pr_debug("Total microcode saved: %d\n", mc_saved_data.mc_saved_count); 401 pr_debug("Total microcode saved: %d\n", mc_saved_data.num_saved);
404 402
405 collect_cpu_info_early(&uci); 403 collect_cpu_info_early(&uci);
406 404
@@ -409,7 +407,7 @@ static void show_saved_mc(void)
409 rev = uci.cpu_sig.rev; 407 rev = uci.cpu_sig.rev;
410 pr_debug("CPU: sig=0x%x, pf=0x%x, rev=0x%x\n", sig, pf, rev); 408 pr_debug("CPU: sig=0x%x, pf=0x%x, rev=0x%x\n", sig, pf, rev);
411 409
412 for (i = 0; i < mc_saved_data.mc_saved_count; i++) { 410 for (i = 0; i < mc_saved_data.num_saved; i++) {
413 struct microcode_header_intel *mc_saved_header; 411 struct microcode_header_intel *mc_saved_header;
414 struct extended_sigtable *ext_header; 412 struct extended_sigtable *ext_header;
415 int ext_sigcount; 413 int ext_sigcount;
@@ -465,7 +463,7 @@ int save_mc_for_early(u8 *mc)
465{ 463{
466 struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT]; 464 struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
467 unsigned int mc_saved_count_init; 465 unsigned int mc_saved_count_init;
468 unsigned int mc_saved_count; 466 unsigned int num_saved;
469 struct microcode_intel **mc_saved; 467 struct microcode_intel **mc_saved;
470 int ret = 0; 468 int ret = 0;
471 int i; 469 int i;
@@ -476,23 +474,23 @@ int save_mc_for_early(u8 *mc)
476 */ 474 */
477 mutex_lock(&x86_cpu_microcode_mutex); 475 mutex_lock(&x86_cpu_microcode_mutex);
478 476
479 mc_saved_count_init = mc_saved_data.mc_saved_count; 477 mc_saved_count_init = mc_saved_data.num_saved;
480 mc_saved_count = mc_saved_data.mc_saved_count; 478 num_saved = mc_saved_data.num_saved;
481 mc_saved = mc_saved_data.mc_saved; 479 mc_saved = mc_saved_data.mc_saved;
482 480
483 if (mc_saved && mc_saved_count) 481 if (mc_saved && num_saved)
484 memcpy(mc_saved_tmp, mc_saved, 482 memcpy(mc_saved_tmp, mc_saved,
485 mc_saved_count * sizeof(struct microcode_intel *)); 483 num_saved * sizeof(struct microcode_intel *));
486 /* 484 /*
487 * Save the microcode patch mc in mc_save_tmp structure if it's a newer 485 * Save the microcode patch mc in mc_save_tmp structure if it's a newer
488 * version. 486 * version.
489 */ 487 */
490 mc_saved_count = _save_mc(mc_saved_tmp, mc, mc_saved_count); 488 num_saved = _save_mc(mc_saved_tmp, mc, num_saved);
491 489
492 /* 490 /*
493 * Save the mc_save_tmp in global mc_saved_data. 491 * Save the mc_save_tmp in global mc_saved_data.
494 */ 492 */
495 ret = save_microcode(&mc_saved_data, mc_saved_tmp, mc_saved_count); 493 ret = save_microcode(&mc_saved_data, mc_saved_tmp, num_saved);
496 if (ret) { 494 if (ret) {
497 pr_err("Cannot save microcode patch.\n"); 495 pr_err("Cannot save microcode patch.\n");
498 goto out; 496 goto out;
@@ -536,7 +534,7 @@ static bool __init load_builtin_intel_microcode(struct cpio_data *cp)
536 534
537static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin"; 535static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin";
538static __init enum ucode_state 536static __init enum ucode_state
539scan_microcode(struct mc_saved_data *mc_saved_data, unsigned long *initrd, 537scan_microcode(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
540 unsigned long start, unsigned long size, 538 unsigned long start, unsigned long size,
541 struct ucode_cpu_info *uci) 539 struct ucode_cpu_info *uci)
542{ 540{
@@ -551,14 +549,18 @@ scan_microcode(struct mc_saved_data *mc_saved_data, unsigned long *initrd,
551 cd.data = NULL; 549 cd.data = NULL;
552 cd.size = 0; 550 cd.size = 0;
553 551
554 cd = find_cpio_data(p, (void *)start, size, &offset); 552 /* try built-in microcode if no initrd */
555 if (!cd.data) { 553 if (!size) {
556 if (!load_builtin_intel_microcode(&cd)) 554 if (!load_builtin_intel_microcode(&cd))
557 return UCODE_ERROR; 555 return UCODE_ERROR;
556 } else {
557 cd = find_cpio_data(p, (void *)start, size, &offset);
558 if (!cd.data)
559 return UCODE_ERROR;
558 } 560 }
559 561
560 return get_matching_model_microcode(0, start, cd.data, cd.size, 562 return get_matching_model_microcode(start, cd.data, cd.size,
561 mc_saved_data, initrd, uci); 563 mcs, mc_ptrs, uci);
562} 564}
563 565
564/* 566/*
@@ -567,14 +569,11 @@ scan_microcode(struct mc_saved_data *mc_saved_data, unsigned long *initrd,
567static void 569static void
568print_ucode_info(struct ucode_cpu_info *uci, unsigned int date) 570print_ucode_info(struct ucode_cpu_info *uci, unsigned int date)
569{ 571{
570 int cpu = smp_processor_id(); 572 pr_info_once("microcode updated early to revision 0x%x, date = %04x-%02x-%02x\n",
571 573 uci->cpu_sig.rev,
572 pr_info("CPU%d microcode updated early to revision 0x%x, date = %04x-%02x-%02x\n", 574 date & 0xffff,
573 cpu, 575 date >> 24,
574 uci->cpu_sig.rev, 576 (date >> 16) & 0xff);
575 date & 0xffff,
576 date >> 24,
577 (date >> 16) & 0xff);
578} 577}
579 578
580#ifdef CONFIG_X86_32 579#ifdef CONFIG_X86_32
@@ -603,19 +602,19 @@ void show_ucode_info_early(void)
603 */ 602 */
604static void print_ucode(struct ucode_cpu_info *uci) 603static void print_ucode(struct ucode_cpu_info *uci)
605{ 604{
606 struct microcode_intel *mc_intel; 605 struct microcode_intel *mc;
607 int *delay_ucode_info_p; 606 int *delay_ucode_info_p;
608 int *current_mc_date_p; 607 int *current_mc_date_p;
609 608
610 mc_intel = uci->mc; 609 mc = uci->mc;
611 if (mc_intel == NULL) 610 if (!mc)
612 return; 611 return;
613 612
614 delay_ucode_info_p = (int *)__pa_nodebug(&delay_ucode_info); 613 delay_ucode_info_p = (int *)__pa_nodebug(&delay_ucode_info);
615 current_mc_date_p = (int *)__pa_nodebug(&current_mc_date); 614 current_mc_date_p = (int *)__pa_nodebug(&current_mc_date);
616 615
617 *delay_ucode_info_p = 1; 616 *delay_ucode_info_p = 1;
618 *current_mc_date_p = mc_intel->hdr.date; 617 *current_mc_date_p = mc->hdr.date;
619} 618}
620#else 619#else
621 620
@@ -630,37 +629,35 @@ static inline void flush_tlb_early(void)
630 629
631static inline void print_ucode(struct ucode_cpu_info *uci) 630static inline void print_ucode(struct ucode_cpu_info *uci)
632{ 631{
633 struct microcode_intel *mc_intel; 632 struct microcode_intel *mc;
634 633
635 mc_intel = uci->mc; 634 mc = uci->mc;
636 if (mc_intel == NULL) 635 if (!mc)
637 return; 636 return;
638 637
639 print_ucode_info(uci, mc_intel->hdr.date); 638 print_ucode_info(uci, mc->hdr.date);
640} 639}
641#endif 640#endif
642 641
643static int apply_microcode_early(struct ucode_cpu_info *uci, bool early) 642static int apply_microcode_early(struct ucode_cpu_info *uci, bool early)
644{ 643{
645 struct microcode_intel *mc_intel; 644 struct microcode_intel *mc;
646 unsigned int val[2]; 645 unsigned int val[2];
647 646
648 mc_intel = uci->mc; 647 mc = uci->mc;
649 if (mc_intel == NULL) 648 if (!mc)
650 return 0; 649 return 0;
651 650
652 /* write microcode via MSR 0x79 */ 651 /* write microcode via MSR 0x79 */
653 native_wrmsr(MSR_IA32_UCODE_WRITE, 652 native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits);
654 (unsigned long) mc_intel->bits, 653 native_wrmsrl(MSR_IA32_UCODE_REV, 0);
655 (unsigned long) mc_intel->bits >> 16 >> 16);
656 native_wrmsr(MSR_IA32_UCODE_REV, 0, 0);
657 654
658 /* As documented in the SDM: Do a CPUID 1 here */ 655 /* As documented in the SDM: Do a CPUID 1 here */
659 sync_core(); 656 sync_core();
660 657
661 /* get the current revision from MSR 0x8B */ 658 /* get the current revision from MSR 0x8B */
662 native_rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); 659 native_rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
663 if (val[1] != mc_intel->hdr.rev) 660 if (val[1] != mc->hdr.rev)
664 return -1; 661 return -1;
665 662
666#ifdef CONFIG_X86_64 663#ifdef CONFIG_X86_64
@@ -672,25 +669,26 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early)
672 if (early) 669 if (early)
673 print_ucode(uci); 670 print_ucode(uci);
674 else 671 else
675 print_ucode_info(uci, mc_intel->hdr.date); 672 print_ucode_info(uci, mc->hdr.date);
676 673
677 return 0; 674 return 0;
678} 675}
679 676
680/* 677/*
681 * This function converts microcode patch offsets previously stored in 678 * This function converts microcode patch offsets previously stored in
682 * mc_saved_in_initrd to pointers and stores the pointers in mc_saved_data. 679 * mc_tmp_ptrs to pointers and stores the pointers in mc_saved_data.
683 */ 680 */
684int __init save_microcode_in_initrd_intel(void) 681int __init save_microcode_in_initrd_intel(void)
685{ 682{
686 unsigned int count = mc_saved_data.mc_saved_count; 683 unsigned int count = mc_saved_data.num_saved;
687 struct microcode_intel *mc_saved[MAX_UCODE_COUNT]; 684 struct microcode_intel *mc_saved[MAX_UCODE_COUNT];
688 int ret = 0; 685 int ret = 0;
689 686
690 if (count == 0) 687 if (!count)
691 return ret; 688 return ret;
692 689
693 copy_initrd_ptrs(mc_saved, mc_saved_in_initrd, initrd_start, count); 690 copy_ptrs(mc_saved, mc_tmp_ptrs, get_initrd_start(), count);
691
694 ret = save_microcode(&mc_saved_data, mc_saved, count); 692 ret = save_microcode(&mc_saved_data, mc_saved, count);
695 if (ret) 693 if (ret)
696 pr_err("Cannot save microcode patches from initrd.\n"); 694 pr_err("Cannot save microcode patches from initrd.\n");
@@ -701,8 +699,7 @@ int __init save_microcode_in_initrd_intel(void)
701} 699}
702 700
703static void __init 701static void __init
704_load_ucode_intel_bsp(struct mc_saved_data *mc_saved_data, 702_load_ucode_intel_bsp(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
705 unsigned long *initrd,
706 unsigned long start, unsigned long size) 703 unsigned long start, unsigned long size)
707{ 704{
708 struct ucode_cpu_info uci; 705 struct ucode_cpu_info uci;
@@ -710,11 +707,11 @@ _load_ucode_intel_bsp(struct mc_saved_data *mc_saved_data,
710 707
711 collect_cpu_info_early(&uci); 708 collect_cpu_info_early(&uci);
712 709
713 ret = scan_microcode(mc_saved_data, initrd, start, size, &uci); 710 ret = scan_microcode(mcs, mc_ptrs, start, size, &uci);
714 if (ret != UCODE_OK) 711 if (ret != UCODE_OK)
715 return; 712 return;
716 713
717 ret = load_microcode(mc_saved_data, initrd, start, &uci); 714 ret = load_microcode(mcs, mc_ptrs, start, &uci);
718 if (ret != UCODE_OK) 715 if (ret != UCODE_OK)
719 return; 716 return;
720 717
@@ -728,53 +725,49 @@ void __init load_ucode_intel_bsp(void)
728 struct boot_params *p; 725 struct boot_params *p;
729 726
730 p = (struct boot_params *)__pa_nodebug(&boot_params); 727 p = (struct boot_params *)__pa_nodebug(&boot_params);
731 start = p->hdr.ramdisk_image;
732 size = p->hdr.ramdisk_size; 728 size = p->hdr.ramdisk_size;
733 729
734 _load_ucode_intel_bsp( 730 /*
735 (struct mc_saved_data *)__pa_nodebug(&mc_saved_data), 731 * Set start only if we have an initrd image. We cannot use initrd_start
736 (unsigned long *)__pa_nodebug(&mc_saved_in_initrd), 732 * because it is not set that early yet.
737 start, size); 733 */
734 start = (size ? p->hdr.ramdisk_image : 0);
735
736 _load_ucode_intel_bsp((struct mc_saved_data *)__pa_nodebug(&mc_saved_data),
737 (unsigned long *)__pa_nodebug(&mc_tmp_ptrs),
738 start, size);
738#else 739#else
739 start = boot_params.hdr.ramdisk_image + PAGE_OFFSET;
740 size = boot_params.hdr.ramdisk_size; 740 size = boot_params.hdr.ramdisk_size;
741 start = (size ? boot_params.hdr.ramdisk_image + PAGE_OFFSET : 0);
741 742
742 _load_ucode_intel_bsp(&mc_saved_data, mc_saved_in_initrd, start, size); 743 _load_ucode_intel_bsp(&mc_saved_data, mc_tmp_ptrs, start, size);
743#endif 744#endif
744} 745}
745 746
746void load_ucode_intel_ap(void) 747void load_ucode_intel_ap(void)
747{ 748{
748 struct mc_saved_data *mc_saved_data_p; 749 unsigned long *mcs_tmp_p;
750 struct mc_saved_data *mcs_p;
749 struct ucode_cpu_info uci; 751 struct ucode_cpu_info uci;
750 unsigned long *mc_saved_in_initrd_p;
751 unsigned long initrd_start_addr;
752 enum ucode_state ret; 752 enum ucode_state ret;
753#ifdef CONFIG_X86_32 753#ifdef CONFIG_X86_32
754 unsigned long *initrd_start_p;
755 754
756 mc_saved_in_initrd_p = 755 mcs_tmp_p = (unsigned long *)__pa_nodebug(mc_tmp_ptrs);
757 (unsigned long *)__pa_nodebug(mc_saved_in_initrd); 756 mcs_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
758 mc_saved_data_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
759 initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start);
760 initrd_start_addr = (unsigned long)__pa_nodebug(*initrd_start_p);
761#else 757#else
762 mc_saved_data_p = &mc_saved_data; 758 mcs_tmp_p = mc_tmp_ptrs;
763 mc_saved_in_initrd_p = mc_saved_in_initrd; 759 mcs_p = &mc_saved_data;
764 initrd_start_addr = initrd_start;
765#endif 760#endif
766 761
767 /* 762 /*
768 * If there is no valid ucode previously saved in memory, no need to 763 * If there is no valid ucode previously saved in memory, no need to
769 * update ucode on this AP. 764 * update ucode on this AP.
770 */ 765 */
771 if (mc_saved_data_p->mc_saved_count == 0) 766 if (!mcs_p->num_saved)
772 return; 767 return;
773 768
774 collect_cpu_info_early(&uci); 769 collect_cpu_info_early(&uci);
775 ret = load_microcode(mc_saved_data_p, mc_saved_in_initrd_p, 770 ret = load_microcode(mcs_p, mcs_tmp_p, get_initrd_start_addr(), &uci);
776 initrd_start_addr, &uci);
777
778 if (ret != UCODE_OK) 771 if (ret != UCODE_OK)
779 return; 772 return;
780 773
@@ -786,13 +779,13 @@ void reload_ucode_intel(void)
786 struct ucode_cpu_info uci; 779 struct ucode_cpu_info uci;
787 enum ucode_state ret; 780 enum ucode_state ret;
788 781
789 if (!mc_saved_data.mc_saved_count) 782 if (!mc_saved_data.num_saved)
790 return; 783 return;
791 784
792 collect_cpu_info_early(&uci); 785 collect_cpu_info_early(&uci);
793 786
794 ret = load_microcode_early(mc_saved_data.mc_saved, 787 ret = load_microcode_early(mc_saved_data.mc_saved,
795 mc_saved_data.mc_saved_count, &uci); 788 mc_saved_data.num_saved, &uci);
796 if (ret != UCODE_OK) 789 if (ret != UCODE_OK)
797 return; 790 return;
798 791
@@ -825,7 +818,7 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
825 * return 0 - no update found 818 * return 0 - no update found
826 * return 1 - found update 819 * return 1 - found update
827 */ 820 */
828static int get_matching_mc(struct microcode_intel *mc_intel, int cpu) 821static int get_matching_mc(struct microcode_intel *mc, int cpu)
829{ 822{
830 struct cpu_signature cpu_sig; 823 struct cpu_signature cpu_sig;
831 unsigned int csig, cpf, crev; 824 unsigned int csig, cpf, crev;
@@ -836,39 +829,36 @@ static int get_matching_mc(struct microcode_intel *mc_intel, int cpu)
836 cpf = cpu_sig.pf; 829 cpf = cpu_sig.pf;
837 crev = cpu_sig.rev; 830 crev = cpu_sig.rev;
838 831
839 return has_newer_microcode(mc_intel, csig, cpf, crev); 832 return has_newer_microcode(mc, csig, cpf, crev);
840} 833}
841 834
842static int apply_microcode_intel(int cpu) 835static int apply_microcode_intel(int cpu)
843{ 836{
844 struct microcode_intel *mc_intel; 837 struct microcode_intel *mc;
845 struct ucode_cpu_info *uci; 838 struct ucode_cpu_info *uci;
839 struct cpuinfo_x86 *c;
846 unsigned int val[2]; 840 unsigned int val[2];
847 int cpu_num = raw_smp_processor_id();
848 struct cpuinfo_x86 *c = &cpu_data(cpu_num);
849
850 uci = ucode_cpu_info + cpu;
851 mc_intel = uci->mc;
852 841
853 /* We should bind the task to the CPU */ 842 /* We should bind the task to the CPU */
854 BUG_ON(cpu_num != cpu); 843 if (WARN_ON(raw_smp_processor_id() != cpu))
844 return -1;
855 845
856 if (mc_intel == NULL) 846 uci = ucode_cpu_info + cpu;
847 mc = uci->mc;
848 if (!mc)
857 return 0; 849 return 0;
858 850
859 /* 851 /*
860 * Microcode on this CPU could be updated earlier. Only apply the 852 * Microcode on this CPU could be updated earlier. Only apply the
861 * microcode patch in mc_intel when it is newer than the one on this 853 * microcode patch in mc when it is newer than the one on this
862 * CPU. 854 * CPU.
863 */ 855 */
864 if (get_matching_mc(mc_intel, cpu) == 0) 856 if (!get_matching_mc(mc, cpu))
865 return 0; 857 return 0;
866 858
867 /* write microcode via MSR 0x79 */ 859 /* write microcode via MSR 0x79 */
868 wrmsr(MSR_IA32_UCODE_WRITE, 860 wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits);
869 (unsigned long) mc_intel->bits, 861 wrmsrl(MSR_IA32_UCODE_REV, 0);
870 (unsigned long) mc_intel->bits >> 16 >> 16);
871 wrmsr(MSR_IA32_UCODE_REV, 0, 0);
872 862
873 /* As documented in the SDM: Do a CPUID 1 here */ 863 /* As documented in the SDM: Do a CPUID 1 here */
874 sync_core(); 864 sync_core();
@@ -876,16 +866,19 @@ static int apply_microcode_intel(int cpu)
876 /* get the current revision from MSR 0x8B */ 866 /* get the current revision from MSR 0x8B */
877 rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); 867 rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
878 868
879 if (val[1] != mc_intel->hdr.rev) { 869 if (val[1] != mc->hdr.rev) {
880 pr_err("CPU%d update to revision 0x%x failed\n", 870 pr_err("CPU%d update to revision 0x%x failed\n",
881 cpu_num, mc_intel->hdr.rev); 871 cpu, mc->hdr.rev);
882 return -1; 872 return -1;
883 } 873 }
874
884 pr_info("CPU%d updated to revision 0x%x, date = %04x-%02x-%02x\n", 875 pr_info("CPU%d updated to revision 0x%x, date = %04x-%02x-%02x\n",
885 cpu_num, val[1], 876 cpu, val[1],
886 mc_intel->hdr.date & 0xffff, 877 mc->hdr.date & 0xffff,
887 mc_intel->hdr.date >> 24, 878 mc->hdr.date >> 24,
888 (mc_intel->hdr.date >> 16) & 0xff); 879 (mc->hdr.date >> 16) & 0xff);
880
881 c = &cpu_data(cpu);
889 882
890 uci->cpu_sig.rev = val[1]; 883 uci->cpu_sig.rev = val[1];
891 c->microcode = val[1]; 884 c->microcode = val[1];
diff --git a/arch/x86/kernel/cpu/microcode/intel_lib.c b/arch/x86/kernel/cpu/microcode/intel_lib.c
index b96896bcbdaf..2ce1a7dc45b7 100644
--- a/arch/x86/kernel/cpu/microcode/intel_lib.c
+++ b/arch/x86/kernel/cpu/microcode/intel_lib.c
@@ -49,7 +49,7 @@ int microcode_sanity_check(void *mc, int print_err)
49 unsigned long total_size, data_size, ext_table_size; 49 unsigned long total_size, data_size, ext_table_size;
50 struct microcode_header_intel *mc_header = mc; 50 struct microcode_header_intel *mc_header = mc;
51 struct extended_sigtable *ext_header = NULL; 51 struct extended_sigtable *ext_header = NULL;
52 int sum, orig_sum, ext_sigcount = 0, i; 52 u32 sum, orig_sum, ext_sigcount = 0, i;
53 struct extended_signature *ext_sig; 53 struct extended_signature *ext_sig;
54 54
55 total_size = get_totalsize(mc_header); 55 total_size = get_totalsize(mc_header);
@@ -57,69 +57,85 @@ int microcode_sanity_check(void *mc, int print_err)
57 57
58 if (data_size + MC_HEADER_SIZE > total_size) { 58 if (data_size + MC_HEADER_SIZE > total_size) {
59 if (print_err) 59 if (print_err)
60 pr_err("error! Bad data size in microcode data file\n"); 60 pr_err("Error: bad microcode data file size.\n");
61 return -EINVAL; 61 return -EINVAL;
62 } 62 }
63 63
64 if (mc_header->ldrver != 1 || mc_header->hdrver != 1) { 64 if (mc_header->ldrver != 1 || mc_header->hdrver != 1) {
65 if (print_err) 65 if (print_err)
66 pr_err("error! Unknown microcode update format\n"); 66 pr_err("Error: invalid/unknown microcode update format.\n");
67 return -EINVAL; 67 return -EINVAL;
68 } 68 }
69
69 ext_table_size = total_size - (MC_HEADER_SIZE + data_size); 70 ext_table_size = total_size - (MC_HEADER_SIZE + data_size);
70 if (ext_table_size) { 71 if (ext_table_size) {
72 u32 ext_table_sum = 0;
73 u32 *ext_tablep;
74
71 if ((ext_table_size < EXT_HEADER_SIZE) 75 if ((ext_table_size < EXT_HEADER_SIZE)
72 || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) { 76 || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) {
73 if (print_err) 77 if (print_err)
74 pr_err("error! Small exttable size in microcode data file\n"); 78 pr_err("Error: truncated extended signature table.\n");
75 return -EINVAL; 79 return -EINVAL;
76 } 80 }
81
77 ext_header = mc + MC_HEADER_SIZE + data_size; 82 ext_header = mc + MC_HEADER_SIZE + data_size;
78 if (ext_table_size != exttable_size(ext_header)) { 83 if (ext_table_size != exttable_size(ext_header)) {
79 if (print_err) 84 if (print_err)
80 pr_err("error! Bad exttable size in microcode data file\n"); 85 pr_err("Error: extended signature table size mismatch.\n");
81 return -EFAULT; 86 return -EFAULT;
82 } 87 }
88
83 ext_sigcount = ext_header->count; 89 ext_sigcount = ext_header->count;
84 }
85 90
86 /* check extended table checksum */ 91 /*
87 if (ext_table_size) { 92 * Check extended table checksum: the sum of all dwords that
88 int ext_table_sum = 0; 93 * comprise a valid table must be 0.
89 int *ext_tablep = (int *)ext_header; 94 */
95 ext_tablep = (u32 *)ext_header;
90 96
91 i = ext_table_size / DWSIZE; 97 i = ext_table_size / sizeof(u32);
92 while (i--) 98 while (i--)
93 ext_table_sum += ext_tablep[i]; 99 ext_table_sum += ext_tablep[i];
100
94 if (ext_table_sum) { 101 if (ext_table_sum) {
95 if (print_err) 102 if (print_err)
96 pr_warn("aborting, bad extended signature table checksum\n"); 103 pr_warn("Bad extended signature table checksum, aborting.\n");
97 return -EINVAL; 104 return -EINVAL;
98 } 105 }
99 } 106 }
100 107
101 /* calculate the checksum */ 108 /*
109 * Calculate the checksum of update data and header. The checksum of
110 * valid update data and header including the extended signature table
111 * must be 0.
112 */
102 orig_sum = 0; 113 orig_sum = 0;
103 i = (MC_HEADER_SIZE + data_size) / DWSIZE; 114 i = (MC_HEADER_SIZE + data_size) / sizeof(u32);
104 while (i--) 115 while (i--)
105 orig_sum += ((int *)mc)[i]; 116 orig_sum += ((u32 *)mc)[i];
117
106 if (orig_sum) { 118 if (orig_sum) {
107 if (print_err) 119 if (print_err)
108 pr_err("aborting, bad checksum\n"); 120 pr_err("Bad microcode data checksum, aborting.\n");
109 return -EINVAL; 121 return -EINVAL;
110 } 122 }
123
111 if (!ext_table_size) 124 if (!ext_table_size)
112 return 0; 125 return 0;
113 /* check extended signature checksum */ 126
127 /*
128 * Check extended signature checksum: 0 => valid.
129 */
114 for (i = 0; i < ext_sigcount; i++) { 130 for (i = 0; i < ext_sigcount; i++) {
115 ext_sig = (void *)ext_header + EXT_HEADER_SIZE + 131 ext_sig = (void *)ext_header + EXT_HEADER_SIZE +
116 EXT_SIGNATURE_SIZE * i; 132 EXT_SIGNATURE_SIZE * i;
117 sum = orig_sum 133
118 - (mc_header->sig + mc_header->pf + mc_header->cksum) 134 sum = (mc_header->sig + mc_header->pf + mc_header->cksum) -
119 + (ext_sig->sig + ext_sig->pf + ext_sig->cksum); 135 (ext_sig->sig + ext_sig->pf + ext_sig->cksum);
120 if (sum) { 136 if (sum) {
121 if (print_err) 137 if (print_err)
122 pr_err("aborting, bad checksum\n"); 138 pr_err("Bad extended signature checksum, aborting.\n");
123 return -EINVAL; 139 return -EINVAL;
124 } 140 }
125 } 141 }