9ae3a8
From 4e903b8594bb59a953e66ca0fb422079f6f6b573 Mon Sep 17 00:00:00 2001
9ae3a8
From: Eduardo Habkost <ehabkost@redhat.com>
9ae3a8
Date: Wed, 21 Aug 2019 14:30:05 +0200
9ae3a8
Subject: [PATCH 1/3] target-i386: Support "invariant tsc" flag
9ae3a8
MIME-Version: 1.0
9ae3a8
Content-Type: text/plain; charset=UTF-8
9ae3a8
Content-Transfer-Encoding: 8bit
9ae3a8
9ae3a8
RH-Author: Eduardo Habkost <ehabkost@redhat.com>
9ae3a8
Message-id: <20190821143006.23516-2-ehabkost@redhat.com>
9ae3a8
Patchwork-id: 90101
9ae3a8
O-Subject: [RHEL-7.8 qemu-kvm PATCH 1/2] target-i386: Support "invariant tsc" flag
9ae3a8
Bugzilla: 1626871
9ae3a8
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
RH-Acked-by: Bandan Das <bsd@redhat.com>
9ae3a8
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
9ae3a8
9ae3a8
From: Marcelo Tosatti <mtosatti@redhat.com>
9ae3a8
9ae3a8
Expose "Invariant TSC" flag, if KVM is enabled. From Intel documentation:
9ae3a8
9ae3a8
17.13.1 Invariant TSC The time stamp counter in newer processors may
9ae3a8
support an enhancement, referred to as invariant TSC. Processor’s
9ae3a8
support for invariant TSC is indicated by CPUID.80000007H:EDX[8].
9ae3a8
The invariant TSC will run at a constant rate in all ACPI P-, C-.
9ae3a8
and T-states. This is the architectural behavior moving forward. On
9ae3a8
processors with invariant TSC support, the OS may use the TSC for wall
9ae3a8
clock timer services (instead of ACPI or HPET timers). TSC reads are
9ae3a8
much more efficient and do not incur the overhead associated with a ring
9ae3a8
transition or access to a platform resource.
9ae3a8
9ae3a8
Backport notes:
9ae3a8
  One extra line to remove invtsc was added to
9ae3a8
  kvm_cpu_fill_host(), to replace the unmigratable_flags field,
9ae3a8
  and fix the same issue fixed by upstream commit 120eee7d1fdb
