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.c290
1 files changed, 123 insertions, 167 deletions
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index b4349119f8..e0ba36cc23 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -776,94 +776,6 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
*/
.no_autoenable_flags = ~0U,
},
- /*
- * .feat_names are commented out for Hyper-V enlightenments because we
- * don't want to have two different ways for enabling them on QEMU command
- * line. Some features (e.g. "hyperv_time", "hyperv_vapic", ...) require
- * enabling several feature bits simultaneously, exposing these bits
- * individually may just confuse guests.
- */
- [FEAT_HYPERV_EAX] = {
- .type = CPUID_FEATURE_WORD,
- .feat_names = {
- NULL /* hv_msr_vp_runtime_access */, NULL /* hv_msr_time_refcount_access */,
- NULL /* hv_msr_synic_access */, NULL /* hv_msr_stimer_access */,
- NULL /* hv_msr_apic_access */, NULL /* hv_msr_hypercall_access */,
- NULL /* hv_vpindex_access */, NULL /* hv_msr_reset_access */,
- NULL /* hv_msr_stats_access */, NULL /* hv_reftsc_access */,
- NULL /* hv_msr_idle_access */, NULL /* hv_msr_frequency_access */,
- NULL /* hv_msr_debug_access */, NULL /* hv_msr_reenlightenment_access */,
- NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- },
- .cpuid = { .eax = 0x40000003, .reg = R_EAX, },
- },
- [FEAT_HYPERV_EBX] = {
- .type = CPUID_FEATURE_WORD,
- .feat_names = {
- NULL /* hv_create_partitions */, NULL /* hv_access_partition_id */,
- NULL /* hv_access_memory_pool */, NULL /* hv_adjust_message_buffers */,
- NULL /* hv_post_messages */, NULL /* hv_signal_events */,
- NULL /* hv_create_port */, NULL /* hv_connect_port */,
- NULL /* hv_access_stats */, NULL, NULL, NULL /* hv_debugging */,
- NULL /* hv_cpu_power_management */, NULL /* hv_configure_profiler */,
- NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- },
- .cpuid = { .eax = 0x40000003, .reg = R_EBX, },
- },
- [FEAT_HYPERV_EDX] = {
- .type = CPUID_FEATURE_WORD,
- .feat_names = {
- NULL /* hv_mwait */, NULL /* hv_guest_debugging */,
- NULL /* hv_perf_monitor */, NULL /* hv_cpu_dynamic_part */,
- NULL /* hv_hypercall_params_xmm */, NULL /* hv_guest_idle_state */,
- NULL, NULL,
- NULL, NULL, NULL /* hv_guest_crash_msr */, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- },
- .cpuid = { .eax = 0x40000003, .reg = R_EDX, },
- },
- [FEAT_HV_RECOMM_EAX] = {
- .type = CPUID_FEATURE_WORD,
- .feat_names = {
- NULL /* hv_recommend_pv_as_switch */,
- NULL /* hv_recommend_pv_tlbflush_local */,
- NULL /* hv_recommend_pv_tlbflush_remote */,
- NULL /* hv_recommend_msr_apic_access */,
- NULL /* hv_recommend_msr_reset */,
- NULL /* hv_recommend_relaxed_timing */,
- NULL /* hv_recommend_dma_remapping */,
- NULL /* hv_recommend_int_remapping */,
- NULL /* hv_recommend_x2apic_msrs */,
- NULL /* hv_recommend_autoeoi_deprecation */,
- NULL /* hv_recommend_pv_ipi */,
- NULL /* hv_recommend_ex_hypercalls */,
- NULL /* hv_hypervisor_is_nested */,
- NULL /* hv_recommend_int_mbec */,
- NULL /* hv_recommend_evmcs */,
- NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- },
- .cpuid = { .eax = 0x40000004, .reg = R_EAX, },
- },
- [FEAT_HV_NESTED_EAX] = {
- .type = CPUID_FEATURE_WORD,
- .cpuid = { .eax = 0x4000000A, .reg = R_EAX, },
- },
[FEAT_SVM] = {
.type = CPUID_FEATURE_WORD,
.feat_names = {
@@ -1576,7 +1488,7 @@ typedef struct X86CPUDefinition {
int stepping;
FeatureWordArray features;
const char *model_id;
- CPUCaches *cache_info;
+ const CPUCaches *const cache_info;
/*
* Definitions for alternative versions of CPU model.
* List is terminated by item with version == 0.
@@ -1589,7 +1501,7 @@ typedef struct X86CPUDefinition {
/* Reference to a specific CPU model version */
struct X86CPUModel {
/* Base CPU definition */
- X86CPUDefinition *cpudef;
+ const X86CPUDefinition *cpudef;
/* CPU model version */
X86CPUVersion version;
const char *note;
@@ -1601,14 +1513,15 @@ struct X86CPUModel {
};
/* Get full model name for CPU version */
-static char *x86_cpu_versioned_model_name(X86CPUDefinition *cpudef,
+static char *x86_cpu_versioned_model_name(const X86CPUDefinition *cpudef,
X86CPUVersion version)
{
assert(version > 0);
return g_strdup_printf("%s-v%d", cpudef->name, (int)version);
}
-static const X86CPUVersionDefinition *x86_cpu_def_get_versions(X86CPUDefinition *def)
+static const X86CPUVersionDefinition *
+x86_cpu_def_get_versions(const X86CPUDefinition *def)
{
/* When X86CPUDefinition::versions is NULL, we register only v1 */
static const X86CPUVersionDefinition default_version_list[] = {
@@ -1619,7 +1532,7 @@ static const X86CPUVersionDefinition *x86_cpu_def_get_versions(X86CPUDefinition
return def->versions ?: default_version_list;
}
-static CPUCaches epyc_cache_info = {
+static const CPUCaches epyc_cache_info = {
.l1d_cache = &(CPUCacheInfo) {
.type = DATA_CACHE,
.level = 1,
@@ -1669,7 +1582,7 @@ static CPUCaches epyc_cache_info = {
},
};
-static CPUCaches epyc_rome_cache_info = {
+static const CPUCaches epyc_rome_cache_info = {
.l1d_cache = &(CPUCacheInfo) {
.type = DATA_CACHE,
.level = 1,
@@ -1719,7 +1632,7 @@ static CPUCaches epyc_rome_cache_info = {
},
};
-static CPUCaches epyc_milan_cache_info = {
+static const CPUCaches epyc_milan_cache_info = {
.l1d_cache = &(CPUCacheInfo) {
.type = DATA_CACHE,
.level = 1,
@@ -1797,14 +1710,14 @@ static CPUCaches epyc_milan_cache_info = {
* PT in VMX operation
*/
-static X86CPUDefinition builtin_x86_defs[] = {
+static const X86CPUDefinition builtin_x86_defs[] = {
{
.name = "qemu64",
.level = 0xd,
.vendor = CPUID_VENDOR_AMD,
- .family = 6,
- .model = 6,
- .stepping = 3,
+ .family = 15,
+ .model = 107,
+ .stepping = 1,
.features[FEAT_1_EDX] =
PPRO_FEATURES |
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
@@ -2802,12 +2715,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
CPUID_7_0_EBX_SMAP,
- /* Missing: XSAVES (not supported by some Linux versions,
- * including v4.1 to v4.12).
- * KVM doesn't yet expose any XSAVES state save component,
- * and the only one defined in Skylake (processor tracing)
- * probably will block migration anyway.
- */
+ /* XSAVES is added in version 4 */
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
CPUID_XSAVE_XGETBV1,
@@ -2883,6 +2791,15 @@ static X86CPUDefinition builtin_x86_defs[] = {
{ /* end of list */ }
}
},
+ {
+ .version = 4,
+ .note = "IBRS, XSAVES, no TSX",
+ .props = (PropValue[]) {
+ { "xsaves", "on" },
+ { "vmx-xsaves", "on" },
+ { /* end of list */ }
+ }
+ },
{ /* end of list */ }
}
},
@@ -2922,12 +2839,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT,
.features[FEAT_7_0_ECX] =
CPUID_7_0_ECX_PKU,
- /* Missing: XSAVES (not supported by some Linux versions,
- * including v4.1 to v4.12).
- * KVM doesn't yet expose any XSAVES state save component,
- * and the only one defined in Skylake (processor tracing)
- * probably will block migration anyway.
- */
+ /* XSAVES is added in version 5 */
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
CPUID_XSAVE_XGETBV1,
@@ -3015,6 +2927,15 @@ static X86CPUDefinition builtin_x86_defs[] = {
{ /* end of list */ }
}
},
+ {
+ .version = 5,
+ .note = "IBRS, XSAVES, EPT switching, no TSX",
+ .props = (PropValue[]) {
+ { "xsaves", "on" },
+ { "vmx-xsaves", "on" },
+ { /* end of list */ }
+ }
+ },
{ /* end of list */ }
}
},
@@ -3057,12 +2978,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_ECX_AVX512VNNI,
.features[FEAT_7_0_EDX] =
CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
- /* Missing: XSAVES (not supported by some Linux versions,
- * including v4.1 to v4.12).
- * KVM doesn't yet expose any XSAVES state save component,
- * and the only one defined in Skylake (processor tracing)
- * probably will block migration anyway.
- */
+ /* XSAVES is added in version 5 */
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
CPUID_XSAVE_XGETBV1,
@@ -3146,6 +3062,14 @@ static X86CPUDefinition builtin_x86_defs[] = {
{ /* end of list */ }
},
},
+ { .version = 5,
+ .note = "ARCH_CAPABILITIES, EPT switching, XSAVES, no TSX",
+ .props = (PropValue[]) {
+ { "xsaves", "on" },
+ { "vmx-xsaves", "on" },
+ { /* end of list */ }
+ },
+ },
{ /* end of list */ }
}
},
@@ -3195,13 +3119,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
MSR_ARCH_CAP_PSCHANGE_MC_NO | MSR_ARCH_CAP_TAA_NO,
.features[FEAT_7_1_EAX] =
CPUID_7_1_EAX_AVX_VNNI | CPUID_7_1_EAX_AVX512_BF16,
- /*
- * Missing: XSAVES (not supported by some Linux versions,
- * including v4.1 to v4.12).
- * KVM doesn't yet expose any XSAVES state save component,
- * and the only one defined in Skylake (processor tracing)
- * probably will block migration anyway.
- */
+ /* XSAVES is added in version 2 */
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
CPUID_XSAVE_XGETBV1,
@@ -3257,6 +3175,18 @@ static X86CPUDefinition builtin_x86_defs[] = {
.features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
.xlevel = 0x80000008,
.model_id = "Intel Xeon Processor (Cooperlake)",
+ .versions = (X86CPUVersionDefinition[]) {
+ { .version = 1 },
+ { .version = 2,
+ .note = "XSAVES",
+ .props = (PropValue[]) {
+ { "xsaves", "on" },
+ { "vmx-xsaves", "on" },
+ { /* end of list */ }
+ },
+ },
+ { /* end of list */ }
+ }
},
{
.name = "Icelake-Client",
@@ -3299,12 +3229,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_ECX_AVX512_VPOPCNTDQ,
.features[FEAT_7_0_EDX] =
CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
- /* Missing: XSAVES (not supported by some Linux versions,
- * including v4.1 to v4.12).
- * KVM doesn't yet expose any XSAVES state save component,
- * and the only one defined in Skylake (processor tracing)
- * probably will block migration anyway.
- */
+ /* XSAVES is added in version 3 */
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
CPUID_XSAVE_XGETBV1,
@@ -3372,6 +3297,15 @@ static X86CPUDefinition builtin_x86_defs[] = {
{ /* end of list */ }
},
},
+ {
+ .version = 3,
+ .note = "no TSX, XSAVES, deprecated",
+ .props = (PropValue[]) {
+ { "xsaves", "on" },
+ { "vmx-xsaves", "on" },
+ { /* end of list */ }
+ },
+ },
{ /* end of list */ }
},
.deprecation_note = "use Icelake-Server instead"
@@ -3420,12 +3354,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57,
.features[FEAT_7_0_EDX] =
CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
- /* Missing: XSAVES (not supported by some Linux versions,
- * including v4.1 to v4.12).
- * KVM doesn't yet expose any XSAVES state save component,
- * and the only one defined in Skylake (processor tracing)
- * probably will block migration anyway.
- */
+ /* XSAVES is added in version 5 */
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
CPUID_XSAVE_XGETBV1,
@@ -3518,6 +3447,15 @@ static X86CPUDefinition builtin_x86_defs[] = {
{ /* end of list */ }
},
},
+ {
+ .version = 5,
+ .note = "XSAVES",
+ .props = (PropValue[]) {
+ { "xsaves", "on" },
+ { "vmx-xsaves", "on" },
+ { /* end of list */ }
+ },
+ },
{ /* end of list */ }
}
},
@@ -3552,13 +3490,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
.features[FEAT_7_0_EDX] =
CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_ARCH_CAPABILITIES |
CPUID_7_0_EDX_SPEC_CTRL_SSBD,
- /*
- * Missing: XSAVES (not supported by some Linux versions,
- * including v4.1 to v4.12).
- * KVM doesn't yet expose any XSAVES state save component,
- * and the only one defined in Skylake (processor tracing)
- * probably will block migration anyway.
- */
+ /* XSAVES is added in version 3 */
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | CPUID_XSAVE_XGETBV1,
.features[FEAT_6_EAX] =
@@ -3625,6 +3557,15 @@ static X86CPUDefinition builtin_x86_defs[] = {
{ /* end of list */ },
},
},
+ {
+ .version = 3,
+ .note = "XSAVES, no MPX, no MONITOR",
+ .props = (PropValue[]) {
+ { "xsaves", "on" },
+ { "vmx-xsaves", "on" },
+ { /* end of list */ },
+ },
+ },
{ /* end of list */ },
},
},
@@ -3683,13 +3624,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_EDX_CORE_CAPABILITY,
.features[FEAT_CORE_CAPABILITY] =
MSR_CORE_CAP_SPLIT_LOCK_DETECT,
- /*
- * Missing: XSAVES (not supported by some Linux versions,
- * including v4.1 to v4.12).
- * KVM doesn't yet expose any XSAVES state save component,
- * and the only one defined in Skylake (processor tracing)
- * probably will block migration anyway.
- */
+ /* XSAVES is is added in version 3 */
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
CPUID_XSAVE_XGETBV1,
@@ -3754,6 +3689,15 @@ static X86CPUDefinition builtin_x86_defs[] = {
{ /* end of list */ },
},
},
+ {
+ .version = 3,
+ .note = "XSAVES, no MPX",
+ .props = (PropValue[]) {
+ { "xsaves", "on" },
+ { "vmx-xsaves", "on" },
+ { /* end of list */ },
+ },
+ },
{ /* end of list */ },
},
},
@@ -4035,11 +3979,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT,
- /*
- * Missing: XSAVES (not supported by some Linux versions,
- * including v4.1 to v4.12).
- * KVM doesn't yet expose any XSAVES state save component.
- */
+ /* XSAVES is added in version 2 */
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
CPUID_XSAVE_XGETBV1,
@@ -4050,6 +3990,17 @@ static X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x8000001E,
.model_id = "Hygon Dhyana Processor",
.cache_info = &epyc_cache_info,
+ .versions = (X86CPUVersionDefinition[]) {
+ { .version = 1 },
+ { .version = 2,
+ .note = "XSAVES",
+ .props = (PropValue[]) {
+ { "xsaves", "on" },
+ { /* end of list */ }
+ },
+ },
+ { /* end of list */ }
+ }
},
{
.name = "EPYC-Rome",
@@ -4246,9 +4197,15 @@ static void max_x86_cpu_initfn(Object *obj)
*/
object_property_set_str(OBJECT(cpu), "vendor", CPUID_VENDOR_AMD,
&error_abort);
+#ifdef TARGET_X86_64
+ object_property_set_int(OBJECT(cpu), "family", 15, &error_abort);
+ object_property_set_int(OBJECT(cpu), "model", 107, &error_abort);
+ object_property_set_int(OBJECT(cpu), "stepping", 1, &error_abort);
+#else
object_property_set_int(OBJECT(cpu), "family", 6, &error_abort);
object_property_set_int(OBJECT(cpu), "model", 6, &error_abort);
object_property_set_int(OBJECT(cpu), "stepping", 3, &error_abort);
+#endif
object_property_set_str(OBJECT(cpu), "model-id",
"QEMU TCG CPU version " QEMU_HW_VERSION,
&error_abort);
@@ -5023,7 +4980,7 @@ static void x86_cpu_apply_version_props(X86CPU *cpu, X86CPUModel *model)
*/
static void x86_cpu_load_model(X86CPU *cpu, X86CPUModel *model)
{
- X86CPUDefinition *def = model->cpudef;
+ const X86CPUDefinition *def = model->cpudef;
CPUX86State *env = &cpu->env;
FeatureWord w;
@@ -5110,7 +5067,7 @@ static void x86_register_cpu_model_type(const char *name, X86CPUModel *model)
type_register(&ti);
}
-static void x86_register_cpudef_types(X86CPUDefinition *def)
+static void x86_register_cpudef_types(const X86CPUDefinition *def)
{
X86CPUModel *m;
const X86CPUVersionDefinition *vdef;
@@ -6096,17 +6053,16 @@ static void x86_cpu_hyperv_realize(X86CPU *cpu)
/* Hyper-V vendor id */
if (!cpu->hyperv_vendor) {
- memcpy(cpu->hyperv_vendor_id, "Microsoft Hv", 12);
- } else {
- len = strlen(cpu->hyperv_vendor);
-
- if (len > 12) {
- warn_report("hv-vendor-id truncated to 12 characters");
- len = 12;
- }
- memset(cpu->hyperv_vendor_id, 0, 12);
- memcpy(cpu->hyperv_vendor_id, cpu->hyperv_vendor, len);
+ object_property_set_str(OBJECT(cpu), "hv-vendor-id", "Microsoft Hv",
+ &error_abort);
+ }
+ len = strlen(cpu->hyperv_vendor);
+ if (len > 12) {
+ warn_report("hv-vendor-id truncated to 12 characters");
+ len = 12;
}
+ memset(cpu->hyperv_vendor_id, 0, 12);
+ memcpy(cpu->hyperv_vendor_id, cpu->hyperv_vendor, len);
/* 'Hv#1' interface identification*/
cpu->hyperv_interface_id[0] = 0x31237648;