| From foo@baz Tue Aug 14 16:14:56 CEST 2018 |
| From: Borislav Petkov <bp@suse.de> |
| Date: Fri, 22 Jun 2018 11:34:11 +0200 |
| Subject: x86/CPU/AMD: Move TOPOEXT reenablement before reading smp_num_siblings |
| |
| From: Borislav Petkov <bp@suse.de> |
| |
| commit 7ce2f0393ea2396142b7faf6ee9b1f3676d08a5f upstream |
| |
| The TOPOEXT reenablement is a workaround for broken BIOSen which didn't |
| enable the CPUID bit. amd_get_topology_early(), however, relies on |
| that bit being set so that it can read out the CPUID leaf and set |
| smp_num_siblings properly. |
| |
| Move the reenablement up to early_init_amd(). While at it, simplify |
| amd_get_topology_early(). |
| |
| [dwmw2: Backport to 4.9] |
| |
| Signed-off-by: Borislav Petkov <bp@suse.de> |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/x86/kernel/cpu/amd.c | 39 +++++++++++++++++++-------------------- |
| 1 file changed, 19 insertions(+), 20 deletions(-) |
| |
| --- a/arch/x86/kernel/cpu/amd.c |
| +++ b/arch/x86/kernel/cpu/amd.c |
| @@ -300,12 +300,8 @@ static int nearby_node(int apicid) |
| |
| static void amd_get_topology_early(struct cpuinfo_x86 *c) |
| { |
| - if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { |
| - u32 eax, ebx, ecx, edx; |
| - |
| - cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); |
| - smp_num_siblings = ((ebx >> 8) & 0xff) + 1; |
| - } |
| + if (cpu_has(c, X86_FEATURE_TOPOEXT)) |
| + smp_num_siblings = ((cpuid_ebx(0x8000001e) >> 8) & 0xff) + 1; |
| } |
| |
| /* |
| @@ -326,7 +322,6 @@ static void amd_get_topology(struct cpui |
| cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); |
| |
| node_id = ecx & 0xff; |
| - smp_num_siblings = ((ebx >> 8) & 0xff) + 1; |
| |
| if (c->x86 == 0x15) |
| c->cu_id = ebx & 0xff; |
| @@ -578,6 +573,8 @@ static void bsp_init_amd(struct cpuinfo_ |
| |
| static void early_init_amd(struct cpuinfo_x86 *c) |
| { |
| + u64 value; |
| + |
| early_init_amd_mc(c); |
| |
| /* |
| @@ -645,6 +642,21 @@ static void early_init_amd(struct cpuinf |
| if (cpu_has_amd_erratum(c, amd_erratum_400)) |
| set_cpu_bug(c, X86_BUG_AMD_E400); |
| |
| + |
| + /* Re-enable TopologyExtensions if switched off by BIOS */ |
| + if (c->x86 == 0x15 && |
| + (c->x86_model >= 0x10 && c->x86_model <= 0x6f) && |
| + !cpu_has(c, X86_FEATURE_TOPOEXT)) { |
| + |
| + if (msr_set_bit(0xc0011005, 54) > 0) { |
| + rdmsrl(0xc0011005, value); |
| + if (value & BIT_64(54)) { |
| + set_cpu_cap(c, X86_FEATURE_TOPOEXT); |
| + pr_info_once(FW_INFO "CPU: Re-enabling disabled Topology Extensions Support.\n"); |
| + } |
| + } |
| + } |
| + |
| amd_get_topology_early(c); |
| } |
| |
| @@ -737,19 +749,6 @@ static void init_amd_bd(struct cpuinfo_x |
| { |
| u64 value; |
| |
| - /* re-enable TopologyExtensions if switched off by BIOS */ |
| - if ((c->x86_model >= 0x10) && (c->x86_model <= 0x6f) && |
| - !cpu_has(c, X86_FEATURE_TOPOEXT)) { |
| - |
| - if (msr_set_bit(0xc0011005, 54) > 0) { |
| - rdmsrl(0xc0011005, value); |
| - if (value & BIT_64(54)) { |
| - set_cpu_cap(c, X86_FEATURE_TOPOEXT); |
| - pr_info_once(FW_INFO "CPU: Re-enabling disabled Topology Extensions Support.\n"); |
| - } |
| - } |
| - } |
| - |
| /* |
| * The way access filter has a performance penalty on some workloads. |
| * Disable it on the affected CPUs. |