x86: Fix boot failures on older AMD CPU's
People with old AMD chips are getting hung boots, because commit
bcb80e5387
("x86, microcode, AMD: Add microcode revision to
/proc/cpuinfo") moved the microcode detection too early into
"early_init_amd()".
At that point we are *so* early in the booth that the exception tables
haven't even been set up yet, so the whole
rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
doesn't actually work: if the rdmsr does a GP fault (due to non-existant
MSR register on older CPU's), we can't fix it up yet, and the boot fails.
Fix it by simply moving the code to a slightly later point in the boot
(init_amd() instead of early_init_amd()), since the kernel itself
doesn't even really care about the microcode patchlevel at this point
(or really ever: it's made available to user space in /proc/cpuinfo, and
updated if you do a microcode load).
Reported-tested-and-bisected-by: Larry Finger <Larry.Finger@lwfinger.net>
Tested-by: Bob Tracy <rct@gherkin.frus.com>
Acked-by: Borislav Petkov <borislav.petkov@amd.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
e5fd47bfab
commit
8e8da023f5
|
@ -442,8 +442,6 @@ static void __cpuinit bsp_init_amd(struct cpuinfo_x86 *c)
|
||||||
|
|
||||||
static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
|
static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
|
||||||
{
|
{
|
||||||
u32 dummy;
|
|
||||||
|
|
||||||
early_init_amd_mc(c);
|
early_init_amd_mc(c);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -473,12 +471,12 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
|
||||||
set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
|
set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __cpuinit init_amd(struct cpuinfo_x86 *c)
|
static void __cpuinit init_amd(struct cpuinfo_x86 *c)
|
||||||
{
|
{
|
||||||
|
u32 dummy;
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
unsigned long long value;
|
unsigned long long value;
|
||||||
|
|
||||||
|
@ -657,6 +655,8 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
|
||||||
checking_wrmsrl(MSR_AMD64_MCx_MASK(4), mask);
|
checking_wrmsrl(MSR_AMD64_MCx_MASK(4), mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
|
|
Loading…
Reference in New Issue