9ae3a8
  ("target-i386: Set migratable=yes by default on "host" CPU
9ae3a8
  mooel").
9ae3a8
9ae3a8
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
9ae3a8
[ehabkost: redo feature filtering to use .tcg_features]
9ae3a8
[ehabkost: add CPUID_APM_INVTSC macro, add it to .unmigratable_flags]
9ae3a8
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
9ae3a8
Signed-off-by: Andreas Färber <afaerber@suse.de>
9ae3a8
(cherry picked from commit 303752a9068bfe84b9b05f1cd5ad5ff65b7f3ea6)
9ae3a8
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
9ae3a8
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 target-i386/cpu.c | 26 ++++++++++++++++++++++++++
9ae3a8
 target-i386/cpu.h |  4 ++++
9ae3a8
 2 files changed, 30 insertions(+)
9ae3a8
9ae3a8
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
9ae3a8
index c2fcd1e..c74f597 100644
9ae3a8
--- a/target-i386/cpu.c
9ae3a8
+++ b/target-i386/cpu.c
9ae3a8
@@ -199,6 +199,17 @@ static const char *cpuid_xsave_feature_name[] = {
9ae3a8
     NULL, NULL, NULL, NULL,
9ae3a8
 };
9ae3a8
 
9ae3a8
+static const char *cpuid_apm_edx_feature_name[] = {
9ae3a8
+    NULL, NULL, NULL, NULL,
9ae3a8
+    NULL, NULL, NULL, NULL,
9ae3a8
+    "invtsc", NULL, NULL, NULL,
9ae3a8
+    NULL, NULL, NULL, NULL,
9ae3a8
+    NULL, NULL, NULL, NULL,
9ae3a8
+    NULL, NULL, NULL, NULL,
9ae3a8
+    NULL, NULL, NULL, NULL,
9ae3a8
+    NULL, NULL, NULL, NULL,
9ae3a8
+};
9ae3a8
+
9ae3a8
 #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
9ae3a8
 #define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
9ae3a8
           CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
9ae3a8
@@ -258,6 +269,7 @@ static const char *cpuid_xsave_feature_name[] = {
9ae3a8
           CPUID_7_0_EBX_RDSEED */
9ae3a8
 #define TCG_7_0_ECX_FEATURES 0
9ae3a8
 #define TCG_7_0_EDX_FEATURES 0
9ae3a8
+#define TCG_APM_FEATURES 0
9ae3a8
 
9ae3a8
 
9ae3a8
 typedef struct FeatureWordInfo {
9ae3a8
@@ -326,6 +338,12 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
9ae3a8
         .cpuid_reg = R_EDX,
9ae3a8
         .tcg_features = TCG_7_0_EDX_FEATURES,
9ae3a8
     },
9ae3a8
+    [FEAT_8000_0007_EDX] = {
9ae3a8
+        .feat_names = cpuid_apm_edx_feature_name,
9ae3a8
+        .cpuid_eax = 0x80000007,
9ae3a8
+        .cpuid_reg = R_EDX,
9ae3a8
+        .tcg_features = TCG_APM_FEATURES,
9ae3a8
+    },
9ae3a8
     [FEAT_8000_0008_EBX] = {
9ae3a8
         .feat_names = cpuid_80000008_ebx_feature_name,
9ae3a8
         .cpuid_eax = 0x80000008,
9ae3a8
@@ -1750,6 +1768,8 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
9ae3a8
 
9ae3a8
     /* arch-facilities: deprecated (see comment on x86_cpu_realizefn()) */
9ae3a8
     x86_cpu_def->features[FEAT_7_0_EDX] &= ~CPUID_7_0_EDX_ARCH_CAPABILITIES;
9ae3a8
+    /* invtsc: not migratable, so not enabled by default */
9ae3a8
+    x86_cpu_def->features[FEAT_8000_0007_EDX] &= ~CPUID_APM_INVTSC;
9ae3a8
 
9ae3a8
 #endif /* CONFIG_KVM */
9ae3a8
 }
9ae3a8
@@ -2805,6 +2825,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
9ae3a8
         *ecx = 0x02008140;
9ae3a8
         *edx = 0;
9ae3a8
         break;
9ae3a8
+    case 0x80000007:
9ae3a8
+        *eax = 0;
9ae3a8
+        *ebx = 0;
9ae3a8
+        *ecx = 0;
9ae3a8
+        *edx = env->features[FEAT_8000_0007_EDX];
9ae3a8
+        break;
9ae3a8
     case 0x80000008:
9ae3a8
         /* virtual & phys address size in low 2 bytes. */
9ae3a8
 /* XXX: This value must match the one used in the MMU code. */
9ae3a8
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
9ae3a8
index 5d47ab8..cbbc34f 100644
9ae3a8
--- a/target-i386/cpu.h
9ae3a8
+++ b/target-i386/cpu.h
9ae3a8
@@ -408,6 +408,7 @@ typedef enum FeatureWord {
9ae3a8
     FEAT_7_0_EDX,       /* CPUID[EAX=7,ECX=0].EDX */
9ae3a8
     FEAT_8000_0001_EDX, /* CPUID[8000_0001].EDX */
9ae3a8
     FEAT_8000_0001_ECX, /* CPUID[8000_0001].ECX */
9ae3a8
+    FEAT_8000_0007_EDX, /* CPUID[8000_0007].EDX */
9ae3a8
     FEAT_8000_0008_EBX, /* CPUID[8000_0008].EBX */
9ae3a8
     FEAT_C000_0001_EDX, /* CPUID[C000_0001].EDX */
9ae3a8
     FEAT_KVM,           /* CPUID[4000_0001].EAX (KVM_CPUID_FEATURES) */
9ae3a8
@@ -613,6 +614,9 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
9ae3a8
 #define CPUID_XSAVE_XGETBV1    (1U << 2)
9ae3a8
 #define CPUID_XSAVE_XSAVES     (1U << 3)
9ae3a8
 
9ae3a8
+/* CPUID[0x80000007].EDX flags: */
9ae3a8
+#define CPUID_APM_INVTSC       (1U << 8)
9ae3a8
+
9ae3a8
 #define CPUID_VENDOR_SZ      12
9ae3a8
 
9ae3a8
 #define CPUID_VENDOR_INTEL_1 0x756e6547 /* "Genu" */
9ae3a8
-- 
9ae3a8
1.8.3.1
9ae3a8