114 lines
4.2 KiB
Diff
114 lines
4.2 KiB
Diff
|
|
From 49cb3c9f3cc3a567ce2e6159bf27328c64b6601d Mon Sep 17 00:00:00 2001
|
||
|
|
From: Paolo Bonzini <pbonzini@redhat.com>
|
||
|
|
Date: Wed, 23 Mar 2022 12:33:25 +0100
|
||
|
|
Subject: [PATCH 10/10] KVM: x86: workaround invalid CPUID[0xD,9] info on some
|
||
|
|
AMD processors
|
||
|
|
MIME-Version: 1.0
|
||
|
|
Content-Type: text/plain; charset=UTF-8
|
||
|
|
Content-Transfer-Encoding: 8bit
|
||
|
|
|
||
|
|
from mainline-v7.0.0-rc2
|
||
|
|
commit 58f7db26f21c690cf9a669c314cfd7371506084a
|
||
|
|
category: feature
|
||
|
|
feature: SPR AMX support for Qemu
|
||
|
|
bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I5VHOB
|
||
|
|
|
||
|
|
Intel-SIG: commit 58f7db26f21c ("KVM: x86: workaround invalid CPUID[0xD,9] info
|
||
|
|
on some AMD processors")
|
||
|
|
|
||
|
|
----------------------------------------------------------------
|
||
|
|
|
||
|
|
KVM: x86: workaround invalid CPUID[0xD,9] info on some AMD processors
|
||
|
|
|
||
|
|
Some AMD processors expose the PKRU extended save state even if they do not have
|
||
|
|
the related PKU feature in CPUID. Worse, when they do they report a size of
|
||
|
|
64, whereas the expected size of the PKRU extended save state is 8, therefore
|
||
|
|
the esa->size == eax assertion does not hold.
|
||
|
|
|
||
|
|
The state is already ignored by KVM_GET_SUPPORTED_CPUID because it
|
||
|
|
was not enabled in the host XCR0. However, QEMU kvm_cpu_xsave_init()
|
||
|
|
runs before QEMU invokes arch_prctl() to enable dynamically-enabled
|
||
|
|
save states such as XTILEDATA, and KVM_GET_SUPPORTED_CPUID hides save
|
||
|
|
states that have yet to be enabled. Therefore, kvm_cpu_xsave_init()
|
||
|
|
needs to consult the host CPUID instead of KVM_GET_SUPPORTED_CPUID,
|
||
|
|
and dies with an assertion failure.
|
||
|
|
|
||
|
|
When setting up the ExtSaveArea array to match the host, ignore features that
|
||
|
|
KVM does not report as supported. This will cause QEMU to skip the incorrect
|
||
|
|
CPUID leaf instead of tripping the assertion.
|
||
|
|
|
||
|
|
Closes: https://gitlab.com/qemu-project/qemu/-/issues/916
|
||
|
|
Reported-by: Daniel P. Berrangé <berrange@redhat.com>
|
||
|
|
Analyzed-by: Yang Zhong <yang.zhong@intel.com>
|
||
|
|
Reported-by: Peter Krempa <pkrempa@redhat.com>
|
||
|
|
Tested-by: Daniel P. Berrangé <berrange@redhat.com>
|
||
|
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||
|
|
Signed-off-by: Jason Zeng <jason.zeng@intel.com>
|
||
|
|
---
|
||
|
|
target/i386/cpu.c | 4 ++--
|
||
|
|
target/i386/cpu.h | 2 ++
|
||
|
|
target/i386/kvm/kvm-cpu.c | 19 ++++++++++++-------
|
||
|
|
3 files changed, 16 insertions(+), 9 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
|
||
|
|
index 1bc03d3eef..551b47ab1e 100644
|
||
|
|
--- a/target/i386/cpu.c
|
||
|
|
+++ b/target/i386/cpu.c
|
||
|
|
@@ -4973,8 +4973,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 eaa99c302f..290f1beaea 100644
|
||
|
|
--- a/target/i386/cpu.h
|
||
|
|
+++ b/target/i386/cpu.h
|
||
|
|
@@ -605,6 +605,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;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
--
|
||
|
|
2.27.0
|
||
|
|
|