diff options
Diffstat (limited to 'target-i386/cpu.c')
-rw-r--r-- | target-i386/cpu.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 89b4ac7ec5..388bc5c527 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -238,6 +238,8 @@ typedef struct x86_def_t { /* Store the results of Centaur's CPUID instructions */ uint32_t ext4_features; uint32_t xlevel2; + /* The feature bits on CPUID[EAX=7,ECX=0].EBX */ + uint32_t cpuid_7_0_ebx_features; } x86_def_t; #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE) @@ -521,6 +523,12 @@ static int cpu_x86_fill_host(x86_def_t *x86_cpu_def) x86_cpu_def->ext_features = ecx; x86_cpu_def->features = edx; + if (kvm_enabled() && x86_cpu_def->level >= 7) { + x86_cpu_def->cpuid_7_0_ebx_features = kvm_arch_get_supported_cpuid(kvm_state, 0x7, 0, R_EBX); + } else { + x86_cpu_def->cpuid_7_0_ebx_features = 0; + } + host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx); x86_cpu_def->xlevel = eax; @@ -1185,6 +1193,7 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model) env->cpuid_kvm_features = def->kvm_features; env->cpuid_svm_features = def->svm_features; env->cpuid_ext4_features = def->ext4_features; + env->cpuid_7_0_ebx = def->cpuid_7_0_ebx_features; env->cpuid_xlevel2 = def->xlevel2; object_property_set_int(OBJECT(cpu), (int64_t)def->tsc_khz * 1000, "tsc-frequency", &error); @@ -1451,13 +1460,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *edx = 0; break; case 7: - if (kvm_enabled()) { - KVMState *s = env->kvm_state; - - *eax = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EAX); - *ebx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EBX); - *ecx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_ECX); - *edx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EDX); + /* Structured Extended Feature Flags Enumeration Leaf */ + if (count == 0) { + *eax = 0; /* Maximum ECX value for sub-leaves */ + *ebx = env->cpuid_7_0_ebx; /* Feature flags */ + *ecx = 0; /* Reserved */ + *edx = 0; /* Reserved */ } else { *eax = 0; *ebx = 0; |