aboutsummaryrefslogtreecommitdiff
path: root/target/i386/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/i386/cpu.c')
-rw-r--r--target/i386/cpu.c55
1 files changed, 51 insertions, 4 deletions
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 6d85149..455caff 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1397,7 +1397,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
.type = CPUID_FEATURE_WORD,
.feat_names = {
"no-nested-data-bp", "fs-gs-base-ns", "lfence-always-serializing", NULL,
- NULL, NULL, "null-sel-clr-base", NULL,
+ NULL, "verw-clear", "null-sel-clr-base", NULL,
"auto-ibrs", NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
@@ -1415,6 +1415,22 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
.tcg_features = 0,
.unmigratable_flags = 0,
},
+ [FEAT_8000_0021_ECX] = {
+ .type = CPUID_FEATURE_WORD,
+ .feat_names = {
+ NULL, "tsa-sq-no", "tsa-l1-no", NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ },
+ .cpuid = { .eax = 0x80000021, .reg = R_ECX, },
+ .tcg_features = 0,
+ .unmigratable_flags = 0,
+ },
[FEAT_8000_0022_EAX] = {
.type = CPUID_FEATURE_WORD,
.feat_names = {
@@ -7539,6 +7555,20 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w)
#endif
break;
+ case FEAT_7_0_EDX:
+ /*
+ * Windows does not like ARCH_CAPABILITIES on AMD machines at all.
+ * Do not show the fake ARCH_CAPABILITIES MSR that KVM sets up,
+ * except if needed for migration.
+ *
+ * When arch_cap_always_on is removed, this tweak can move to
+ * kvm_arch_get_supported_cpuid.
+ */
+ if (cpu && IS_AMD_CPU(&cpu->env) && !cpu->arch_cap_always_on) {
+ unavail = CPUID_7_0_EDX_ARCH_CAPABILITIES;
+ }
+ break;
+
default:
break;
}
@@ -7894,6 +7924,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
/* Fixup overflow: max value for bits 23-16 is 255. */
*ebx |= MIN(num, 255) << 16;
}
+ if (cpu->pdcm_on_even_without_pmu) {
+ if (!cpu->enable_pmu) {
+ *ecx &= ~CPUID_EXT_PDCM;
+ }
+ }
break;
case 2: { /* cache info: needed for Pentium Pro compatibility */
const CPUCaches *caches;
@@ -8507,6 +8542,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*eax = *ebx = *ecx = *edx = 0;
*eax = env->features[FEAT_8000_0021_EAX];
*ebx = env->features[FEAT_8000_0021_EBX];
+ *ecx = env->features[FEAT_8000_0021_ECX];
break;
case 0x80000022:
*eax = *ebx = *ecx = *edx = 0;
@@ -8613,7 +8649,11 @@ static void x86_cpu_reset_hold(Object *obj, ResetType type)
env->idt.limit = 0xffff;
env->gdt.limit = 0xffff;
+#if defined(CONFIG_USER_ONLY)
+ env->ldt.limit = 0;
+#else
env->ldt.limit = 0xffff;
+#endif
env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
env->tr.limit = 0xffff;
env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
@@ -8944,9 +8984,11 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
}
}
- /* PDCM is fixed1 bit for TDX */
- if (!cpu->enable_pmu && !is_tdx_vm()) {
- env->features[FEAT_1_ECX] &= ~CPUID_EXT_PDCM;
+ if (!cpu->pdcm_on_even_without_pmu) {
+ /* PDCM is fixed1 bit for TDX */
+ if (!cpu->enable_pmu && !is_tdx_vm()) {
+ env->features[FEAT_1_ECX] &= ~CPUID_EXT_PDCM;
+ }
}
for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) {
@@ -10004,6 +10046,11 @@ static const Property x86_cpu_properties[] = {
true),
DEFINE_PROP_BOOL("x-l1-cache-per-thread", X86CPU, l1_cache_per_core, true),
DEFINE_PROP_BOOL("x-force-cpuid-0x1f", X86CPU, force_cpuid_0x1f, false),
+
+ DEFINE_PROP_BOOL("x-arch-cap-always-on", X86CPU,
+ arch_cap_always_on, false),
+ DEFINE_PROP_BOOL("x-pdcm-on-even-without-pmu", X86CPU,
+ pdcm_on_even_without_pmu, false),
};
#ifndef CONFIG_USER_ONLY