@@ -312,6 +312,16 @@ static void pc_init_pci(MachineState *machine)
static void pc_compat_2_3(MachineState *machine)
{
+ x86_cpu_compat_set_features("Westmere", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
+ x86_cpu_compat_set_features("SandyBridge", FEAT_6_EAX, 0,
+ CPUID_6_EAX_ARAT);
+ x86_cpu_compat_set_features("IvyBridge", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
+ x86_cpu_compat_set_features("Haswell-noTSX", FEAT_6_EAX, 0,
+ CPUID_6_EAX_ARAT);
+ x86_cpu_compat_set_features("Haswell", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
+ x86_cpu_compat_set_features("Broadwell-noTSC", FEAT_6_EAX, 0,
+ CPUID_6_EAX_ARAT);
+ x86_cpu_compat_set_features("Broadwell", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
}
static void pc_compat_2_2(MachineState *machine)
@@ -284,6 +284,17 @@ static const char *cpuid_xsave_feature_name[] = {
NULL, NULL, NULL, NULL,
};
+static const char *cpuid_6_feature_name[] = {
+ NULL, NULL, "arat", 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,
+};
+
#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
@@ -339,6 +350,7 @@ static const char *cpuid_xsave_feature_name[] = {
CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
CPUID_7_0_EBX_RDSEED */
#define TCG_APM_FEATURES 0
+#define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT
typedef struct FeatureWordInfo {
@@ -408,6 +420,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
.cpuid_reg = R_EAX,
.tcg_features = 0,
},
+ [FEAT_6_EAX] = {
+ .feat_names = cpuid_6_feature_name,
+ .cpuid_eax = 6, .cpuid_reg = R_EAX,
+ .tcg_features = TCG_6_EAX_FEATURES,
+ },
};
typedef struct X86RegisterInfo32 {
@@ -1001,6 +1018,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
.features[FEAT_8000_0001_ECX] =
CPUID_EXT3_LAHF_LM,
+ .features[FEAT_6_EAX] =
+ CPUID_6_EAX_ARAT,
.xlevel = 0x8000000A,
.model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
},
@@ -1030,6 +1049,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_EXT3_LAHF_LM,
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT,
+ .features[FEAT_6_EAX] =
+ CPUID_6_EAX_ARAT,
.xlevel = 0x8000000A,
.model_id = "Intel Xeon E312xx (Sandy Bridge)",
},
@@ -1062,6 +1083,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_EXT3_LAHF_LM,
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT,
+ .features[FEAT_6_EAX] =
+ CPUID_6_EAX_ARAT,
.xlevel = 0x8000000A,
.model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge)",
},
@@ -1096,6 +1119,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID,
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT,
+ .features[FEAT_6_EAX] =
+ CPUID_6_EAX_ARAT,
.xlevel = 0x8000000A,
.model_id = "Intel Core Processor (Haswell, no TSX)",
}, {
@@ -1130,6 +1155,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_EBX_RTM,
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT,
+ .features[FEAT_6_EAX] =
+ CPUID_6_EAX_ARAT,
.xlevel = 0x8000000A,
.model_id = "Intel Core Processor (Haswell)",
},
@@ -1166,6 +1193,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_EBX_SMAP,
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT,
+ .features[FEAT_6_EAX] =
+ CPUID_6_EAX_ARAT,
.xlevel = 0x8000000A,
.model_id = "Intel Core Processor (Broadwell, no TSX)",
},
@@ -1202,6 +1231,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_EBX_SMAP,
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT,
+ .features[FEAT_6_EAX] =
+ CPUID_6_EAX_ARAT,
.xlevel = 0x8000000A,
.model_id = "Intel Core Processor (Broadwell)",
},
@@ -2358,7 +2389,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
break;
case 6:
/* Thermal and Power Leaf */
- *eax = 0;
+ *eax = env->features[FEAT_6_EAX];
*ebx = 0;
*ecx = 0;
*edx = 0;
@@ -412,6 +412,7 @@ typedef enum FeatureWord {
FEAT_KVM, /* CPUID[4000_0001].EAX (KVM_CPUID_FEATURES) */
FEAT_SVM, /* CPUID[8000_000A].EDX */
FEAT_XSAVE, /* CPUID[EAX=0xd,ECX=1].EAX */
+ FEAT_6_EAX, /* CPUID[6].EAX */
FEATURE_WORDS,
} FeatureWord;
@@ -577,6 +578,8 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
#define CPUID_XSAVE_XGETBV1 (1U << 2)
#define CPUID_XSAVE_XSAVES (1U << 3)
+#define CPUID_6_EAX_ARAT (1U << 2)
+
/* CPUID[0x80000007].EDX flags: */
#define CPUID_APM_INVTSC (1U << 8)
@@ -233,6 +233,8 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
if (!kvm_irqchip_in_kernel()) {
ret &= ~CPUID_EXT_X2APIC;
}
+ } else if (function == 6 && reg == R_EAX) {
+ ret |= CPUID_6_EAX_ARAT; /* safe to allow because of emulated APIC */
} else if (function == 0x80000001 && reg == R_EDX) {
/* On Intel, kvm returns cpuid according to the Intel spec,
* so add missing bits according to the AMD spec: