diff options
| author | Borislav Petkov <bp@suse.de> | 2014-06-24 07:25:04 -0400 |
|---|---|---|
| committer | H. Peter Anvin <hpa@linux.intel.com> | 2014-07-14 15:21:40 -0400 |
| commit | 26bfa5f89486a8926cd4d4ca81a04d3f0f174934 (patch) | |
| tree | 5a51e1be2db950be44ffb3fb05f2df00811bda0f | |
| parent | 80a208bd3948aceddf0429bd9f9b4cd858d526df (diff) | |
x86, amd: Cleanup init_amd
Distribute family-specific code to corresponding functions.
Also,
* move the direct mapping splitting around the TSEG SMM area to
bsp_init_amd().
* kill ancient comment about what we should do for K5.
* merge amd_k7_smp_check() into its only caller init_amd_k7 and drop
cpu_has_mp macro.
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: http://lkml.kernel.org/r/1403609105-8332-3-git-send-email-bp@alien8.de
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
| -rw-r--r-- | arch/x86/kernel/cpu/amd.c | 339 |
1 files changed, 161 insertions, 178 deletions
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 8714a78414bf..bc360d3df60e 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <asm/processor.h> | 8 | #include <asm/processor.h> |
| 9 | #include <asm/apic.h> | 9 | #include <asm/apic.h> |
| 10 | #include <asm/cpu.h> | 10 | #include <asm/cpu.h> |
| 11 | #include <asm/smp.h> | ||
| 11 | #include <asm/pci-direct.h> | 12 | #include <asm/pci-direct.h> |
| 12 | 13 | ||
| 13 | #ifdef CONFIG_X86_64 | 14 | #ifdef CONFIG_X86_64 |
| @@ -50,7 +51,6 @@ static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) | |||
| 50 | return wrmsr_safe_regs(gprs); | 51 | return wrmsr_safe_regs(gprs); |
| 51 | } | 52 | } |
| 52 | 53 | ||
| 53 | #ifdef CONFIG_X86_32 | ||
| 54 | /* | 54 | /* |
| 55 | * B step AMD K6 before B 9730xxxx have hardware bugs that can cause | 55 | * B step AMD K6 before B 9730xxxx have hardware bugs that can cause |
| 56 | * misexecution of code under Linux. Owners of such processors should | 56 | * misexecution of code under Linux. Owners of such processors should |
| @@ -70,6 +70,7 @@ __asm__(".globl vide\n\t.align 4\nvide: ret"); | |||
| 70 | 70 | ||
| 71 | static void init_amd_k5(struct cpuinfo_x86 *c) | 71 | static void init_amd_k5(struct cpuinfo_x86 *c) |
| 72 | { | 72 | { |
| 73 | #ifdef CONFIG_X86_32 | ||
| 73 | /* | 74 | /* |
| 74 | * General Systems BIOSen alias the cpu frequency registers | 75 | * General Systems BIOSen alias the cpu frequency registers |
| 75 | * of the Elan at 0x000df000. Unfortuantly, one of the Linux | 76 | * of the Elan at 0x000df000. Unfortuantly, one of the Linux |
| @@ -83,11 +84,12 @@ static void init_amd_k5(struct cpuinfo_x86 *c) | |||
| 83 | if (inl(CBAR) & CBAR_ENB) | 84 | if (inl(CBAR) & CBAR_ENB) |
| 84 | outl(0 | CBAR_KEY, CBAR); | 85 | outl(0 | CBAR_KEY, CBAR); |
| 85 | } | 86 | } |
| 87 | #endif | ||
| 86 | } | 88 | } |
| 87 | 89 | ||
| 88 | |||
| 89 | static void init_amd_k6(struct cpuinfo_x86 *c) | 90 | static void init_amd_k6(struct cpuinfo_x86 *c) |
| 90 | { | 91 | { |
| 92 | #ifdef CONFIG_X86_32 | ||
| 91 | u32 l, h; | 93 | u32 l, h; |
| 92 | int mbytes = get_num_physpages() >> (20-PAGE_SHIFT); | 94 | int mbytes = get_num_physpages() >> (20-PAGE_SHIFT); |
| 93 | 95 | ||
| @@ -176,10 +178,44 @@ static void init_amd_k6(struct cpuinfo_x86 *c) | |||
| 176 | /* placeholder for any needed mods */ | 178 | /* placeholder for any needed mods */ |
| 177 | return; | 179 | return; |
| 178 | } | 180 | } |
| 181 | #endif | ||
| 179 | } | 182 | } |
| 180 | 183 | ||
| 181 | static void amd_k7_smp_check(struct cpuinfo_x86 *c) | 184 | static void init_amd_k7(struct cpuinfo_x86 *c) |
| 182 | { | 185 | { |
| 186 | #ifdef CONFIG_X86_32 | ||
| 187 | u32 l, h; | ||
| 188 | |||
| 189 | /* | ||
| 190 | * Bit 15 of Athlon specific MSR 15, needs to be 0 | ||
| 191 | * to enable SSE on Palomino/Morgan/Barton CPU's. | ||
| 192 | * If the BIOS didn't enable it already, enable it here. | ||
| 193 | */ | ||
| 194 | if (c->x86_model >= 6 && c->x86_model <= 10) { | ||
| 195 | if (!cpu_has(c, X86_FEATURE_XMM)) { | ||
| 196 | printk(KERN_INFO "Enabling disabled K7/SSE Support.\n"); | ||
| 197 | msr_clear_bit(MSR_K7_HWCR, 15); | ||
| 198 | set_cpu_cap(c, X86_FEATURE_XMM); | ||
| 199 | } | ||
| 200 | } | ||
| 201 | |||
| 202 | /* | ||
| 203 | * It's been determined by AMD that Athlons since model 8 stepping 1 | ||
| 204 | * are more robust with CLK_CTL set to 200xxxxx instead of 600xxxxx | ||
| 205 | * As per AMD technical note 27212 0.2 | ||
| 206 | */ | ||
| 207 | if ((c->x86_model == 8 && c->x86_mask >= 1) || (c->x86_model > 8)) { | ||
| 208 | rdmsr(MSR_K7_CLK_CTL, l, h); | ||
| 209 | if ((l & 0xfff00000) != 0x20000000) { | ||
| 210 | printk(KERN_INFO | ||
| 211 | "CPU: CLK_CTL MSR was %x. Reprogramming to %x\n", | ||
| 212 | l, ((l & 0x000fffff)|0x20000000)); | ||
| 213 | wrmsr(MSR_K7_CLK_CTL, (l & 0x000fffff)|0x20000000, h); | ||
| 214 | } | ||
| 215 | } | ||
| 216 | |||
| 217 | set_cpu_cap(c, X86_FEATURE_K7); | ||
| 218 | |||
| 183 | /* calling is from identify_secondary_cpu() ? */ | 219 | /* calling is from identify_secondary_cpu() ? */ |
| 184 | if (!c->cpu_index) | 220 | if (!c->cpu_index) |
| 185 | return; | 221 | return; |
| @@ -207,7 +243,7 @@ static void amd_k7_smp_check(struct cpuinfo_x86 *c) | |||
| 207 | if (((c->x86_model == 6) && (c->x86_mask >= 2)) || | 243 | if (((c->x86_model == 6) && (c->x86_mask >= 2)) || |
| 208 | ((c->x86_model == 7) && (c->x86_mask >= 1)) || | 244 | ((c->x86_model == 7) && (c->x86_mask >= 1)) || |
| 209 | (c->x86_model > 7)) | 245 | (c->x86_model > 7)) |
| 210 | if (cpu_has_mp) | 246 | if (cpu_has(c, X86_FEATURE_MP)) |
| 211 | return; | 247 | return; |
| 212 | 248 | ||
| 213 | /* If we get here, not a certified SMP capable AMD system. */ | 249 | /* If we get here, not a certified SMP capable AMD system. */ |
| @@ -219,45 +255,8 @@ static void amd_k7_smp_check(struct cpuinfo_x86 *c) | |||
| 219 | WARN_ONCE(1, "WARNING: This combination of AMD" | 255 | WARN_ONCE(1, "WARNING: This combination of AMD" |
| 220 | " processors is not suitable for SMP.\n"); | 256 | " processors is not suitable for SMP.\n"); |
| 221 | add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_NOW_UNRELIABLE); | 257 | add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_NOW_UNRELIABLE); |
| 222 | } | ||
| 223 | |||
| 224 | static void init_amd_k7(struct cpuinfo_x86 *c) | ||
| 225 | { | ||
| 226 | u32 l, h; | ||
| 227 | |||
| 228 | /* | ||
| 229 | * Bit 15 of Athlon specific MSR 15, needs to be 0 | ||
| 230 | * to enable SSE on Palomino/Morgan/Barton CPU's. | ||
| 231 | * If the BIOS didn't enable it already, enable it here. | ||
| 232 | */ | ||
| 233 | if (c->x86_model >= 6 && c->x86_model <= 10) { | ||
| 234 | if (!cpu_has(c, X86_FEATURE_XMM)) { | ||
| 235 | printk(KERN_INFO "Enabling disabled K7/SSE Support.\n"); | ||
| 236 | msr_clear_bit(MSR_K7_HWCR, 15); | ||
| 237 | set_cpu_cap(c, X86_FEATURE_XMM); | ||
| 238 | } | ||
| 239 | } | ||
| 240 | |||
| 241 | /* | ||
| 242 | * It's been determined by AMD that Athlons since model 8 stepping 1 | ||
| 243 | * are more robust with CLK_CTL set to 200xxxxx instead of 600xxxxx | ||
| 244 | * As per AMD technical note 27212 0.2 | ||
| 245 | */ | ||
| 246 | if ((c->x86_model == 8 && c->x86_mask >= 1) || (c->x86_model > 8)) { | ||
| 247 | rdmsr(MSR_K7_CLK_CTL, l, h); | ||
| 248 | if ((l & 0xfff00000) != 0x20000000) { | ||
| 249 | printk(KERN_INFO | ||
| 250 | "CPU: CLK_CTL MSR was %x. Reprogramming to %x\n", | ||
| 251 | l, ((l & 0x000fffff)|0x20000000)); | ||
| 252 | wrmsr(MSR_K7_CLK_CTL, (l & 0x000fffff)|0x20000000, h); | ||
| 253 | } | ||
| 254 | } | ||
| 255 | |||
| 256 | set_cpu_cap(c, X86_FEATURE_K7); | ||
| 257 | |||
| 258 | amd_k7_smp_check(c); | ||
| 259 | } | ||
| 260 | #endif | 258 | #endif |
| 259 | } | ||
| 261 | 260 | ||
| 262 | #ifdef CONFIG_NUMA | 261 | #ifdef CONFIG_NUMA |
| 263 | /* | 262 | /* |
| @@ -446,6 +445,26 @@ static void early_init_amd_mc(struct cpuinfo_x86 *c) | |||
| 446 | 445 | ||
| 447 | static void bsp_init_amd(struct cpuinfo_x86 *c) | 446 | static void bsp_init_amd(struct cpuinfo_x86 *c) |
| 448 | { | 447 | { |
| 448 | |||
| 449 | #ifdef CONFIG_X86_64 | ||
| 450 | if (c->x86 >= 0xf) { | ||
| 451 | unsigned long long tseg; | ||
| 452 | |||
| 453 | /* | ||
| 454 | * Split up direct mapping around the TSEG SMM area. | ||
| 455 | * Don't do it for gbpages because there seems very little | ||
| 456 | * benefit in doing so. | ||
| 457 | */ | ||
| 458 | if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg)) { | ||
| 459 | unsigned long pfn = tseg >> PAGE_SHIFT; | ||
| 460 | |||
| 461 | printk(KERN_DEBUG "tseg: %010llx\n", tseg); | ||
| 462 | if (pfn_range_is_mapped(pfn, pfn + 1)) | ||
| 463 | set_memory_4k((unsigned long)__va(tseg), 1); | ||
| 464 | } | ||
| 465 | } | ||
| 466 | #endif | ||
| 467 | |||
| 449 | if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { | 468 | if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { |
| 450 | 469 | ||
| 451 | if (c->x86 > 0x10 || | 470 | if (c->x86 > 0x10 || |
| @@ -515,10 +534,100 @@ static const int amd_erratum_383[]; | |||
| 515 | static const int amd_erratum_400[]; | 534 | static const int amd_erratum_400[]; |
| 516 | static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum); | 535 | static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum); |
| 517 | 536 | ||
| 537 | static void init_amd_k8(struct cpuinfo_x86 *c) | ||
| 538 | { | ||
| 539 | u32 level; | ||
| 540 | u64 value; | ||
| 541 | |||
| 542 | /* On C+ stepping K8 rep microcode works well for copy/memset */ | ||
| 543 | level = cpuid_eax(1); | ||
| 544 | if ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58) | ||
| 545 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | ||
| 546 | |||
| 547 | /* | ||
| 548 | * Some BIOSes incorrectly force this feature, but only K8 revision D | ||
| 549 | * (model = 0x14) and later actually support it. | ||
| 550 | * (AMD Erratum #110, docId: 25759). | ||
| 551 | */ | ||
| 552 | if (c->x86_model < 0x14 && cpu_has(c, X86_FEATURE_LAHF_LM)) { | ||
| 553 | clear_cpu_cap(c, X86_FEATURE_LAHF_LM); | ||
| 554 | if (!rdmsrl_amd_safe(0xc001100d, &value)) { | ||
| 555 | value &= ~BIT_64(32); | ||
| 556 | wrmsrl_amd_safe(0xc001100d, value); | ||
| 557 | } | ||
| 558 | } | ||
| 559 | |||
| 560 | if (!c->x86_model_id[0]) | ||
| 561 | strcpy(c->x86_model_id, "Hammer"); | ||
| 562 | } | ||
| 563 | |||
| 564 | static void init_amd_gh(struct cpuinfo_x86 *c) | ||
| 565 | { | ||
| 566 | #ifdef CONFIG_X86_64 | ||
| 567 | /* do this for boot cpu */ | ||
| 568 | if (c == &boot_cpu_data) | ||
| 569 | check_enable_amd_mmconf_dmi(); | ||
| 570 | |||
| 571 | fam10h_check_enable_mmcfg(); | ||
| 572 | #endif | ||
| 573 | |||
| 574 | /* | ||
| 575 | * Disable GART TLB Walk Errors on Fam10h. We do this here because this | ||
| 576 | * is always needed when GART is enabled, even in a kernel which has no | ||
| 577 | * MCE support built in. BIOS should disable GartTlbWlk Errors already. | ||
| 578 | * If it doesn't, we do it here as suggested by the BKDG. | ||
| 579 | * | ||
| 580 | * Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=33012 | ||
| 581 | */ | ||
| 582 | msr_set_bit(MSR_AMD64_MCx_MASK(4), 10); | ||
| 583 | |||
| 584 | /* | ||
| 585 | * On family 10h BIOS may not have properly enabled WC+ support, causing | ||
| 586 | * it to be converted to CD memtype. This may result in performance | ||
| 587 | * degradation for certain nested-paging guests. Prevent this conversion | ||
| 588 | * by clearing bit 24 in MSR_AMD64_BU_CFG2. | ||
| 589 | * | ||
| 590 | * NOTE: we want to use the _safe accessors so as not to #GP kvm | ||
| 591 | * guests on older kvm hosts. | ||
| 592 | */ | ||
| 593 | msr_clear_bit(MSR_AMD64_BU_CFG2, 24); | ||
| 594 | |||
| 595 | if (cpu_has_amd_erratum(c, amd_erratum_383)) | ||
| 596 | set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH); | ||
| 597 | } | ||
| 598 | |||
| 599 | static void init_amd_bd(struct cpuinfo_x86 *c) | ||
| 600 | { | ||
| 601 | u64 value; | ||
| 602 | |||
| 603 | /* re-enable TopologyExtensions if switched off by BIOS */ | ||
| 604 | if ((c->x86_model >= 0x10) && (c->x86_model <= 0x1f) && | ||
| 605 | !cpu_has(c, X86_FEATURE_TOPOEXT)) { | ||
| 606 | |||
| 607 | if (msr_set_bit(0xc0011005, 54) > 0) { | ||
| 608 | rdmsrl(0xc0011005, value); | ||
| 609 | if (value & BIT_64(54)) { | ||
| 610 | set_cpu_cap(c, X86_FEATURE_TOPOEXT); | ||
| 611 | pr_info(FW_INFO "CPU: Re-enabling disabled Topology Extensions Support.\n"); | ||
| 612 | } | ||
| 613 | } | ||
| 614 | } | ||
| 615 | |||
| 616 | /* | ||
| 617 | * The way access filter has a performance penalty on some workloads. | ||
| 618 | * Disable it on the affected CPUs. | ||
| 619 | */ | ||
| 620 | if ((c->x86_model >= 0x02) && (c->x86_model < 0x20)) { | ||
| 621 | if (!rdmsrl_safe(0xc0011021, &value) && !(value & 0x1E)) { | ||
| 622 | value |= 0x1E; | ||
| 623 | wrmsrl_safe(0xc0011021, value); | ||
| 624 | } | ||
| 625 | } | ||
| 626 | } | ||
| 627 | |||
| 518 | static void init_amd(struct cpuinfo_x86 *c) | 628 | static void init_amd(struct cpuinfo_x86 *c) |
| 519 | { | 629 | { |
| 520 | u32 dummy; | 630 | u32 dummy; |
| 521 | unsigned long long value; | ||
| 522 | 631 | ||
| 523 | #ifdef CONFIG_SMP | 632 | #ifdef CONFIG_SMP |
| 524 | /* | 633 | /* |
| @@ -540,100 +649,29 @@ static void init_amd(struct cpuinfo_x86 *c) | |||
| 540 | */ | 649 | */ |
| 541 | clear_cpu_cap(c, 0*32+31); | 650 | clear_cpu_cap(c, 0*32+31); |
| 542 | 651 | ||
| 543 | #ifdef CONFIG_X86_64 | ||
| 544 | /* On C+ stepping K8 rep microcode works well for copy/memset */ | ||
| 545 | if (c->x86 == 0xf) { | ||
| 546 | u32 level; | ||
| 547 | |||
| 548 | level = cpuid_eax(1); | ||
| 549 | if ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58) | ||
| 550 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | ||
| 551 | |||
| 552 | /* | ||
| 553 | * Some BIOSes incorrectly force this feature, but only K8 | ||
| 554 | * revision D (model = 0x14) and later actually support it. | ||
| 555 | * (AMD Erratum #110, docId: 25759). | ||
| 556 | */ | ||
| 557 | if (c->x86_model < 0x14 && cpu_has(c, X86_FEATURE_LAHF_LM)) { | ||
| 558 | clear_cpu_cap(c, X86_FEATURE_LAHF_LM); | ||
| 559 | if (!rdmsrl_amd_safe(0xc001100d, &value)) { | ||
| 560 | value &= ~(1ULL << 32); | ||
| 561 | wrmsrl_amd_safe(0xc001100d, value); | ||
| 562 | } | ||
| 563 | } | ||
| 564 | |||
| 565 | } | ||
| 566 | if (c->x86 >= 0x10) | 652 | if (c->x86 >= 0x10) |
| 567 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | 653 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); |
| 568 | 654 | ||
| 569 | /* get apicid instead of initial apic id from cpuid */ | 655 | /* get apicid instead of initial apic id from cpuid */ |
| 570 | c->apicid = hard_smp_processor_id(); | 656 | c->apicid = hard_smp_processor_id(); |
| 571 | #else | ||
| 572 | |||
| 573 | /* | ||
| 574 | * FIXME: We should handle the K5 here. Set up the write | ||
| 575 | * range and also turn on MSR 83 bits 4 and 31 (write alloc, | ||
| 576 | * no bus pipeline) | ||
| 577 | */ | ||
| 578 | |||
| 579 | switch (c->x86) { | ||
| 580 | case 4: | ||
| 581 | init_amd_k5(c); | ||
| 582 | break; | ||
| 583 | case 5: | ||
| 584 | init_amd_k6(c); | ||
| 585 | break; | ||
| 586 | case 6: /* An Athlon/Duron */ | ||
| 587 | init_amd_k7(c); | ||
| 588 | break; | ||
| 589 | } | ||
| 590 | 657 | ||
| 591 | /* K6s reports MCEs but don't actually have all the MSRs */ | 658 | /* K6s reports MCEs but don't actually have all the MSRs */ |
| 592 | if (c->x86 < 6) | 659 | if (c->x86 < 6) |
| 593 | clear_cpu_cap(c, X86_FEATURE_MCE); | 660 | clear_cpu_cap(c, X86_FEATURE_MCE); |
| 594 | #endif | 661 | |
| 662 | switch (c->x86) { | ||
| 663 | case 4: init_amd_k5(c); break; | ||
| 664 | case 5: init_amd_k6(c); break; | ||
| 665 | case 6: init_amd_k7(c); break; | ||
| 666 | case 0xf: init_amd_k8(c); break; | ||
| 667 | case 0x10: init_amd_gh(c); break; | ||
| 668 | case 0x15: init_amd_bd(c); break; | ||
| 669 | } | ||
| 595 | 670 | ||
| 596 | /* Enable workaround for FXSAVE leak */ | 671 | /* Enable workaround for FXSAVE leak */ |
| 597 | if (c->x86 >= 6) | 672 | if (c->x86 >= 6) |
| 598 | set_cpu_bug(c, X86_BUG_FXSAVE_LEAK); | 673 | set_cpu_bug(c, X86_BUG_FXSAVE_LEAK); |
| 599 | 674 | ||
| 600 | if (!c->x86_model_id[0]) { | ||
| 601 | switch (c->x86) { | ||
| 602 | case 0xf: | ||
| 603 | /* Should distinguish Models here, but this is only | ||
| 604 | a fallback anyways. */ | ||
| 605 | strcpy(c->x86_model_id, "Hammer"); | ||
| 606 | break; | ||
| 607 | } | ||
| 608 | } | ||
| 609 | |||
| 610 | /* re-enable TopologyExtensions if switched off by BIOS */ | ||
| 611 | if ((c->x86 == 0x15) && | ||
| 612 | (c->x86_model >= 0x10) && (c->x86_model <= 0x1f) && | ||
| 613 | !cpu_has(c, X86_FEATURE_TOPOEXT)) { | ||
| 614 | |||
| 615 | if (msr_set_bit(0xc0011005, 54) > 0) { | ||
| 616 | rdmsrl(0xc0011005, value); | ||
| 617 | if (value & BIT_64(54)) { | ||
| 618 | set_cpu_cap(c, X86_FEATURE_TOPOEXT); | ||
| 619 | pr_info(FW_INFO "CPU: Re-enabling disabled Topology Extensions Support.\n"); | ||
| 620 | } | ||
| 621 | } | ||
| 622 | } | ||
| 623 | |||
| 624 | /* | ||
| 625 | * The way access filter has a performance penalty on some workloads. | ||
| 626 | * Disable it on the affected CPUs. | ||
| 627 | */ | ||
| 628 | if ((c->x86 == 0x15) && | ||
| 629 | (c->x86_model >= 0x02) && (c->x86_model < 0x20)) { | ||
| 630 | |||
| 631 | if (!rdmsrl_safe(0xc0011021, &value) && !(value & 0x1E)) { | ||
| 632 | value |= 0x1E; | ||
| 633 | wrmsrl_safe(0xc0011021, value); | ||
| 634 | } | ||
| 635 | } | ||
| 636 | |||
| 637 | cpu_detect_cache_sizes(c); | 675 | cpu_detect_cache_sizes(c); |
| 638 | 676 | ||
| 639 | /* Multi core CPU? */ | 677 | /* Multi core CPU? */ |
| @@ -656,33 +694,6 @@ static void init_amd(struct cpuinfo_x86 *c) | |||
| 656 | set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC); | 694 | set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC); |
| 657 | } | 695 | } |
| 658 | 696 | ||
| 659 | #ifdef CONFIG_X86_64 | ||
| 660 | if (c->x86 == 0x10) { | ||
| 661 | /* do this for boot cpu */ | ||
| 662 | if (c == &boot_cpu_data) | ||
| 663 | check_enable_amd_mmconf_dmi(); | ||
| 664 | |||
| 665 | fam10h_check_enable_mmcfg(); | ||
| 666 | } | ||
| 667 | |||
| 668 | if (c == &boot_cpu_data && c->x86 >= 0xf) { | ||
| 669 | unsigned long long tseg; | ||
| 670 | |||
| 671 | /* | ||
| 672 | * Split up direct mapping around the TSEG SMM area. | ||
| 673 | * Don't do it for gbpages because there seems very little | ||
| 674 | * benefit in doing so. | ||
| 675 | */ | ||
| 676 | if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg)) { | ||
| 677 | unsigned long pfn = tseg >> PAGE_SHIFT; | ||
| 678 | |||
| 679 | printk(KERN_DEBUG "tseg: %010llx\n", tseg); | ||
| 680 | if (pfn_range_is_mapped(pfn, pfn + 1)) | ||
| 681 | set_memory_4k((unsigned long)__va(tseg), 1); | ||
| 682 | } | ||
| 683 | } | ||
| 684 | #endif | ||
| 685 | |||
| 686 | /* | 697 | /* |
| 687 | * Family 0x12 and above processors have APIC timer | 698 | * Family 0x12 and above processors have APIC timer |
| 688 | * running in deep C states. | 699 | * running in deep C states. |
| @@ -690,34 +701,6 @@ static void init_amd(struct cpuinfo_x86 *c) | |||
| 690 | if (c->x86 > 0x11) | 701 | if (c->x86 > 0x11) |
| 691 | set_cpu_cap(c, X86_FEATURE_ARAT); | 702 | set_cpu_cap(c, X86_FEATURE_ARAT); |
| 692 | 703 | ||
| 693 | if (c->x86 == 0x10) { | ||
| 694 | /* | ||
| 695 | * Disable GART TLB Walk Errors on Fam10h. We do this here | ||
| 696 | * because this is always needed when GART is enabled, even in a | ||
| 697 | * kernel which has no MCE support built in. | ||
| 698 | * BIOS should disable GartTlbWlk Errors already. If | ||
| 699 | * it doesn't, do it here as suggested by the BKDG. | ||
| 700 | * | ||
| 701 | * Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=33012 | ||
| 702 | */ | ||
| 703 | msr_set_bit(MSR_AMD64_MCx_MASK(4), 10); | ||
| 704 | |||
| 705 | /* | ||
| 706 | * On family 10h BIOS may not have properly enabled WC+ support, | ||
| 707 | * causing it to be converted to CD memtype. This may result in | ||
| 708 | * performance degradation for certain nested-paging guests. | ||
| 709 | * Prevent this conversion by clearing bit 24 in | ||
| 710 | * MSR_AMD64_BU_CFG2. | ||
| 711 | * | ||
| 712 | * NOTE: we want to use the _safe accessors so as not to #GP kvm | ||
| 713 | * guests on older kvm hosts. | ||
| 714 | */ | ||
| 715 | msr_clear_bit(MSR_AMD64_BU_CFG2, 24); | ||
| 716 | |||
| 717 | if (cpu_has_amd_erratum(c, amd_erratum_383)) | ||
| 718 | set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH); | ||
| 719 | } | ||
| 720 | |||
| 721 | if (cpu_has_amd_erratum(c, amd_erratum_400)) | 704 | if (cpu_has_amd_erratum(c, amd_erratum_400)) |
| 722 | set_cpu_bug(c, X86_BUG_AMD_APIC_C1E); | 705 | set_cpu_bug(c, X86_BUG_AMD_APIC_C1E); |
| 723 | 706 | ||
