1a1fe6bc5SPekka Enberg #include "kvm/kvm.h" 2a1fe6bc5SPekka Enberg #include "kvm/util.h" 3a1fe6bc5SPekka Enberg 4a1fe6bc5SPekka Enberg #include <sys/ioctl.h> 5a1fe6bc5SPekka Enberg #include <stdlib.h> 6a1fe6bc5SPekka Enberg #include <assert.h> 7a1fe6bc5SPekka Enberg 8*1e1b3818SPekka Enberg #define CPUID_FUNC_PERFMON 0x0A 9*1e1b3818SPekka Enberg 10a1fe6bc5SPekka Enberg #define MAX_KVM_CPUID_ENTRIES 100 11a1fe6bc5SPekka Enberg 12*1e1b3818SPekka Enberg static void filter_cpuid(struct kvm_cpuid2 *kvm_cpuid) 13*1e1b3818SPekka Enberg { 14*1e1b3818SPekka Enberg unsigned int i; 15*1e1b3818SPekka Enberg 16*1e1b3818SPekka Enberg /* 17*1e1b3818SPekka Enberg * Filter CPUID functions that are not supported by the hypervisor. 18*1e1b3818SPekka Enberg */ 19*1e1b3818SPekka Enberg for (i = 0; i < kvm_cpuid->nent; i++) { 20*1e1b3818SPekka Enberg struct kvm_cpuid_entry2 *entry = &kvm_cpuid->entries[i]; 21*1e1b3818SPekka Enberg 22*1e1b3818SPekka Enberg switch (entry->function) { 23*1e1b3818SPekka Enberg case CPUID_FUNC_PERFMON: 24*1e1b3818SPekka Enberg entry->eax = 0x00; /* disable it */ 25*1e1b3818SPekka Enberg break; 26*1e1b3818SPekka Enberg default: 27*1e1b3818SPekka Enberg /* Keep the CPUID function as -is */ 28*1e1b3818SPekka Enberg break; 29*1e1b3818SPekka Enberg }; 30*1e1b3818SPekka Enberg } 31*1e1b3818SPekka Enberg } 32*1e1b3818SPekka Enberg 33a1fe6bc5SPekka Enberg void kvm__setup_cpuid(struct kvm *self) 34a1fe6bc5SPekka Enberg { 35a1fe6bc5SPekka Enberg struct kvm_cpuid2 *kvm_cpuid; 36a1fe6bc5SPekka Enberg 37bb988cf5SAsias He kvm_cpuid = calloc(1, sizeof(*kvm_cpuid) + MAX_KVM_CPUID_ENTRIES * sizeof(*kvm_cpuid->entries)); 38a1fe6bc5SPekka Enberg 39bb988cf5SAsias He kvm_cpuid->nent = MAX_KVM_CPUID_ENTRIES; 40bb988cf5SAsias He if (ioctl(self->sys_fd, KVM_GET_SUPPORTED_CPUID, kvm_cpuid) < 0) 41bb988cf5SAsias He die_perror("KVM_GET_SUPPORTED_CPUID failed"); 42a1fe6bc5SPekka Enberg 43*1e1b3818SPekka Enberg filter_cpuid(kvm_cpuid); 44*1e1b3818SPekka Enberg 45a1fe6bc5SPekka Enberg if (ioctl(self->vcpu_fd, KVM_SET_CPUID2, kvm_cpuid) < 0) 46a1fe6bc5SPekka Enberg die_perror("KVM_SET_CPUID2 failed"); 47a1fe6bc5SPekka Enberg 48bb988cf5SAsias He free(kvm_cpuid); 49a1fe6bc5SPekka Enberg } 50