Commit 2b34233c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'ras_updates_for_v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 RAS updates from Borislav Petkov:

 - Enable additional logging mode on older Xeons (Tony Luck)

 - Pass error records logged by firmware through the MCE decoding chain
   to provide human-readable error descriptions instead of raw values
   (Smita Koralahalli)

 - Some #MC handler fixes (Gabriele Paoloni)

 - The usual small fixes and cleanups all over.

* tag 'ras_updates_for_v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/mce: Rename kill_it to kill_current_task
  x86/mce: Remove redundant call to irq_work_queue()
  x86/mce: Panic for LMCE only if mca_cfg.tolerant < 3
  x86/mce: Move the mce_panic() call and 'kill_it' assignments to the right places
  x86/mce, cper: Pass x86 CPER through the MCA handling chain
  x86/mce: Use "safe" MSR functions when enabling additional error logging
  x86/mce: Correct the detection of invalid notifier priorities
  x86/mce: Assign boolean values to a bool variable
  x86/mce: Enable additional error logging on certain Intel CPUs
  x86/mce: Remove unneeded break
parents 9e7f2588 e1c06d23
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -159,6 +159,8 @@ static inline u64 x86_default_get_root_pointer(void)
extern int x86_acpi_numa_init(void);
#endif /* CONFIG_ACPI_NUMA */

struct cper_ia_proc_ctx;

#ifdef CONFIG_ACPI_APEI
static inline pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr)
{
@@ -177,6 +179,15 @@ static inline pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr)
	 */
	return PAGE_KERNEL_NOENC;
}

int arch_apei_report_x86_error(struct cper_ia_proc_ctx *ctx_info,
			       u64 lapic_id);
#else
static inline int arch_apei_report_x86_error(struct cper_ia_proc_ctx *ctx_info,
					     u64 lapic_id)
{
	return -EINVAL;
}
#endif

#define ACPI_TABLE_UPGRADE_MAX_PHYS (max_low_pfn_mapped << PAGE_SHIFT)
+8 −1
Original line number Diff line number Diff line
@@ -177,7 +177,8 @@ enum mce_notifier_prios {
	MCE_PRIO_EXTLOG,
	MCE_PRIO_UC,
	MCE_PRIO_EARLY,
	MCE_PRIO_CEC
	MCE_PRIO_CEC,
	MCE_PRIO_HIGHEST = MCE_PRIO_CEC
};

struct notifier_block;
@@ -198,16 +199,22 @@ static inline void enable_copy_mc_fragile(void)
}
#endif

struct cper_ia_proc_ctx;

#ifdef CONFIG_X86_MCE
int mcheck_init(void);
void mcheck_cpu_init(struct cpuinfo_x86 *c);
void mcheck_cpu_clear(struct cpuinfo_x86 *c);
void mcheck_vendor_init_severity(void);
int apei_smca_report_x86_error(struct cper_ia_proc_ctx *ctx_info,
			       u64 lapic_id);
#else
static inline int mcheck_init(void) { return 0; }
static inline void mcheck_cpu_init(struct cpuinfo_x86 *c) {}
static inline void mcheck_cpu_clear(struct cpuinfo_x86 *c) {}
static inline void mcheck_vendor_init_severity(void) {}
static inline int apei_smca_report_x86_error(struct cper_ia_proc_ctx *ctx_info,
					     u64 lapic_id) { return -EINVAL; }
#endif

#ifdef CONFIG_X86_ANCIENT_MCE
+1 −0
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@
#define MSR_IA32_MCG_CAP		0x00000179
#define MSR_IA32_MCG_STATUS		0x0000017a
#define MSR_IA32_MCG_CTL		0x0000017b
#define MSR_ERROR_CONTROL		0x0000017f
#define MSR_IA32_MCG_EXT_CTL		0x000004d0

#define MSR_OFFCORE_RSP_0		0x000001a6
+5 −0
Original line number Diff line number Diff line
@@ -43,3 +43,8 @@ void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
	apei_mce_report_mem_error(sev, mem_err);
#endif
}

int arch_apei_report_x86_error(struct cper_ia_proc_ctx *ctx_info, u64 lapic_id)
{
	return apei_smca_report_x86_error(ctx_info, lapic_id);
}
+61 −0
Original line number Diff line number Diff line
@@ -51,6 +51,67 @@ void apei_mce_report_mem_error(int severity, struct cper_sec_mem_err *mem_err)
}
EXPORT_SYMBOL_GPL(apei_mce_report_mem_error);

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));
	unsigned int cpu;
	struct mce m;

	if (!boot_cpu_has(X86_FEATURE_SMCA))
		return -EINVAL;

	/*
	 * The starting address of the register array extracted from BERT must
	 * match with the first expected register in the register layout of
	 * SMCA address space. This address corresponds to banks's MCA_STATUS
	 * register.
	 *
	 * Match any MCi_STATUS register by turning off bank numbers.
	 */
	if ((ctx_info->msr_addr & MSR_AMD64_SMCA_MC0_STATUS) !=
				  MSR_AMD64_SMCA_MC0_STATUS)
		return -EINVAL;

	/*
	 * The register array size must be large enough to include all the
	 * SMCA registers which need to be extracted.
	 *
	 * The number of registers in the register array is determined by
	 * Register Array Size/8 as defined in UEFI spec v2.8, sec N.2.4.2.2.
	 * The register layout is fixed and currently the raw data in the
	 * register array includes 6 SMCA registers which the kernel can
	 * extract.
	 */
	if (ctx_info->reg_arr_size < 48)
		return -EINVAL;

	mce_setup(&m);

	m.extcpu = -1;
	m.socketid = -1;

	for_each_possible_cpu(cpu) {
		if (cpu_data(cpu).initial_apicid == lapic_id) {
			m.extcpu = cpu;
			m.socketid = cpu_data(m.extcpu).phys_proc_id;
			break;
		}
	}

	m.apicid = lapic_id;
	m.bank = (ctx_info->msr_addr >> 4) & 0xFF;
	m.status = *i_mce;
	m.addr = *(i_mce + 1);
	m.misc = *(i_mce + 2);
	/* Skipping MCA_CONFIG */
	m.ipid = *(i_mce + 4);
	m.synd = *(i_mce + 5);

	mce_log(&m);

	return 0;
}

#define CPER_CREATOR_MCE						\
	GUID_INIT(0x75a574e3, 0x5052, 0x4b29, 0x8a, 0x8e, 0xbe, 0x2c,	\
		  0x64, 0x90, 0xb8, 0x9d)
Loading