aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-02 19:28:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-02 19:28:10 -0400
commitfdd78889aad2ec85b2f5a8ed232215dca7a22a3b (patch)
treed99e66e9afe26bebf89204d15443c42b9345bc21
parentd652df0b2f0b9c2e655be0d6f90989fae0a511b4 (diff)
parent9608d33b8210c993af4430d661a6474946480c9b (diff)
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
-rw-r--r--Documentation/x86/early-microcode.txt11
-rw-r--r--arch/x86/Kconfig14
-rw-r--r--arch/x86/include/asm/microcode_amd.h78
-rw-r--r--arch/x86/include/asm/microcode_intel.h2
-rw-r--r--arch/x86/kernel/Makefile1
-rw-r--r--arch/x86/kernel/microcode_amd.c133
-rw-r--r--arch/x86/kernel/microcode_amd_early.c302
-rw-r--r--arch/x86/kernel/microcode_core_early.c49
-rw-r--r--arch/x86/kernel/microcode_intel_early.c6
9 files changed, 509 insertions, 87 deletions
diff --git a/Documentation/x86/early-microcode.txt b/Documentation/x86/early-microcode.txt
index 4aaf0dfb0cb8..d62bea6796da 100644
--- a/Documentation/x86/early-microcode.txt
+++ b/Documentation/x86/early-microcode.txt
@@ -11,7 +11,8 @@ file and loaded to CPUs during boot time.
11The format of the combined initrd image is microcode in cpio format followed by 11The format of the combined initrd image is microcode in cpio format followed by
12the initrd image (maybe compressed). Kernel parses the combined initrd image 12the initrd image (maybe compressed). Kernel parses the combined initrd image
13during boot time. The microcode file in cpio name space is: 13during boot time. The microcode file in cpio name space is:
14kernel/x86/microcode/GenuineIntel.bin 14on Intel: kernel/x86/microcode/GenuineIntel.bin
15on AMD : kernel/x86/microcode/AuthenticAMD.bin
15 16
16During BSP boot (before SMP starts), if the kernel finds the microcode file in 17During BSP boot (before SMP starts), if the kernel finds the microcode file in
17the initrd file, it parses the microcode and saves matching microcode in memory. 18the 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.
34 35
35mkdir initrd 36mkdir initrd
36cd initrd 37cd initrd
37mkdir kernel 38mkdir -p kernel/x86/microcode
38mkdir kernel/x86 39cp ../microcode.bin kernel/x86/microcode/GenuineIntel.bin (or AuthenticAMD.bin)
39mkdir kernel/x86/microcode 40find . | cpio -o -H newc >../ucode.cpio
40cp ../microcode.bin kernel/x86/microcode/GenuineIntel.bin
41find .|cpio -oc >../ucode.cpio
42cd .. 41cd ..
43cat ucode.cpio /boot/initrd-3.5.0.img >/boot/initrd-3.5.0.ucode.img 42cat ucode.cpio /boot/initrd-3.5.0.img >/boot/initrd-3.5.0.ucode.img
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index c49b4dc8ffe0..34d1db1e7f40 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1058,8 +1058,16 @@ config MICROCODE_INTEL_LIB
1058 depends on MICROCODE_INTEL 1058 depends on MICROCODE_INTEL
1059 1059
1060config MICROCODE_INTEL_EARLY 1060config MICROCODE_INTEL_EARLY
1061 def_bool n
1062
1063config MICROCODE_AMD_EARLY
1064 def_bool n
1065
1066config MICROCODE_EARLY
1061 bool "Early load microcode" 1067 bool "Early load microcode"
1062 depends on MICROCODE_INTEL && BLK_DEV_INITRD 1068 depends on MICROCODE=y && BLK_DEV_INITRD
1069 select MICROCODE_INTEL_EARLY if MICROCODE_INTEL
1070 select MICROCODE_AMD_EARLY if MICROCODE_AMD
1063 default y 1071 default y
1064 help 1072 help
1065 This option provides functionality to read additional microcode data 1073 This option provides functionality to read additional microcode data
@@ -1067,10 +1075,6 @@ config MICROCODE_INTEL_EARLY
1067 microcode to CPU's as early as possible. No functional change if no 1075 microcode to CPU's as early as possible. No functional change if no
1068 microcode data is glued to the initrd, therefore it's safe to say Y. 1076 microcode data is glued to the initrd, therefore it's safe to say Y.
1069 1077
1070config MICROCODE_EARLY
1071 def_bool y
1072 depends on MICROCODE_INTEL_EARLY
1073
1074config X86_MSR 1078config X86_MSR
1075 tristate "/dev/cpu/*/msr - Model-specific register support" 1079 tristate "/dev/cpu/*/msr - Model-specific register support"
1076 ---help--- 1080 ---help---
diff --git a/arch/x86/include/asm/microcode_amd.h b/arch/x86/include/asm/microcode_amd.h
new file mode 100644
index 000000000000..c6b043f40271
--- /dev/null
+++ b/arch/x86/include/asm/microcode_amd.h
@@ -0,0 +1,78 @@
1#ifndef _ASM_X86_MICROCODE_AMD_H
2#define _ASM_X86_MICROCODE_AMD_H
3
4#include <asm/microcode.h>
5
6#define UCODE_MAGIC 0x00414d44
7#define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000
8#define UCODE_UCODE_TYPE 0x00000001
9
10#define SECTION_HDR_SIZE 8
11#define CONTAINER_HDR_SZ 12
12
13struct equiv_cpu_entry {
14 u32 installed_cpu;
15 u32 fixed_errata_mask;
16 u32 fixed_errata_compare;
17 u16 equiv_cpu;
18 u16 res;
19} __attribute__((packed));
20
21struct microcode_header_amd {
22 u32 data_code;
23 u32 patch_id;
24 u16 mc_patch_data_id;
25 u8 mc_patch_data_len;
26 u8 init_flag;
27 u32 mc_patch_data_checksum;
28 u32 nb_dev_id;
29 u32 sb_dev_id;
30 u16 processor_rev_id;
31 u8 nb_rev_id;
32 u8 sb_rev_id;
33 u8 bios_api_rev;
34 u8 reserved1[3];
35 u32 match_reg[8];
36} __attribute__((packed));
37
38struct microcode_amd {
39 struct microcode_header_amd hdr;
40 unsigned int mpb[0];
41};
42
43static inline u16 find_equiv_id(struct equiv_cpu_entry *equiv_cpu_table,
44 unsigned int sig)
45{
46 int i = 0;
47
48 if (!equiv_cpu_table)
49 return 0;
50
51 while (equiv_cpu_table[i].installed_cpu != 0) {
52 if (sig == equiv_cpu_table[i].installed_cpu)
53 return equiv_cpu_table[i].equiv_cpu;
54
55 i++;
56 }
57 return 0;
58}
59
60extern int __apply_microcode_amd(struct microcode_amd *mc_amd);
61extern int apply_microcode_amd(int cpu);
62extern enum ucode_state load_microcode_amd(int cpu, const u8 *data, size_t size);
63
64#ifdef CONFIG_MICROCODE_AMD_EARLY
65#ifdef CONFIG_X86_32
66#define MPB_MAX_SIZE PAGE_SIZE
67extern u8 amd_bsp_mpb[MPB_MAX_SIZE];
68#endif
69extern void __init load_ucode_amd_bsp(void);
70extern void __cpuinit load_ucode_amd_ap(void);
71extern int __init save_microcode_in_initrd_amd(void);
72#else
73static inline void __init load_ucode_amd_bsp(void) {}
74static inline void __cpuinit load_ucode_amd_ap(void) {}
75static inline int __init save_microcode_in_initrd_amd(void) { return -EINVAL; }
76#endif
77
78#endif /* _ASM_X86_MICROCODE_AMD_H */
diff --git a/arch/x86/include/asm/microcode_intel.h b/arch/x86/include/asm/microcode_intel.h
index 5356f927d411..87a085333cbf 100644
--- a/arch/x86/include/asm/microcode_intel.h
+++ b/arch/x86/include/asm/microcode_intel.h
@@ -67,10 +67,12 @@ update_match_revision(struct microcode_header_intel *mc_header, int rev);
67extern void __init load_ucode_intel_bsp(void); 67extern void __init load_ucode_intel_bsp(void);
68extern void __cpuinit load_ucode_intel_ap(void); 68extern void __cpuinit load_ucode_intel_ap(void);
69extern void show_ucode_info_early(void); 69extern void show_ucode_info_early(void);
70extern int __init save_microcode_in_initrd_intel(void);
70#else 71#else
71static inline __init void load_ucode_intel_bsp(void) {} 72static inline __init void load_ucode_intel_bsp(void) {}
72static inline __cpuinit void load_ucode_intel_ap(void) {} 73static inline __cpuinit void load_ucode_intel_ap(void) {}
73static inline void show_ucode_info_early(void) {} 74static inline void show_ucode_info_early(void) {}
75static inline int __init save_microcode_in_initrd_intel(void) { return -EINVAL; }
74#endif 76#endif
75 77
76#if defined(CONFIG_MICROCODE_INTEL_EARLY) && defined(CONFIG_HOTPLUG_CPU) 78#if defined(CONFIG_MICROCODE_INTEL_EARLY) && defined(CONFIG_HOTPLUG_CPU)
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 4ce822ed58f5..612ed3435c0d 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -93,6 +93,7 @@ obj-$(CONFIG_MICROCODE_INTEL_LIB) += microcode_intel_lib.o
93microcode-y := microcode_core.o 93microcode-y := microcode_core.o
94microcode-$(CONFIG_MICROCODE_INTEL) += microcode_intel.o 94microcode-$(CONFIG_MICROCODE_INTEL) += microcode_intel.o
95microcode-$(CONFIG_MICROCODE_AMD) += microcode_amd.o 95microcode-$(CONFIG_MICROCODE_AMD) += microcode_amd.o
96obj-$(CONFIG_MICROCODE_AMD_EARLY) += microcode_amd_early.o
96obj-$(CONFIG_MICROCODE) += microcode.o 97obj-$(CONFIG_MICROCODE) += microcode.o