Pablo Greco e6a3ae
From a31ce6a9fa171f677bf52dd0b0076e7b92d9ae33 Mon Sep 17 00:00:00 2001
Pablo Greco e6a3ae
From: Paolo Bonzini <pbonzini@redhat.com>
Pablo Greco e6a3ae
Date: Fri, 22 Nov 2019 11:53:41 +0000
Pablo Greco e6a3ae
Subject: [PATCH 08/16] target/i386: expand feature words to 64 bits
Pablo Greco e6a3ae
Pablo Greco e6a3ae
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
Pablo Greco e6a3ae
Message-id: <20191122115348.25000-9-pbonzini@redhat.com>
Pablo Greco e6a3ae
Patchwork-id: 92612
Pablo Greco e6a3ae
O-Subject: [RHEL8.2/rhel qemu-kvm PATCH 08/15] target/i386: expand feature words to 64 bits
Pablo Greco e6a3ae
Bugzilla: 1689270
Pablo Greco e6a3ae
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Pablo Greco e6a3ae
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
Pablo Greco e6a3ae
RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
Pablo Greco e6a3ae
Pablo Greco e6a3ae
VMX requires 64-bit feature words for the IA32_VMX_EPT_VPID_CAP
Pablo Greco e6a3ae
and IA32_VMX_BASIC MSRs.  (The VMX control MSRs are 64-bit wide but
Pablo Greco e6a3ae
actually have only 32 bits of information).
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Pablo Greco e6a3ae
(cherry picked from commit ede146c2e720b670350c7ef5e9af44e80a73fe97)
Pablo Greco e6a3ae
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Pablo Greco e6a3ae
---
Pablo Greco e6a3ae
 include/sysemu/kvm.h |  2 +-
Pablo Greco e6a3ae
 target/i386/cpu.c    | 71 +++++++++++++++++++++++++++-------------------------
Pablo Greco e6a3ae
 target/i386/cpu.h    |  2 +-
Pablo Greco e6a3ae
 target/i386/kvm.c    |  2 +-
Pablo Greco e6a3ae
 4 files changed, 40 insertions(+), 37 deletions(-)
Pablo Greco e6a3ae
Pablo Greco e6a3ae
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
Pablo Greco e6a3ae
index 3cf04cf..2c7f841 100644
Pablo Greco e6a3ae
--- a/include/sysemu/kvm.h
Pablo Greco e6a3ae
+++ b/include/sysemu/kvm.h
Pablo Greco e6a3ae
@@ -466,7 +466,7 @@ int kvm_vm_check_extension(KVMState *s, unsigned int extension);
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
Pablo Greco e6a3ae
                                       uint32_t index, int reg);
