diff mbox series

[Bionic,5/5] x86/MCE/AMD: Fix the thresholding machineryinitialization order

Message ID 20190509192345.5321-6-kim.naru@amd.com
State New
Headers show
Series AMD Rome: Additional patches | expand

Commit Message

Naru, Kim May 9, 2019, 7:23 p.m. UTC
BugLink: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1819485

    x86/MCE/AMD: Fix the thresholding machinery initialization order

    Currently, the code sets up the thresholding interrupt vector and only
    then goes about initializing the thresholding banks. Which is wrong,
    because an early thresholding interrupt would cause a NULL pointer
    dereference when accessing those banks and prevent the machine from
    booting.

    Therefore, set the thresholding interrupt vector only *after* having
    initialized the banks successfully.

    Fixes: 18807ddb7f88 ("x86/mce/AMD: Reset Threshold Limit after logging error")
    Reported-by: Rafał Miłecki <rafal@milecki.pl>
    Reported-by: John Clemens <clemej@gmail.com>
    (backported from commit 60c8144afc287ef09ce8c1230c6aa972659ba1bb)
    Signed-off-by: Borislav Petkov <bp@suse.de>
    Tested-by: Rafał Miłecki <rafal@milecki.pl>
    Tested-by: John Clemens <john@deater.net>
    Cc: Aravind Gopalakrishnan <aravindksg.lkml@gmail.com>
    Cc: linux-edac@vger.kernel.org
    Cc: stable@vger.kernel.org
    Cc: Tony Luck <tony.luck@intel.com>
    Cc: x86@kernel.org
    Cc: Yazen Ghannam <Yazen.Ghannam@amd.com>
    Link: https://lkml.kernel.org/r/20181127101700.2964-1-zajec5@gmail.com
    Link: https://bugzilla.kernel.org/show_bug.cgi?id=201291
---
 arch/x86/kernel/cpu/mcheck/mce_amd.c | 19 ++++++-------------
 1 file changed, 6 insertions(+), 13 deletions(-)
diff mbox series

Patch

diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index 6ac306cd27fe..8f344bcbfec7 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -56,7 +56,7 @@ 
 /* Threshold LVT offset is at MSR0xC0000410[15:12] */
 #define SMCA_THR_LVT_OFF	0xF000
 
-static bool thresholding_en;
+static bool thresholding_irq_en;
 
 static const char * const th_names[] = {
 	"load_store",
@@ -533,9 +533,8 @@  prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr,
 
 set_offset:
 	offset = setup_APIC_mce_threshold(offset, new);
-
-	if ((offset == new) && (mce_threshold_vector != amd_threshold_interrupt))
-		mce_threshold_vector = amd_threshold_interrupt;
+	if (offset == new)
+		thresholding_irq_en = true;
 
 done:
 	mce_threshold_block_init(&b, offset);
@@ -1345,9 +1344,6 @@  int mce_threshold_remove_device(unsigned int cpu)
 {
 	unsigned int bank;
 
-	if (!thresholding_en)
-		return 0;
-
 	for (bank = 0; bank < mca_cfg.banks; ++bank) {
 		if (!(per_cpu(bank_map, cpu) & (1 << bank)))
 			continue;
@@ -1365,9 +1361,6 @@  int mce_threshold_create_device(unsigned int cpu)
 	struct threshold_bank **bp;
 	int err = 0;
 
-	if (!thresholding_en)
-		return 0;
-
 	bp = per_cpu(threshold_banks, cpu);
 	if (bp)
 		return 0;
@@ -1396,9 +1389,6 @@  static __init int threshold_init_device(void)
 {
 	unsigned lcpu = 0;
 
-	if (mce_threshold_vector == amd_threshold_interrupt)
-		thresholding_en = true;
-
 	/* to hit CPUs online before the notifier is up */
 	for_each_online_cpu(lcpu) {
 		int err = mce_threshold_create_device(lcpu);
@@ -1407,6 +1397,9 @@  static __init int threshold_init_device(void)
 			return err;
 	}
 
+	if (thresholding_irq_en)
+		mce_threshold_vector = amd_threshold_interrupt;
+
 	return 0;
 }
 /*