aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/microcode
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/cpu/microcode')
-rw-r--r--arch/x86/kernel/cpu/microcode/amd.c5
-rw-r--r--arch/x86/kernel/cpu/microcode/core.c22
-rw-r--r--arch/x86/kernel/cpu/microcode/intel.c9
3 files changed, 21 insertions, 15 deletions
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 6a31e2691f3a..079e81733a58 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -384,8 +384,9 @@ void load_ucode_amd_ap(unsigned int family)
384reget: 384reget:
385 if (!get_builtin_microcode(&cp, family)) { 385 if (!get_builtin_microcode(&cp, family)) {
386#ifdef CONFIG_BLK_DEV_INITRD 386#ifdef CONFIG_BLK_DEV_INITRD
387 cp = find_cpio_data(ucode_path, (void *)initrd_start, 387 if (!initrd_gone)
388 initrd_end - initrd_start, NULL); 388 cp = find_cpio_data(ucode_path, (void *)initrd_start,
389 initrd_end - initrd_start, NULL);
389#endif 390#endif
390 if (!(cp.data && cp.size)) { 391 if (!(cp.data && cp.size)) {
391 /* 392 /*
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index 2af69d27da62..73102d932760 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -46,6 +46,8 @@
46static struct microcode_ops *microcode_ops; 46static struct microcode_ops *microcode_ops;
47static bool dis_ucode_ldr = true; 47static bool dis_ucode_ldr = true;
48 48
49bool initrd_gone;
50
49LIST_HEAD(microcode_cache); 51LIST_HEAD(microcode_cache);
50 52
51/* 53/*
@@ -190,21 +192,24 @@ void load_ucode_ap(void)
190static int __init save_microcode_in_initrd(void) 192static int __init save_microcode_in_initrd(void)
191{ 193{
192 struct cpuinfo_x86 *c = &boot_cpu_data; 194 struct cpuinfo_x86 *c = &boot_cpu_data;
195 int ret = -EINVAL;
193 196
194 switch (c->x86_vendor) { 197 switch (c->x86_vendor) {
195 case X86_VENDOR_INTEL: 198 case X86_VENDOR_INTEL:
196 if (c->x86 >= 6) 199 if (c->x86 >= 6)
197 return save_microcode_in_initrd_intel(); 200 ret = save_microcode_in_initrd_intel();
198 break; 201 break;
199 case X86_VENDOR_AMD: 202 case X86_VENDOR_AMD:
200 if (c->x86 >= 0x10) 203 if (c->x86 >= 0x10)
201 return save_microcode_in_initrd_amd(c->x86); 204 ret = save_microcode_in_initrd_amd(c->x86);
202 break; 205 break;
203 default: 206 default:
204 break; 207 break;
205 } 208 }
206 209
207 return -EINVAL; 210 initrd_gone = true;
211
212 return ret;
208} 213}
209 214
210struct cpio_data find_microcode_in_initrd(const char *path, bool use_pa) 215struct cpio_data find_microcode_in_initrd(const char *path, bool use_pa)
@@ -247,9 +252,16 @@ struct cpio_data find_microcode_in_initrd(const char *path, bool use_pa)
247 * has the virtual address of the beginning of the initrd. It also 252 * has the virtual address of the beginning of the initrd. It also
248 * possibly relocates the ramdisk. In either case, initrd_start contains 253 * possibly relocates the ramdisk. In either case, initrd_start contains
249 * the updated address so use that instead. 254 * the updated address so use that instead.
255 *
256 * initrd_gone is for the hotplug case where we've thrown out initrd
257 * already.
250 */ 258 */
251 if (!use_pa && initrd_start) 259 if (!use_pa) {
252 start = initrd_start; 260 if (initrd_gone)
261 return (struct cpio_data){ NULL, 0, "" };
262 if (initrd_start)
263 start = initrd_start;
264 }
253 265
254 return find_cpio_data(path, (void *)start, size, NULL); 266 return find_cpio_data(path, (void *)start, size, NULL);
255#else /* !CONFIG_BLK_DEV_INITRD */ 267#else /* !CONFIG_BLK_DEV_INITRD */
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 3f329b74e040..8325d8a09ab0 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -41,7 +41,7 @@
41 41
42static const char ucode_path[] = "kernel/x86/microcode/GenuineIntel.bin"; 42static const char ucode_path[] = "kernel/x86/microcode/GenuineIntel.bin";
43 43
44/* Current microcode patch used in early patching */ 44/* Current microcode patch used in early patching on the APs. */
45struct microcode_intel *intel_ucode_patch; 45struct microcode_intel *intel_ucode_patch;
46 46
47static inline bool cpu_signatures_match(unsigned int s1, unsigned int p1, 47static inline bool cpu_signatures_match(unsigned int s1, unsigned int p1,
@@ -607,12 +607,6 @@ int __init save_microcode_in_initrd_intel(void)
607 struct ucode_cpu_info uci; 607 struct ucode_cpu_info uci;
608 struct cpio_data cp; 608 struct cpio_data cp;
609 609
610 /*
611 * AP loading didn't find any microcode patch, no need to save anything.
612 */
613 if (!intel_ucode_patch || IS_ERR(intel_ucode_patch))
614 return 0;
615
616 if (!load_builtin_intel_microcode(&cp)) 610 if (!load_builtin_intel_microcode(&cp))
617 cp = find_microcode_in_initrd(ucode_path, false); 611 cp = find_microcode_in_initrd(ucode_path, false);
618 612
@@ -628,7 +622,6 @@ int __init save_microcode_in_initrd_intel(void)
628 return 0; 622 return 0;
629} 623}
630 624
631
632/* 625/*
633 * @res_patch, output: a pointer to the patch we found. 626 * @res_patch, output: a pointer to the patch we found.
634 */ 627 */