Pablo Greco e6a3ae
-uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index);
Pablo Greco e6a3ae
+uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index);
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len);
Pablo Greco e6a3ae
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
Pablo Greco e6a3ae
index a7360b3..3e77830 100644
Pablo Greco e6a3ae
--- a/target/i386/cpu.c
Pablo Greco e6a3ae
+++ b/target/i386/cpu.c
Pablo Greco e6a3ae
@@ -785,7 +785,7 @@ typedef struct FeatureWordInfo {
Pablo Greco e6a3ae
      * In cases of disagreement between feature naming conventions,
Pablo Greco e6a3ae
      * aliases may be added.
Pablo Greco e6a3ae
      */
Pablo Greco e6a3ae
-    const char *feat_names[32];
Pablo Greco e6a3ae
+    const char *feat_names[64];
Pablo Greco e6a3ae
     union {
Pablo Greco e6a3ae
         /* If type==CPUID_FEATURE_WORD */
Pablo Greco e6a3ae
         struct {
Pablo Greco e6a3ae
@@ -799,11 +799,11 @@ typedef struct FeatureWordInfo {
Pablo Greco e6a3ae
             uint32_t index;
Pablo Greco e6a3ae
         } msr;
Pablo Greco e6a3ae
     };
Pablo Greco e6a3ae
-    uint32_t tcg_features; /* Feature flags supported by TCG */
Pablo Greco e6a3ae
-    uint32_t unmigratable_flags; /* Feature flags known to be unmigratable */
Pablo Greco e6a3ae
-    uint32_t migratable_flags; /* Feature flags known to be migratable */
Pablo Greco e6a3ae
+    uint64_t tcg_features; /* Feature flags supported by TCG */
Pablo Greco e6a3ae
+    uint64_t unmigratable_flags; /* Feature flags known to be unmigratable */
Pablo Greco e6a3ae
+    uint64_t migratable_flags; /* Feature flags known to be migratable */
Pablo Greco e6a3ae
     /* Features that shouldn't be auto-enabled by "-cpu host" */
Pablo Greco e6a3ae
-    uint32_t no_autoenable_flags;
Pablo Greco e6a3ae
+    uint64_t no_autoenable_flags;
Pablo Greco e6a3ae
 } FeatureWordInfo;
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
Pablo Greco e6a3ae
@@ -1175,7 +1175,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 typedef struct FeatureMask {
Pablo Greco e6a3ae
     FeatureWord index;
Pablo Greco e6a3ae
-    uint32_t mask;
Pablo Greco e6a3ae
+    uint64_t mask;
Pablo Greco e6a3ae
 } FeatureMask;
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 typedef struct FeatureDep {
Pablo Greco e6a3ae
@@ -1185,11 +1185,11 @@ typedef struct FeatureDep {
Pablo Greco e6a3ae
 static FeatureDep feature_dependencies[] = {
Pablo Greco e6a3ae
     {
Pablo Greco e6a3ae
         .from = { FEAT_7_0_EDX,             CPUID_7_0_EDX_ARCH_CAPABILITIES },
Pablo Greco e6a3ae
-        .to = { FEAT_ARCH_CAPABILITIES,     ~0u },
Pablo Greco e6a3ae
+        .to = { FEAT_ARCH_CAPABILITIES,     ~0ull },
Pablo Greco e6a3ae
     },
Pablo Greco e6a3ae
     {
Pablo Greco e6a3ae
         .from = { FEAT_7_0_EDX,             CPUID_7_0_EDX_CORE_CAPABILITY },
Pablo Greco e6a3ae
-        .to = { FEAT_CORE_CAPABILITY,       ~0u },
Pablo Greco e6a3ae
+        .to = { FEAT_CORE_CAPABILITY,       ~0ull },
Pablo Greco e6a3ae
     },
Pablo Greco e6a3ae
 };
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
@@ -1301,14 +1301,14 @@ const char *get_register_name_32(unsigned int reg)
Pablo Greco e6a3ae
  * Returns the set of feature flags that are supported and migratable by
Pablo Greco e6a3ae
  * QEMU, for a given FeatureWord.
Pablo Greco e6a3ae
  */
Pablo Greco e6a3ae
-static uint32_t x86_cpu_get_migratable_flags(FeatureWord w)
Pablo Greco e6a3ae
+static uint64_t x86_cpu_get_migratable_flags(FeatureWord w)
Pablo Greco e6a3ae
 {
Pablo Greco e6a3ae
     FeatureWordInfo *wi = &feature_word_info[w];
Pablo Greco e6a3ae
-    uint32_t r = 0;
Pablo Greco e6a3ae
+    uint64_t r = 0;
Pablo Greco e6a3ae
     int i;
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-    for (i = 0; i < 32; i++) {
Pablo Greco e6a3ae
-        uint32_t f = 1U << i;
Pablo Greco e6a3ae
+    for (i = 0; i < 64; i++) {
Pablo Greco e6a3ae
+        uint64_t f = 1ULL << i;
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
         /* If the feature name is known, it is implicitly considered migratable,
Pablo Greco e6a3ae
          * unless it is explicitly set in unmigratable_flags */
Pablo Greco e6a3ae
@@ -2948,7 +2948,7 @@ void x86_cpu_change_kvm_default(const char *prop, const char *value)
Pablo Greco e6a3ae
     assert(pv->prop);
Pablo Greco e6a3ae
 }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
Pablo Greco e6a3ae
+static uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
Pablo Greco e6a3ae
                                                    bool migratable_only);
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 static bool lmce_supported(void)
Pablo Greco e6a3ae
@@ -3142,7 +3142,7 @@ static bool x86_cpu_have_filtered_features(X86CPU *cpu)
Pablo Greco e6a3ae
     return false;
Pablo Greco e6a3ae
 }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint32_t mask,
Pablo Greco e6a3ae
+static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint64_t mask,
Pablo Greco e6a3ae
                                       const char *verbose_prefix)
Pablo Greco e6a3ae
 {
Pablo Greco e6a3ae
     CPUX86State *env = &cpu->env;
Pablo Greco e6a3ae
@@ -3159,8 +3159,8 @@ static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint32_t mask,
Pablo Greco e6a3ae
         return;
Pablo Greco e6a3ae
     }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-    for (i = 0; i < 32; ++i) {
Pablo Greco e6a3ae
-        if ((1UL << i) & mask) {
Pablo Greco e6a3ae
+    for (i = 0; i < 64; ++i) {
Pablo Greco e6a3ae
+        if ((1ULL << i) & mask) {
Pablo Greco e6a3ae
             feat_word_str = feature_word_description(f, i);
Pablo Greco e6a3ae
             warn_report("%s: %s%s%s [bit %d]",
Pablo Greco e6a3ae
                         verbose_prefix,
Pablo Greco e6a3ae
@@ -3403,7 +3403,7 @@ static void x86_cpu_get_feature_words(Object *obj, Visitor *v,
Pablo Greco e6a3ae
                                       const char *name, void *opaque,
Pablo Greco e6a3ae
                                       Error **errp)
Pablo Greco e6a3ae
 {
Pablo Greco e6a3ae
-    uint32_t *array = (uint32_t *)opaque;
Pablo Greco e6a3ae
+    uint64_t *array = (uint64_t *)opaque;
Pablo Greco e6a3ae
     FeatureWord w;
Pablo Greco e6a3ae
     X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
Pablo Greco e6a3ae
     X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
Pablo Greco e6a3ae
@@ -3487,6 +3487,7 @@ static inline void feat2prop(char *s)
Pablo Greco e6a3ae
 /* Return the feature property name for a feature flag bit */
Pablo Greco e6a3ae
 static const char *x86_cpu_feature_name(FeatureWord w, int bitnr)
Pablo Greco e6a3ae
 {
Pablo Greco e6a3ae
+    const char *name;
Pablo Greco e6a3ae
     /* XSAVE components are automatically enabled by other features,
Pablo Greco e6a3ae
      * so return the original feature name instead
Pablo Greco e6a3ae
      */
Pablo Greco e6a3ae
@@ -3500,9 +3501,11 @@ static const char *x86_cpu_feature_name(FeatureWord w, int bitnr)
Pablo Greco e6a3ae
         }
Pablo Greco e6a3ae
     }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-    assert(bitnr < 32);
Pablo Greco e6a3ae
+    assert(bitnr < 64);
Pablo Greco e6a3ae
     assert(w < FEATURE_WORDS);
Pablo Greco e6a3ae
-    return feature_word_info[w].feat_names[bitnr];
Pablo Greco e6a3ae
+    name = feature_word_info[w].feat_names[bitnr];
Pablo Greco e6a3ae
+    assert(bitnr < 32 || !(name && feature_word_info[w].type == CPUID_FEATURE_WORD));
Pablo Greco e6a3ae
+    return name;
Pablo Greco e6a3ae
 }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 /* Compatibily hack to maintain legacy +-feat semantic,
Pablo Greco e6a3ae
@@ -3619,10 +3622,10 @@ static void x86_cpu_list_feature_names(FeatureWordArray features,
Pablo Greco e6a3ae
     strList **next = feat_names;
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
     for (w = 0; w < FEATURE_WORDS; w++) {
Pablo Greco e6a3ae
-        uint32_t filtered = features[w];
Pablo Greco e6a3ae
+        uint64_t filtered = features[w];
Pablo Greco e6a3ae
         int i;
Pablo Greco e6a3ae
-        for (i = 0; i < 32; i++) {
Pablo Greco e6a3ae
-            if (filtered & (1UL << i)) {
Pablo Greco e6a3ae
+        for (i = 0; i < 64; i++) {
Pablo Greco e6a3ae
+            if (filtered & (1ULL << i)) {
Pablo Greco e6a3ae
                 strList *new = g_new0(strList, 1);
Pablo Greco e6a3ae
                 new->value = g_strdup(x86_cpu_feature_name(w, i));
Pablo Greco e6a3ae
                 *next = new;
Pablo Greco e6a3ae
@@ -3760,7 +3763,7 @@ void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
Pablo Greco e6a3ae
     names = NULL;
Pablo Greco e6a3ae
     for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
Pablo Greco e6a3ae
         FeatureWordInfo *fw = &feature_word_info[i];
Pablo Greco e6a3ae
-        for (j = 0; j < 32; j++) {
Pablo Greco e6a3ae
+        for (j = 0; j < 64; j++) {
Pablo Greco e6a3ae
             if (fw->feat_names[j]) {
Pablo Greco e6a3ae
                 names = g_list_append(names, (gpointer)fw->feat_names[j]);
Pablo Greco e6a3ae
             }
Pablo Greco e6a3ae
@@ -3807,11 +3810,11 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
Pablo Greco e6a3ae
     return cpu_list;
Pablo Greco e6a3ae
 }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
Pablo Greco e6a3ae
+static uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
Pablo Greco e6a3ae
                                                    bool migratable_only)
Pablo Greco e6a3ae
 {
Pablo Greco e6a3ae
     FeatureWordInfo *wi = &feature_word_info[w];
Pablo Greco e6a3ae
-    uint32_t r = 0;
Pablo Greco e6a3ae
+    uint64_t r = 0;
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
     if (kvm_enabled()) {
Pablo Greco e6a3ae
         switch (wi->type) {
Pablo Greco e6a3ae
@@ -3950,7 +3953,7 @@ static QDict *x86_cpu_static_props(void)
Pablo Greco e6a3ae
     for (w = 0; w < FEATURE_WORDS; w++) {
Pablo Greco e6a3ae
         FeatureWordInfo *fi = &feature_word_info[w];
Pablo Greco e6a3ae
         int bit;
Pablo Greco e6a3ae
-        for (bit = 0; bit < 32; bit++) {
Pablo Greco e6a3ae
+        for (bit = 0; bit < 64; bit++) {
Pablo Greco e6a3ae
             if (!fi->feat_names[bit]) {
Pablo Greco e6a3ae
                 continue;
Pablo Greco e6a3ae
             }
Pablo Greco e6a3ae
@@ -5015,7 +5018,7 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
Pablo Greco e6a3ae
     for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) {
Pablo Greco e6a3ae
         FeatureDep *d = &feature_dependencies[i];
Pablo Greco e6a3ae
         if (!(env->features[d->from.index] & d->from.mask)) {
Pablo Greco e6a3ae
-            uint32_t unavailable_features = env->features[d->to.index] & d->to.mask;
Pablo Greco e6a3ae
+            uint64_t unavailable_features = env->features[d->to.index] & d->to.mask;
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
             /* Not an error unless the dependent feature was added explicitly.  */
Pablo Greco e6a3ae
             mark_unavailable_features(cpu, d->to.index,
Pablo Greco e6a3ae
@@ -5094,10 +5097,10 @@ static void x86_cpu_filter_features(X86CPU *cpu, bool verbose)
Pablo Greco e6a3ae
     }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
     for (w = 0; w < FEATURE_WORDS; w++) {
Pablo Greco e6a3ae
-        uint32_t host_feat =
Pablo Greco e6a3ae
+        uint64_t host_feat =
Pablo Greco e6a3ae
             x86_cpu_get_supported_feature_word(w, false);
Pablo Greco e6a3ae
-        uint32_t requested_features = env->features[w];
Pablo Greco e6a3ae
-        uint32_t unavailable_features = requested_features & ~host_feat;
Pablo Greco e6a3ae
+        uint64_t requested_features = env->features[w];
Pablo Greco e6a3ae
+        uint64_t unavailable_features = requested_features & ~host_feat;
Pablo Greco e6a3ae
         mark_unavailable_features(cpu, w, unavailable_features, prefix);
Pablo Greco e6a3ae
     }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
@@ -5380,7 +5383,7 @@ static void x86_cpu_unrealizefn(DeviceState *dev, Error **errp)
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 typedef struct BitProperty {
Pablo Greco e6a3ae
     FeatureWord w;
Pablo Greco e6a3ae
-    uint32_t mask;
Pablo Greco e6a3ae
+    uint64_t mask;
Pablo Greco e6a3ae
 } BitProperty;
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 static void x86_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
Pablo Greco e6a3ae
@@ -5388,7 +5391,7 @@ static void x86_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
Pablo Greco e6a3ae
 {
Pablo Greco e6a3ae
     X86CPU *cpu = X86_CPU(obj);
Pablo Greco e6a3ae
     BitProperty *fp = opaque;
Pablo Greco e6a3ae
-    uint32_t f = cpu->env.features[fp->w];
Pablo Greco e6a3ae
+    uint64_t f = cpu->env.features[fp->w];
Pablo Greco e6a3ae
     bool value = (f & fp->mask) == fp->mask;
Pablo Greco e6a3ae
     visit_type_bool(v, name, &value, errp);
Pablo Greco e6a3ae
 }
Pablo Greco e6a3ae
@@ -5441,7 +5444,7 @@ static void x86_cpu_register_bit_prop(X86CPU *cpu,
Pablo Greco e6a3ae
 {
Pablo Greco e6a3ae
     BitProperty *fp;
Pablo Greco e6a3ae
     ObjectProperty *op;
Pablo Greco e6a3ae
-    uint32_t mask = (1UL << bitnr);
Pablo Greco e6a3ae
+    uint64_t mask = (1ULL << bitnr);
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
     op = object_property_find(OBJECT(cpu), prop_name, NULL);
Pablo Greco e6a3ae
     if (op) {
Pablo Greco e6a3ae
@@ -5577,7 +5580,7 @@ static void x86_cpu_initfn(Object *obj)
Pablo Greco e6a3ae
     for (w = 0; w < FEATURE_WORDS; w++) {
Pablo Greco e6a3ae
         int bitnr;
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-        for (bitnr = 0; bitnr < 32; bitnr++) {
Pablo Greco e6a3ae
+        for (bitnr = 0; bitnr < 64; bitnr++) {
Pablo Greco e6a3ae
             x86_cpu_register_feature_bit_props(cpu, w, bitnr);
Pablo Greco e6a3ae
         }
Pablo Greco e6a3ae
     }
Pablo Greco e6a3ae
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
Pablo Greco e6a3ae
index f9b93be..edba84e 100644
Pablo Greco e6a3ae
--- a/target/i386/cpu.h
Pablo Greco e6a3ae
+++ b/target/i386/cpu.h
Pablo Greco e6a3ae
@@ -506,7 +506,7 @@ typedef enum FeatureWord {
Pablo Greco e6a3ae
     FEATURE_WORDS,
Pablo Greco e6a3ae
 } FeatureWord;
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-typedef uint32_t FeatureWordArray[FEATURE_WORDS];
Pablo Greco e6a3ae
+typedef uint64_t FeatureWordArray[FEATURE_WORDS];
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 /* cpuid_features bits */
Pablo Greco e6a3ae
 #define CPUID_FP87 (1U << 0)
Pablo Greco e6a3ae
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
Pablo Greco e6a3ae
index 2290c5d..85abd37 100644
Pablo Greco e6a3ae
--- a/target/i386/kvm.c
Pablo Greco e6a3ae
+++ b/target/i386/kvm.c
Pablo Greco e6a3ae
@@ -423,7 +423,7 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
Pablo Greco e6a3ae
     return ret;
Pablo Greco e6a3ae
 }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
Pablo Greco e6a3ae
+uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
Pablo Greco e6a3ae
 {
Pablo Greco e6a3ae
     struct {
Pablo Greco e6a3ae
         struct kvm_msrs info;
Pablo Greco e6a3ae
-- 
Pablo Greco e6a3ae
1.8.3.1
Pablo Greco e6a3ae