3

我想处理 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 处理程序,然后使用 APIC 触发 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);
  }
}

现在我输入“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、Intel Pentium 4 Dual-core 上工作。

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

1 回答 1

2

没有人?我的伙伴又给了我3天,所以我看了源码和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是中断行号,而不是中断向量号。查找ULK3 PDF,P203,定时器中断有IRQ 0,但它的INT nr 是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。

于 2012-03-27T09:29:23.767 回答