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

Commit fdd78889 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'x86-microcode-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 microcode loading update from Ingo Molnar:
 "Two main changes that improve microcode loading on AMD CPUs:

   - Add support for all-in-one binary microcode files that concatenate
     the microcode images of multiple processor families, by Jacob Shin

   - Add early microcode loading (embedded in the initrd) support, also
     by Jacob Shin"

* 'x86-microcode-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86, microcode, amd: Another early loading fixup
  x86, microcode, amd: Allow multiple families' bin files appended together
  x86, microcode, amd: Make find_ucode_in_initrd() __init
  x86, microcode, amd: Fix warnings and errors on with CONFIG_MICROCODE=m
  x86, microcode, amd: Early microcode patch loading support for AMD
  x86, microcode, amd: Refactor functions to prepare for early loading
  x86, microcode: Vendor abstract out save_microcode_in_initrd()
  x86, microcode, intel: Correct typo in printk
parents d652df0b 9608d33b
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -11,7 +11,8 @@ file and loaded to CPUs during boot time.
The format of the combined initrd image is microcode in cpio format followed by
the initrd image (maybe compressed). Kernel parses the combined initrd image
during boot time. The microcode file in cpio name space is:
kernel/x86/microcode/GenuineIntel.bin
on Intel: kernel/x86/microcode/GenuineIntel.bin
on AMD  : kernel/x86/microcode/AuthenticAMD.bin

During BSP boot (before SMP starts), if the kernel finds the microcode file in
the initrd file, it parses the microcode and saves matching microcode in memory.
@@ -34,10 +35,8 @@ original initrd image /boot/initrd-3.5.0.img.

mkdir initrd
cd initrd
mkdir kernel
mkdir kernel/x86
mkdir kernel/x86/microcode
cp ../microcode.bin kernel/x86/microcode/GenuineIntel.bin
find .|cpio -oc >../ucode.cpio
mkdir -p kernel/x86/microcode
cp ../microcode.bin kernel/x86/microcode/GenuineIntel.bin (or AuthenticAMD.bin)
find . | cpio -o -H newc >../ucode.cpio
cd ..
cat ucode.cpio /boot/initrd-3.5.0.img >/boot/initrd-3.5.0.ucode.img
+9 −5
Original line number Diff line number Diff line
@@ -1058,8 +1058,16 @@ config MICROCODE_INTEL_LIB
	depends on MICROCODE_INTEL

config MICROCODE_INTEL_EARLY
	def_bool n

config MICROCODE_AMD_EARLY
	def_bool n

config MICROCODE_EARLY
	bool "Early load microcode"
	depends on MICROCODE_INTEL && BLK_DEV_INITRD
	depends on MICROCODE=y && BLK_DEV_INITRD
	select MICROCODE_INTEL_EARLY if MICROCODE_INTEL
	select MICROCODE_AMD_EARLY if MICROCODE_AMD
	default y
	help
	  This option provides functionality to read additional microcode data
@@ -1067,10 +1075,6 @@ config MICROCODE_INTEL_EARLY
	  microcode to CPU's as early as possible. No functional change if no
	  microcode data is glued to the initrd, therefore it's safe to say Y.

config MICROCODE_EARLY
	def_bool y
	depends on MICROCODE_INTEL_EARLY

config X86_MSR
	tristate "/dev/cpu/*/msr - Model-specific register support"
	---help---
+78 −0
Original line number Diff line number Diff line
#ifndef _ASM_X86_MICROCODE_AMD_H
#define _ASM_X86_MICROCODE_AMD_H

#include <asm/microcode.h>

#define UCODE_MAGIC			0x00414d44
#define UCODE_EQUIV_CPU_TABLE_TYPE	0x00000000
#define UCODE_UCODE_TYPE		0x00000001

#define SECTION_HDR_SIZE		8
#define CONTAINER_HDR_SZ		12

struct equiv_cpu_entry {
	u32	installed_cpu;
	u32	fixed_errata_mask;
	u32	fixed_errata_compare;
	u16	equiv_cpu;
	u16	res;
} __attribute__((packed));

struct microcode_header_amd {
	u32	data_code;
	u32	patch_id;
	u16	mc_patch_data_id;
	u8	mc_patch_data_len;
	u8	init_flag;
	u32	mc_patch_data_checksum;
	u32	nb_dev_id;
	u32	sb_dev_id;
	u16	processor_rev_id;
	u8	nb_rev_id;
	u8	sb_rev_id;
	u8	bios_api_rev;
	u8	reserved1[3];
	u32	match_reg[8];
} __attribute__((packed));

struct microcode_amd {
	struct microcode_header_amd	hdr;
	unsigned int			mpb[0];
};

static inline u16 find_equiv_id(struct equiv_cpu_entry *equiv_cpu_table,
				unsigned int sig)
{
	int i = 0;

	if (!equiv_cpu_table)
		return 0;

	while (equiv_cpu_table[i].installed_cpu != 0) {
		if (sig == equiv_cpu_table[i].installed_cpu)
			return equiv_cpu_table[i].equiv_cpu;

		i++;
	}
	return 0;
}

extern int __apply_microcode_amd(struct microcode_amd *mc_amd);
extern int apply_microcode_amd(int cpu);
extern enum ucode_state load_microcode_amd(int cpu, const u8 *data, size_t size);

#ifdef CONFIG_MICROCODE_AMD_EARLY
#ifdef CONFIG_X86_32
#define MPB_MAX_SIZE PAGE_SIZE
extern u8 amd_bsp_mpb[MPB_MAX_SIZE];
#endif
extern void __init load_ucode_amd_bsp(void);
extern void __cpuinit load_ucode_amd_ap(void);
extern int __init save_microcode_in_initrd_amd(void);
#else
static inline void __init load_ucode_amd_bsp(void) {}
static inline void __cpuinit load_ucode_amd_ap(void) {}
static inline int __init save_microcode_in_initrd_amd(void) { return -EINVAL; }
#endif

#endif /* _ASM_X86_MICROCODE_AMD_H */
+2 −0
Original line number Diff line number Diff line
@@ -67,10 +67,12 @@ update_match_revision(struct microcode_header_intel *mc_header, int rev);
extern void __init load_ucode_intel_bsp(void);
extern void __cpuinit load_ucode_intel_ap(void);
extern void show_ucode_info_early(void);
extern int __init save_microcode_in_initrd_intel(void);
#else
static inline __init void load_ucode_intel_bsp(void) {}
static inline __cpuinit void load_ucode_intel_ap(void) {}
static inline void show_ucode_info_early(void) {}
static inline int __init save_microcode_in_initrd_intel(void) { return -EINVAL; }
#endif

#if defined(CONFIG_MICROCODE_INTEL_EARLY) && defined(CONFIG_HOTPLUG_CPU)
+1 −0
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ obj-$(CONFIG_MICROCODE_INTEL_LIB) += microcode_intel_lib.o
microcode-y				:= microcode_core.o
microcode-$(CONFIG_MICROCODE_INTEL)	+= microcode_intel.o
microcode-$(CONFIG_MICROCODE_AMD)	+= microcode_amd.o
obj-$(CONFIG_MICROCODE_AMD_EARLY)	+= microcode_amd_early.o
obj-$(CONFIG_MICROCODE)			+= microcode.o

obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
Loading