commit dac6ca243c4c49a9ca7507d3d66140ebfac8b04b upstream. With CONFIG_DEBUG_PREEMPT enabled, I get: BUG: using smp_processor_id() in preemptible [00000000] code: swapper/0/1 caller is debug_smp_processor_id CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.12.0-rc2+ #2 Call Trace: dump_stack check_preemption_disabled debug_smp_processor_id save_microcode_in_initrd_amd ? microcode_init save_microcode_in_initrd ... because, well, it says it above, we're using smp_processor_id() in preemptible code. But passing the CPU number is not really needed. It is only used to determine whether we're on the BSP, and, if so, to save the microcode patch for early loading. [ We don't absolutely need to do it on the BSP but we do that customarily there. ] Instead, convert that function parameter to a boolean which denotes whether the patch should be saved or not, thereby avoiding the use of smp_processor_id() in preemptible code. Signed-off-by: Borislav Petkov <bp@suse.de> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/20170528200414.31305-1-bp@alien8.de Signed-off-by: Ingo Molnar <mingo@kernel.org> [arnd: rebased to 4.9, after running into warning: arch/x86/kernel/cpu/microcode/amd.c:881:30: self-comparison always evaluates to true] Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
79 lines
1.8 KiB
C
79 lines
1.8 KiB
C
#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);
|
|
|
|
#define PATCH_MAX_SIZE PAGE_SIZE
|
|
extern u8 amd_ucode_patch[PATCH_MAX_SIZE];
|
|
|
|
#ifdef CONFIG_MICROCODE_AMD
|
|
extern void __init load_ucode_amd_bsp(unsigned int family);
|
|
extern void load_ucode_amd_ap(void);
|
|
extern int __init save_microcode_in_initrd_amd(void);
|
|
void reload_ucode_amd(void);
|
|
#else
|
|
static inline void __init load_ucode_amd_bsp(unsigned int family) {}
|
|
static inline void load_ucode_amd_ap(void) {}
|
|
static inline int __init save_microcode_in_initrd_amd(void) { return -EINVAL; }
|
|
void reload_ucode_amd(void) {}
|
|
#endif
|
|
|
|
extern bool check_current_patch_level(u32 *rev, bool early);
|
|
#endif /* _ASM_X86_MICROCODE_AMD_H */
|