]> Git Repo - J-linux.git/commitdiff
x86/mce: Define mce_prep_record() helpers for common and per-CPU fields
authorYazen Ghannam <[email protected]>
Tue, 30 Jul 2024 18:29:57 +0000 (13:29 -0500)
committerBorislav Petkov (AMD) <[email protected]>
Thu, 1 Aug 2024 16:20:25 +0000 (18:20 +0200)
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 <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Reviewed-by: Nikolay Borisov <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
arch/x86/kernel/cpu/mce/core.c
arch/x86/kernel/cpu/mce/internal.h

index dd5192ef52e0b04d1976e2a7b2bab8cc23860fe7..2a938f429c4d50274df7ae831bbd2fb8271192ab 100644 (file)
@@ -117,20 +117,32 @@ static struct irq_work mce_irq_work;
  */
 BLOCKING_NOTIFIER_HEAD(x86_mce_decoder_chain);
 
-/* Do initial initialization of a struct mce */
-void mce_prep_record(struct mce *m)
+void mce_prep_record_common(struct mce *m)
 {
        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 */
-       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;
+       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)
+{
+       mce_prep_record_common(m);
+       mce_prep_record_per_cpu(smp_processor_id(), m);
 }
 
 DEFINE_PER_CPU(struct mce, injectm);
index 01f8f03969e63efeb87afe08856e5dc97c3d5d69..43c7f3b71df59cfb8ef4826129cbc874d94fab12 100644 (file)
@@ -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);
This page took 0.056588 seconds and 4 git commands to generate.