1

I followed steps and indications given here and can get now counter overflow interrupt one time. But I cannot get it multple times. Whatever I managed, the Iterrupt does note fires up any more. Despite I take care of clearing the interrupt mask.

Bernard
  • 33
  • 3

2 Answers2

1

It's hard to tell without any code but if you already received the first PMI then the counters registers are set correctly and the problem probably lies in the upper layers1.

I would check:

  1. To have sent the EOI to the LAPIC.
     
    I assume you configured the PMI register of the local APIC with a fixed vector.
    In this case, you have to send an EOI to the EOI register.
    Quoting Intel (Chapter 10.8.5, Volume 3)

    For all interrupts except those delivered with the NMI, SMI, INIT, ExtINT, the start-up, or INIT-Deassert delivery mode, the interrupt handler must include a write to the end-of-interrupt (EOI) register.

    Sample code:

    mov DWORD [APIC_BASE+0xb0], eax
    

     
    The effective address, for an un-relocated LAPIC, is 0xfee000b0.
    The written value is not relevant, I picked up a register to keep the encoding of the instruction short.
    Of course, you have to access the LAPIC properly for your context.
     

  2. To have the IF flag set
     
    To have the IF flag clear is an unlikely hypothesis but it is also quite easy to rule out.
    Since an interrupt gate (but not a trap gate) clears the IF be sure the way you chose to exit the ISR restores IF properly.


1 If I remember correctly, the PMIs don't need to be rearmed.

Margaret Bloom
  • 41,768
  • 5
  • 78
  • 124
1

This question is discussed in this forum where they discovered that it is a bug in the kernel. However, your can circumvent it doing this: At any place where you need to reprogram the msr MSR_PERF_FIXED_CTR0 (0x38d), place these lines:

Msr::write(Msr::MSR_PERF_FIXED_CTR0, 0xfffffffffff0ull);
Msr::write(Msr::MSR_PERF_FIXED_CTRL, 0x0);
Msr::write(Msr::MSR_PERF_FIXED_CTR0, 0xfffffffffff0ull);
Msr::write(Msr::MSR_PERF_FIXED_CTRL, 0xa);

The switching between the values 0x0 and 0xa causes the kernel to reprogram the counter.

Mahouk
  • 902
  • 9
  • 28