Skip to content

Commit d320a9f

Browse files
committed
Merge: MCA: add support for 56 bit addresses
MR: https://gitlab.com/redhat/rhel/src/kernel/rhel-9/-/merge_requests/867 Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2164637 Tested: by me, sanity These series add MCA support for addresses using 56 bits instead of the current 55 bits limit. Signed-off-by: Aristeu Rozanski <arozansk@redhat.com> Approved-by: David Arcari <darcari@redhat.com> Approved-by: John B. Wyatt IV <jwyatt@redhat.com> Signed-off-by: Jan Stancek <jstancek@redhat.com>
2 parents 0d1cea7 + 3d789c1 commit d320a9f

File tree

3 files changed

+49
-23
lines changed

3 files changed

+49
-23
lines changed

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

Lines changed: 3 additions & 9 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

@@ -736,15 +738,7 @@ static void __log_error(unsigned int bank, u64 status, u64 addr, u64 misc)
736738
if (m.status & MCI_STATUS_ADDRV) {
737739
m.addr = addr;
738740

739-
/*
740-
* Extract [55:<lsb>] where lsb is the least significant
741-
* *valid* bit of the address bits.
742-
*/
743-
if (mce_flags.smca) {
744-
u8 lsb = (m.addr >> 56) & 0x3f;
745-
746-
m.addr &= GENMASK_ULL(55, lsb);
747-
}
741+
smca_extract_err_addr(&m);
748742
}
749743

750744
if (mce_flags.smca) {

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

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +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-
bool init; /* initialise bank? */
73-
};
74-
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);
7571

7672
#define ATTR_LEN 16
7773
/* One object for each MCE bank, shared by all CPUs */
@@ -652,15 +648,7 @@ static noinstr void mce_read_aux(struct mce *m, int i)
652648
m->addr <<= shift;
653649
}
654650

655-
/*
656-
* Extract [55:<lsb>] where lsb is the least significant
657-
* *valid* bit of the address bits.
658-
*/
659-
if (mce_flags.smca) {
660-
u8 lsb = (m->addr >> 56) & 0x3f;
661-
662-
m->addr &= GENMASK_ULL(55, lsb);
663-
}
651+
smca_extract_err_addr(m);
664652
}
665653

666654
if (mce_flags.smca) {

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

Lines changed: 44 additions & 0 deletions
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,
@@ -188,8 +206,34 @@ extern bool filter_mce(struct mce *m);
188206

189207
#ifdef CONFIG_X86_MCE_AMD
190208
extern bool amd_filter_mce(struct mce *m);
209+
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+
*/
214+
static __always_inline void smca_extract_err_addr(struct mce *m)
215+
{
216+
u8 lsb;
217+
218+
if (!mce_flags.smca)
219+
return;
220+
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+
229+
lsb = (m->addr >> 56) & 0x3f;
230+
231+
m->addr &= GENMASK_ULL(55, lsb);
232+
}
233+
191234
#else
192235
static inline bool amd_filter_mce(struct mce *m) { return false; }
236+
static inline void smca_extract_err_addr(struct mce *m) { }
193237
#endif
194238

195239
#ifdef CONFIG_X86_ANCIENT_MCE

0 commit comments

Comments
 (0)