xref: /linux/arch/x86/include/asm/nmi.h (revision ab93e0dd72c37d378dd936f031ffb83ff2bd87ce)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_X86_NMI_H
3 #define _ASM_X86_NMI_H
4 
5 #include <linux/irq_work.h>
6 #include <linux/pm.h>
7 #include <asm/irq.h>
8 #include <asm/io.h>
9 
10 #ifdef CONFIG_X86_LOCAL_APIC
11 
12 extern int reserve_perfctr_nmi(unsigned int);
13 extern void release_perfctr_nmi(unsigned int);
14 extern int reserve_evntsel_nmi(unsigned int);
15 extern void release_evntsel_nmi(unsigned int);
16 
17 #endif /* CONFIG_X86_LOCAL_APIC */
18 
19 extern int unknown_nmi_panic;
20 extern int panic_on_unrecovered_nmi;
21 extern int panic_on_io_nmi;
22 
23 /* NMI handler flags */
24 #define NMI_FLAG_FIRST	1
25 
26 /**
27  * enum - NMI types.
28  * @NMI_LOCAL:    Local NMI, CPU-specific NMI generated by the Local APIC.
29  * @NMI_UNKNOWN:  Unknown NMI, the source of the NMI may not be identified.
30  * @NMI_SERR:     System Error NMI, typically triggered by PCI errors.
31  * @NMI_IO_CHECK: I/O Check NMI, related to I/O errors.
32  * @NMI_MAX:      Maximum value for NMI types.
33  *
34  * NMI types are used to categorize NMIs and to dispatch them to the
35  * appropriate handler.
36  */
37 enum {
38 	NMI_LOCAL=0,
39 	NMI_UNKNOWN,
40 	NMI_SERR,
41 	NMI_IO_CHECK,
42 	NMI_MAX
43 };
44 
45 /* NMI handler return values */
46 #define NMI_DONE	0
47 #define NMI_HANDLED	1
48 
49 typedef int (*nmi_handler_t)(unsigned int, struct pt_regs *);
50 
51 struct nmiaction {
52 	struct list_head	list;
53 	nmi_handler_t		handler;
54 	u64			max_duration;
55 	unsigned long		flags;
56 	const char		*name;
57 };
58 
59 /**
60  * register_nmi_handler - Register a handler for a specific NMI type
61  * @t:    NMI type (e.g. NMI_LOCAL)
62  * @fn:   The NMI handler
63  * @fg:   Flags associated with the NMI handler
64  * @n:    Name of the NMI handler
65  * @init: Optional __init* attributes for struct nmiaction
66  *
67  * Adds the provided handler to the list of handlers for the specified
68  * NMI type. Handlers flagged with NMI_FLAG_FIRST would be executed first.
69  *
70  * Sometimes the source of an NMI can't be reliably determined which
71  * results in an NMI being tagged as "unknown". Register an additional
72  * handler using the NMI type - NMI_UNKNOWN to handle such cases. The
73  * caller would get one last chance to assume responsibility for the
74  * NMI.
75  *
76  * Return: 0 on success, or an error code on failure.
77  */
78 #define register_nmi_handler(t, fn, fg, n, init...)	\
79 ({							\
80 	static struct nmiaction init fn##_na = {	\
81 		.list = LIST_HEAD_INIT(fn##_na.list),	\
82 		.handler = (fn),			\
83 		.name = (n),				\
84 		.flags = (fg),				\
85 	};						\
86 	__register_nmi_handler((t), &fn##_na);		\
87 })
88 
89 int __register_nmi_handler(unsigned int, struct nmiaction *);
90 
91 /**
92  * unregister_nmi_handler - Unregister a handler for a specific NMI type
93  * @type: NMI type (e.g. NMI_LOCAL)
94  * @name: Name of the NMI handler used during registration
95  *
96  * Removes the handler associated with the specified NMI type from the
97  * NMI handler list. The "name" is used as a lookup key to identify the
98  * handler.
99  */
100 void unregister_nmi_handler(unsigned int type, const char *name);
101 
102 void set_emergency_nmi_handler(unsigned int type, nmi_handler_t handler);
103 
104 void stop_nmi(void);
105 void restart_nmi(void);
106 void local_touch_nmi(void);
107 
108 #endif /* _ASM_X86_NMI_H */
109