Skip to content

Commit 3d789c1

Browse files
committed
x86/mce: Add support for Extended Physical Address MCA changes
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2164637 Tested: by me, sanity commit fcd343a Author: Smita Koralahalli <Smita.KoralahalliChannabasappa@amd.com> Date: Tue Dec 6 11:36:07 2022 -0600 x86/mce: Add support for Extended Physical Address MCA changes Newer AMD CPUs support more physical address bits. That is, the MCA_ADDR registers on Scalable MCA systems contain the ErrorAddr in bits [56:0] instead of [55:0]. Hence, the existing LSB field from bits [61:56] in MCA_ADDR must be moved around to accommodate the larger ErrorAddr size. MCA_CONFIG[McaLsbInStatusSupported] indicates this change. If set, the LSB field will be found in MCA_STATUS rather than MCA_ADDR. Each logical CPU has unique MCA bank in hardware and is not shared with other logical CPUs. Additionally, on SMCA systems, each feature bit may be different for each bank within same logical CPU. Check for MCA_CONFIG[McaLsbInStatusSupported] for each MCA bank and for each CPU. Additionally, all MCA banks do not support maximum ErrorAddr bits in MCA_ADDR. Some banks might support fewer bits but the remaining bits are marked as reserved. [ Yazen: Rebased and fixed up formatting. bp: Massage comments. ] Signed-off-by: Smita Koralahalli <Smita.KoralahalliChannabasappa@amd.com> Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Link: https://lore.kernel.org/r/20221206173607.1185907-5-yazen.ghannam@amd.com Signed-off-by: Aristeu Rozanski <arozansk@redhat.com>
1 parent b986680 commit 3d789c1

File tree

3 files changed

+33
-8
lines changed

3 files changed

+33
-8
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,8 @@ static void smca_configure(unsigned int bank, unsigned int cpu)
306306
if ((low & BIT(5)) && !((high >> 5) & 0x3))
307307
high |= BIT(5);
308308

309+
this_cpu_ptr(mce_banks_array)[bank].lsb_in_status = !!(low & BIT(8));
310+
309311
wrmsr(smca_config, low, high);
310312
}
311313

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

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,7 @@ DEFINE_PER_CPU(unsigned, mce_exception_count);
6767

6868
DEFINE_PER_CPU_READ_MOSTLY(unsigned int, mce_num_banks);
6969

70-
struct mce_bank {
71-
u64 ctl; /* subevents to enable */
72-
73-
__u64 init : 1, /* initialise bank? */
74-
__reserved_1 : 63;
75-
};
76-
static DEFINE_PER_CPU_READ_MOSTLY(struct mce_bank[MAX_NR_BANKS], mce_banks_array);
70+
DEFINE_PER_CPU_READ_MOSTLY(struct mce_bank[MAX_NR_BANKS], mce_banks_array);
7771

7872
#define ATTR_LEN 16
7973
/* One object for each MCE bank, shared by all CPUs */

arch/x86/kernel/cpu/mce/internal.h

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,24 @@ struct mce_vendor_flags {
174174

175175
extern struct mce_vendor_flags mce_flags;
176176

177+
struct mce_bank {
178+
/* subevents to enable */
179+
u64 ctl;
180+
181+
/* initialise bank? */
182+
__u64 init : 1,
183+
184+
/*
185+
* (AMD) MCA_CONFIG[McaLsbInStatusSupported]: When set, this bit indicates
186+
* the LSB field is found in MCA_STATUS and not in MCA_ADDR.
187+
*/
188+
lsb_in_status : 1,
189+
190+
__reserved_1 : 62;
191+
};
192+
193+
DECLARE_PER_CPU_READ_MOSTLY(struct mce_bank[MAX_NR_BANKS], mce_banks_array);
194+
177195
enum mca_msr {
178196
MCA_CTL,
179197
MCA_STATUS,
@@ -189,14 +207,25 @@ extern bool filter_mce(struct mce *m);
189207
#ifdef CONFIG_X86_MCE_AMD
190208
extern bool amd_filter_mce(struct mce *m);
191209

192-
/* Extract [55:<lsb>] where lsb is the LS-*valid* bit of the address bits. */
210+
/*
211+
* If MCA_CONFIG[McaLsbInStatusSupported] is set, extract ErrAddr in bits
212+
* [56:0] of MCA_STATUS, else in bits [55:0] of MCA_ADDR.
213+
*/
193214
static __always_inline void smca_extract_err_addr(struct mce *m)
194215
{
195216
u8 lsb;
196217

197218
if (!mce_flags.smca)
198219
return;
199220

221+
if (this_cpu_ptr(mce_banks_array)[m->bank].lsb_in_status) {
222+
lsb = (m->status >> 24) & 0x3f;
223+
224+
m->addr &= GENMASK_ULL(56, lsb);
225+
226+
return;
227+
}
228+
200229
lsb = (m->addr >> 56) & 0x3f;
201230

202231
m->addr &= GENMASK_ULL(55, lsb);

0 commit comments

Comments
 (0)