summaryrefslogtreecommitdiff
path: root/target-i386
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@siemens.com>2015-06-07 11:15:08 +0200
committerEduardo Habkost <ehabkost@redhat.com>2015-07-07 10:47:16 -0300
commit28b8e4d0bf93ba176b4b7be819d537383c5a9060 (patch)
tree00626fe13d21b9400719c5c60ff47bc5bdcb9f94 /target-i386
parent1452673888f6d7f0454276d049846c9bec659233 (diff)
downloadqemu-28b8e4d0bf93ba176b4b7be819d537383c5a9060.tar.gz
qemu-28b8e4d0bf93ba176b4b7be819d537383c5a9060.tar.bz2
qemu-28b8e4d0bf93ba176b4b7be819d537383c5a9060.zip
i386: Introduce ARAT CPU feature
ARAT signals that the APIC timer does not stop in power saving states. As our APICs are emulated, it's fine to expose this feature to guests, at least when asking for KVM host features or with CPU types that include the flag. The exact model number that introduced the feature is not known, but reports can be found that it's at least available since Sandy Bridge. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Acked-by: Paolo Bonzini <pbonzini@redhat.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Diffstat (limited to 'target-i386')
-rw-r--r--target-i386/cpu.c33
-rw-r--r--target-i386/cpu.h3
-rw-r--r--target-i386/kvm.c2
3 files changed, 37 insertions, 1 deletions
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 36b07f99aa..b4f9461969 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -286,6 +286,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)
@@ -341,6 +352,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 {
@@ -410,6 +422,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 {
@@ -1003,6 +1020,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)",
},
@@ -1032,6 +1051,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)",
},
@@ -1064,6 +1085,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)",
},
@@ -1098,6 +1121,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)",
}, {
@@ -1132,6 +1157,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)",
},
@@ -1168,6 +1195,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)",
},
@@ -1204,6 +1233,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)",
},
@@ -2359,7 +2390,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;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index ac39291b48..0bfe64c5b9 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -415,6 +415,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;
@@ -580,6 +581,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)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 9038bf7077..066d03d99e 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -238,6 +238,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: