diff mbox

[v3] i386: Introduce ARAT CPU feature

Message ID 5563F821.7080202@web.de (mailing list archive)
State New, archived
Headers show

Commit Message

Jan Kiszka May 26, 2015, 4:35 a.m. UTC
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(-)

Comments

Eduardo Habkost May 26, 2015, 5:18 p.m. UTC | #1
(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.
Eduardo Habkost May 26, 2015, 5:25 p.m. UTC | #2
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 mbox

Patch

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: