My company develops a hypervisor, and this question concerns use of AMD's SVM (Secure-Virtual-Machine) API.
I'd like to track exactly how many instructions have executed in my guest operating system in a given period. AMD has kindly provided so-called "HO" and "GO" or "HostOnly" and "GuestOnly" bits in the PerfEvtSel MSRs (0xc0010000..3) in their implementation of their 0x10h family CPUs (Phenom x2, etc.). The BKDG for Family 0x10h indicates that these bits are 40 and 41 of the 64bit PerfEvtSel register. However, the BKDG for Family 0x11h does not state the existence of HostOnly and GuestOnly bits!
The code I have looks like this:
reg_svm_pes_set_unit_mask(&pes, 0x00);
reg_svm_pes_set_usr(&pes, 1); // Count user mode cycles
reg_svm_pes_set_os(&pes, 1); // Count system cycles
reg_svm_pes_set_e(&pes, 0); // Level, not edge
reg_svm_pes_set_pc(&pes, 0);
reg_svm_pes_set_int(&pes, 1); // Trigger interrupt on overflow
reg_svm_pes_set_en(&pes, enabled);
reg_svm_pes_set_inv(&pes, 0); // No invert sense
reg_svm_pes_set_go(&pes, 1); // Count in the guest
reg_svm_pes_set_ho(&pes, 0); // And not in the host...
You have to take my word for it that each of these is a correctly-written inline function that sets the appropriate bit in the PMC register, and that the given code successfully writes and can read back bits 40 and 41 of the MSR. I have verified this.
What I experience is that the counter counts both in the guest and the host. This makes it very difficult to get an exact accounting of only what has happened in the guest.
My questions are:
- Do the HostOnly and GuestOnly bits work on Family 0x10h CPUs?
- Is there some other machine state that I need to configure in order for this to function?
- Has anyone ever seen this feature of this CPU work?
- Does anyone know why the BKDG for Family 0x11h CPUs doesn't list this feature as being present. That is, the bits in question are reserved on that family.
- Is there any other known method of making SVM implementations turn off PMCs while in the host?