diff options
Diffstat (limited to 'arch/x86/kernel/cpu/microcode')
-rw-r--r-- | arch/x86/kernel/cpu/microcode/amd.c | 5 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/microcode/core.c | 22 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/microcode/intel.c | 9 |
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) | |||
384 | reget: | 384 | reget: |
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 @@ | |||
46 | static struct microcode_ops *microcode_ops; | 46 | static struct microcode_ops *microcode_ops; |
47 | static bool dis_ucode_ldr = true; | 47 | static bool dis_ucode_ldr = true; |
48 | 48 | ||
49 | bool initrd_gone; | ||
50 | |||
49 | LIST_HEAD(microcode_cache); | 51 | LIST_HEAD(microcode_cache); |
50 | 52 | ||
51 | /* | 53 | /* |
@@ -190,21 +192,24 @@ void load_ucode_ap(void) | |||
190 | static int __init save_microcode_in_initrd(void) | 192 | static 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 | ||
210 | struct cpio_data find_microcode_in_initrd(const char *path, bool use_pa) | 215 | struct 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 | ||
42 | static const char ucode_path[] = "kernel/x86/microcode/GenuineIntel.bin"; | 42 | static 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. */ |
45 | struct microcode_intel *intel_ucode_patch; | 45 | struct microcode_intel *intel_ucode_patch; |
46 | 46 | ||
47 | static inline bool cpu_signatures_match(unsigned int s1, unsigned int p1, | 47 | static 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 | */ |