x86/microcode/AMD: Change load_microcode_amd()'s param to bool to fix preemptibility bug
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>
This commit is contained in:
Родитель
5ed02dbb49
Коммит
dac6ca243c
|
@ -320,7 +320,7 @@ void load_ucode_amd_ap(unsigned int cpuid_1_eax)
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum ucode_state
|
static enum ucode_state
|
||||||
load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size);
|
load_microcode_amd(bool save, u8 family, const u8 *data, size_t size);
|
||||||
|
|
||||||
int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax)
|
int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax)
|
||||||
{
|
{
|
||||||
|
@ -338,8 +338,7 @@ int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax)
|
||||||
if (!desc.mc)
|
if (!desc.mc)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ret = load_microcode_amd(smp_processor_id(), x86_family(cpuid_1_eax),
|
ret = load_microcode_amd(true, x86_family(cpuid_1_eax), desc.data, desc.size);
|
||||||
desc.data, desc.size);
|
|
||||||
if (ret != UCODE_OK)
|
if (ret != UCODE_OK)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -675,7 +674,7 @@ static enum ucode_state __load_microcode_amd(u8 family, const u8 *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum ucode_state
|
static enum ucode_state
|
||||||
load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size)
|
load_microcode_amd(bool save, u8 family, const u8 *data, size_t size)
|
||||||
{
|
{
|
||||||
enum ucode_state ret;
|
enum ucode_state ret;
|
||||||
|
|
||||||
|
@ -689,8 +688,8 @@ load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size)
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
/* save BSP's matching patch for early load */
|
/* save BSP's matching patch for early load */
|
||||||
if (cpu_data(cpu).cpu_index == boot_cpu_data.cpu_index) {
|
if (save) {
|
||||||
struct ucode_patch *p = find_patch(cpu);
|
struct ucode_patch *p = find_patch(0);
|
||||||
if (p) {
|
if (p) {
|
||||||
memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
|
memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
|
||||||
memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data),
|
memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data),
|
||||||
|
@ -722,11 +721,12 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device,
|
||||||
{
|
{
|
||||||
char fw_name[36] = "amd-ucode/microcode_amd.bin";
|
char fw_name[36] = "amd-ucode/microcode_amd.bin";
|
||||||
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
||||||
|
bool bsp = c->cpu_index == boot_cpu_data.cpu_index;
|
||||||
enum ucode_state ret = UCODE_NFOUND;
|
enum ucode_state ret = UCODE_NFOUND;
|
||||||
const struct firmware *fw;
|
const struct firmware *fw;
|
||||||
|
|
||||||
/* reload ucode container only on the boot cpu */
|
/* reload ucode container only on the boot cpu */
|
||||||
if (!refresh_fw || c->cpu_index != boot_cpu_data.cpu_index)
|
if (!refresh_fw || !bsp)
|
||||||
return UCODE_OK;
|
return UCODE_OK;
|
||||||
|
|
||||||
if (c->x86 >= 0x15)
|
if (c->x86 >= 0x15)
|
||||||
|
@ -743,7 +743,7 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device,
|
||||||
goto fw_release;
|
goto fw_release;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = load_microcode_amd(cpu, c->x86, fw->data, fw->size);
|
ret = load_microcode_amd(bsp, c->x86, fw->data, fw->size);
|
||||||
|
|
||||||
fw_release:
|
fw_release:
|
||||||
release_firmware(fw);
|
release_firmware(fw);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче