1*5c3d55faSPekka Enberg #include "kvm/kvm-cpu.h" 2*5c3d55faSPekka Enberg 3a1fe6bc5SPekka Enberg #include "kvm/kvm.h" 4a1fe6bc5SPekka Enberg #include "kvm/util.h" 5a1fe6bc5SPekka Enberg 6a1fe6bc5SPekka Enberg #include <sys/ioctl.h> 7a1fe6bc5SPekka Enberg #include <stdlib.h> 8a1fe6bc5SPekka Enberg #include <assert.h> 9a1fe6bc5SPekka Enberg 101e1b3818SPekka Enberg #define CPUID_FUNC_PERFMON 0x0A 111e1b3818SPekka Enberg 12a1fe6bc5SPekka Enberg #define MAX_KVM_CPUID_ENTRIES 100 13a1fe6bc5SPekka Enberg 141e1b3818SPekka Enberg static void filter_cpuid(struct kvm_cpuid2 *kvm_cpuid) 151e1b3818SPekka Enberg { 161e1b3818SPekka Enberg unsigned int i; 171e1b3818SPekka Enberg 181e1b3818SPekka Enberg /* 191e1b3818SPekka Enberg * Filter CPUID functions that are not supported by the hypervisor. 201e1b3818SPekka Enberg */ 211e1b3818SPekka Enberg for (i = 0; i < kvm_cpuid->nent; i++) { 221e1b3818SPekka Enberg struct kvm_cpuid_entry2 *entry = &kvm_cpuid->entries[i]; 231e1b3818SPekka Enberg 241e1b3818SPekka Enberg switch (entry->function) { 251e1b3818SPekka Enberg case CPUID_FUNC_PERFMON: 261e1b3818SPekka Enberg entry->eax = 0x00; /* disable it */ 271e1b3818SPekka Enberg break; 281e1b3818SPekka Enberg default: 291e1b3818SPekka Enberg /* Keep the CPUID function as -is */ 301e1b3818SPekka Enberg break; 311e1b3818SPekka Enberg }; 321e1b3818SPekka Enberg } 331e1b3818SPekka Enberg } 341e1b3818SPekka Enberg 35*5c3d55faSPekka Enberg void kvm_cpu__setup_cpuid(struct kvm_cpu *self) 36a1fe6bc5SPekka Enberg { 37a1fe6bc5SPekka Enberg struct kvm_cpuid2 *kvm_cpuid; 38a1fe6bc5SPekka Enberg 39bb988cf5SAsias He kvm_cpuid = calloc(1, sizeof(*kvm_cpuid) + MAX_KVM_CPUID_ENTRIES * sizeof(*kvm_cpuid->entries)); 40a1fe6bc5SPekka Enberg 41bb988cf5SAsias He kvm_cpuid->nent = MAX_KVM_CPUID_ENTRIES; 42*5c3d55faSPekka Enberg if (ioctl(self->kvm->sys_fd, KVM_GET_SUPPORTED_CPUID, kvm_cpuid) < 0) 43bb988cf5SAsias He die_perror("KVM_GET_SUPPORTED_CPUID failed"); 44a1fe6bc5SPekka Enberg 451e1b3818SPekka Enberg filter_cpuid(kvm_cpuid); 461e1b3818SPekka Enberg 47a1fe6bc5SPekka Enberg if (ioctl(self->vcpu_fd, KVM_SET_CPUID2, kvm_cpuid) < 0) 48a1fe6bc5SPekka Enberg die_perror("KVM_SET_CPUID2 failed"); 49a1fe6bc5SPekka Enberg 50bb988cf5SAsias He free(kvm_cpuid); 51a1fe6bc5SPekka Enberg } 52