From 6c5456474e7f0b63be66d44b0595001e2a8b44d5 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 6 Jun 2016 17:10:42 +0200 Subject: x86/microcode: Fix loading precedence So it can happen that even with builtin microcode, CONFIG_BLK_DEV_INITRD=y gets forgotten enabled. Or, even with that disabled, an initrd image gets supplied by the boot loader, by omission or is simply forgotten there. And since we do look at boot_params.hdr.ramdisk_* to know whether we have received an initrd, we might get puzzled. So let's just make the loader look for builtin microcode first and if found, ignore the ramdisk image. If no builtin found, it falls back to scanning the supplied initrd, of course. For that, we move all the initrd scanning in a separate __scan_microcode_initrd() function and fall back to it only if load_builtin_intel_microcode() has failed. Reported-and-tested-by: Gabriel Craciunescu Signed-off-by: Borislav Petkov Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1465225850-7352-2-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/microcode/amd.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'arch/x86/kernel/cpu/microcode/amd.c') diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 8581963894c7..11dd1cc8e444 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -61,19 +61,20 @@ static u16 this_equiv_id; static struct cpio_data ucode_cpio; -/* - * Microcode patch container file is prepended to the initrd in cpio format. - * See Documentation/x86/early-microcode.txt - */ -static __initdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin"; - static struct cpio_data __init find_ucode_in_initrd(void) { +#ifdef CONFIG_BLK_DEV_INITRD long offset = 0; char *path; void *start; size_t size; + /* + * Microcode patch container file is prepended to the initrd in cpio + * format. See Documentation/x86/early-microcode.txt + */ + static __initdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin"; + #ifdef CONFIG_X86_32 struct boot_params *p; @@ -89,9 +90,12 @@ static struct cpio_data __init find_ucode_in_initrd(void) path = ucode_path; start = (void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET); size = boot_params.hdr.ramdisk_size; -#endif +#endif /* !CONFIG_X86_32 */ return find_cpio_data(path, start, size, &offset); +#else + return (struct cpio_data){ NULL, 0, "" }; +#endif } static size_t compute_container_size(u8 *data, u32 total_size) @@ -289,11 +293,11 @@ void __init load_ucode_amd_bsp(unsigned int family) size = &ucode_cpio.size; #endif - cp = find_ucode_in_initrd(); - if (!cp.data) { - if (!load_builtin_amd_microcode(&cp, family)) - return; - } + if (!load_builtin_amd_microcode(&cp, family)) + cp = find_ucode_in_initrd(); + + if (!(cp.data && cp.size)) + return; *data = cp.data; *size = cp.size; -- cgit v1.2.3-70-g09d2 From 852ad5b94524fd76d49944b9db0a93f7c9ee5814 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 6 Jun 2016 17:10:45 +0200 Subject: x86/microcode: Get rid of find_cpio_data()'s dummy offset arg The microcode loader doesn't use it and now that that arg has been made optional in find_cpio_data(), get rid of it here. No functionality change. Signed-off-by: Borislav Petkov Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1465225850-7352-5-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/microcode/amd.c | 3 +-- arch/x86/kernel/cpu/microcode/intel.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'arch/x86/kernel/cpu/microcode/amd.c') diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 11dd1cc8e444..b1d1e345f5f5 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -64,7 +64,6 @@ static struct cpio_data ucode_cpio; static struct cpio_data __init find_ucode_in_initrd(void) { #ifdef CONFIG_BLK_DEV_INITRD - long offset = 0; char *path; void *start; size_t size; @@ -92,7 +91,7 @@ static struct cpio_data __init find_ucode_in_initrd(void) size = boot_params.hdr.ramdisk_size; #endif /* !CONFIG_X86_32 */ - return find_cpio_data(path, start, size, &offset); + return find_cpio_data(path, start, size, NULL); #else return (struct cpio_data){ NULL, 0, "" }; #endif diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index 5835d5b0db81..2ad40b73c8df 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -685,7 +685,6 @@ static __init enum ucode_state __scan_microcode_initrd(struct cpio_data *cd, struct ucode_blobs *blbp) { #ifdef CONFIG_BLK_DEV_INITRD - long offset = 0; static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin"; char *p = IS_ENABLED(CONFIG_X86_32) ? (char *)__pa_nodebug(ucode_name) : ucode_name; @@ -716,7 +715,7 @@ __scan_microcode_initrd(struct cpio_data *cd, struct ucode_blobs *blbp) } # endif - *cd = find_cpio_data(p, (void *)start, size, &offset); + *cd = find_cpio_data(p, (void *)start, size, NULL); if (cd->data) { blbp->start = start; blbp->valid = true; -- cgit v1.2.3-70-g09d2 From a13004a2449c56a83d5816e81d850ea92b6837c2 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 6 Jun 2016 17:10:49 +0200 Subject: x86/microcode/AMD: Make amd_ucode_patch[] static It is used only in amd.c now. No functionality change. Signed-off-by: Borislav Petkov Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1465225850-7352-9-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar --- arch/x86/include/asm/microcode_amd.h | 1 - arch/x86/kernel/cpu/microcode/amd.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/x86/kernel/cpu/microcode/amd.c') diff --git a/arch/x86/include/asm/microcode_amd.h b/arch/x86/include/asm/microcode_amd.h index adfc847a395e..15eb75484cc0 100644 --- a/arch/x86/include/asm/microcode_amd.h +++ b/arch/x86/include/asm/microcode_amd.h @@ -62,7 +62,6 @@ extern int apply_microcode_amd(int cpu); extern enum ucode_state load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size); #define PATCH_MAX_SIZE PAGE_SIZE -extern u8 amd_ucode_patch[PATCH_MAX_SIZE]; #ifdef CONFIG_MICROCODE_AMD extern void __init load_ucode_amd_bsp(unsigned int family); diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index b1d1e345f5f5..27a0228c9cae 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -56,7 +56,7 @@ static u8 *container; static size_t container_size; static u32 ucode_new_rev; -u8 amd_ucode_patch[PATCH_MAX_SIZE]; +static u8 amd_ucode_patch[PATCH_MAX_SIZE]; static u16 this_equiv_id; static struct cpio_data ucode_cpio; -- cgit v1.2.3-70-g09d2