arch/x86/kernel/nmi.c
Source file repositories/reference/linux-study-clean/arch/x86/kernel/nmi.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/kernel/nmi.c- Extension
.c- Size
- 21674 bytes
- Lines
- 752
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/spinlock.hlinux/kprobes.hlinux/kdebug.hlinux/sched/debug.hlinux/nmi.hlinux/debugfs.hlinux/delay.hlinux/hardirq.hlinux/ratelimit.hlinux/slab.hlinux/export.hlinux/atomic.hlinux/sched/clock.hlinux/kvm_types.hasm/cpu_entry_area.hasm/traps.hasm/mach_traps.hasm/nmi.hasm/x86_init.hasm/reboot.hasm/cache.hasm/nospec-branch.hasm/microcode.hasm/sev.hasm/fred.htrace/events/nmi.h
Detected Declarations
struct nmi_descstruct nmi_statsenum nmi_statesfunction setup_unknown_nmi_panicfunction nmi_warning_debugfsfunction nmi_check_durationfunction nmi_handlefunction __register_nmi_handlerfunction unregister_nmi_handlerfunction list_for_each_entry_rcufunction set_emergency_nmi_handlerfunction pci_serr_errorfunction io_check_errorfunction unknown_nmi_errorfunction default_do_nmifunction nmi_backtrace_stall_snapfunction for_each_cpufunction nmi_backtrace_stall_checkfunction for_each_cpufunction stop_nmifunction restart_nmifunction local_touch_nmimodule init nmi_warning_debugfsexport __register_nmi_handlerexport unregister_nmi_handler
Annotated Snippet
struct nmi_desc {
raw_spinlock_t lock;
nmi_handler_t emerg_handler;
struct list_head head;
};
#define NMI_DESC_INIT(type) { \
.lock = __RAW_SPIN_LOCK_UNLOCKED(&nmi_desc[type].lock), \
.head = LIST_HEAD_INIT(nmi_desc[type].head), \
}
static struct nmi_desc nmi_desc[NMI_MAX] = {
NMI_DESC_INIT(NMI_LOCAL),
NMI_DESC_INIT(NMI_UNKNOWN),
NMI_DESC_INIT(NMI_SERR),
NMI_DESC_INIT(NMI_IO_CHECK),
};
#define nmi_to_desc(type) (&nmi_desc[type])
struct nmi_stats {
unsigned int normal;
unsigned int unknown;
unsigned int external;
unsigned int swallow;
unsigned long recv_jiffies;
unsigned long idt_seq;
unsigned long idt_nmi_seq;
unsigned long idt_ignored;
atomic_long_t idt_calls;
unsigned long idt_seq_snap;
unsigned long idt_nmi_seq_snap;
unsigned long idt_ignored_snap;
long idt_calls_snap;
};
static DEFINE_PER_CPU(struct nmi_stats, nmi_stats);
static int ignore_nmis __read_mostly;
int unknown_nmi_panic;
int panic_on_unrecovered_nmi;
int panic_on_io_nmi;
/*
* Prevent NMI reason port (0x61) being accessed simultaneously, can
* only be used in NMI handler.
*/
static DEFINE_RAW_SPINLOCK(nmi_reason_lock);
static int __init setup_unknown_nmi_panic(char *str)
{
unknown_nmi_panic = 1;
return 1;
}
__setup("unknown_nmi_panic", setup_unknown_nmi_panic);
static u64 nmi_longest_ns = 1 * NSEC_PER_MSEC;
static int __init nmi_warning_debugfs(void)
{
debugfs_create_u64("nmi_longest_ns", 0644,
arch_debugfs_dir, &nmi_longest_ns);
return 0;
}
fs_initcall(nmi_warning_debugfs);
static void nmi_check_duration(struct nmiaction *action, u64 duration)
{
int remainder_ns, decimal_msecs;
if (duration < nmi_longest_ns || duration < action->max_duration)
return;
action->max_duration = duration;
/* Convert duration from nsec to msec */
remainder_ns = do_div(duration, NSEC_PER_MSEC);
decimal_msecs = remainder_ns / NSEC_PER_USEC;
pr_info_ratelimited("INFO: NMI handler (%ps) took too long to run: %lld.%03d msecs\n",
action->handler, duration, decimal_msecs);
}
static int nmi_handle(unsigned int type, struct pt_regs *regs)
{
struct nmi_desc *desc = nmi_to_desc(type);
nmi_handler_t ehandler;
struct nmiaction *a;
int handled=0;
Annotation
- Immediate include surface: `linux/spinlock.h`, `linux/kprobes.h`, `linux/kdebug.h`, `linux/sched/debug.h`, `linux/nmi.h`, `linux/debugfs.h`, `linux/delay.h`, `linux/hardirq.h`.
- Detected declarations: `struct nmi_desc`, `struct nmi_stats`, `enum nmi_states`, `function setup_unknown_nmi_panic`, `function nmi_warning_debugfs`, `function nmi_check_duration`, `function nmi_handle`, `function __register_nmi_handler`, `function unregister_nmi_handler`, `function list_for_each_entry_rcu`.
- Atlas domain: Architecture Layer / arch/x86.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.