Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/MCE/AMD: Carve out the MC4_MISC thresholding quirk

The MC4_MISC thresholding quirk needs to be applied during S5 -> S0 and
S3 -> S0 state transitions, which follow different code paths. Carve it
out into a separate function and call it mce_amd_feature_init() where
the two code paths of the state transitions converge.

[ bp: massage commit message and the carved out function. ]

Signed-off-by: Shirish S <shirish.s@amd.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Vishal Verma <vishal.l.verma@intel.com>
Cc: Yazen Ghannam <yazen.ghannam@amd.com>
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/1547651417-23583-3-git-send-email-shirish.s@amd.com

authored by

Shirish S and committed by
Borislav Petkov
30aa3d26 c95b323d

+36 -29
+36
arch/x86/kernel/cpu/mce/amd.c
··· 545 545 return offset; 546 546 } 547 547 548 + /* 549 + * Turn off MC4_MISC thresholding banks on all family 0x15 models since 550 + * they're not supported there. 551 + */ 552 + void disable_err_thresholding(struct cpuinfo_x86 *c) 553 + { 554 + int i; 555 + u64 hwcr; 556 + bool need_toggle; 557 + u32 msrs[] = { 558 + 0x00000413, /* MC4_MISC0 */ 559 + 0xc0000408, /* MC4_MISC1 */ 560 + }; 561 + 562 + if (c->x86 != 0x15) 563 + return; 564 + 565 + rdmsrl(MSR_K7_HWCR, hwcr); 566 + 567 + /* McStatusWrEn has to be set */ 568 + need_toggle = !(hwcr & BIT(18)); 569 + 570 + if (need_toggle) 571 + wrmsrl(MSR_K7_HWCR, hwcr | BIT(18)); 572 + 573 + /* Clear CntP bit safely */ 574 + for (i = 0; i < ARRAY_SIZE(msrs); i++) 575 + msr_clear_bit(msrs[i], 62); 576 + 577 + /* restore old settings */ 578 + if (need_toggle) 579 + wrmsrl(MSR_K7_HWCR, hwcr); 580 + } 581 + 548 582 /* cpu init entry point, called from mce.c with preempt off */ 549 583 void mce_amd_feature_init(struct cpuinfo_x86 *c) 550 584 { 551 585 u32 low = 0, high = 0, address = 0; 552 586 unsigned int bank, block, cpu = smp_processor_id(); 553 587 int offset = -1; 588 + 589 + disable_err_thresholding(c); 554 590 555 591 for (bank = 0; bank < mca_cfg.banks; ++bank) { 556 592 if (mce_flags.smca)
-29
arch/x86/kernel/cpu/mce/core.c
··· 1611 1611 if (c->x86 == 0x15 && c->x86_model <= 0xf) 1612 1612 mce_flags.overflow_recov = 1; 1613 1613 1614 - /* 1615 - * Turn off MC4_MISC thresholding banks on all models since 1616 - * they're not supported there. 1617 - */ 1618 - if (c->x86 == 0x15) { 1619 - int i; 1620 - u64 hwcr; 1621 - bool need_toggle; 1622 - u32 msrs[] = { 1623 - 0x00000413, /* MC4_MISC0 */ 1624 - 0xc0000408, /* MC4_MISC1 */ 1625 - }; 1626 - 1627 - rdmsrl(MSR_K7_HWCR, hwcr); 1628 - 1629 - /* McStatusWrEn has to be set */ 1630 - need_toggle = !(hwcr & BIT(18)); 1631 - 1632 - if (need_toggle) 1633 - wrmsrl(MSR_K7_HWCR, hwcr | BIT(18)); 1634 - 1635 - /* Clear CntP bit safely */ 1636 - for (i = 0; i < ARRAY_SIZE(msrs); i++) 1637 - msr_clear_bit(msrs[i], 62); 1638 - 1639 - /* restore old settings */ 1640 - if (need_toggle) 1641 - wrmsrl(MSR_K7_HWCR, hwcr); 1642 - } 1643 1614 } 1644 1615 1645 1616 if (c->x86_vendor == X86_VENDOR_INTEL) {