Skip to content

Commit cca9cc0

Browse files
KAGA-KOKOsuryasaimadhu
authored andcommitted
x86/mce/amd: Protect a not-fully initialized bank from the thresholding interrupt
Make sure the thresholding bank descriptor is fully initialized when the thresholding interrupt fires after a hotplug event. [ bp: Write commit message and document long-forgotten bank_map. ] Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent c9bf318 commit cca9cc0

File tree

1 file changed

+17
-2
lines changed
  • arch/x86/kernel/cpu/mce

1 file changed

+17
-2
lines changed

arch/x86/kernel/cpu/mce/amd.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,12 @@ EXPORT_SYMBOL_GPL(smca_banks);
192192
static char buf_mcatype[MAX_MCATYPE_NAME_LEN];
193193

194194
static DEFINE_PER_CPU(struct threshold_bank **, threshold_banks);
195-
static DEFINE_PER_CPU(unsigned int, bank_map); /* see which banks are on */
195+
196+
/*
197+
* A list of the banks enabled on each logical CPU. Controls which respective
198+
* descriptors to initialize later in mce_threshold_create_device().
199+
*/
200+
static DEFINE_PER_CPU(unsigned int, bank_map);
196201

197202
/* Map of banks that have more than MCA_MISC0 available. */
198203
static DEFINE_PER_CPU(u32, smca_misc_banks_map);
@@ -1016,13 +1021,22 @@ static void log_and_reset_block(struct threshold_block *block)
10161021
static void amd_threshold_interrupt(void)
10171022
{
10181023
struct threshold_block *first_block = NULL, *block = NULL, *tmp = NULL;
1024+
struct threshold_bank **bp = this_cpu_read(threshold_banks);
10191025
unsigned int bank, cpu = smp_processor_id();
10201026

1027+
/*
1028+
* Validate that the threshold bank has been initialized already. The
1029+
* handler is installed at boot time, but on a hotplug event the
1030+
* interrupt might fire before the data has been initialized.
1031+
*/
1032+
if (!bp)
1033+
return;
1034+
10211035
for (bank = 0; bank < this_cpu_read(mce_num_banks); ++bank) {
10221036
if (!(per_cpu(bank_map, cpu) & (1 << bank)))
10231037
continue;
10241038

1025-
first_block = per_cpu(threshold_banks, cpu)[bank]->blocks;
1039+
first_block = bp[bank]->blocks;
10261040
if (!first_block)
10271041
continue;
10281042

@@ -1247,6 +1261,7 @@ static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb
12471261

12481262
INIT_LIST_HEAD(&b->miscj);
12491263

1264+
/* This is safe as @tb is not visible yet */
12501265
if (tb->blocks)
12511266
list_add(&b->miscj, &tb->blocks->miscj);
12521267
else

0 commit comments

Comments
 (0)