Skip to content

Commit d84c035

Browse files
committed
x86/mce: Define mce_prep_record() helpers for common and per-CPU fields
JIRA: https://issues.redhat.com/browse/RHEL-52657 Tested: by AMD commit f9bbb8a Author: Yazen Ghannam <yazen.ghannam@amd.com> Date: Tue Jul 30 13:29:57 2024 -0500 x86/mce: Define mce_prep_record() helpers for common and per-CPU fields Generally, MCA information for an error is gathered on the CPU that reported the error. In this case, CPU-specific information from the running CPU will be correct. However, this will be incorrect if the MCA information is gathered while running on a CPU that didn't report the error. One example is creating an MCA record using mce_prep_record() for errors reported from ACPI. Split mce_prep_record() so that there is a helper function to gather common, i.e. not CPU-specific, information and another helper for CPU-specific information. Leave mce_prep_record() defined as-is for the common case when running on the reporting CPU. Get MCG_CAP in the global helper even though the register is per-CPU. This value is not already cached per-CPU like other values. And it does not assist with any per-CPU decoding or handling. Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Reviewed-by: Nikolay Borisov <nik.borisov@suse.com> Link: https://lore.kernel.org/r/20240730182958.4117158-3-yazen.ghannam@amd.com Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Signed-off-by: Aristeu Rozanski <arozansk@redhat.com>
1 parent 185e101 commit d84c035

File tree

2 files changed

+25
-11
lines changed

2 files changed

+25
-11
lines changed

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

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,20 +116,32 @@ static struct irq_work mce_irq_work;
116116
*/
117117
BLOCKING_NOTIFIER_HEAD(x86_mce_decoder_chain);
118118

119-
/* Do initial initialization of a struct mce */
120-
void mce_prep_record(struct mce *m)
119+
void mce_prep_record_common(struct mce *m)
121120
{
122121
memset(m, 0, sizeof(struct mce));
123-
m->cpu = m->extcpu = smp_processor_id();
122+
123+
m->cpuid = cpuid_eax(1);
124+
m->cpuvendor = boot_cpu_data.x86_vendor;
125+
m->mcgcap = __rdmsr(MSR_IA32_MCG_CAP);
124126
/* need the internal __ version to avoid deadlocks */
125-
m->time = __ktime_get_real_seconds();
126-
m->cpuvendor = boot_cpu_data.x86_vendor;
127-
m->cpuid = cpuid_eax(1);
128-
m->socketid = cpu_data(m->extcpu).topo.pkg_id;
129-
m->apicid = cpu_data(m->extcpu).topo.initial_apicid;
130-
m->mcgcap = __rdmsr(MSR_IA32_MCG_CAP);
131-
m->ppin = cpu_data(m->extcpu).ppin;
132-
m->microcode = boot_cpu_data.microcode;
127+
m->time = __ktime_get_real_seconds();
128+
}
129+
130+
void mce_prep_record_per_cpu(unsigned int cpu, struct mce *m)
131+
{
132+
m->cpu = cpu;
133+
m->extcpu = cpu;
134+
m->apicid = cpu_data(cpu).topo.initial_apicid;
135+
m->microcode = cpu_data(cpu).microcode;
136+
m->ppin = topology_ppin(cpu);
137+
m->socketid = topology_physical_package_id(cpu);
138+
}
139+
140+
/* Do initial initialization of a struct mce */
141+
void mce_prep_record(struct mce *m)
142+
{
143+
mce_prep_record_common(m);
144+
mce_prep_record_per_cpu(smp_processor_id(), m);
133145
}
134146

135147
DEFINE_PER_CPU(struct mce, injectm);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ enum mca_msr {
209209

210210
/* Decide whether to add MCE record to MCE event pool or filter it out. */
211211
extern bool filter_mce(struct mce *m);
212+
void mce_prep_record_common(struct mce *m);
213+
void mce_prep_record_per_cpu(unsigned int cpu, struct mce *m);
212214

213215
#ifdef CONFIG_X86_MCE_AMD
214216
extern bool amd_filter_mce(struct mce *m);

0 commit comments

Comments
 (0)