x86/microcode changes for v4.6
Subsystems (3)
Linus,
Please pull the latest x86-microcode-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-microcode-for-linus
# HEAD: 4ace2e7a48ab426eaa9745ace4c50c6a7adb3992 x86/microcode/intel: Drop orig_sum from ext signature checksum
The biggest change in this cycle was the separation of the microcode loading mechanism from the initrd code plus the support of built-in microcode images. There were also lots cleanups and general restructuring. (by Borislav Petkov)
Thanks,
Ingo
------------------>
Andrzej Hajda (1):
x86/microcode: Use kmemdup() rather than duplicating its implementation
Boris Ostrovsky (1):
x86/microcode: Remove unnecessary paravirt_enabled check
Borislav Petkov (20):
x86/microcode: Untangle from BLK_DEV_INITRD x86/microcode/intel: Make early loader look for builtin microcode too x86/microcode: Remove redundant __setup() param parsing x86/microcode: Issue update message only once x86/microcode/AMD: Drop redundant printk prefix x86/microcode/intel: Rename local variables of type struct mc_saved_data x86/microcode/intel: Rename mc_saved_count to num_saved x86/microcode/intel: Rename mc_intel variable to mc x86/microcode/intel: Move the BUG_ON up and turn it into WARN_ON x86/microcode/intel: Cleanup apply_microcode_intel() x86/microcode/intel: Use *wrmsrl variants x86/microcode/intel: Rename mc_saved_in_initrd x86/microcode/intel: Remove unused arg of get_matching_model_microcode() x86/microcode/intel: Cleanup get_matching_model_microcode() x86/microcode/AMD: Issue microcode updated message later x86/microcode: Document builtin microcode loading method x86/microcode/intel: Get rid of DWSIZE
x86/microcode/intel: Merge two consecutive if-statements x86/microcode/intel: Improve microcode sanity-checking error messages x86/microcode/intel: Drop orig_sum from ext signature checksum
Chris Bainbridge (1):
x86/microcode/intel: Change checksum variables to u32
Dan Carpenter (1):
x86/microcode: Remove an unneeded NULL check
Documentation/x86/early-microcode.txt | 25 +++ arch/x86/Kconfig | 27 +-- arch/x86/include/asm/microcode.h | 26 +++ arch/x86/include/asm/microcode_intel.h | 1 - arch/x86/kernel/cpu/microcode/amd.c | 15 +- arch/x86/kernel/cpu/microcode/core.c | 19 +- arch/x86/kernel/cpu/microcode/intel.c | 285 +++++++++++++++--------------- arch/x86/kernel/cpu/microcode/intel_lib.c | 58 +++--- 8 files changed, 253 insertions(+), 203 deletions(-)
Documentation/x86/early-microcode.txt +25 -0
@@ -40,3 +40,28 @@ 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 + +Builtin microcode +================= + +We can also load builtin microcode supplied through the regular firmware +builtin method CONFIG_FIRMWARE_IN_KERNEL. Here's an example: + +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin" +CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware" + +This basically means, you have the following tree structure locally: + +/lib/firmware/ +|-- amd-ucode +... +| |-- microcode_amd_fam15h.bin +... +|-- intel-ucode +... +| |-- 06-3a-09 +... + +so that the build system can find those files and integrate them into +the final kernel image. The early loader finds them and applies them.
arch/x86/Kconfig +14 -13
@@ -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"
arch/x86/include/asm/microcode.h +26 -0
@@ -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 */
arch/x86/include/asm/microcode_intel.h +0 -1
@@ -40,7 +40,6 @@ struct extended_sigtable {#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE)#define EXT_HEADER_SIZE (sizeof(struct extended_sigtable))#define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature)) -#define DWSIZE (sizeof(u32))#define get_totalsize (mc) \ (((struct microcode_intel *)mc)->hdr.datasize ? \
arch/x86/kernel/cpu/microcode/amd.c +6 -9
@@ -431,10 +431,6 @@ int __init save_microcode_in_initrd_amd(void)else container = cont_va; -if (ucode_new_rev) -pr_info ("microcode: updated early to new patch_level=0x%08x\n" , - ucode_new_rev); - eax =cpuid_eax (0x00000001 ); eax = ((eax >>8 ) &0xf ) + ((eax >>20 ) &0xff );
@@ -469,8 +465,7 @@ void reload_ucode_amd(void)if (mc && rev < mc->hdr.patch_id) {if (!__apply_microcode_amd (mc)) { ucode_new_rev = mc->hdr.patch_id; -pr_info ("microcode: reload patch_level=0x%08x\n" , - ucode_new_rev); +pr_info ("reload patch_level=0x%08x\n" , ucode_new_rev); } } }
@@ -793,15 +788,13 @@ static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover)return -EINVAL ; } - patch->data =kzalloc (patch_size,GFP_KERNEL ); + patch->data =kmemdup (fw +SECTION_HDR_SIZE , patch_size,GFP_KERNEL );if (!patch->data) {pr_err ("Patch data allocation failure.\n" );kfree (patch);return -EINVAL ; } -/* All looks ok, copy patch... */ -memcpy (patch->data, fw +SECTION_HDR_SIZE , patch_size);INIT_LIST_HEAD (&patch->plist); patch->patch_id = mc_hdr->patch_id; patch->equiv_cpu = proc_id;
@@ -957,6 +950,10 @@ struct microcode_ops * __init init_amd_microcode(void)return NULL ; } +if (ucode_new_rev) +pr_info_once ("microcode updated early to new patch_level=0x%08x\n" , + ucode_new_rev); +return µcode_amd_ops; }
arch/x86/kernel/cpu/microcode/core.c +6 -13
@@ -43,16 +43,8 @@#define MICROCODE_VERSION "2.01"static struct microcode_ops *microcode_ops; -static bool dis_ucode_ldr; -static int __init disable_loader (char *str) -{ - dis_ucode_ldr = true; -return 1 ; -} -__setup ("dis_ucode_ldr" , disable_loader); -/* * Synchronization. *
@@ -81,15 +73,16 @@ struct cpu_info_ctx {static bool __init check_loader_disabled_bsp (void ) { +static const char *__dis_opt_str ="dis_ucode_ldr" ; +#ifdef CONFIG_X86_32 const char *cmdline = (const char *)__pa_nodebug (boot_command_line); -const char *opt ="dis_ucode_ldr" ; -const char *option = (const char *)__pa_nodebug (opt); +const char *option = (const char *)__pa_nodebug (__dis_opt_str);bool *res = (bool *)__pa_nodebug (&dis_ucode_ldr);#else /* CONFIG_X86_64 */ const char *cmdline = boot_command_line; -const char *option ="dis_ucode_ldr" ; +const char *option = __dis_opt_str;bool *res = &dis_ucode_ldr;#endif
@@ -479,7 +472,7 @@ static enum ucode_state microcode_init_cpu(int cpu, bool refresh_fw)enum ucode_state ustate;struct ucode_cpu_info *uci = ucode_cpu_info + cpu; -if (uci && uci->valid) +if (uci->valid)return UCODE_OK ;if (collect_cpu_info (cpu))
@@ -630,7 +623,7 @@ int __init microcode_init(void)struct cpuinfo_x86 *c = &boot_cpu_data;int error; -if (paravirt_enabled () || dis_ucode_ldr) +if (dis_ucode_ldr)return -EINVAL ;if (c->x86_vendor ==X86_VENDOR_INTEL )
arch/x86/kernel/cpu/microcode/intel.c +139 -146
618 lines not on this page · raw message
arch/x86/kernel/cpu/microcode/intel_lib.c +37 -21
113 lines not on this page · raw message