Skip to content
Snippets Groups Projects
  • Torsten Kaiser's avatar
    84516098
    x86, microcode, AMD: Fix early microcode loading · 84516098
    Torsten Kaiser authored
    
    load_microcode_amd() (and the helper it is using) should not have an
    cpu parameter. The microcode loading does not depend on the CPU wrt the
    patches loaded since they will end up in a global list for all CPUs
    anyway.
    
    The change from cpu to x86family in load_microcode_amd()
    now allows to drop the code messing with cpu_data(cpu) from
    collect_cpu_info_amd_early(), which is wrong anyway because at that
    point the per-cpu cpu_info is not yet setup (These values would later be
    overwritten by smp_store_boot_cpu_info() / smp_store_cpu_info()).
    
    Fold the rest of collect_cpu_info_amd_early() into load_ucode_amd_ap(),
    because its only used at one place and without the cpuinfo_x86 accesses
    it was not much left.
    
    Signed-off-by: default avatarTorsten Kaiser <just.for.lkml@googlemail.com>
    [ Fengguang: build fix ]
    Signed-off-by: default avatarFengguang Wu <fengguang.wu@intel.com>
    [ Boris: adapt it to current tree. ]
    Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
    84516098
    History
    x86, microcode, AMD: Fix early microcode loading
    Torsten Kaiser authored
    
    load_microcode_amd() (and the helper it is using) should not have an
    cpu parameter. The microcode loading does not depend on the CPU wrt the
    patches loaded since they will end up in a global list for all CPUs
    anyway.
    
    The change from cpu to x86family in load_microcode_amd()
    now allows to drop the code messing with cpu_data(cpu) from
    collect_cpu_info_amd_early(), which is wrong anyway because at that
    point the per-cpu cpu_info is not yet setup (These values would later be
    overwritten by smp_store_boot_cpu_info() / smp_store_cpu_info()).
    
    Fold the rest of collect_cpu_info_amd_early() into load_ucode_amd_ap(),
    because its only used at one place and without the cpuinfo_x86 accesses
    it was not much left.
    
    Signed-off-by: default avatarTorsten Kaiser <just.for.lkml@googlemail.com>
    [ Fengguang: build fix ]
    Signed-off-by: default avatarFengguang Wu <fengguang.wu@intel.com>
    [ Boris: adapt it to current tree. ]
    Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
microcode_amd.h 1.78 KiB
#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(u8 family, 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 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 load_ucode_amd_ap(void) {}
static inline int __init save_microcode_in_initrd_amd(void) { return -EINVAL; }
#endif

#endif /* _ASM_X86_MICROCODE_AMD_H */