#include "qemu/hw-version.h"
#include "cpu.h"
#include "tcg/helper-tcg.h"
-#include "sysemu/reset.h"
#include "sysemu/hvf.h"
+#include "hvf/hvf-i386.h"
#include "kvm/kvm_i386.h"
#include "sev.h"
#include "qapi/error.h"
#include "hw/qdev-properties.h"
#include "hw/i386/topology.h"
#ifndef CONFIG_USER_ONLY
+#include "sysemu/reset.h"
#include "qapi/qapi-commands-machine-target.h"
#include "exec/address-spaces.h"
#include "hw/boards.h"
CPUID_7_0_EBX_PCOMMIT | CPUID_7_0_EBX_CLFLUSHOPT | \
CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_FSGSBASE | \
CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_RDSEED | \
- CPUID_7_0_EBX_KERNEL_FEATURES)
+ CPUID_7_0_EBX_SHA_NI | CPUID_7_0_EBX_KERNEL_FEATURES)
/* missing:
CPUID_7_0_EBX_HLE
CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM */
-#if defined CONFIG_SOFTMMU || defined CONFIG_LINUX
+#if !defined CONFIG_USER_ONLY || defined CONFIG_LINUX
#define TCG_7_0_ECX_RDPID CPUID_7_0_ECX_RDPID
#else
#define TCG_7_0_ECX_RDPID 0
#define TCG_7_0_EDX_FEATURES (CPUID_7_0_EDX_FSRM | CPUID_7_0_EDX_KERNEL_FEATURES)
#define TCG_7_1_EAX_FEATURES (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | \
- CPUID_7_1_EAX_FSRC)
+ CPUID_7_1_EAX_FSRC | CPUID_7_1_EAX_CMPCCXADD)
#define TCG_7_1_EDX_FEATURES 0
#define TCG_7_2_EDX_FEATURES 0
#define TCG_APM_FEATURES 0
},
.cpuid = {.eax = 1, .reg = R_EDX, },
.tcg_features = TCG_FEATURES,
+ .no_autoenable_flags = CPUID_HT,
},
[FEAT_1_ECX] = {
.type = CPUID_FEATURE_WORD,
.feat_names = {
NULL, NULL, NULL, NULL,
"avx-vnni-int8", "avx-ne-convert", NULL, NULL,
- NULL, NULL, NULL, NULL,
+ "amx-complex", NULL, NULL, NULL,
NULL, NULL, "prefetchiti", NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, "sbdr-ssdp-no", "fbsdp-no", "psdp-no",
NULL, "fb-clear", NULL, NULL,
NULL, NULL, NULL, NULL,
- "pbrsb-no", NULL, NULL, NULL,
+ "pbrsb-no", NULL, "gds-no", NULL,
NULL, NULL, NULL, NULL,
},
.msr = {
"vmx-invpcid-exit", "vmx-vmfunc", "vmx-shadow-vmcs", "vmx-encls-exit",
"vmx-rdseed-exit", "vmx-pml", NULL, NULL,
"vmx-xsaves", NULL, NULL, NULL,
- NULL, "vmx-tsc-scaling", NULL, NULL,
+ NULL, "vmx-tsc-scaling", "vmx-enable-user-wait-pause", NULL,
NULL, NULL, NULL, NULL,
},
.msr = {
.feat_names = {
[54] = "vmx-ins-outs",
[55] = "vmx-true-ctls",
+ [56] = "vmx-any-errcode",
},
.msr = {
.index = MSR_IA32_VMX_BASIC,
.from = { FEAT_8000_0001_ECX, CPUID_EXT3_SVM },
.to = { FEAT_SVM, ~0ull },
},
+ {
+ .from = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_ENABLE_USER_WAIT_PAUSE },
+ .to = { FEAT_7_0_ECX, CPUID_7_0_ECX_WAITPKG },
+ },
};
typedef struct X86RegisterInfo32 {
{
const char *class_name = object_class_get_name(OBJECT_CLASS(cc));
assert(g_str_has_suffix(class_name, X86_CPU_TYPE_SUFFIX));
- return g_strndup(class_name,
- strlen(class_name) - strlen(X86_CPU_TYPE_SUFFIX));
+ return cpu_model_from_type(class_name);
}
typedef struct X86CPUVersionDefinition {
int i;
if (strlen(value) != CPUID_VENDOR_SZ) {
- error_setg(errp, QERR_PROPERTY_VALUE_BAD, "", "vendor", value);
+ error_setg(errp, "value of property 'vendor' must consist of"
+ " exactly " stringify(CPUID_VENDOR_SZ) " characters");
return;
}
return name;
}
-/* Compatibily hack to maintain legacy +-feat semantic,
+/* Compatibility hack to maintain legacy +-feat semantic,
* where +-feat overwrites any feature set by
* feat=on|feat even if the later is parsed after +-feat
* (i.e. "-x2apic,x2apic=on" will result in x2apic disabled)
memset(&env->user_features, 0, sizeof(env->user_features));
}
-static gchar *x86_gdb_arch_name(CPUState *cs)
+static const gchar *x86_gdb_arch_name(CPUState *cs)
{
#ifdef TARGET_X86_64
- return g_strdup("i386:x86-64");
+ return "i386:x86-64";
#else
- return g_strdup("i386");
+ return "i386";
#endif
}
/* Versioned models: */
for (vdef = x86_cpu_def_get_versions(def); vdef->version; vdef++) {
- X86CPUModel *m = g_new0(X86CPUModel, 1);
g_autofree char *name =
x86_cpu_versioned_model_name(def, vdef->version);
+
+ m = g_new0(X86CPUModel, 1);
m->cpudef = def;
m->version = vdef->version;
m->note = vdef->note;
X86CPUTopoInfo topo_info;
topo_info.dies_per_pkg = env->nr_dies;
- topo_info.cores_per_die = cs->nr_cores;
+ topo_info.cores_per_die = cs->nr_cores / env->nr_dies;
topo_info.threads_per_core = cs->nr_threads;
/* Calculate & apply limits for different index ranges */
*/
if (*eax & 31) {
int host_vcpus_per_cache = 1 + ((*eax & 0x3FFC000) >> 14);
- int vcpus_per_socket = env->nr_dies * cs->nr_cores *
- cs->nr_threads;
+ int vcpus_per_socket = cs->nr_cores * cs->nr_threads;
if (cs->nr_cores > 1) {
*eax &= ~0xFC000000;
*eax |= (pow2ceil(cs->nr_cores) - 1) << 26;
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 */
* 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) {
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;
*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;
}
break;
case 1:
*eax = apicid_die_offset(&topo_info);
- *ebx = cs->nr_cores * cs->nr_threads;
+ *ebx = topo_info.cores_per_die * topo_info.threads_per_core;
*ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
break;
case 2:
*eax = apicid_pkg_offset(&topo_info);
- *ebx = env->nr_dies * cs->nr_cores * cs->nr_threads;
+ *ebx = cs->nr_cores * cs->nr_threads;
*ecx |= CPUID_TOPOLOGY_LEVEL_DIE;
break;
default:
* The initial value of xcr0 and ebx == 0, On host without kvm
* commit 412a3c41(e.g., CentOS 6), the ebx's value always == 0
* even through guest update xcr0, this will crash some legacy guest
- * (e.g., CentOS 6), So set ebx == ecx to workaroud it.
+ * (e.g., CentOS 6), So set ebx == ecx to workaround it.
*/
*ebx = kvm_enabled() ? *ecx : xsave_area_size(env->xcr0, false);
} else if (count == 1) {
} 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];
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;
}
}
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) ||
static bool ht_warned;
unsigned requested_lbr_fmt;
+#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
/* Use pc-relative instructions in system-mode */
-#ifndef CONFIG_USER_ONLY
cs->tcg_cflags |= CF_PCREL;
#endif
return;
}
- if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
+ if (env->features[FEAT_1_EDX] & (CPUID_PSE36 | CPUID_PAE)) {
cpu->phys_bits = 36;
} else {
cpu->phys_bits = 32;
CPUX86State *env = &cpu->env;
env->nr_dies = 1;
- cpu_set_cpustate_pointers(cpu);
object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
x86_cpu_get_feature_words,
.name = TYPE_X86_CPU,
.parent = TYPE_CPU,
.instance_size = sizeof(X86CPU),
+ .instance_align = __alignof(X86CPU),
.instance_init = x86_cpu_initfn,
.instance_post_init = x86_cpu_post_initfn,