]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
x86/microcode: Untangle from BLK_DEV_INITRD
authorBorislav Petkov <bp@suse.de>
Wed, 3 Feb 2016 11:33:29 +0000 (12:33 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 12 Apr 2016 16:08:32 +0000 (09:08 -0700)
commit 5f9c01aa7c49a2d74474d6d879a797b8badf29e6 upstream.

Thomas Voegtle reported that doing oldconfig with a .config which has
CONFIG_MICROCODE enabled but BLK_DEV_INITRD disabled prevents the
microcode loading mechanism from being built.

So untangle it from the BLK_DEV_INITRD dependency so that oldconfig
doesn't turn it off and add an explanatory text to its Kconfig help what
the supported methods for supplying microcode are.

Reported-by: Thomas Voegtle <tv@lio96.de>
Tested-by: Thomas Voegtle <tv@lio96.de>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1454499225-21544-2-git-send-email-bp@alien8.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/Kconfig
arch/x86/include/asm/microcode.h
arch/x86/kernel/cpu/microcode/intel.c

index db3622f22b618303a8bc9c3c2f34762f400dbafb..436639a316248532dee15c0ab527346c02448788 100644 (file)
@@ -1126,22 +1126,23 @@ config MICROCODE
        bool "CPU microcode loading support"
        default y
        depends on CPU_SUP_AMD || CPU_SUP_INTEL
-       depends on BLK_DEV_INITRD
        select FW_LOADER
        ---help---
-
          If you say Y here, you will be able to update the microcode on
-         certain Intel and AMD processors. The Intel support is for the
-         IA32 family, e.g. Pentium Pro, Pentium II, Pentium III, Pentium 4,
-         Xeon etc. The AMD support is for families 0x10 and later. You will
-         obviously need the actual microcode binary data itself which is not
-         shipped with the Linux kernel.
-
-         This option selects the general module only, you need to select
-         at least one vendor specific module as well.
-
-         To compile this driver as a module, choose M here: the module
-         will be called microcode.
+         Intel and AMD processors. The Intel support is for the IA32 family,
+         e.g. Pentium Pro, Pentium II, Pentium III, Pentium 4, Xeon etc. The
+         AMD support is for families 0x10 and later. You will obviously need
+         the actual microcode binary data itself which is not shipped with
+         the Linux kernel.
+
+         The preferred method to load microcode from a detached initrd is described
+         in Documentation/x86/early-microcode.txt. For that you need to enable
+         CONFIG_BLK_DEV_INITRD in order for the loader to be able to scan the
+         initrd for microcode blobs.
+
+         In addition, you can build-in the microcode into the kernel. For that you
+         need to enable FIRMWARE_IN_KERNEL and add the vendor-supplied microcode
+         to the CONFIG_EXTRA_FIRMWARE config option.
 
 config MICROCODE_INTEL
        bool "Intel microcode loading support"
index 34e62b1dcfce46a606fbe78d7d55131513d859d3..712b24ed3a64c95e18869717280ee72532191b35 100644 (file)
@@ -2,6 +2,7 @@
 #define _ASM_X86_MICROCODE_H
 
 #include <linux/earlycpio.h>
+#include <linux/initrd.h>
 
 #define native_rdmsr(msr, val1, val2)                  \
 do {                                                   \
@@ -168,4 +169,29 @@ static inline void reload_early_microcode(void)                    { }
 static inline bool
 get_builtin_firmware(struct cpio_data *cd, const char *name)   { return false; }
 #endif
+
+static inline unsigned long get_initrd_start(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+       return initrd_start;
+#else
+       return 0;
+#endif
+}
+
+static inline unsigned long get_initrd_start_addr(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+#ifdef CONFIG_X86_32
+       unsigned long *initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start);
+
+       return (unsigned long)__pa_nodebug(*initrd_start_p);
+#else
+       return get_initrd_start();
+#endif
+#else /* CONFIG_BLK_DEV_INITRD */
+       return 0;
+#endif
+}
+
 #endif /* _ASM_X86_MICROCODE_H */
index 5e3a310d54f305bd293132b502e90c615e7cca9f..ac8975a652804a19eed6f84528b7ac8c93b0fcc0 100644 (file)
@@ -698,7 +698,7 @@ int __init save_microcode_in_initrd_intel(void)
        if (count == 0)
                return ret;
 
-       copy_initrd_ptrs(mc_saved, mc_saved_in_initrd, initrd_start, count);
+       copy_initrd_ptrs(mc_saved, mc_saved_in_initrd, get_initrd_start(), count);
        ret = save_microcode(&mc_saved_data, mc_saved, count);
        if (ret)
                pr_err("Cannot save microcode patches from initrd.\n");
@@ -760,20 +760,14 @@ void load_ucode_intel_ap(void)
        struct mc_saved_data *mc_saved_data_p;
        struct ucode_cpu_info uci;
        unsigned long *mc_saved_in_initrd_p;
-       unsigned long initrd_start_addr;
        enum ucode_state ret;
 #ifdef CONFIG_X86_32
-       unsigned long *initrd_start_p;
 
-       mc_saved_in_initrd_p =
-               (unsigned long *)__pa_nodebug(mc_saved_in_initrd);
+       mc_saved_in_initrd_p = (unsigned long *)__pa_nodebug(mc_saved_in_initrd);
        mc_saved_data_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
-       initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start);
-       initrd_start_addr = (unsigned long)__pa_nodebug(*initrd_start_p);
 #else
-       mc_saved_data_p = &mc_saved_data;
        mc_saved_in_initrd_p = mc_saved_in_initrd;
-       initrd_start_addr = initrd_start;
+       mc_saved_data_p = &mc_saved_data;
 #endif
 
        /*
@@ -785,7 +779,7 @@ void load_ucode_intel_ap(void)
 
        collect_cpu_info_early(&uci);
        ret = load_microcode(mc_saved_data_p, mc_saved_in_initrd_p,
-                            initrd_start_addr, &uci);
+                            get_initrd_start_addr(), &uci);
 
        if (ret != UCODE_OK)
                return;