mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 09:04:39 +02:00
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>
This commit is contained in:
parent
5ad21a2497
commit
f9bbb8ad0c
|
|
@ -117,20 +117,32 @@ static struct irq_work mce_irq_work;
|
|||
*/
|
||||
BLOCKING_NOTIFIER_HEAD(x86_mce_decoder_chain);
|
||||
|
||||
void mce_prep_record_common(struct mce *m)
|
||||
{
|
||||
memset(m, 0, sizeof(struct mce));
|
||||
|
||||
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 */
|
||||
m->time = __ktime_get_real_seconds();
|
||||
}
|
||||
|
||||
void mce_prep_record_per_cpu(unsigned int cpu, struct mce *m)
|
||||
{
|
||||
m->cpu = cpu;
|
||||
m->extcpu = cpu;
|
||||
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)
|
||||
{
|
||||
memset(m, 0, sizeof(struct mce));
|
||||
m->cpu = m->extcpu = smp_processor_id();
|
||||
/* need the internal __ version to avoid deadlocks */
|
||||
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;
|
||||
m->apicid = cpu_data(m->extcpu).topo.initial_apicid;
|
||||
m->mcgcap = __rdmsr(MSR_IA32_MCG_CAP);
|
||||
m->ppin = cpu_data(m->extcpu).ppin;
|
||||
m->microcode = boot_cpu_data.microcode;
|
||||
mce_prep_record_common(m);
|
||||
mce_prep_record_per_cpu(smp_processor_id(), m);
|
||||
}
|
||||
|
||||
DEFINE_PER_CPU(struct mce, injectm);
|
||||
|
|
|
|||
|
|
@ -261,6 +261,8 @@ enum mca_msr {
|
|||
|
||||
/* Decide whether to add MCE record to MCE event pool or filter it out. */
|
||||
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
|
||||
extern bool amd_filter_mce(struct mce *m);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user