Commit 30f5a756 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'ras-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull RAS updates from Borislav Petkov:

 - Misc fixes to the MCE code all over the place, by Jan H. Schönherr.

 - Initial support for AMD F19h and other cleanups to amd64_edac, by
   Yazen Ghannam.

 - Other small cleanups.

* 'ras-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  EDAC/mce_amd: Make fam_ops static global
  EDAC/amd64: Drop some family checks for newer systems
  EDAC/amd64: Add family ops for Family 19h Models 00h-0Fh
  x86/amd_nb: Add Family 19h PCI IDs
  EDAC/mce_amd: Always load on SMCA systems
  x86/MCE/AMD, EDAC/mce_amd: Add new Load Store unit McaType
  x86/mce: Fix use of uninitialized MCE message string
  x86/mce: Fix mce=nobootlog
  x86/mce: Take action on UCNA/Deferred errors again
  x86/mce: Remove mce_inject_log() in favor of mce_log()
  x86/mce: Pass MCE message to mce_panic() on failed kernel recovery
  x86/mce/therm_throt: Mark throttle_active_work() as __maybe_unused
parents b62061b8 86e9f9d6
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -144,7 +144,7 @@ struct mce_log_buffer {

enum mce_notifier_prios {
	MCE_PRIO_FIRST		= INT_MAX,
	MCE_PRIO_SRAO		= INT_MAX - 1,
	MCE_PRIO_UC		= INT_MAX - 1,
	MCE_PRIO_EXTLOG		= INT_MAX - 2,
	MCE_PRIO_NFIT		= INT_MAX - 3,
	MCE_PRIO_EDAC		= INT_MAX - 4,
@@ -290,6 +290,7 @@ extern void apei_mce_report_mem_error(int corrected,
/* These may be used by multiple smca_hwid_mcatypes */
enum smca_bank_types {
	SMCA_LS = 0,	/* Load Store */
	SMCA_LS_V2,	/* Load Store */
	SMCA_IF,	/* Instruction Fetch */
	SMCA_L2_CACHE,	/* L2 Cache */
	SMCA_DE,	/* Decoder Unit */
+3 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#define PCI_DEVICE_ID_AMD_17H_M10H_DF_F4 0x15ec
#define PCI_DEVICE_ID_AMD_17H_M30H_DF_F4 0x1494
#define PCI_DEVICE_ID_AMD_17H_M70H_DF_F4 0x1444
#define PCI_DEVICE_ID_AMD_19H_DF_F4	0x1654

/* Protect the PCI config register pairs used for SMN and DF indirect access. */
static DEFINE_MUTEX(smn_mutex);
@@ -52,6 +53,7 @@ const struct pci_device_id amd_nb_misc_ids[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) },
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) },
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) },
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_DF_F3) },
	{}
};
EXPORT_SYMBOL_GPL(amd_nb_misc_ids);
@@ -66,6 +68,7 @@ static const struct pci_device_id amd_nb_link_ids[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F4) },
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F4) },
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F4) },
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_DF_F4) },
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) },
	{}
};
+2 −0
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ struct smca_bank_name {

static struct smca_bank_name smca_names[] = {
	[SMCA_LS]	= { "load_store",	"Load Store Unit" },
	[SMCA_LS_V2]	= { "load_store",	"Load Store Unit" },
	[SMCA_IF]	= { "insn_fetch",	"Instruction Fetch Unit" },
	[SMCA_L2_CACHE]	= { "l2_cache",		"L2 Cache" },
	[SMCA_DE]	= { "decode_unit",	"Decode Unit" },
@@ -138,6 +139,7 @@ static struct smca_hwid smca_hwid_mcatypes[] = {

	/* ZN Core (HWID=0xB0) MCA types */
	{ SMCA_LS,	 HWID_MCATYPE(0xB0, 0x0), 0x1FFFFF },
	{ SMCA_LS_V2,	 HWID_MCATYPE(0xB0, 0x10), 0xFFFFFF },
	{ SMCA_IF,	 HWID_MCATYPE(0xB0, 0x1), 0x3FFF },
	{ SMCA_L2_CACHE, HWID_MCATYPE(0xB0, 0x2), 0xF },
	{ SMCA_DE,	 HWID_MCATYPE(0xB0, 0x3), 0x1FF },
+29 −41
Original line number Diff line number Diff line
@@ -53,8 +53,6 @@

#include "internal.h"

static DEFINE_MUTEX(mce_log_mutex);

/* sysfs synchronization */
static DEFINE_MUTEX(mce_sysfs_mutex);

@@ -156,19 +154,10 @@ void mce_log(struct mce *m)
	if (!mce_gen_pool_add(m))
		irq_work_queue(&mce_irq_work);
}

void mce_inject_log(struct mce *m)
{
	mutex_lock(&mce_log_mutex);
	mce_log(m);
	mutex_unlock(&mce_log_mutex);
}
EXPORT_SYMBOL_GPL(mce_inject_log);

static struct notifier_block mce_srao_nb;
EXPORT_SYMBOL_GPL(mce_log);

/*
 * We run the default notifier if we have only the SRAO, the first and the
 * We run the default notifier if we have only the UC, the first and the
 * default notifier registered. I.e., the mandatory NUM_DEFAULT_NOTIFIERS
 * notifiers registered on the chain.
 */
@@ -594,26 +583,29 @@ static struct notifier_block first_nb = {
	.priority	= MCE_PRIO_FIRST,
};

static int srao_decode_notifier(struct notifier_block *nb, unsigned long val,
static int uc_decode_notifier(struct notifier_block *nb, unsigned long val,
			      void *data)
{
	struct mce *mce = (struct mce *)data;
	unsigned long pfn;

	if (!mce)
	if (!mce || !mce_usable_address(mce))
		return NOTIFY_DONE;

	if (mce->severity != MCE_AO_SEVERITY &&
	    mce->severity != MCE_DEFERRED_SEVERITY)
		return NOTIFY_DONE;

	if (mce_usable_address(mce) && (mce->severity == MCE_AO_SEVERITY)) {
	pfn = mce->addr >> PAGE_SHIFT;
	if (!memory_failure(pfn, 0))
		set_mce_nospec(pfn);
	}

	return NOTIFY_OK;
}
static struct notifier_block mce_srao_nb = {
	.notifier_call	= srao_decode_notifier,
	.priority	= MCE_PRIO_SRAO,

static struct notifier_block mce_uc_nb = {
	.notifier_call	= uc_decode_notifier,
	.priority	= MCE_PRIO_UC,
};

static int mce_default_notifier(struct notifier_block *nb, unsigned long val,
@@ -763,26 +755,22 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
log_it:
		error_seen = true;

		mce_read_aux(&m, i);
		if (flags & MCP_DONTLOG)
			goto clear_it;

		mce_read_aux(&m, i);
		m.severity = mce_severity(&m, mca_cfg.tolerant, NULL, false);

		/*
		 * Don't get the IP here because it's unlikely to
		 * have anything to do with the actual error location.
		 */
		if (!(flags & MCP_DONTLOG) && !mca_cfg.dont_log_ce)

		if (mca_cfg.dont_log_ce && !mce_usable_address(&m))
			goto clear_it;

		mce_log(&m);
		else if (mce_usable_address(&m)) {
			/*
			 * Although we skipped logging this, we still want
			 * to take action. Add to the pool so the registered
			 * notifiers will see it.
			 */
			if (!mce_gen_pool_add(&m))
				mce_schedule_work();
		}

clear_it:
		/*
		 * Clear state for this bank.
		 */
@@ -807,7 +795,7 @@ EXPORT_SYMBOL_GPL(machine_check_poll);
static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp,
			  struct pt_regs *regs)
{
	char *tmp;
	char *tmp = *msg;
	int i;

	for (i = 0; i < this_cpu_read(mce_num_banks); i++) {
@@ -1232,8 +1220,8 @@ void do_machine_check(struct pt_regs *regs, long error_code)
	DECLARE_BITMAP(toclear, MAX_NR_BANKS);
	struct mca_config *cfg = &mca_cfg;
	int cpu = smp_processor_id();
	char *msg = "Unknown";
	struct mce m, *final;
	char *msg = NULL;
	int worst = 0;

	/*
@@ -1365,7 +1353,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
		ist_end_non_atomic();
	} else {
		if (!fixup_exception(regs, X86_TRAP_MC, error_code, 0))
			mce_panic("Failed kernel mode recovery", &m, NULL);
			mce_panic("Failed kernel mode recovery", &m, msg);
	}

out_ist:
@@ -2041,7 +2029,7 @@ int __init mcheck_init(void)
{
	mcheck_intel_therm_init();
	mce_register_decode_chain(&first_nb);
	mce_register_decode_chain(&mce_srao_nb);
	mce_register_decode_chain(&mce_uc_nb);
	mce_register_decode_chain(&mce_default_nb);
	mcheck_vendor_init_severity();

+1 −1
Original line number Diff line number Diff line
@@ -494,7 +494,7 @@ static void do_inject(void)
		i_mce.status |= MCI_STATUS_SYNDV;

	if (inj_type == SW_INJ) {
		mce_inject_log(&i_mce);
		mce_log(&i_mce);
		return;
	}

Loading