4

I have a situation with catching the performance monitoring interrupt (PMI - especially instruction counter) on qemu-kvm. The code below works fine on real machine (Intel Core TM i5-4300U) but on qemu-kvm (qemu-system-x86_64 -cpu host), I do not see even one PMI. Though the counter works normally. I can check it increments well.

However, I have tested with Linux kernel, and it catches the overflow interrupt very well on the same qemu-kvm. So there is obviously a step I am missing when it comes to configure the performance monitoring counter on Qemu-kvm.

Can someone point it out to me? Here is the pseudo-code:

#define LAPIC_SVR           0xF0
#define LAPIC_LVT_PERFM      0x340,
#define CPU_LOCAL_APIC      0xFFFFFFFFBFFFE000
#define NMI_DELIVERY_MODE    0x4 << 8                            //NMI
#define MSR_PERF_GLOBAL_CTRL    0x38F
#define MSR_PERF_FIXED_CTRL     0x38D
#define MSR_PERF_FIXED_CTR0     0x309
#define MSR_PERF_GLOBAL_OVF_CTRL 0x390

/*Configure LAPIC*/
apic_base = Msr::read<Paddr>(Msr::IA32_APIC_BASE)
map(CPU_LOCAL_APIC, apic_base & 0xFFFFF000)                                                                // No caching, etc.
Msr::write (Msr::IA32_APIC_BASE, apic_base | 0x800);
write (LAPIC_SVR, read (LAPIC_SVR) | 0x100);
*reinterpret_cast<uint32 volatile *>(CPU_LOCAL_APIC + LAPIC_LVT_PERFM) = NMI_DELIVERY_MODE;

/*Configure MSR_PERF_FIXED_CTR0 to have overflow interrupt*/
Msr::write(Msr::MSR_PERF_GLOBAL_CTRL, Msr::read<uint64>(Msr::MSR_PERF_GLOBAL_CTRL) | (1ull<<32));          // enable IA32_PERF_FIXED_CTR0
Msr::write(Msr::MSR_PERF_FIXED_CTRL, 0xa);                                                                 // configure IA32_PERF_FIXED_CTR0 to count in user mode and interrupt on overflow
Msr::write(Msr::MSR_PERF_FIXED_CTR0, (1<<48) - 0x1000);                                                    // overflow after 0x1000 instruction
Msr::write(Msr::MSR_PERF_GLOBAL_OVF_CTRL, Msr::read<uint64>(Msr::MSR_PERF_GLOBAL_OVF_CTRL) & ~(1UL<<32));  // clear overflow condition
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Mahouk
  • 902
  • 9
  • 28
  • Virtualizing / passing through performance counters is a problem with many VMs. Upvoted and retagged so hopefully this can get an answer. – Peter Cordes Mar 10 '18 at 02:39

0 Answers0