Почему я не могу справиться с NMI? - PullRequest
2 голосов
/ 26 марта 2012

Я хочу обработать 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 (результат = 0), и NMI были запущены 5 раз, но я не нашел жало, которое должно быть выведено в nmi_handler. Я работаю на Ubuntu 10.04 LTS, двухъядерном процессоре Intel Pentium 4.

  • Означает ли это, что мой обработчик NMI не выполнялся?
  • Как мне обработать NMI в Linux?

1 Ответ

1 голос
/ 27 марта 2012

Nobody? Мой партнер дал мне еще 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.

...