0727d3
From ea5299b5dde7d0b6b2f93cb646e6a24c9f105466 Mon Sep 17 00:00:00 2001
0727d3
From: Paolo Bonzini <pbonzini@redhat.com>
0727d3
Date: Wed, 23 Mar 2022 12:33:25 +0100
0727d3
Subject: [PATCH 13/24] KVM: x86: workaround invalid CPUID[0xD,9] info on some
0727d3
 AMD processors
0727d3
MIME-Version: 1.0
0727d3
Content-Type: text/plain; charset=UTF-8
0727d3
Content-Transfer-Encoding: 8bit
0727d3
0727d3
RH-Author: Paul Lai <plai@redhat.com>
0727d3
RH-MergeRequest: 176: Enable KVM AMX support
0727d3
RH-Commit: [13/13] 38f147c911258e84e01336271ebd23a1c24371fc
0727d3
RH-Bugzilla: 1916415
0727d3
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
0727d3
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
0727d3
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
0727d3
0727d3
Some AMD processors expose the PKRU extended save state even if they do not have
0727d3
the related PKU feature in CPUID.  Worse, when they do they report a size of
0727d3
64, whereas the expected size of the PKRU extended save state is 8, therefore
0727d3
the esa->size == eax assertion does not hold.
0727d3
0727d3
The state is already ignored by KVM_GET_SUPPORTED_CPUID because it
0727d3
was not enabled in the host XCR0.  However, QEMU kvm_cpu_xsave_init()
0727d3
runs before QEMU invokes arch_prctl() to enable dynamically-enabled
0727d3
save states such as XTILEDATA, and KVM_GET_SUPPORTED_CPUID hides save
0727d3
states that have yet to be enabled.  Therefore, kvm_cpu_xsave_init()
0727d3
needs to consult the host CPUID instead of KVM_GET_SUPPORTED_CPUID,
0727d3
and dies with an assertion failure.
0727d3
0727d3
When setting up the ExtSaveArea array to match the host, ignore features that
0727d3
KVM does not report as supported.  This will cause QEMU to skip the incorrect
0727d3
CPUID leaf instead of tripping the assertion.
0727d3
0727d3
Closes: https://gitlab.com/qemu-project/qemu/-/issues/916
0727d3
Reported-by: Daniel P. Berrangé <berrange@redhat.com>
0727d3
Analyzed-by: Yang Zhong <yang.zhong@intel.com>
0727d3
Reported-by: Peter Krempa <pkrempa@redhat.com>
0727d3
Tested-by: Daniel P. Berrangé <berrange@redhat.com>
0727d3
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
0727d3
(cherry picked from commit 58f7db26f21c690cf9a669c314cfd7371506084a)
0727d3
Signed-off-by: Paul Lai <plai@redhat.com>
0727d3
---
0727d3
 target/i386/cpu.c         |  4 ++--
0727d3
 target/i386/cpu.h         |  2 ++
0727d3
 target/i386/kvm/kvm-cpu.c | 19 ++++++++++++-------
0727d3
 3 files changed, 16 insertions(+), 9 deletions(-)
0727d3
0727d3
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
0727d3
index 09e08f7f38..0543b846ff 100644
0727d3
--- a/target/i386/cpu.c
0727d3
+++ b/target/i386/cpu.c
0727d3
@@ -4980,8 +4980,8 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
0727d3
     return cpu_list;
0727d3
 }
0727d3
 
0727d3
-static uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
0727d3
-                                                   bool migratable_only)
0727d3
+uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
0727d3
+                                            bool migratable_only)
0727d3
 {
0727d3
     FeatureWordInfo *wi = &feature_word_info[w];
0727d3
     uint64_t r = 0;
0727d3
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
0727d3
index 8ab2a4042a..006b735fe4 100644
0727d3
--- a/target/i386/cpu.h
0727d3
+++ b/target/i386/cpu.h
0727d3
@@ -604,6 +604,8 @@ typedef enum FeatureWord {
0727d3
 } FeatureWord;
0727d3
 
0727d3
 typedef uint64_t FeatureWordArray[FEATURE_WORDS];
0727d3
+uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
0727d3
+                                            bool migratable_only);
0727d3
 
0727d3
 /* cpuid_features bits */
0727d3
 #define CPUID_FP87 (1U << 0)
0727d3
diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c
0727d3
index bdc967c484..74c1396a93 100644
0727d3
--- a/target/i386/kvm/kvm-cpu.c
0727d3
+++ b/target/i386/kvm/kvm-cpu.c
0727d3
@@ -99,13 +99,18 @@ static void kvm_cpu_xsave_init(void)
0727d3
     for (i = XSTATE_SSE_BIT + 1; i < XSAVE_STATE_AREA_COUNT; i++) {
0727d3
         ExtSaveArea *esa = &x86_ext_save_areas[i];
0727d3
 
0727d3
-        if (esa->size) {
0727d3
-            host_cpuid(0xd, i, &eax, &ebx, &ecx, &edx;;
0727d3
-            if (eax != 0) {
0727d3
-                assert(esa->size == eax);
0727d3
-                esa->offset = ebx;
0727d3
-                esa->ecx = ecx;
0727d3
-            }
0727d3
+        if (!esa->size) {
0727d3
+            continue;
0727d3
+        }
0727d3
+        if ((x86_cpu_get_supported_feature_word(esa->feature, false) & esa->bits)
0727d3
+            != esa->bits) {
0727d3
+            continue;
0727d3
+        }
0727d3
+        host_cpuid(0xd, i, &eax, &ebx, &ecx, &edx;;
0727d3
+        if (eax != 0) {
0727d3
+            assert(esa->size == eax);
0727d3
+            esa->offset = ebx;
0727d3
+            esa->ecx = ecx;
0727d3
         }
0727d3
     }
0727d3
 }
0727d3
-- 
0727d3
2.35.3
0727d3