Message ID | 5563F821.7080202@web.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
(Fixing subject line) On Tue, May 26, 2015 at 06:35:45AM +0200, Jan Kiszka wrote: > From: Jan Kiszka <jan.kiszka@siemens.com> > > 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> > --- > > 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(-) > > diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c > index 212e263..b675d2c 100644 > --- a/hw/i386/pc_piix.c > +++ b/hw/i386/pc_piix.c > @@ -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 > diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c > index e67f2de..38c3cf2 100644 > --- a/hw/i386/pc_q35.c > +++ b/hw/i386/pc_q35.c > @@ -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.
On Tue, May 26, 2015 at 02:18:32PM -0300, Eduardo Habkost wrote: > (Fixing subject line) > > On Tue, May 26, 2015 at 06:35:45AM +0200, Jan Kiszka wrote: > > From: Jan Kiszka <jan.kiszka@siemens.com> > > > > 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> > > --- > > > > 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(-) > > > > diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c > > index 212e263..b675d2c 100644 > > --- a/hw/i386/pc_piix.c > > +++ b/hw/i386/pc_piix.c > > @@ -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 > > diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c > > index e67f2de..38c3cf2 100644 > > --- a/hw/i386/pc_q35.c > > +++ b/hw/i386/pc_q35.c > > @@ -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. 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)
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 212e263..b675d2c 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -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 diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index e67f2de..38c3cf2 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -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 diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 1b35168..365af62 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -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",\ diff --git a/target-i386/cpu.c b/target-i386/cpu.c index e38943e..c273d24 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: