On Mon, May 25, 2015 at 04:47:49PM +0200, Jan Kiszka wrote: > From: Jan Kiszka <jan.kiszka@xxxxxxxxxxx> > > 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@xxxxxxxxxxx> For PC changes Acked-by: Michael S. Tsirkin <mst@xxxxxxxxxx> but Eduardo needs to review this one. > --- > > Changes in v3 (too quick...): > - fix typo in cpu model name > - also cover q35 > > hw/i386/pc_piix.c | 10 ++++++++++ > hw/i386/pc_q35.c | 10 ++++++++++ > target-i386/cpu.c | 33 ++++++++++++++++++++++++++++++++- > target-i386/cpu.h | 3 +++ > target-i386/kvm.c | 2 ++ > 5 files changed, 57 insertions(+), 1 deletion(-) > > diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c > index 212e263..8a29af1 100644 > --- a/hw/i386/pc_piix.c > +++ b/hw/i386/pc_piix.c > @@ -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-noTSX", 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) > diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c > index e67f2de..ca736d4 100644 > --- a/hw/i386/pc_q35.c > +++ b/hw/i386/pc_q35.c > @@ -291,6 +291,16 @@ static void pc_q35_init(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-noTSX", 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) > diff --git a/target-i386/cpu.c b/target-i386/cpu.c > index 3305e09..e435a08 100644 > --- a/target-i386/cpu.c > +++ b/target-i386/cpu.c > @@ -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; > diff --git a/target-i386/cpu.h b/target-i386/cpu.h > index 4ee12ca..800158e 100644 > --- a/target-i386/cpu.h > +++ b/target-i386/cpu.h > @@ -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) > > diff --git a/target-i386/kvm.c b/target-i386/kvm.c > index a26d25a..b786359 100644 > --- a/target-i386/kvm.c > +++ b/target-i386/kvm.c > @@ -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: > -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html