[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20230127151601.1068324-1-muralimk@amd.com>
Date: Fri, 27 Jan 2023 15:16:01 +0000
From: Muralidhara M K <muralimk@....com>
To: <linux-edac@...r.kernel.org>, <x86@...nel.org>
CC: <linux-kernel@...r.kernel.org>, <bp@...en8.de>, <mingo@...hat.com>,
<mchehab@...nel.org>, <yazen.ghannam@....com>, <nchatrad@....com>,
Muralidhara M K <muralimk@....com>
Subject: [PATCH] x86/MCE/AMD: avoid shift-out-of-bounds when decoding bank
Fix dump stack due to shift-out-of-bounds in
arch/x86/kernel/cpu/mce/amd.c when UBSAN configs are enabled.
Maximum number of MCA banks is 64 (MAX_NR_BANKS) from commit
a0bc32b3cacf ("x86/mce: Increase maximum number of banks to 64").
But the driver uses 32 bit variable(bank_map and smca_misc_banks_map)
to manage the list of banks which causes out-of-bounds warnings.
So, fix would be to change the data types of bank_map and
smca_misc_banks_map in addition to switch the bit mask assignment to
use BIT_ULL() for 64-bit type.
Signed-off-by: Muralidhara M K <muralimk@....com>
---
arch/x86/kernel/cpu/mce/amd.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c
index 10fb5b5c9efa..5518272061bf 100644
--- a/arch/x86/kernel/cpu/mce/amd.c
+++ b/arch/x86/kernel/cpu/mce/amd.c
@@ -235,10 +235,10 @@ static DEFINE_PER_CPU(struct threshold_bank **, threshold_banks);
* A list of the banks enabled on each logical CPU. Controls which respective
* descriptors to initialize later in mce_threshold_create_device().
*/
-static DEFINE_PER_CPU(unsigned int, bank_map);
+static DEFINE_PER_CPU(u64, bank_map);
/* Map of banks that have more than MCA_MISC0 available. */
-static DEFINE_PER_CPU(u32, smca_misc_banks_map);
+static DEFINE_PER_CPU(u64, smca_misc_banks_map);
static void amd_threshold_interrupt(void);
static void amd_deferred_error_interrupt(void);
@@ -267,7 +267,7 @@ static void smca_set_misc_banks_map(unsigned int bank, unsigned int cpu)
return;
if (low & MASK_BLKPTR_LO)
- per_cpu(smca_misc_banks_map, cpu) |= BIT(bank);
+ per_cpu(smca_misc_banks_map, cpu) |= BIT_ULL(bank);
}
@@ -528,7 +528,7 @@ static u32 smca_get_block_address(unsigned int bank, unsigned int block,
if (!block)
return MSR_AMD64_SMCA_MCx_MISC(bank);
- if (!(per_cpu(smca_misc_banks_map, cpu) & BIT(bank)))
+ if (!(per_cpu(smca_misc_banks_map, cpu) & BIT_ULL(bank)))
return 0;
return MSR_AMD64_SMCA_MCx_MISCy(bank, block - 1);
@@ -572,7 +572,7 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr,
int new;
if (!block)
- per_cpu(bank_map, cpu) |= (1 << bank);
+ per_cpu(bank_map, cpu) |= BIT_ULL(bank);
memset(&b, 0, sizeof(b));
b.cpu = cpu;
@@ -884,7 +884,7 @@ static void amd_threshold_interrupt(void)
return;
for (bank = 0; bank < this_cpu_read(mce_num_banks); ++bank) {
- if (!(per_cpu(bank_map, cpu) & (1 << bank)))
+ if (!(per_cpu(bank_map, cpu) & BIT_ULL(bank)))
continue;
first_block = bp[bank]->blocks;
@@ -1362,7 +1362,7 @@ int mce_threshold_create_device(unsigned int cpu)
return -ENOMEM;
for (bank = 0; bank < numbanks; ++bank) {
- if (!(this_cpu_read(bank_map) & (1 << bank)))
+ if (!(this_cpu_read(bank_map) & BIT_ULL(bank)))
continue;
err = threshold_create_bank(bp, cpu, bank);
if (err) {
--
2.25.1
Powered by blists - more mailing lists