summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--target/i386/cpu.c4
-rw-r--r--target/i386/cpu.h2
-rw-r--r--target/i386/kvm/kvm-cpu.c19
3 files changed, 16 insertions, 9 deletions
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index a88d6554c8..ec3b50bf6e 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4981,8 +4981,8 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
     return cpu_list;
 }
 
-static uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
-                                                   bool migratable_only)
+uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
+                                            bool migratable_only)
 {
     FeatureWordInfo *wi = &feature_word_info[w];
     uint64_t r = 0;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 5e406088a9..e31e6bd8b8 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -606,6 +606,8 @@ typedef enum FeatureWord {
 } FeatureWord;
 
 typedef uint64_t FeatureWordArray[FEATURE_WORDS];
+uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
+                                            bool migratable_only);
 
 /* cpuid_features bits */
 #define CPUID_FP87 (1U << 0)
diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c
index a35a1bf9fe..5eb955ce9a 100644
--- a/target/i386/kvm/kvm-cpu.c
+++ b/target/i386/kvm/kvm-cpu.c
@@ -99,13 +99,18 @@ static void kvm_cpu_xsave_init(void)
     for (i = XSTATE_SSE_BIT + 1; i < XSAVE_STATE_AREA_COUNT; i++) {
         ExtSaveArea *esa = &x86_ext_save_areas[i];
 
-        if (esa->size) {
-            host_cpuid(0xd, i, &eax, &ebx, &ecx, &edx);
-            if (eax != 0) {
-                assert(esa->size == eax);
-                esa->offset = ebx;
-                esa->ecx = ecx;
-            }
+        if (!esa->size) {
+            continue;
+        }
+        if ((x86_cpu_get_supported_feature_word(esa->feature, false) & esa->bits)
+            != esa->bits) {
+            continue;
+        }
+        host_cpuid(0xd, i, &eax, &ebx, &ecx, &edx);
+        if (eax != 0) {
+            assert(esa->size == eax);
+            esa->offset = ebx;
+            esa->ecx = ecx;
         }
     }
 }