#include #include #include #include #include #include #include #include static atomic_t nmi_count = ATOMIC_INIT(0); static atomic_t request_count = ATOMIC_INIT(0); static int do_nmi(void *dev_id, struct pt_regs *regs, int cpu, int handled) { atomic_inc(&nmi_count); return NOTIFY_DONE; } static ssize_t do_read(struct file *file, char *buf, size_t count, loff_t *ppos) { int rv; long last_jiffies = jiffies; struct nmi_handler nmi_handler = { .link = LIST_HEAD_INIT(nmi_handler.link), .dev_name = "nmi_test", .dev_id = NULL, .handler = do_nmi, .priority = 0, /* Call us last. */ }; printk("NMI test: start test\n"); for (;;) { if (signal_pending(current)) return -ERESTARTSYS; rv = request_nmi(&nmi_handler); if (rv) { printk(KERN_WARNING "NMI test: Can't register nmi handler\n"); return rv; } // set_current_state(TASK_INTERRUPTIBLE); // schedule_timeout(1); release_nmi(&nmi_handler); atomic_inc(&request_count); if ((jiffies - last_jiffies) >= HZ) { last_jiffies = jiffies; printk("NMIs = %d, requests=%d\n", atomic_read(&nmi_count), atomic_read(&request_count)); } } return 0; } static int do_open(struct inode *ino, struct file *filep) { return 0; } static int do_close(struct inode *ino, struct file *filep) { printk("NMI test: in close\n"); return 0; } static struct file_operations nmi_test_fops = { .owner = THIS_MODULE, .read = do_read, .write = NULL, .ioctl = NULL, .open = do_open, .release = do_close, }; static struct miscdevice nmi_test_miscdev = { 130, "nmi_test", &nmi_test_fops }; static int __init nmi_test_init(void) { int rv; rv = misc_register(&nmi_test_miscdev); if (rv < 0) { printk("NMI test: Unable to register misc device\n"); return rv; } printk(KERN_INFO "NMI test by " "Corey Minyard (minyard@mvista.com)\n"); return 0; } static void __exit nmi_test_exit(void) { /* Make sure no one can call us any more. */ misc_deregister(&nmi_test_miscdev); } module_exit(nmi_test_exit); module_init(nmi_test_init); MODULE_LICENSE("GPL");