|
@@ -6154,6 +6154,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|
|
case 7:
|
|
|
/* Structured Extended Feature Flags Enumeration Leaf */
|
|
|
if (count == 0) {
|
|
|
+ uint32_t eax_0_unused, ebx_0, ecx_0, edx_0_unused;
|
|
|
+
|
|
|
/* Maximum ECX value for sub-leaves */
|
|
|
*eax = env->cpuid_level_func7;
|
|
|
*ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
|
|
@@ -6168,17 +6170,15 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|
|
* support enabling SGX and/or SGX flexible launch control,
|
|
|
* then we need to update the VM's CPUID values accordingly.
|
|
|
*/
|
|
|
- if ((*ebx & CPUID_7_0_EBX_SGX) &&
|
|
|
- (!kvm_enabled() ||
|
|
|
- !(kvm_arch_get_supported_cpuid(cs->kvm_state, 0x7, 0, R_EBX) &
|
|
|
- CPUID_7_0_EBX_SGX))) {
|
|
|
+ x86_cpu_get_supported_cpuid(0x7, 0,
|
|
|
+ &eax_0_unused, &ebx_0,
|
|
|
+ &ecx_0, &edx_0_unused);
|
|
|
+ if ((*ebx & CPUID_7_0_EBX_SGX) && !(ebx_0 & CPUID_7_0_EBX_SGX)) {
|
|
|
*ebx &= ~CPUID_7_0_EBX_SGX;
|
|
|
}
|
|
|
|
|
|
- if ((*ecx & CPUID_7_0_ECX_SGX_LC) &&
|
|
|
- (!(*ebx & CPUID_7_0_EBX_SGX) || !kvm_enabled() ||
|
|
|
- !(kvm_arch_get_supported_cpuid(cs->kvm_state, 0x7, 0, R_ECX) &
|
|
|
- CPUID_7_0_ECX_SGX_LC))) {
|
|
|
+ if ((*ecx & CPUID_7_0_ECX_SGX_LC)
|
|
|
+ && (!(*ebx & CPUID_7_0_EBX_SGX) || !(ecx_0 & CPUID_7_0_ECX_SGX_LC))) {
|
|
|
*ecx &= ~CPUID_7_0_ECX_SGX_LC;
|
|
|
}
|
|
|
} else if (count == 1) {
|
|
@@ -6207,7 +6207,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|
|
break;
|
|
|
case 0xA:
|
|
|
/* Architectural Performance Monitoring Leaf */
|
|
|
- if (accel_uses_host_cpuid() && cpu->enable_pmu) {
|
|
|
+ if (cpu->enable_pmu) {
|
|
|
x86_cpu_get_supported_cpuid(0xA, count, eax, ebx, ecx, edx);
|
|
|
} else {
|
|
|
*eax = 0;
|
|
@@ -6247,8 +6247,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|
|
*ebx &= 0xffff; /* The count doesn't need to be reliable. */
|
|
|
break;
|
|
|
case 0x1C:
|
|
|
- if (accel_uses_host_cpuid() && cpu->enable_pmu &&
|
|
|
- (env->features[FEAT_7_0_EDX] & CPUID_7_0_EDX_ARCH_LBR)) {
|
|
|
+ if (cpu->enable_pmu && (env->features[FEAT_7_0_EDX] & CPUID_7_0_EDX_ARCH_LBR)) {
|
|
|
x86_cpu_get_supported_cpuid(0x1C, 0, eax, ebx, ecx, edx);
|
|
|
*edx = 0;
|
|
|
}
|
|
@@ -6322,9 +6321,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|
|
} else {
|
|
|
*ecx &= ~XSTATE_ARCH_LBR_MASK;
|
|
|
}
|
|
|
- } else if (count == 0xf &&
|
|
|
- accel_uses_host_cpuid() && cpu->enable_pmu &&
|
|
|
- (env->features[FEAT_7_0_EDX] & CPUID_7_0_EDX_ARCH_LBR)) {
|
|
|
+ } else if (count == 0xf && cpu->enable_pmu
|
|
|
+ && (env->features[FEAT_7_0_EDX] & CPUID_7_0_EDX_ARCH_LBR)) {
|
|
|
x86_cpu_get_supported_cpuid(0xD, count, eax, ebx, ecx, edx);
|
|
|
} else if (count < ARRAY_SIZE(x86_ext_save_areas)) {
|
|
|
const ExtSaveArea *esa = &x86_ext_save_areas[count];
|
|
@@ -7121,8 +7119,8 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
|
|
|
env->cpuid_xlevel2 = env->cpuid_min_xlevel2;
|
|
|
}
|
|
|
|
|
|
- if (kvm_enabled()) {
|
|
|
- kvm_hyperv_expand_features(cpu, errp);
|
|
|
+ if (kvm_enabled() && !kvm_hyperv_expand_features(cpu, errp)) {
|
|
|
+ return;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -7152,14 +7150,14 @@ static void x86_cpu_filter_features(X86CPU *cpu, bool verbose)
|
|
|
mark_unavailable_features(cpu, w, unavailable_features, prefix);
|
|
|
}
|
|
|
|
|
|
- if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) &&
|
|
|
- kvm_enabled()) {
|
|
|
- KVMState *s = CPU(cpu)->kvm_state;
|
|
|
- uint32_t eax_0 = kvm_arch_get_supported_cpuid(s, 0x14, 0, R_EAX);
|
|
|
- uint32_t ebx_0 = kvm_arch_get_supported_cpuid(s, 0x14, 0, R_EBX);
|
|
|
- uint32_t ecx_0 = kvm_arch_get_supported_cpuid(s, 0x14, 0, R_ECX);
|
|
|
- uint32_t eax_1 = kvm_arch_get_supported_cpuid(s, 0x14, 1, R_EAX);
|
|
|
- uint32_t ebx_1 = kvm_arch_get_supported_cpuid(s, 0x14, 1, R_EBX);
|
|
|
+ if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) {
|
|
|
+ uint32_t eax_0, ebx_0, ecx_0, edx_0_unused;
|
|
|
+ uint32_t eax_1, ebx_1, ecx_1_unused, edx_1_unused;
|
|
|
+
|
|
|
+ x86_cpu_get_supported_cpuid(0x14, 0,
|
|
|
+ &eax_0, &ebx_0, &ecx_0, &edx_0_unused);
|
|
|
+ x86_cpu_get_supported_cpuid(0x14, 1,
|
|
|
+ &eax_1, &ebx_1, &ecx_1_unused, &edx_1_unused);
|
|
|
|
|
|
if (!eax_0 ||
|
|
|
((ebx_0 & INTEL_PT_MINIMAL_EBX) != INTEL_PT_MINIMAL_EBX) ||
|