/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_NMI_H #define _ASM_X86_NMI_H #include #include #include #include #ifdef CONFIG_X86_LOCAL_APIC extern int reserve_perfctr_nmi(unsigned int); extern void release_perfctr_nmi(unsigned int); extern int reserve_evntsel_nmi(unsigned int); extern void release_evntsel_nmi(unsigned int); #endif /* CONFIG_X86_LOCAL_APIC */ extern int unknown_nmi_panic; extern int panic_on_unrecovered_nmi; extern int panic_on_io_nmi; /* NMI handler flags */ #define NMI_FLAG_FIRST 1 /** * enum - NMI types. * @NMI_LOCAL: Local NMI, CPU-specific NMI generated by the Local APIC. * @NMI_UNKNOWN: Unknown NMI, the source of the NMI may not be identified. * @NMI_SERR: System Error NMI, typically triggered by PCI errors. * @NMI_IO_CHECK: I/O Check NMI, related to I/O errors. * @NMI_MAX: Maximum value for NMI types. * * NMI types are used to categorize NMIs and to dispatch them to the * appropriate handler. */ enum { NMI_LOCAL=0, NMI_UNKNOWN, NMI_SERR, NMI_IO_CHECK, NMI_MAX }; /* NMI handler return values */ #define NMI_DONE 0 #define NMI_HANDLED 1 typedef int (*nmi_handler_t)(unsigned int, struct pt_regs *); struct nmiaction { struct list_head list; nmi_handler_t handler; u64 max_duration; unsigned long flags; const char *name; }; /** * register_nmi_handler - Register a handler for a specific NMI type * @t: NMI type (e.g. NMI_LOCAL) * @fn: The NMI handler * @fg: Flags associated with the NMI handler * @n: Name of the NMI handler * @init: Optional __init* attributes for struct nmiaction * * Adds the provided handler to the list of handlers for the specified * NMI type. Handlers flagged with NMI_FLAG_FIRST would be executed first. * * Sometimes the source of an NMI can't be reliably determined which * results in an NMI being tagged as "unknown". Register an additional * handler using the NMI type - NMI_UNKNOWN to handle such cases. The * caller would get one last chance to assume responsibility for the * NMI. * * Return: 0 on success, or an error code on failure. */ #define register_nmi_handler(t, fn, fg, n, init...) \ ({ \ static struct nmiaction init fn##_na = { \ .list = LIST_HEAD_INIT(fn##_na.list), \ .handler = (fn), \ .name = (n), \ .flags = (fg), \ }; \ __register_nmi_handler((t), &fn##_na); \ }) int __register_nmi_handler(unsigned int, struct nmiaction *); /** * unregister_nmi_handler - Unregister a handler for a specific NMI type * @type: NMI type (e.g. NMI_LOCAL) * @name: Name of the NMI handler used during registration * * Removes the handler associated with the specified NMI type from the * NMI handler list. The "name" is used as a lookup key to identify the * handler. */ void unregister_nmi_handler(unsigned int type, const char *name); void set_emergency_nmi_handler(unsigned int type, nmi_handler_t handler); void stop_nmi(void); void restart_nmi(void); void local_touch_nmi(void); #endif /* _ASM_X86_NMI_H */