i386: Introduce ARAT CPU feature
PATCH 1/1 i386: Introduce ARAT CPU feature
From: Jan Kiszka <[email protected]>
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.
--- target-i386/cpu.c | 33 ++++++++++++++++++++++++++++++++- target-i386/cpu.h | 3 +++ target-i386/kvm.c | 2 ++ 3 files changed, 37 insertions(+), 1 deletion(-)
target-i386/cpu.c +32 -1
@@ -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 ;
target-i386/cpu.h +3 -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)
target-i386/kvm.c +2 -0
@@ -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:
Paolo Bonzini
maintainerQuoted 10 lines · Jan Kiszka
From: Jan Kiszka <[email protected]>
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 <[email protected]>
This looks good, but you need to disable it in older machine types.
Paolo
Quoted 155 lines
--- target-i386/cpu.c | 33 ++++++++++++++++++++++++++++++++- target-i386/cpu.h | 3 +++ target-i386/kvm.c | 2 ++ 3 files changed, 37 insertions(+), 1 deletion(-)target-i386/cpu.c +32
-1@@ -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 ;target-i386/cpu.h +3
-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)target-i386/kvm.c +2
-0@@ -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:
PATCH v2 1/1 i386: Introduce ARAT CPU feature
From: Jan Kiszka <[email protected]>
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.
---
Changes in v2:
- remove feature from Intel CPU types in compat machines
hw/i386/pc_piix.c | 10 ++++++++++ target-i386/cpu.c | 33 ++++++++++++++++++++++++++++++++- target-i386/cpu.h | 3 +++ target-i386/kvm.c | 2 ++ 4 files changed, 47 insertions(+), 1 deletion(-)
hw/i386/pc_piix.c +10 -0
@@ -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)
target-i386/cpu.c +32 -1
@@ -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 ;
target-i386/cpu.h +3 -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)
target-i386/kvm.c +2 -0
@@ -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:
Signature · 1 line
2.1.4
Paolo Bonzini
maintainerhw/i386/pc_piix.c static void pc_init_pci(MachineState *machine) · line 323
Quoted 11 lines · Jan Kiszka
static void
pc_compat_2_3(MachineState *machine)
{hw/i386/pc_piix.c +9
-0+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 );
noTSX.
Also, I think this doesn't cover Q35. Eduardo has patches to clean that up so that (I think) less duplication is required.
Paolo
Quoted 3 lines
+
x86_cpu_compat_set_features("Broadwell", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
}
Quoted 13 lines · Paolo Bonzini
hw/i386/pc_piix.c static void pc_init_pci(MachineState *machine) · line 323
Quoted 11 lines · Jan Kiszka
static void
pc_compat_2_3(MachineState *machine)
{hw/i386/pc_piix.c +9
-0+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 );
Quoted 4 lines
noTSX.
Also, I think this doesn't cover Q35. Eduardo has patches to clean that up so that (I think) less duplication is required.
pc_compat_*() removal/deduplication will require a few PC cleanup series to be included first, so it may take a while. But PC_COMPAT_* is not duplicated, and with the feature flag property patch that is now in the x86 tree[1], you can use PC_COMPAT_2_3[2] to do the above, with something like:
{ .driver = TYPE_X86_CPU, .property = "arat", .value = "off" },
(As no CPU model had ARAT enabled in QEMU 2.3, setting it to off on TYPE_X86_CPU is simpler than enumerating the CPU models above).
[1] https://github.com/ehabkost/qemu.git x86
[2] The following series defines PC_COMPAT_2_3:
[PATCH v2 00/13] pc, hw, spapr: Cleanup of {HW, PC, SPAPR}_COMPAT_* macros
Signature · 1 line
Eduardo
PATCH v3 1/1 i386: Introduce ARAT CPU feature
From: Jan Kiszka <[email protected]>
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.
---
Changes in v4:
- followed suggestions by Eduardo, now using PC_COMPAT_2_3 define
hw/i386/pc_piix.c | 4 ++++ hw/i386/pc_q35.c | 4 ++++ include/hw/i386/pc.h | 8 ++++++++ target-i386/cpu.c | 33 ++++++++++++++++++++++++++++++++- target-i386/cpu.h | 3 +++ target-i386/kvm.c | 2 ++ 6 files changed, 53 insertions(+), 1 deletion(-)
hw/i386/pc_piix.c +4 -0
@@ -543,6 +543,10 @@ static QEMUMachine pc_i440fx_machine_v2_3 = { PC_I440FX_2_3_MACHINE_OPTIONS, .name = "pc-i440fx-2.3", .init = pc_init_pci_2_3, + .compat_props = (GlobalProperty []) { +PC_COMPAT_2_3 , + {/* end of list */ } + }, };#define PC_I440FX_2_2_MACHINE_OPTIONS PC_I440FX_2_3_MACHINE_OPTIONS
hw/i386/pc_q35.c +4 -0
@@ -439,6 +439,10 @@ static QEMUMachine pc_q35_machine_v2_3 = { PC_Q35_2_3_MACHINE_OPTIONS, .name = "pc-q35-2.3", .init = pc_q35_init_2_3, + .compat_props = (GlobalProperty []) { +PC_COMPAT_2_3 , + {/* end of list */ } + }, };#define PC_Q35_2_2_MACHINE_OPTIONS PC_Q35_2_3_MACHINE_OPTIONS
include/hw/i386/pc.h +8 -0
@@ -295,7 +295,15 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);int e820_get_num_entries (void );bool e820_get_entry (int ,uint32_t ,uint64_t *,uint64_t *); +#define PC_COMPAT_2_3 \ + {\ + .driver = TYPE_X86_CPU,\ + .property = "arat",\ + .value = "off",\ + } +#define PC_COMPAT_2_0 \ + PC_COMPAT_2_3, \ HW_COMPAT_2_1, \ {\ .driver = "virtio-scsi-pci",\
target-i386/cpu.c +32 -1
@@ -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 ;
target-i386/cpu.h +3 -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)
target-i386/kvm.c +2 -0
@@ -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:
Signature · 1 line
2.1.4
(Fixing subject line)
Quoted 43 lines · Jan Kiszka
From: Jan Kiszka <[email protected]>
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 <[email protected]>---
Changes in v4:
- followed suggestions by Eduardo, now usingPC_COMPAT_2_3definehw/i386/pc_piix.c | 4 ++++ hw/i386/pc_q35.c | 4 ++++ include/hw/i386/pc.h | 8 ++++++++ target-i386/cpu.c | 33 ++++++++++++++++++++++++++++++++- target-i386/cpu.h | 3 +++ target-i386/kvm.c | 2 ++ 6 files changed, 53 insertions(+), 1 deletion(-)hw/i386/pc_piix.c +4
-0@@ -543,6 +543,10 @@ static QEMUMachine pc_i440fx_machine_v2_3 = { PC_I440FX_2_3_MACHINE_OPTIONS, .name = "pc-i440fx-2.3", .init = pc_init_pci_2_3, + .compat_props = (GlobalProperty []) { +PC_COMPAT_2_3 , + {/* end of list */ } + }, };#define PC_I440FX_2_2_MACHINE_OPTIONS PC_I440FX_2_3_MACHINE_OPTIONShw/i386/pc_q35.c +0
-0
hw/i386/pc_q35.c static QEMUMachine pc_q35_machine_v2_3 = { · line 446
Quoted 8 lines
hw/i386/pc_q35.c +4
-0@@ -439,6 +439,10 @@ static QEMUMachine pc_q35_machine_v2_3 = { PC_Q35_2_3_MACHINE_OPTIONS, .name = "pc-q35-2.3", .init = pc_q35_init_2_3, + .compat_props = (GlobalProperty []) { +PC_COMPAT_2_3 , + {/* end of list */ } + }, };
This breaks pc-*-2.2 and pc-*-2.1, because 2.2 nas no .compat_props set, and 2.1 has .compat_props = HW_COMPAT_2_1.
Those issues are fixed by the series:
[PATCH v2 00/13] pc, hw, spapr: Cleanup of {HW, PC, SPAPR}_COMPAT_* macros
I suggest we base this patch on top of it.
Signature · 1 line
Eduardo
Quoted 58 lines · Eduardo Habkost
(Fixing subject line)
Quoted 43 lines · Jan Kiszka
From: Jan Kiszka <[email protected]>
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 <[email protected]>---
Changes in v4:
- followed suggestions by Eduardo, now usingPC_COMPAT_2_3definehw/i386/pc_piix.c | 4 ++++ hw/i386/pc_q35.c | 4 ++++ include/hw/i386/pc.h | 8 ++++++++ target-i386/cpu.c | 33 ++++++++++++++++++++++++++++++++- target-i386/cpu.h | 3 +++ target-i386/kvm.c | 2 ++ 6 files changed, 53 insertions(+), 1 deletion(-)hw/i386/pc_piix.c +4
-0@@ -543,6 +543,10 @@ static QEMUMachine pc_i440fx_machine_v2_3 = { PC_I440FX_2_3_MACHINE_OPTIONS, .name = "pc-i440fx-2.3", .init = pc_init_pci_2_3, + .compat_props = (GlobalProperty []) { +PC_COMPAT_2_3 , + {/* end of list */ } + }, };#define PC_I440FX_2_2_MACHINE_OPTIONS PC_I440FX_2_3_MACHINE_OPTIONShw/i386/pc_q35.c +0
-0hw/i386/pc_q35.c static QEMUMachine pc_q35_machine_v2_3 = { · line 446
Quoted 8 lines
hw/i386/pc_q35.c +4
-0@@ -439,6 +439,10 @@ static QEMUMachine pc_q35_machine_v2_3 = { PC_Q35_2_3_MACHINE_OPTIONS, .name = "pc-q35-2.3", .init = pc_q35_init_2_3, + .compat_props = (GlobalProperty []) { +PC_COMPAT_2_3 , + {/* end of list */ } + }, };This breaks pc-*-2.2 and pc-*-2.1, because 2.2 nas no .compat_props set, and 2.1 has .compat_props =
HW_COMPAT_2_1.
Quoted 4 lines
Those issues are fixed by the series:
[PATCH v2 00/13] pc, hw, spapr: Cleanup of {HW, PC, SPAPR}_COMPAT_* macrosI suggest we base this patch on top of it.
For reference, the PC compat series I have submitted recently are available on git, at:
git://github.com/ehabkost/qemu-hacks.git work/pc-compat-cleanup2 (Subject: pc, hw, spapr: Cleanup of {HW, PC, SPAPR}_COMPAT_* macros)
git://github.com/ehabkost/qemu-hacks.git work/pc-compat-macros (Subject: pc: Don't use QEMUMachine, simplify compat+init code)
Signature · 1 line
Eduardo