为什么我不能处理NMI?

我想要处理NMI,并在发生NMI时做一些事情。 首先我写一个天真的nmi处理程序

static irqreturn_t nmi_handler(int irq, void* dev_id) { printk("-#_#- I'm TT, I am handling NMI.\n"); return IRQ_HANDLED; } 

并写一个模块注册我的nmi处理程序,然后使用API​​C触发NMI 5次:

 static void __init ipi_init(void) { printk("-#_#- I'm coming again, hahaha!\n"); int result = request_irq(NMI_VECTOR, nmi_handler, IRQF_DISABLED, "NMI Watchdog", NULL); printk("--- the result of request_irq is: %d\n", result); int i; for (i = 0; i < 5; ++i) { apic->send_IPI_allbutself(NMI_VECTOR); ssleep(1); } } 

现在我input“insmod xxx.ko”来安装这个模块,然后检查/ var / log / syslog:

 kernel: [ 1166.231005] -#_#- I'm coming again, hahaha! kernel: [ 1166.231028] --- the result of request_irq is: 0 kernel: [ 1166.231050] Uhhuh. NMI received for unknown reason 00 on CPU 1. kernel: [ 1166.231055] Do you have a strange power saving mode enabled? kernel: [ 1166.231058] Dazed and confused, but trying to continue kernel: [ 1167.196293] Uhhuh. NMI received for unknown reason 00 on CPU 1. kernel: [ 1167.196293] Do you have a strange power saving mode enabled? kernel: [ 1167.196293] Dazed and confused, but trying to continue kernel: [ 1168.201288] Uhhuh. NMI received for unknown reason 00 on CPU 1. kernel: [ 1168.201288] Do you have a strange power saving mode enabled? kernel: [ 1168.201288] Dazed and confused, but trying to continue kernel: [ 1169.235553] Uhhuh. NMI received for unknown reason 00 on CPU 1. kernel: [ 1169.235553] Do you have a strange power saving mode enabled? kernel: [ 1169.235553] Dazed and confused, but trying to continue kernel: [ 1170.236343] Uhhuh. NMI received for unknown reason 00 on CPU 1. kernel: [ 1170.236343] Do you have a strange power saving mode enabled? kernel: [ 1170.236343] Dazed and confused, but trying to continue 

它显示我成功注册了nmi_handler(result = 0),并且NMI被触发了5次,但是我没有发现应该在nmi_handler中输出的sting。 我在Ubuntu 10.04 LTS,英特尔奔腾4双核上工作。

  • 这是否意味着我的NMI处理程序没有执行?
  • 我如何在Linux中处理NMI?

没有人? 我的伙伴给了我三天时间,所以我读了源代码和ULK3,现在我可以回答问题1:

  • 这是否意味着我的NMI手柄没有执行?

实际上, IRQ号码INT向量号码不同的 ! 函数request_irq()调用setup_irq():

 /** * setup_irq - setup an interrupt * @irq: Interrupt line to setup * @act: irqaction for the interrupt * * Used to statically setup interrupts in the early boot process. */ int setup_irq(unsigned int irq, struct irqaction *act) { struct irq_desc *desc = irq_to_desc(irq); return __setup_irq(irq, desc, act); } 

看看这个: @irq: Interrupt line to setup :中@irq: Interrupt line to setup 。 参数irq是中断行号,而不是中断向量号。 查找ULK3 PDF,P203,定时器中断有IRQ 0,但其INT INT为32! 所以我触发INT2(NMI),但我的处理程序实际上处理INT34! 我想在源代码中找到更多的证据(例如,如何将IRQ转换为INT?我修改了我的处理程序和init,我请求irq = 2,Linux分配INT = 50),但是什么也没有,期望linux-xxx/arch/x86/include/asm/irq_vectors.h

 /* * IDT vectors usable for external interrupt sources start * at 0x20: */ #define FIRST_EXTERNAL_VECTOR 0x20 

等我一会儿…让我读更多的代码来回答问题2。