Commit d0a63f0e authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'ras_core_for_v6.12_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 RAS updates from Borislav Petkov:

 - Reorganize the struct mce populating functions so that MCA errors
   reported through BIOS' BERT method can report the correct CPU number
   the error has been detected on

* tag 'ras_core_for_v6.12_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/mce: Use mce_prep_record() helpers for apei_smca_report_x86_error()
  x86/mce: Define mce_prep_record() helpers for common and per-CPU fields
  x86/mce: Rename mce_setup() to mce_prep_record()
parents 79f1a6ad 793aa4bf
...@@ -221,7 +221,7 @@ static inline int apei_smca_report_x86_error(struct cper_ia_proc_ctx *ctx_info, ...@@ -221,7 +221,7 @@ static inline int apei_smca_report_x86_error(struct cper_ia_proc_ctx *ctx_info,
u64 lapic_id) { return -EINVAL; } u64 lapic_id) { return -EINVAL; }
#endif #endif
void mce_setup(struct mce *m); void mce_prep_record(struct mce *m);
void mce_log(struct mce *m); void mce_log(struct mce *m);
DECLARE_PER_CPU(struct device *, mce_device); DECLARE_PER_CPU(struct device *, mce_device);
......
...@@ -780,7 +780,7 @@ static void __log_error(unsigned int bank, u64 status, u64 addr, u64 misc) ...@@ -780,7 +780,7 @@ static void __log_error(unsigned int bank, u64 status, u64 addr, u64 misc)
{ {
struct mce m; struct mce m;
mce_setup(&m); mce_prep_record(&m);
m.status = status; m.status = status;
m.misc = misc; m.misc = misc;
......
...@@ -44,7 +44,7 @@ void apei_mce_report_mem_error(int severity, struct cper_sec_mem_err *mem_err) ...@@ -44,7 +44,7 @@ void apei_mce_report_mem_error(int severity, struct cper_sec_mem_err *mem_err)
else else
lsb = PAGE_SHIFT; lsb = PAGE_SHIFT;
mce_setup(&m); mce_prep_record(&m);
m.bank = -1; m.bank = -1;
/* Fake a memory read error with unknown channel */ /* Fake a memory read error with unknown channel */
m.status = MCI_STATUS_VAL | MCI_STATUS_EN | MCI_STATUS_ADDRV | MCI_STATUS_MISCV | 0x9f; m.status = MCI_STATUS_VAL | MCI_STATUS_EN | MCI_STATUS_ADDRV | MCI_STATUS_MISCV | 0x9f;
...@@ -66,6 +66,7 @@ EXPORT_SYMBOL_GPL(apei_mce_report_mem_error); ...@@ -66,6 +66,7 @@ EXPORT_SYMBOL_GPL(apei_mce_report_mem_error);
int apei_smca_report_x86_error(struct cper_ia_proc_ctx *ctx_info, u64 lapic_id) int apei_smca_report_x86_error(struct cper_ia_proc_ctx *ctx_info, u64 lapic_id)
{ {
const u64 *i_mce = ((const u64 *) (ctx_info + 1)); const u64 *i_mce = ((const u64 *) (ctx_info + 1));
bool apicid_found = false;
unsigned int cpu; unsigned int cpu;
struct mce m; struct mce m;
...@@ -97,20 +98,19 @@ int apei_smca_report_x86_error(struct cper_ia_proc_ctx *ctx_info, u64 lapic_id) ...@@ -97,20 +98,19 @@ int apei_smca_report_x86_error(struct cper_ia_proc_ctx *ctx_info, u64 lapic_id)
if (ctx_info->reg_arr_size < 48) if (ctx_info->reg_arr_size < 48)
return -EINVAL; return -EINVAL;
mce_setup(&m);
m.extcpu = -1;
m.socketid = -1;
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
if (cpu_data(cpu).topo.initial_apicid == lapic_id) { if (cpu_data(cpu).topo.initial_apicid == lapic_id) {
m.extcpu = cpu; apicid_found = true;
m.socketid = cpu_data(m.extcpu).topo.pkg_id;
break; break;
} }
} }
m.apicid = lapic_id; if (!apicid_found)
return -EINVAL;
mce_prep_record_common(&m);
mce_prep_record_per_cpu(cpu, &m);
m.bank = (ctx_info->msr_addr >> 4) & 0xFF; m.bank = (ctx_info->msr_addr >> 4) & 0xFF;
m.status = *i_mce; m.status = *i_mce;
m.addr = *(i_mce + 1); m.addr = *(i_mce + 1);
......
...@@ -117,20 +117,32 @@ static struct irq_work mce_irq_work; ...@@ -117,20 +117,32 @@ static struct irq_work mce_irq_work;
*/ */
BLOCKING_NOTIFIER_HEAD(x86_mce_decoder_chain); BLOCKING_NOTIFIER_HEAD(x86_mce_decoder_chain);
/* Do initial initialization of a struct mce */ void mce_prep_record_common(struct mce *m)
void mce_setup(struct mce *m)
{ {
memset(m, 0, sizeof(struct mce)); memset(m, 0, sizeof(struct mce));
m->cpu = m->extcpu = smp_processor_id();
m->cpuid = cpuid_eax(1);
m->cpuvendor = boot_cpu_data.x86_vendor;
m->mcgcap = __rdmsr(MSR_IA32_MCG_CAP);
/* need the internal __ version to avoid deadlocks */ /* need the internal __ version to avoid deadlocks */
m->time = __ktime_get_real_seconds(); m->time = __ktime_get_real_seconds();
m->cpuvendor = boot_cpu_data.x86_vendor; }
m->cpuid = cpuid_eax(1);
m->socketid = cpu_data(m->extcpu).topo.pkg_id; void mce_prep_record_per_cpu(unsigned int cpu, struct mce *m)
m->apicid = cpu_data(m->extcpu).topo.initial_apicid; {
m->mcgcap = __rdmsr(MSR_IA32_MCG_CAP); m->cpu = cpu;
m->ppin = cpu_data(m->extcpu).ppin; m->extcpu = cpu;
m->microcode = boot_cpu_data.microcode; m->apicid = cpu_data(cpu).topo.initial_apicid;
m->microcode = cpu_data(cpu).microcode;
m->ppin = topology_ppin(cpu);
m->socketid = topology_physical_package_id(cpu);
}
/* Do initial initialization of a struct mce */
void mce_prep_record(struct mce *m)
{
mce_prep_record_common(m);
mce_prep_record_per_cpu(smp_processor_id(), m);
} }
DEFINE_PER_CPU(struct mce, injectm); DEFINE_PER_CPU(struct mce, injectm);
...@@ -436,11 +448,11 @@ static noinstr void mce_wrmsrl(u32 msr, u64 v) ...@@ -436,11 +448,11 @@ static noinstr void mce_wrmsrl(u32 msr, u64 v)
static noinstr void mce_gather_info(struct mce *m, struct pt_regs *regs) static noinstr void mce_gather_info(struct mce *m, struct pt_regs *regs)
{ {
/* /*
* Enable instrumentation around mce_setup() which calls external * Enable instrumentation around mce_prep_record() which calls external
* facilities. * facilities.
*/ */
instrumentation_begin(); instrumentation_begin();
mce_setup(m); mce_prep_record(m);
instrumentation_end(); instrumentation_end();
m->mcgstatus = mce_rdmsrl(MSR_IA32_MCG_STATUS); m->mcgstatus = mce_rdmsrl(MSR_IA32_MCG_STATUS);
......
...@@ -261,6 +261,8 @@ enum mca_msr { ...@@ -261,6 +261,8 @@ enum mca_msr {
/* Decide whether to add MCE record to MCE event pool or filter it out. */ /* Decide whether to add MCE record to MCE event pool or filter it out. */
extern bool filter_mce(struct mce *m); extern bool filter_mce(struct mce *m);
void mce_prep_record_common(struct mce *m);
void mce_prep_record_per_cpu(unsigned int cpu, struct mce *m);
#ifdef CONFIG_X86_MCE_AMD #ifdef CONFIG_X86_MCE_AMD
extern bool amd_filter_mce(struct mce *m); extern bool amd_filter_mce(struct mce *m);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment