aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-13 16:25:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-13 16:25:33 -0400
commit0ad5c6b3c2d1183740d225944059b0fdedb2afba (patch)
tree39ddc26c06ada9c039e6d90a071aea4af84a4b02
parent421ec9017f3a1f3f032d894c55c15870f3d474aa (diff)
parent46423ffaf45c2494626841238d8bf75123a28caa (diff)
Merge branch 'x86-microcode-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 microcode changes from Ingo Molnar: "Microcode driver updates: mostly cleanups but also some fixes (Borislav Petkov)" * 'x86-microcode-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/microcode/amd: Drop the pci_ids.h dependency x86/microcode/intel: Fix printing of microcode blobs in show_saved_mc() x86/microcode/intel: Check scan_microcode()'s retval x86/microcode/intel: Sanitize microcode_pointer() x86/microcode/intel: Move mc arg last in get_matching_{microcode|sig} x86/microcode/intel: Simplify generic_load_microcode_early() x86/microcode: Consolidate family,model, ... code x86/microcode/intel: Rename update_match_revision() x86/microcode/intel: Sanitize _save_mc() x86/microcode/intel: Make _save_mc() return the updated saved count x86/microcode/intel: Simplify load_ucode_intel_bsp() x86/microcode/intel: Get rid of last arg to load_ucode_intel_bsp() x86/microcode/intel: Do the mc_saved_src NULL check first x86/microcode/intel: Check if microcode was found before applying x86/microcode/intel: Fix out of bounds memory access to the extended header
-rw-r--r--arch/x86/include/asm/microcode.h73
-rw-r--r--arch/x86/include/asm/microcode_intel.h13
-rw-r--r--arch/x86/kernel/cpu/microcode/amd.c1
-rw-r--r--arch/x86/kernel/cpu/microcode/core_early.c75
-rw-r--r--arch/x86/kernel/cpu/microcode/intel.c4
-rw-r--r--arch/x86/kernel/cpu/microcode/intel_early.c345
-rw-r--r--arch/x86/kernel/cpu/microcode/intel_lib.c22
7 files changed, 259 insertions, 274 deletions
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index 201b520521ed..2fb20d6f7e23 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -75,6 +75,79 @@ static inline void __exit exit_amd_microcode(void) {}
75 75
76#ifdef CONFIG_MICROCODE_EARLY 76#ifdef CONFIG_MICROCODE_EARLY
77#define MAX_UCODE_COUNT 128 77#define MAX_UCODE_COUNT 128
78
79#define QCHAR(a, b, c, d) ((a) + ((b) << 8) + ((c) << 16) + ((d) << 24))
80#define CPUID_INTEL1 QCHAR('G', 'e', 'n', 'u')
81#define CPUID_INTEL2 QCHAR('i', 'n', 'e', 'I')
82#define CPUID_INTEL3 QCHAR('n', 't', 'e', 'l')
83#define CPUID_AMD1 QCHAR('A', 'u', 't', 'h')
84#define CPUID_AMD2 QCHAR('e', 'n', 't', 'i')
85#define CPUID_AMD3 QCHAR('c', 'A', 'M', 'D')
86
87#define CPUID_IS(a, b, c, ebx, ecx, edx) \
88 (!((ebx ^ (a))|(edx ^ (b))|(ecx ^ (c))))
89
90/*
91 * In early loading microcode phase on BSP, boot_cpu_data is not set up yet.
92 * x86_vendor() gets vendor id for BSP.
93 *
94 * In 32 bit AP case, accessing boot_cpu_data needs linear address. To simplify
95 * coding, we still use x86_vendor() to get vendor id for AP.
96 *
97 * x86_vendor() gets vendor information directly from CPUID.
98 */
99static inline int x86_vendor(void)
100{
101 u32 eax = 0x00000000;
102 u32 ebx, ecx = 0, edx;
103
104 native_cpuid(&eax, &ebx, &ecx, &edx);
105
106 if (CPUID_IS(CPUID_INTEL1, CPUID_INTEL2, CPUID_INTEL3, ebx, ecx, edx))
107 return X86_VENDOR_INTEL;
108
109 if (CPUID_IS(CPUID_AMD1, CPUID_AMD2, CPUID_AMD3, ebx, ecx, edx))
110 return X86_VENDOR_AMD;
111
112 return X86_VENDOR_UNKNOWN;
113}
114
115static inline unsigned int __x86_family(unsigned int sig)
116{
117 unsigned int x86;
118
119 x86 = (sig >> 8) & 0xf;
120
121 if (x86 == 0xf)
122 x86 += (sig >> 20) & 0xff;
123
124 return x86;
125}
126
127static inline unsigned int x86_family(void)
128{
129 u32 eax = 0x00000001;
130 u32 ebx, ecx = 0, edx;
131
132 native_cpuid(&eax, &ebx, &ecx, &edx);
133
134 return __x86_family(eax);
135}
136
137static inline unsigned int x86_model(unsigned int sig)
138{
139 unsigned int x86, model;
140
141 x86 = __x86_family(sig);
142
143 model = (sig >> 4) & 0xf;
144
145 if (x86 == 0x6 || x86 == 0xf)
146 model += ((sig >> 16) & 0xf) << 4;
147
148 return model;
149}
150
78extern void __init load_ucode_bsp(void); 151extern void __init load_ucode_bsp(void);
79extern void load_ucode_ap(void); 152extern void load_ucode_ap(void);
80extern int __init save_microcode_in_initrd(void); 153extern int __init save_microcode_in_initrd(void);
diff --git a/arch/x86/include/asm/microcode_intel.h b/arch/x86/include/asm/microcode_intel.h
index dd4c20043ce7..2b9209c46ca9 100644
--- a/arch/x86/include/asm/microcode_intel.h
+++ b/arch/x86/include/asm/microcode_intel.h
@@ -56,12 +56,15 @@ struct extended_sigtable {
56 56
57#define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE) 57#define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE)
58 58
59extern int 59extern int get_matching_microcode(unsigned int csig, int cpf, int rev, void *mc);
60get_matching_microcode(unsigned int csig, int cpf, void *mc, int rev);
61extern int microcode_sanity_check(void *mc, int print_err); 60extern int microcode_sanity_check(void *mc, int print_err);
62extern int get_matching_sig(unsigned int csig, int cpf, void *mc, int rev); 61extern int get_matching_sig(unsigned int csig, int cpf, int rev, void *mc);
63extern int 62
64update_match_revision(struct microcode_header_intel *mc_header, int rev); 63static inline int
64revision_is_newer(struct microcode_header_intel *mc_header, int rev)
65{
66 return (mc_header->rev <= rev) ? 0 : 1;
67}
65 68
66#ifdef CONFIG_MICROCODE_INTEL_EARLY 69#ifdef CONFIG_MICROCODE_INTEL_EARLY
67extern void __init load_ucode_intel_bsp(void); 70extern void __init load_ucode_intel_bsp(void);
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index bfbbe6195e2d..12829c3ced3c 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -21,7 +21,6 @@
21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22 22
23#include <linux/firmware.h> 23#include <linux/firmware.h>
24#include <linux/pci_ids.h>
25#include <linux/uaccess.h> 24#include <linux/uaccess.h>
26#include <linux/vmalloc.h> 25#include <linux/vmalloc.h>
27#include <linux/kernel.h> 26#include <linux/kernel.h>
diff --git a/arch/x86/kernel/cpu/microcode/core_early.c b/arch/x86/kernel/cpu/microcode/core_early.c
index d45df4bd16ab..a413a69cbd74 100644
--- a/arch/x86/kernel/cpu/microcode/core_early.c
+++ b/arch/x86/kernel/cpu/microcode/core_early.c
@@ -23,57 +23,6 @@
23#include <asm/processor.h> 23#include <asm/processor.h>
24#include <asm/cmdline.h> 24#include <asm/cmdline.h>
25 25
26#define QCHAR(a, b, c, d) ((a) + ((b) << 8) + ((c) << 16) + ((d) << 24))
27#define CPUID_INTEL1 QCHAR('G', 'e', 'n', 'u')
28#define CPUID_INTEL2 QCHAR('i', 'n', 'e', 'I')
29#define CPUID_INTEL3 QCHAR('n', 't', 'e', 'l')
30#define CPUID_AMD1 QCHAR('A', 'u', 't', 'h')
31#define CPUID_AMD2 QCHAR('e', 'n', 't', 'i')
32#define CPUID_AMD3 QCHAR('c', 'A', 'M', 'D')
33
34#define CPUID_IS(a, b, c, ebx, ecx, edx) \
35 (!((ebx ^ (a))|(edx ^ (b))|(ecx ^ (c))))
36
37/*
38 * In early loading microcode phase on BSP, boot_cpu_data is not set up yet.
39 * x86_vendor() gets vendor id for BSP.
40 *
41 * In 32 bit AP case, accessing boot_cpu_data needs linear address. To simplify
42 * coding, we still use x86_vendor() to get vendor id for AP.
43 *
44 * x86_vendor() gets vendor information directly through cpuid.
45 */
46static int x86_vendor(void)
47{
48 u32 eax = 0x00000000;
49 u32 ebx, ecx = 0, edx;
50
51 native_cpuid(&eax, &ebx, &ecx, &edx);
52
53 if (CPUID_IS(CPUID_INTEL1, CPUID_INTEL2, CPUID_INTEL3, ebx, ecx, edx))
54 return X86_VENDOR_INTEL;
55
56 if (CPUID_IS(CPUID_AMD1, CPUID_AMD2, CPUID_AMD3, ebx, ecx, edx))
57 return X86_VENDOR_AMD;
58
59 return X86_VENDOR_UNKNOWN;
60}
61
62static int x86_family(void)
63{
64 u32 eax = 0x00000001;
65 u32 ebx, ecx = 0, edx;
66 int x86;
67
68 native_cpuid(&eax, &ebx, &ecx, &edx);
69
70 x86 = (eax >> 8) & 0xf;
71 if (x86 == 15)
72 x86 += (eax >> 20) & 0xff;
73
74 return x86;
75}
76
77static bool __init check_loader_disabled_bsp(void) 26static bool __init check_loader_disabled_bsp(void)
78{ 27{
79#ifdef CONFIG_X86_32 28#ifdef CONFIG_X86_32
@@ -96,7 +45,7 @@ static bool __init check_loader_disabled_bsp(void)
96 45
97void __init load_ucode_bsp(void) 46void __init load_ucode_bsp(void)
98{ 47{
99 int vendor, x86; 48 int vendor, family;
100 49
101 if (check_loader_disabled_bsp()) 50 if (check_loader_disabled_bsp())
102 return; 51 return;
@@ -105,15 +54,15 @@ void __init load_ucode_bsp(void)
105 return; 54 return;
106 55
107 vendor = x86_vendor(); 56 vendor = x86_vendor();
108 x86 = x86_family(); 57 family = x86_family();
109 58
110 switch (vendor) { 59 switch (vendor) {
111 case X86_VENDOR_INTEL: 60 case X86_VENDOR_INTEL:
112 if (x86 >= 6) 61 if (family >= 6)
113 load_ucode_intel_bsp(); 62 load_ucode_intel_bsp();
114 break; 63 break;
115 case X86_VENDOR_AMD: 64 case X86_VENDOR_AMD:
116 if (x86 >= 0x10) 65 if (family >= 0x10)
117 load_ucode_amd_bsp(); 66 load_ucode_amd_bsp();
118 break; 67 break;
119 default: 68 default:
@@ -132,7 +81,7 @@ static bool check_loader_disabled_ap(void)
132 81
133void load_ucode_ap(void) 82void load_ucode_ap(void)
134{ 83{
135 int vendor, x86; 84 int vendor, family;
136 85
137 if (check_loader_disabled_ap()) 86 if (check_loader_disabled_ap())
138 return; 87 return;
@@ -141,15 +90,15 @@ void load_ucode_ap(void)
141 return; 90 return;
142 91
143 vendor = x86_vendor(); 92 vendor = x86_vendor();
144 x86 = x86_family(); 93 family = x86_family();
145 94
146 switch (vendor) { 95 switch (vendor) {
147 case X86_VENDOR_INTEL: 96 case X86_VENDOR_INTEL:
148 if (x86 >= 6) 97 if (family >= 6)
149 load_ucode_intel_ap(); 98 load_ucode_intel_ap();
150 break; 99 break;
151 case X86_VENDOR_AMD: 100 case X86_VENDOR_AMD:
152 if (x86 >= 0x10) 101 if (family >= 0x10)
153 load_ucode_amd_ap(); 102 load_ucode_amd_ap();
154 break; 103 break;
155 default: 104 default:
@@ -179,18 +128,18 @@ int __init save_microcode_in_initrd(void)
179 128
180void reload_early_microcode(void) 129void reload_early_microcode(void)
181{ 130{
182 int vendor, x86; 131 int vendor, family;
183 132
184 vendor = x86_vendor(); 133 vendor = x86_vendor();
185 x86 = x86_family(); 134 family = x86_family();
186 135
187 switch (vendor) { 136 switch (vendor) {
188 case X86_VENDOR_INTEL: 137 case X86_VENDOR_INTEL:
189 if (x86 >= 6) 138 if (family >= 6)
190 reload_ucode_intel(); 139 reload_ucode_intel();
191 break; 140 break;
192 case X86_VENDOR_AMD: 141 case X86_VENDOR_AMD:
193 if (x86 >= 0x10) 142 if (family >= 0x10)
194 reload_ucode_amd(); 143 reload_ucode_amd();
195 break; 144 break;
196 default: 145 default:
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 746e7fd08aad..a41beadb3db9 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -124,7 +124,7 @@ static int get_matching_mc(struct microcode_intel *mc_intel, int cpu)
124 cpf = cpu_sig.pf; 124 cpf = cpu_sig.pf;
125 crev = cpu_sig.rev; 125 crev = cpu_sig.rev;
126 126
127 return get_matching_microcode(csig, cpf, mc_intel, crev); 127 return get_matching_microcode(csig, cpf, crev, mc_intel);
128} 128}
129 129
130static int apply_microcode_intel(int cpu) 130static int apply_microcode_intel(int cpu)
@@ -226,7 +226,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
226 226
227 csig = uci->cpu_sig.sig; 227 csig = uci->cpu_sig.sig;
228 cpf = uci->cpu_sig.pf; 228 cpf = uci->cpu_sig.pf;
229 if (get_matching_microcode(csig, cpf, mc, new_rev)) { 229 if (get_matching_microcode(csig, cpf, new_rev, mc)) {
230 vfree(new_mc); 230 vfree(new_mc);
231 new_rev = mc_header.rev; 231 new_rev = mc_header.rev;
232 new_mc = mc; 232 new_mc = mc;
diff --git a/arch/x86/kernel/cpu/microcode/intel_early.c b/arch/x86/kernel/cpu/microcode/intel_early.c
index 420eb933189c..2f49ab4ac0ae 100644
--- a/arch/x86/kernel/cpu/microcode/intel_early.c
+++ b/arch/x86/kernel/cpu/microcode/intel_early.c
@@ -16,6 +16,14 @@
16 * as published by the Free Software Foundation; either version 16 * as published by the Free Software Foundation; either version
17 * 2 of the License, or (at your option) any later version. 17 * 2 of the License, or (at your option) any later version.
18 */ 18 */
19
20/*
21 * This needs to be before all headers so that pr_debug in printk.h doesn't turn
22 * printk calls into no_printk().
23 *
24 *#define DEBUG
25 */
26
19#include <linux/module.h> 27#include <linux/module.h>
20#include <linux/mm.h> 28#include <linux/mm.h>
21#include <linux/slab.h> 29#include <linux/slab.h>
@@ -28,6 +36,9 @@
28#include <asm/tlbflush.h> 36#include <asm/tlbflush.h>
29#include <asm/setup.h> 37#include <asm/setup.h>
30 38
39#undef pr_fmt
40#define pr_fmt(fmt) "microcode: " fmt
41
31static unsigned long mc_saved_in_initrd[MAX_UCODE_COUNT]; 42static unsigned long mc_saved_in_initrd[MAX_UCODE_COUNT];
32static struct mc_saved_data { 43static struct mc_saved_data {
33 unsigned int mc_saved_count; 44 unsigned int mc_saved_count;
@@ -35,50 +46,45 @@ static struct mc_saved_data {
35} mc_saved_data; 46} mc_saved_data;
36 47
37static enum ucode_state 48static enum ucode_state
38generic_load_microcode_early(struct microcode_intel **mc_saved_p, 49load_microcode_early(struct microcode_intel **saved,
39 unsigned int mc_saved_count, 50 unsigned int num_saved, struct ucode_cpu_info *uci)
40 struct ucode_cpu_info *uci)
41{ 51{
42 struct microcode_intel *ucode_ptr, *new_mc = NULL; 52 struct microcode_intel *ucode_ptr, *new_mc = NULL;
43 int new_rev = uci->cpu_sig.rev; 53 struct microcode_header_intel *mc_hdr;
44 enum ucode_state state = UCODE_OK; 54 int new_rev, ret, i;
45 unsigned int mc_size;
46 struct microcode_header_intel *mc_header;
47 unsigned int csig = uci->cpu_sig.sig;
48 unsigned int cpf = uci->cpu_sig.pf;
49 int i;
50 55
51 for (i = 0; i < mc_saved_count; i++) { 56 new_rev = uci->cpu_sig.rev;
52 ucode_ptr = mc_saved_p[i];
53 57
54 mc_header = (struct microcode_header_intel *)ucode_ptr; 58 for (i = 0; i < num_saved; i++) {
55 mc_size = get_totalsize(mc_header); 59 ucode_ptr = saved[i];
56 if (get_matching_microcode(csig, cpf, ucode_ptr, new_rev)) { 60 mc_hdr = (struct microcode_header_intel *)ucode_ptr;
57 new_rev = mc_header->rev;
58 new_mc = ucode_ptr;
59 }
60 }
61 61
62 if (!new_mc) { 62 ret = get_matching_microcode(uci->cpu_sig.sig,
63 state = UCODE_NFOUND; 63 uci->cpu_sig.pf,
64 goto out; 64 new_rev,
65 ucode_ptr);
66 if (!ret)
67 continue;
68
69 new_rev = mc_hdr->rev;
70 new_mc = ucode_ptr;
65 } 71 }
66 72
73 if (!new_mc)
74 return UCODE_NFOUND;
75
67 uci->mc = (struct microcode_intel *)new_mc; 76 uci->mc = (struct microcode_intel *)new_mc;
68out: 77 return UCODE_OK;
69 return state;
70} 78}
71 79
72static void 80static inline void
73microcode_pointer(struct microcode_intel **mc_saved, 81copy_initrd_ptrs(struct microcode_intel **mc_saved, unsigned long *initrd,
74 unsigned long *mc_saved_in_initrd, 82 unsigned long off, int num_saved)
75 unsigned long initrd_start, int mc_saved_count)
76{ 83{
77 int i; 84 int i;
78 85
79 for (i = 0; i < mc_saved_count; i++) 86 for (i = 0; i < num_saved; i++)
80 mc_saved[i] = (struct microcode_intel *) 87 mc_saved[i] = (struct microcode_intel *)(initrd[i] + off);
81 (mc_saved_in_initrd[i] + initrd_start);
82} 88}
83 89
84#ifdef CONFIG_X86_32 90#ifdef CONFIG_X86_32
@@ -102,55 +108,27 @@ microcode_phys(struct microcode_intel **mc_saved_tmp,
102#endif 108#endif
103 109
104static enum ucode_state 110static enum ucode_state
105load_microcode(struct mc_saved_data *mc_saved_data, 111load_microcode(struct mc_saved_data *mc_saved_data, unsigned long *initrd,
106 unsigned long *mc_saved_in_initrd, 112 unsigned long initrd_start, struct ucode_cpu_info *uci)
107 unsigned long initrd_start,
108 struct ucode_cpu_info *uci)
109{ 113{
110 struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT]; 114 struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
111 unsigned int count = mc_saved_data->mc_saved_count; 115 unsigned int count = mc_saved_data->mc_saved_count;
112 116
113 if (!mc_saved_data->mc_saved) { 117 if (!mc_saved_data->mc_saved) {
114 microcode_pointer(mc_saved_tmp, mc_saved_in_initrd, 118 copy_initrd_ptrs(mc_saved_tmp, initrd, initrd_start, count);
115 initrd_start, count);
116 119
117 return generic_load_microcode_early(mc_saved_tmp, count, uci); 120 return load_microcode_early(mc_saved_tmp, count, uci);
118 } else { 121 } else {
119#ifdef CONFIG_X86_32 122#ifdef CONFIG_X86_32
120 microcode_phys(mc_saved_tmp, mc_saved_data); 123 microcode_phys(mc_saved_tmp, mc_saved_data);
121 return generic_load_microcode_early(mc_saved_tmp, count, uci); 124 return load_microcode_early(mc_saved_tmp, count, uci);
122#else 125#else
123 return generic_load_microcode_early(mc_saved_data->mc_saved, 126 return load_microcode_early(mc_saved_data->mc_saved,
124 count, uci); 127 count, uci);
125#endif 128#endif
126 } 129 }
127} 130}
128 131
129static u8 get_x86_family(unsigned long sig)
130{
131 u8 x86;
132
133 x86 = (sig >> 8) & 0xf;
134
135 if (x86 == 0xf)
136 x86 += (sig >> 20) & 0xff;
137
138 return x86;
139}
140
141static u8 get_x86_model(unsigned long sig)
142{
143 u8 x86, x86_model;
144
145 x86 = get_x86_family(sig);
146 x86_model = (sig >> 4) & 0xf;
147
148 if (x86 == 0x6 || x86 == 0xf)
149 x86_model += ((sig >> 16) & 0xf) << 4;
150
151 return x86_model;
152}
153
154/* 132/*
155 * Given CPU signature and a microcode patch, this function finds if the 133 * Given CPU signature and a microcode patch, this function finds if the
156 * microcode patch has matching family and model with the CPU. 134 * microcode patch has matching family and model with the CPU.
@@ -159,42 +137,40 @@ static enum ucode_state
159matching_model_microcode(struct microcode_header_intel *mc_header, 137matching_model_microcode(struct microcode_header_intel *mc_header,
160 unsigned long sig) 138 unsigned long sig)
161{ 139{
162 u8 x86, x86_model; 140 unsigned int fam, model;
163 u8 x86_ucode, x86_model_ucode; 141 unsigned int fam_ucode, model_ucode;
164 struct extended_sigtable *ext_header; 142 struct extended_sigtable *ext_header;
165 unsigned long total_size = get_totalsize(mc_header); 143 unsigned long total_size = get_totalsize(mc_header);
166 unsigned long data_size = get_datasize(mc_header); 144 unsigned long data_size = get_datasize(mc_header);
167 int ext_sigcount, i; 145 int ext_sigcount, i;
168 struct extended_signature *ext_sig; 146 struct extended_signature *ext_sig;
169 147
170 x86 = get_x86_family(sig); 148 fam = __x86_family(sig);
171 x86_model = get_x86_model(sig); 149 model = x86_model(sig);
172 150
173 x86_ucode = get_x86_family(mc_header->sig); 151 fam_ucode = __x86_family(mc_header->sig);
174 x86_model_ucode = get_x86_model(mc_header->sig); 152 model_ucode = x86_model(mc_header->sig);
175 153
176 if (x86 == x86_ucode && x86_model == x86_model_ucode) 154 if (fam == fam_ucode && model == model_ucode)
177 return UCODE_OK; 155 return UCODE_OK;
178 156
179 /* Look for ext. headers: */ 157 /* Look for ext. headers: */
180 if (total_size <= data_size + MC_HEADER_SIZE) 158 if (total_size <= data_size + MC_HEADER_SIZE)
181 return UCODE_NFOUND; 159 return UCODE_NFOUND;
182 160
183 ext_header = (struct extended_sigtable *) 161 ext_header = (void *) mc_header + data_size + MC_HEADER_SIZE;
184 mc_header + data_size + MC_HEADER_SIZE; 162 ext_sig = (void *)ext_header + EXT_HEADER_SIZE;
185 ext_sigcount = ext_header->count; 163 ext_sigcount = ext_header->count;
186 ext_sig = (void *)ext_header + EXT_HEADER_SIZE;
187 164
188 for (i = 0; i < ext_sigcount; i++) { 165 for (i = 0; i < ext_sigcount; i++) {
189 x86_ucode = get_x86_family(ext_sig->sig); 166 fam_ucode = __x86_family(ext_sig->sig);
190 x86_model_ucode = get_x86_model(ext_sig->sig); 167 model_ucode = x86_model(ext_sig->sig);
191 168
192 if (x86 == x86_ucode && x86_model == x86_model_ucode) 169 if (fam == fam_ucode && model == model_ucode)
193 return UCODE_OK; 170 return UCODE_OK;
194 171
195 ext_sig++; 172 ext_sig++;
196 } 173 }
197
198 return UCODE_NFOUND; 174 return UCODE_NFOUND;
199} 175}
200 176
@@ -204,7 +180,7 @@ save_microcode(struct mc_saved_data *mc_saved_data,
204 unsigned int mc_saved_count) 180 unsigned int mc_saved_count)
205{ 181{
206 int i, j; 182 int i, j;
207 struct microcode_intel **mc_saved_p; 183 struct microcode_intel **saved_ptr;
208 int ret; 184 int ret;
209 185
210 if (!mc_saved_count) 186 if (!mc_saved_count)
@@ -213,39 +189,45 @@ save_microcode(struct mc_saved_data *mc_saved_data,
213 /* 189 /*
214 * Copy new microcode data. 190 * Copy new microcode data.
215 */ 191 */
216 mc_saved_p = kmalloc(mc_saved_count*sizeof(struct microcode_intel *), 192 saved_ptr = kcalloc(mc_saved_count, sizeof(struct microcode_intel *), GFP_KERNEL);
217 GFP_KERNEL); 193 if (!saved_ptr)
218 if (!mc_saved_p)
219 return -ENOMEM; 194 return -ENOMEM;
220 195
221 for (i = 0; i < mc_saved_count; i++) { 196 for (i = 0; i < mc_saved_count; i++) {
222 struct microcode_intel *mc = mc_saved_src[i]; 197 struct microcode_header_intel *mc_hdr;
223 struct microcode_header_intel *mc_header = &mc->hdr; 198 struct microcode_intel *mc;
224 unsigned long mc_size = get_totalsize(mc_header); 199 unsigned long size;
225 mc_saved_p[i] = kmalloc(mc_size, GFP_KERNEL); 200
226 if (!mc_saved_p[i]) {
227 ret = -ENOMEM;
228 goto err;
229 }
230 if (!mc_saved_src[i]) { 201 if (!mc_saved_src[i]) {
231 ret = -EINVAL; 202 ret = -EINVAL;
232 goto err; 203 goto err;
233 } 204 }
234 memcpy(mc_saved_p[i], mc, mc_size); 205
206 mc = mc_saved_src[i];
207 mc_hdr = &mc->hdr;
208 size = get_totalsize(mc_hdr);
209
210 saved_ptr[i] = kmalloc(size, GFP_KERNEL);
211 if (!saved_ptr[i]) {
212 ret = -ENOMEM;
213 goto err;
214 }
215
216 memcpy(saved_ptr[i], mc, size);
235 } 217 }
236 218
237 /* 219 /*
238 * Point to newly saved microcode. 220 * Point to newly saved microcode.
239 */ 221 */
240 mc_saved_data->mc_saved = mc_saved_p; 222 mc_saved_data->mc_saved = saved_ptr;
241 mc_saved_data->mc_saved_count = mc_saved_count; 223 mc_saved_data->mc_saved_count = mc_saved_count;
242 224
243 return 0; 225 return 0;
244 226
245err: 227err:
246 for (j = 0; j <= i; j++) 228 for (j = 0; j <= i; j++)
247 kfree(mc_saved_p[j]); 229 kfree(saved_ptr[j]);
248 kfree(mc_saved_p); 230 kfree(saved_ptr);
249 231
250 return ret; 232 return ret;
251} 233}
@@ -257,48 +239,45 @@ err:
257 * - or if it is a newly discovered microcode patch. 239 * - or if it is a newly discovered microcode patch.
258 * 240 *
259 * The microcode patch should have matching model with CPU. 241 * The microcode patch should have matching model with CPU.
242 *
243 * Returns: The updated number @num_saved of saved microcode patches.
260 */ 244 */
261static void _save_mc(struct microcode_intel **mc_saved, u8 *ucode_ptr, 245static unsigned int _save_mc(struct microcode_intel **mc_saved,
262 unsigned int *mc_saved_count_p) 246 u8 *ucode_ptr, unsigned int num_saved)
263{ 247{
264 int i; 248 struct microcode_header_intel *mc_hdr, *mc_saved_hdr;
265 int found = 0; 249 unsigned int sig, pf, new_rev;
266 unsigned int mc_saved_count = *mc_saved_count_p; 250 int found = 0, i;
267 struct microcode_header_intel *mc_header; 251
252 mc_hdr = (struct microcode_header_intel *)ucode_ptr;
253
254 for (i = 0; i < num_saved; i++) {
255 mc_saved_hdr = (struct microcode_header_intel *)mc_saved[i];
256 sig = mc_saved_hdr->sig;
257 pf = mc_saved_hdr->pf;
258 new_rev = mc_hdr->rev;
259
260 if (!get_matching_sig(sig, pf, new_rev, ucode_ptr))
261 continue;
262
263 found = 1;
264
265 if (!revision_is_newer(mc_hdr, new_rev))
266 continue;
268 267
269 mc_header = (struct microcode_header_intel *)ucode_ptr;
270 for (i = 0; i < mc_saved_count; i++) {
271 unsigned int sig, pf;
272 unsigned int new_rev;
273 struct microcode_header_intel *mc_saved_header =
274 (struct microcode_header_intel *)mc_saved[i];
275 sig = mc_saved_header->sig;
276 pf = mc_saved_header->pf;
277 new_rev = mc_header->rev;
278
279 if (get_matching_sig(sig, pf, ucode_ptr, new_rev)) {
280 found = 1;
281 if (update_match_revision(mc_header, new_rev)) {
282 /*
283 * Found an older ucode saved before.
284 * Replace the older one with this newer
285 * one.
286 */
287 mc_saved[i] =
288 (struct microcode_intel *)ucode_ptr;
289 break;
290 }
291 }
292 }
293 if (i >= mc_saved_count && !found)
294 /* 268 /*
295 * This ucode is first time discovered in ucode file. 269 * Found an older ucode saved earlier. Replace it with
296 * Save it to memory. 270 * this newer one.
297 */ 271 */
298 mc_saved[mc_saved_count++] = 272 mc_saved[i] = (struct microcode_intel *)ucode_ptr;
299 (struct microcode_intel *)ucode_ptr; 273 break;
274 }
275
276 /* Newly detected microcode, save it to memory. */
277 if (i >= num_saved && !found)
278 mc_saved[num_saved++] = (struct microcode_intel *)ucode_ptr;
300 279
301 *mc_saved_count_p = mc_saved_count; 280 return num_saved;
302} 281}
303 282
304/* 283/*
@@ -346,7 +325,7 @@ get_matching_model_microcode(int cpu, unsigned long start,
346 continue; 325 continue;
347 } 326 }
348 327
349 _save_mc(mc_saved_tmp, ucode_ptr, &mc_saved_count); 328 mc_saved_count = _save_mc(mc_saved_tmp, ucode_ptr, mc_saved_count);
350 329
351 ucode_ptr += mc_size; 330 ucode_ptr += mc_size;
352 } 331 }
@@ -372,7 +351,7 @@ out:
372static int collect_cpu_info_early(struct ucode_cpu_info *uci) 351static int collect_cpu_info_early(struct ucode_cpu_info *uci)
373{ 352{
374 unsigned int val[2]; 353 unsigned int val[2];
375 u8 x86, x86_model; 354 unsigned int family, model;
376 struct cpu_signature csig; 355 struct cpu_signature csig;
377 unsigned int eax, ebx, ecx, edx; 356 unsigned int eax, ebx, ecx, edx;
378 357
@@ -387,10 +366,10 @@ static int collect_cpu_info_early(struct ucode_cpu_info *uci)
387 native_cpuid(&eax, &ebx, &ecx, &edx); 366 native_cpuid(&eax, &ebx, &ecx, &edx);
388 csig.sig = eax; 367 csig.sig = eax;
389 368
390 x86 = get_x86_family(csig.sig); 369 family = __x86_family(csig.sig);
391 x86_model = get_x86_model(csig.sig); 370 model = x86_model(csig.sig);
392 371
393 if ((x86_model >= 5) || (x86 > 6)) { 372 if ((model >= 5) || (family > 6)) {
394 /* get processor flags from MSR 0x17 */ 373 /* get processor flags from MSR 0x17 */
395 native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); 374 native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
396 csig.pf = 1 << ((val[1] >> 18) & 7); 375 csig.pf = 1 << ((val[1] >> 18) & 7);
@@ -429,8 +408,7 @@ static void __ref show_saved_mc(void)
429 sig = uci.cpu_sig.sig; 408 sig = uci.cpu_sig.sig;
430 pf = uci.cpu_sig.pf; 409 pf = uci.cpu_sig.pf;
431 rev = uci.cpu_sig.rev; 410 rev = uci.cpu_sig.rev;
432 pr_debug("CPU%d: sig=0x%x, pf=0x%x, rev=0x%x\n", 411 pr_debug("CPU: sig=0x%x, pf=0x%x, rev=0x%x\n", sig, pf, rev);
433 smp_processor_id(), sig, pf, rev);
434 412
435 for (i = 0; i < mc_saved_data.mc_saved_count; i++) { 413 for (i = 0; i < mc_saved_data.mc_saved_count; i++) {
436 struct microcode_header_intel *mc_saved_header; 414 struct microcode_header_intel *mc_saved_header;
@@ -457,8 +435,7 @@ static void __ref show_saved_mc(void)
457 if (total_size <= data_size + MC_HEADER_SIZE) 435 if (total_size <= data_size + MC_HEADER_SIZE)
458 continue; 436 continue;
459 437
460 ext_header = (struct extended_sigtable *) 438 ext_header = (void *) mc_saved_header + data_size + MC_HEADER_SIZE;
461 mc_saved_header + data_size + MC_HEADER_SIZE;
462 ext_sigcount = ext_header->count; 439 ext_sigcount = ext_header->count;
463 ext_sig = (void *)ext_header + EXT_HEADER_SIZE; 440 ext_sig = (void *)ext_header + EXT_HEADER_SIZE;
464 441
@@ -515,8 +492,7 @@ int save_mc_for_early(u8 *mc)
515 * Save the microcode patch mc in mc_save_tmp structure if it's a newer 492 * Save the microcode patch mc in mc_save_tmp structure if it's a newer
516 * version. 493 * version.
517 */ 494 */
518 495 mc_saved_count = _save_mc(mc_saved_tmp, mc, mc_saved_count);
519 _save_mc(mc_saved_tmp, mc, &mc_saved_count);
520 496
521 /* 497 /*
522 * Save the mc_save_tmp in global mc_saved_data. 498 * Save the mc_save_tmp in global mc_saved_data.
@@ -548,12 +524,10 @@ EXPORT_SYMBOL_GPL(save_mc_for_early);
548 524
549static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin"; 525static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin";
550static __init enum ucode_state 526static __init enum ucode_state
551scan_microcode(unsigned long start, unsigned long end, 527scan_microcode(struct mc_saved_data *mc_saved_data, unsigned long *initrd,
552 struct mc_saved_data *mc_saved_data, 528 unsigned long start, unsigned long size,
553 unsigned long *mc_saved_in_initrd, 529 struct ucode_cpu_info *uci)
554 struct ucode_cpu_info *uci)
555{ 530{
556 unsigned int size = end - start + 1;
557 struct cpio_data cd; 531 struct cpio_data cd;
558 long offset = 0; 532 long offset = 0;
559#ifdef CONFIG_X86_32 533#ifdef CONFIG_X86_32
@@ -569,10 +543,8 @@ scan_microcode(unsigned long start, unsigned long end,
569 if (!cd.data) 543 if (!cd.data)
570 return UCODE_ERROR; 544 return UCODE_ERROR;
571 545
572
573 return get_matching_model_microcode(0, start, cd.data, cd.size, 546 return get_matching_model_microcode(0, start, cd.data, cd.size,
574 mc_saved_data, mc_saved_in_initrd, 547 mc_saved_data, initrd, uci);
575 uci);
576} 548}
577 549
578/* 550/*
@@ -704,7 +676,7 @@ int __init save_microcode_in_initrd_intel(void)
704 if (count == 0) 676 if (count == 0)
705 return ret; 677 return ret;
706 678
707 microcode_pointer(mc_saved, mc_saved_in_initrd, initrd_start, count); 679 copy_initrd_ptrs(mc_saved, mc_saved_in_initrd, initrd_start, count);
708 ret = save_microcode(&mc_saved_data, mc_saved, count); 680 ret = save_microcode(&mc_saved_data, mc_saved, count);
709 if (ret) 681 if (ret)
710 pr_err("Cannot save microcode patches from initrd.\n"); 682 pr_err("Cannot save microcode patches from initrd.\n");
@@ -716,52 +688,44 @@ int __init save_microcode_in_initrd_intel(void)
716 688
717static void __init 689static void __init
718_load_ucode_intel_bsp(struct mc_saved_data *mc_saved_data, 690_load_ucode_intel_bsp(struct mc_saved_data *mc_saved_data,
719 unsigned long *mc_saved_in_initrd, 691 unsigned long *initrd,
720 unsigned long initrd_start_early, 692 unsigned long start, unsigned long size)
721 unsigned long initrd_end_early,
722 struct ucode_cpu_info *uci)
723{ 693{
694 struct ucode_cpu_info uci;
724 enum ucode_state ret; 695 enum ucode_state ret;
725 696
726 collect_cpu_info_early(uci); 697 collect_cpu_info_early(&uci);
727 scan_microcode(initrd_start_early, initrd_end_early, mc_saved_data,
728 mc_saved_in_initrd, uci);
729 698
730 ret = load_microcode(mc_saved_data, mc_saved_in_initrd, 699 ret = scan_microcode(mc_saved_data, initrd, start, size, &uci);
731 initrd_start_early, uci); 700 if (ret != UCODE_OK)
701 return;
732 702
733 if (ret == UCODE_OK) 703 ret = load_microcode(mc_saved_data, initrd, start, &uci);
734 apply_microcode_early(uci, true); 704 if (ret != UCODE_OK)
705 return;
706
707 apply_microcode_early(&uci, true);
735} 708}
736 709
737void __init 710void __init load_ucode_intel_bsp(void)
738load_ucode_intel_bsp(void)
739{ 711{
740 u64 ramdisk_image, ramdisk_size; 712 u64 start, size;
741 unsigned long initrd_start_early, initrd_end_early;
742 struct ucode_cpu_info uci;
743#ifdef CONFIG_X86_32 713#ifdef CONFIG_X86_32
744 struct boot_params *boot_params_p; 714 struct boot_params *p;
745 715
746 boot_params_p = (struct boot_params *)__pa_nodebug(&boot_params); 716 p = (struct boot_params *)__pa_nodebug(&boot_params);
747 ramdisk_image = boot_params_p->hdr.ramdisk_image; 717 start = p->hdr.ramdisk_image;
748 ramdisk_size = boot_params_p->hdr.ramdisk_size; 718 size = p->hdr.ramdisk_size;
749 initrd_start_early = ramdisk_image;
750 initrd_end_early = initrd_start_early + ramdisk_size;
751 719
752 _load_ucode_intel_bsp( 720 _load_ucode_intel_bsp(
753 (struct mc_saved_data *)__pa_nodebug(&mc_saved_data), 721 (struct mc_saved_data *)__pa_nodebug(&mc_saved_data),
754 (unsigned long *)__pa_nodebug(&mc_saved_in_initrd), 722 (unsigned long *)__pa_nodebug(&mc_saved_in_initrd),
755 initrd_start_early, initrd_end_early, &uci); 723 start, size);
756#else 724#else
757 ramdisk_image = boot_params.hdr.ramdisk_image; 725 start = boot_params.hdr.ramdisk_image + PAGE_OFFSET;
758 ramdisk_size = boot_params.hdr.ramdisk_size; 726 size = boot_params.hdr.ramdisk_size;
759 initrd_start_early = ramdisk_image + PAGE_OFFSET; 727
760 initrd_end_early = initrd_start_early + ramdisk_size; 728 _load_ucode_intel_bsp(&mc_saved_data, mc_saved_in_initrd, start, size);
761
762 _load_ucode_intel_bsp(&mc_saved_data, mc_saved_in_initrd,
763 initrd_start_early, initrd_end_early,
764 &uci);
765#endif 729#endif
766} 730}
767 731
@@ -771,6 +735,7 @@ void load_ucode_intel_ap(void)
771 struct ucode_cpu_info uci; 735 struct ucode_cpu_info uci;
772 unsigned long *mc_saved_in_initrd_p; 736 unsigned long *mc_saved_in_initrd_p;
773 unsigned long initrd_start_addr; 737 unsigned long initrd_start_addr;
738 enum ucode_state ret;
774#ifdef CONFIG_X86_32 739#ifdef CONFIG_X86_32
775 unsigned long *initrd_start_p; 740 unsigned long *initrd_start_p;
776 741
@@ -793,8 +758,12 @@ void load_ucode_intel_ap(void)
793 return; 758 return;
794 759
795 collect_cpu_info_early(&uci); 760 collect_cpu_info_early(&uci);
796 load_microcode(mc_saved_data_p, mc_saved_in_initrd_p, 761 ret = load_microcode(mc_saved_data_p, mc_saved_in_initrd_p,
797 initrd_start_addr, &uci); 762 initrd_start_addr, &uci);
763
764 if (ret != UCODE_OK)
765 return;
766
798 apply_microcode_early(&uci, true); 767 apply_microcode_early(&uci, true);
799} 768}
800 769
@@ -808,8 +777,8 @@ void reload_ucode_intel(void)
808 777
809 collect_cpu_info_early(&uci); 778 collect_cpu_info_early(&uci);
810 779
811 ret = generic_load_microcode_early(mc_saved_data.mc_saved, 780 ret = load_microcode_early(mc_saved_data.mc_saved,
812 mc_saved_data.mc_saved_count, &uci); 781 mc_saved_data.mc_saved_count, &uci);
813 if (ret != UCODE_OK) 782 if (ret != UCODE_OK)
814 return; 783 return;
815 784
diff --git a/arch/x86/kernel/cpu/microcode/intel_lib.c b/arch/x86/kernel/cpu/microcode/intel_lib.c
index ce69320d0179..cd47a510a3f1 100644
--- a/arch/x86/kernel/cpu/microcode/intel_lib.c
+++ b/arch/x86/kernel/cpu/microcode/intel_lib.c
@@ -38,12 +38,6 @@ update_match_cpu(unsigned int csig, unsigned int cpf,
38 return (!sigmatch(sig, csig, pf, cpf)) ? 0 : 1; 38 return (!sigmatch(sig, csig, pf, cpf)) ? 0 : 1;
39} 39}
40 40
41int
42update_match_revision(struct microcode_header_intel *mc_header, int rev)
43{
44 return (mc_header->rev <= rev) ? 0 : 1;
45}
46
47int microcode_sanity_check(void *mc, int print_err) 41int microcode_sanity_check(void *mc, int print_err)
48{ 42{
49 unsigned long total_size, data_size, ext_table_size; 43 unsigned long total_size, data_size, ext_table_size;
@@ -128,10 +122,9 @@ int microcode_sanity_check(void *mc, int print_err)
128EXPORT_SYMBOL_GPL(microcode_sanity_check); 122EXPORT_SYMBOL_GPL(microcode_sanity_check);
129 123
130/* 124/*
131 * return 0 - no update found 125 * Returns 1 if update has been found, 0 otherwise.
132 * return 1 - found update
133 */ 126 */
134int get_matching_sig(unsigned int csig, int cpf, void *mc, int rev) 127int get_matching_sig(unsigned int csig, int cpf, int rev, void *mc)
135{ 128{
136 struct microcode_header_intel *mc_header = mc; 129 struct microcode_header_intel *mc_header = mc;
137 struct extended_sigtable *ext_header; 130 struct extended_sigtable *ext_header;
@@ -159,16 +152,15 @@ int get_matching_sig(unsigned int csig, int cpf, void *mc, int rev)
159} 152}
160 153
161/* 154/*
162 * return 0 - no update found 155 * Returns 1 if update has been found, 0 otherwise.
163 * return 1 - found update
164 */ 156 */
165int get_matching_microcode(unsigned int csig, int cpf, void *mc, int rev) 157int get_matching_microcode(unsigned int csig, int cpf, int rev, void *mc)
166{ 158{
167 struct microcode_header_intel *mc_header = mc; 159 struct microcode_header_intel *mc_hdr = mc;
168 160
169 if (!update_match_revision(mc_header, rev)) 161 if (!revision_is_newer(mc_hdr, rev))
170 return 0; 162 return 0;
171 163
172 return get_matching_sig(csig, cpf, mc, rev); 164 return get_matching_sig(csig, cpf, rev, mc);
173} 165}
174EXPORT_SYMBOL_GPL(get_matching_microcode); 166EXPORT_SYMBOL_GPL(get_matching_microcode);