uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, uint32_t index, int reg) { struct kvm_cpuid2 *cpuid; int i, max; uint32_t ret = 0; uint32_t cpuid_1_edx; if (!kvm_check_extension(env->kvm_state, KVM_CAP_EXT_CPUID)) { return -1U; } max = 1; while ((cpuid = try_get_cpuid(env->kvm_state, max)) == NULL) { max *= 2; } for (i = 0; i < cpuid->nent; ++i) { if (cpuid->entries[i].function == function && cpuid->entries[i].index == index) { switch (reg) { case R_EAX: ret = cpuid->entries[i].eax; break; case R_EBX: ret = cpuid->entries[i].ebx; break; case R_ECX: ret = cpuid->entries[i].ecx; break; case R_EDX: ret = cpuid->entries[i].edx; switch (function) { case 1: /* KVM before 2.6.30 misreports the following features */ ret |= CPUID_MTRR | CPUID_PAT | CPUID_MCE | CPUID_MCA; break; case 0x80000001: /* On Intel, kvm returns cpuid according to the Intel spec, * so add missing bits according to the AMD spec: */ cpuid_1_edx = kvm_arch_get_supported_cpuid(env, 1, 0, R_EDX); ret |= cpuid_1_edx & 0x183f7ff; break; } break; } } } qemu_free(cpuid); return ret; }