Commit | Line | Data |
---|---|---|
0e325875 BP |
1 | The Linux Microcode Loader |
2 | ||
3 | Authors: Fenghua Yu <fenghua.yu@intel.com> | |
4 | Borislav Petkov <bp@suse.de> | |
5 | ||
6 | The kernel has a x86 microcode loading facility which is supposed to | |
7 | provide microcode loading methods in the OS. Potential use cases are | |
8 | updating the microcode on platforms beyond the OEM End-Of-Life support, | |
9 | and updating the microcode on long-running systems without rebooting. | |
10 | ||
11 | The loader supports three loading methods: | |
12 | ||
13 | 1. Early load microcode | |
14 | ======================= | |
15 | ||
16 | The kernel can update microcode very early during boot. Loading | |
17 | microcode early can fix CPU issues before they are observed during | |
18 | kernel boot time. | |
19 | ||
20 | The microcode is stored in an initrd file. During boot, it is read from | |
21 | it and loaded into the CPU cores. | |
22 | ||
23 | The format of the combined initrd image is microcode in (uncompressed) | |
24 | cpio format followed by the (possibly compressed) initrd image. The | |
25 | loader parses the combined initrd image during boot. | |
26 | ||
27 | The microcode files in cpio name space are: | |
28 | ||
29 | on Intel: kernel/x86/microcode/GenuineIntel.bin | |
30 | on AMD : kernel/x86/microcode/AuthenticAMD.bin | |
31 | ||
32 | During BSP (BootStrapping Processor) boot (pre-SMP), the kernel | |
33 | scans the microcode file in the initrd. If microcode matching the | |
34 | CPU is found, it will be applied in the BSP and later on in all APs | |
35 | (Application Processors). | |
36 | ||
37 | The loader also saves the matching microcode for the CPU in memory. | |
38 | Thus, the cached microcode patch is applied when CPUs resume from a | |
39 | sleep state. | |
40 | ||
41 | Here's a crude example how to prepare an initrd with microcode (this is | |
42 | normally done automatically by the distribution, when recreating the | |
43 | initrd, so you don't really have to do it yourself. It is documented | |
44 | here for future reference only). | |
45 | ||
46 | --- | |
47 | #!/bin/bash | |
48 | ||
49 | if [ -z "$1" ]; then | |
50 | echo "You need to supply an initrd file" | |
51 | exit 1 | |
52 | fi | |
53 | ||
54 | INITRD="$1" | |
55 | ||
56 | DSTDIR=kernel/x86/microcode | |
57 | TMPDIR=/tmp/initrd | |
58 | ||
59 | rm -rf $TMPDIR | |
60 | ||
61 | mkdir $TMPDIR | |
62 | cd $TMPDIR | |
63 | mkdir -p $DSTDIR | |
64 | ||
65 | if [ -d /lib/firmware/amd-ucode ]; then | |
66 | cat /lib/firmware/amd-ucode/microcode_amd*.bin > $DSTDIR/AuthenticAMD.bin | |
67 | fi | |
68 | ||
69 | if [ -d /lib/firmware/intel-ucode ]; then | |
70 | cat /lib/firmware/intel-ucode/* > $DSTDIR/GenuineIntel.bin | |
71 | fi | |
72 | ||
73 | find . | cpio -o -H newc >../ucode.cpio | |
74 | cd .. | |
75 | mv $INITRD $INITRD.orig | |
76 | cat ucode.cpio $INITRD.orig > $INITRD | |
77 | ||
78 | rm -rf $TMPDIR | |
79 | --- | |
80 | ||
81 | The system needs to have the microcode packages installed into | |
82 | /lib/firmware or you need to fixup the paths above if yours are | |
83 | somewhere else and/or you've downloaded them directly from the processor | |
84 | vendor's site. | |
85 | ||
86 | 2. Late loading | |
87 | =============== | |
88 | ||
89 | There are two legacy user space interfaces to load microcode, either through | |
90 | /dev/cpu/microcode or through /sys/devices/system/cpu/microcode/reload file | |
91 | in sysfs. | |
92 | ||
93 | The /dev/cpu/microcode method is deprecated because it needs a special | |
94 | userspace tool for that. | |
95 | ||
96 | The easier method is simply installing the microcode packages your distro | |
97 | supplies and running: | |
98 | ||
99 | # echo 1 > /sys/devices/system/cpu/microcode/reload | |
100 | ||
101 | as root. | |
102 | ||
103 | The loading mechanism looks for microcode blobs in | |
104 | /lib/firmware/{intel-ucode,amd-ucode}. The default distro installation | |
105 | packages already put them there. | |
106 | ||
107 | 3. Builtin microcode | |
108 | ==================== | |
109 | ||
110 | The loader supports also loading of a builtin microcode supplied through | |
111 | the regular firmware builtin method CONFIG_FIRMWARE_IN_KERNEL. Only | |
112 | 64-bit is currently supported. | |
113 | ||
114 | Here's an example: | |
115 | ||
116 | CONFIG_FIRMWARE_IN_KERNEL=y | |
117 | CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin" | |
118 | CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware" | |
119 | ||
120 | This basically means, you have the following tree structure locally: | |
121 | ||
122 | /lib/firmware/ | |
123 | |-- amd-ucode | |
124 | ... | |
125 | | |-- microcode_amd_fam15h.bin | |
126 | ... | |
127 | |-- intel-ucode | |
128 | ... | |
129 | | |-- 06-3a-09 | |
130 | ... | |
131 | ||
132 | so that the build system can find those files and integrate them into | |
133 | the final kernel image. The early loader finds them and applies them. | |
134 | ||
135 | Needless to say, this method is not the most flexible one because it | |
136 | requires rebuilding the kernel each time updated microcode from the CPU | |
137 | vendor is available. |