Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5f9c01aa authored by Borislav Petkov's avatar Borislav Petkov Committed by Ingo Molnar
Browse files

x86/microcode: Untangle from BLK_DEV_INITRD



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: default avatarThomas Voegtle <tv@lio96.de>
Tested-by: default avatarThomas Voegtle <tv@lio96.de>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Cc: <stable@vger.kernel.org> # 4.4
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: default avatarIngo Molnar <mingo@kernel.org>
parent 765bdb40
Loading
Loading
Loading
Loading
+14 −13
Original line number Diff line number Diff line
@@ -1159,22 +1159,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"
+26 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@

#include <asm/cpu.h>
#include <linux/earlycpio.h>
#include <linux/initrd.h>

#define native_rdmsr(msr, val1, val2)			\
do {							\
@@ -143,4 +144,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 */
+4 −10
Original line number Diff line number Diff line
@@ -690,7 +690,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");
@@ -748,20 +748,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

	/*
@@ -773,7 +767,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;