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