@@ -1485,7 +1485,7 @@ static __init int perf_event_ibs_init(void)
if (ret)
goto err_op;
- ret = register_nmi_handler(NMI_LOCAL, perf_ibs_nmi_handler, 0, "perf_ibs");
+ ret = register_nmi_handler(NMI_LOCAL, perf_ibs_nmi_handler, 0, "perf_ibs", NMIS_NO_SOURCE);
if (ret)
goto err_nmi;
@@ -2129,7 +2129,7 @@ static int __init init_hw_perf_events(void)
x86_pmu.config_mask = X86_RAW_EVENT_MASK;
perf_events_lapic_init();
- register_nmi_handler(NMI_LOCAL, perf_event_nmi_handler, 0, "PMI");
+ register_nmi_handler(NMI_LOCAL, perf_event_nmi_handler, 0, "PMI", NMIS_NO_SOURCE);
unconstrained = (struct event_constraint)
__EVENT_CONSTRAINT(0, x86_pmu.cntr_mask64,
@@ -48,12 +48,24 @@ enum {
typedef int (*nmi_handler_t)(unsigned int, struct pt_regs *);
+/**
+ * enum nmi_source_vectors - NMI-source vectors are used to identify the
+ * origin of an NMI and to route the NMI directly to the appropriate
+ * handler.
+ *
+ * @NMIS_NO_SOURCE: Reserved for undefined or unidentified sources.
+ */
+enum nmi_source_vectors {
+ NMIS_NO_SOURCE = 0,
+};
+
struct nmiaction {
struct list_head list;
nmi_handler_t handler;
u64 max_duration;
unsigned long flags;
const char *name;
+ enum nmi_source_vectors source_vector;
};
/**
@@ -62,6 +74,7 @@ struct nmiaction {
* @fn: The NMI handler
* @fg: Flags associated with the NMI handler
* @n: Name of the NMI handler
+ * @src: NMI-source vector for the NMI handler
* @init: Optional __init* attributes for struct nmiaction
*
* Adds the provided handler to the list of handlers for the specified
@@ -75,13 +88,14 @@ struct nmiaction {
*
* Return: 0 on success, or an error code on failure.
*/
-#define register_nmi_handler(t, fn, fg, n, init...) \
+#define register_nmi_handler(t, fn, fg, n, src, init...)\
({ \
static struct nmiaction init fn##_na = { \
.list = LIST_HEAD_INIT(fn##_na.list), \
.handler = (fn), \
.name = (n), \
.flags = (fg), \
+ .source_vector = (src), \
}; \
__register_nmi_handler((t), &fn##_na); \
})
@@ -53,8 +53,7 @@ NOKPROBE_SYMBOL(nmi_cpu_backtrace_handler);
static int __init register_nmi_cpu_backtrace_handler(void)
{
- register_nmi_handler(NMI_LOCAL, nmi_cpu_backtrace_handler,
- 0, "arch_bt");
+ register_nmi_handler(NMI_LOCAL, nmi_cpu_backtrace_handler, 0, "arch_bt", NMIS_NO_SOURCE);
return 0;
}
early_initcall(register_nmi_cpu_backtrace_handler);
@@ -775,7 +775,7 @@ static int __init inject_init(void)
debugfs_init();
- register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0, "mce_notify");
+ register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0, "mce_notify", NMIS_NO_SOURCE);
mce_register_injector_chain(&inject_nb);
setup_inj_struct(&i_mce);
@@ -550,7 +550,7 @@ static void __init ms_hyperv_init_platform(void)
}
register_nmi_handler(NMI_UNKNOWN, hv_nmi_unknown, NMI_FLAG_FIRST,
- "hv_nmi_unknown");
+ "hv_nmi_unknown", NMIS_NO_SOURCE);
#endif
#ifdef CONFIG_X86_IO_APIC
@@ -602,13 +602,11 @@ int kgdb_arch_init(void)
if (retval)
goto out;
- retval = register_nmi_handler(NMI_LOCAL, kgdb_nmi_handler,
- 0, "kgdb");
+ retval = register_nmi_handler(NMI_LOCAL, kgdb_nmi_handler, 0, "kgdb", NMIS_NO_SOURCE);
if (retval)
goto out1;
- retval = register_nmi_handler(NMI_UNKNOWN, kgdb_nmi_handler,
- 0, "kgdb");
+ retval = register_nmi_handler(NMI_UNKNOWN, kgdb_nmi_handler, 0, "kgdb", NMIS_NO_SOURCE);
if (retval)
goto out2;
@@ -41,7 +41,7 @@ static void __init init_nmi_testsuite(void)
{
/* trap all the unknown NMIs we may generate */
register_nmi_handler(NMI_UNKNOWN, nmi_unk_cb, 0, "nmi_selftest_unk",
- __initdata);
+ NMIS_NO_SOURCE, __initdata);
}
static void __init cleanup_nmi_testsuite(void)
@@ -63,8 +63,8 @@ static void __init test_nmi_ipi(struct cpumask *mask)
{
unsigned long timeout;
- if (register_nmi_handler(NMI_LOCAL, test_nmi_ipi_callback,
- NMI_FLAG_FIRST, "nmi_selftest", __initdata)) {
+ if (register_nmi_handler(NMI_LOCAL, test_nmi_ipi_callback, NMI_FLAG_FIRST,
+ "nmi_selftest", NMIS_NO_SOURCE, __initdata)) {
nmi_fail = FAILURE;
return;
}
@@ -142,8 +142,8 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_reboot)
static int register_stop_handler(void)
{
- return register_nmi_handler(NMI_LOCAL, smp_stop_nmi_callback,
- NMI_FLAG_FIRST, "smp_stop");
+ return register_nmi_handler(NMI_LOCAL, smp_stop_nmi_callback, NMI_FLAG_FIRST,
+ "smp_stop", NMIS_NO_SOURCE);
}
static void native_stop_other_cpus(int wait)
@@ -1029,10 +1029,10 @@ static int uv_handle_nmi_ping(unsigned int reason, struct pt_regs *regs)
static void uv_register_nmi_notifier(void)
{
- if (register_nmi_handler(NMI_UNKNOWN, uv_handle_nmi, 0, "uv"))
+ if (register_nmi_handler(NMI_UNKNOWN, uv_handle_nmi, 0, "uv", NMIS_NO_SOURCE))
pr_warn("UV: NMI handler failed to register\n");
- if (register_nmi_handler(NMI_LOCAL, uv_handle_nmi_ping, 0, "uvping"))
+ if (register_nmi_handler(NMI_LOCAL, uv_handle_nmi_ping, 0, "uvping", NMIS_NO_SOURCE))
pr_warn("UV: PING NMI handler failed to register\n");
}
@@ -1421,7 +1421,7 @@ static void ghes_nmi_add(struct ghes *ghes)
{
mutex_lock(&ghes_list_mutex);
if (list_empty(&ghes_nmi))
- register_nmi_handler(NMI_LOCAL, ghes_notify_nmi, 0, "ghes");
+ register_nmi_handler(NMI_LOCAL, ghes_notify_nmi, 0, "ghes", NMIS_NO_SOURCE);
list_add_rcu(&ghes->list, &ghes_nmi);
mutex_unlock(&ghes_list_mutex);
}
@@ -1227,8 +1227,7 @@ static void check_parms(void)
}
}
if (do_nmi && !nmi_handler_registered) {
- rv = register_nmi_handler(NMI_UNKNOWN, ipmi_nmi, 0,
- "ipmi");
+ rv = register_nmi_handler(NMI_UNKNOWN, ipmi_nmi, 0, "ipmi", NMIS_NO_SOURCE);
if (rv) {
pr_warn("Can't register nmi handler\n");
return;
@@ -1419,8 +1419,7 @@ static int register_err_handler(void)
return 0;
}
- rc = register_nmi_handler(NMI_SERR, ecclog_nmi_handler,
- 0, IGEN6_NMI_NAME);
+ rc = register_nmi_handler(NMI_SERR, ecclog_nmi_handler, 0, IGEN6_NMI_NAME, NMIS_NO_SOURCE);
if (rc) {
igen6_printk(KERN_ERR, "Failed to register NMI handler\n");
return rc;
@@ -242,13 +242,13 @@ static int hpwdt_init_nmi_decoding(struct pci_dev *dev)
/*
* Only one function can register for NMI_UNKNOWN
*/
- retval = register_nmi_handler(NMI_UNKNOWN, hpwdt_pretimeout, 0, "hpwdt");
+ retval = register_nmi_handler(NMI_UNKNOWN, hpwdt_pretimeout, 0, "hpwdt", NMIS_NO_SOURCE);
if (retval)
goto error;
- retval = register_nmi_handler(NMI_SERR, hpwdt_pretimeout, 0, "hpwdt");
+ retval = register_nmi_handler(NMI_SERR, hpwdt_pretimeout, 0, "hpwdt", NMIS_NO_SOURCE);
if (retval)
goto error1;
- retval = register_nmi_handler(NMI_IO_CHECK, hpwdt_pretimeout, 0, "hpwdt");
+ retval = register_nmi_handler(NMI_IO_CHECK, hpwdt_pretimeout, 0, "hpwdt", NMIS_NO_SOURCE);
if (retval)
goto error2;