diff mbox series

[RFC,19/22] i386: prepare hyperv_expand_features() to be called at CPU feature expansion time

Message ID 20200904145431.196885-20-vkuznets@redhat.com (mailing list archive)
State New, archived
Headers show
Series i386: KVM: expand Hyper-V features early | expand

Commit Message

Vitaly Kuznetsov Sept. 4, 2020, 2:54 p.m. UTC
If hyperv_expand_features() is called before vCPU is created, cs->kvm_state
is NULL. We can only do the expantion if system wide KVM_GET_SUPPORTED_HV_CPUID
is supported.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 target/i386/kvm.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index b76d4a5a147b..c17e7db5e627 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -986,6 +986,10 @@  static struct kvm_cpuid2 *get_supported_hv_cpuid(CPUState *cs)
     do_sys_ioctl =
         kvm_check_extension(kvm_state, KVM_CAP_SYS_HYPERV_CPUID) > 0;
 
+    if (!do_sys_ioctl && !cs->kvm_state) {
+        return NULL;
+    }
+
     /*
      * When the buffer is too small, KVM_GET_SUPPORTED_HV_CPUID fails with
      * -E2BIG, however, it doesn't report back the right size. Keep increasing
@@ -1023,6 +1027,10 @@  static struct kvm_cpuid2 *get_supported_hv_cpuid_legacy(CPUState *cs)
     struct kvm_cpuid2 *cpuid;
     struct kvm_cpuid_entry2 *entry_feat, *entry_recomm;
 
+    if (!cs->kvm_state) {
+        return NULL;
+    }
+
     /* HV_CPUID_FEATURES, HV_CPUID_ENLIGHTMENT_INFO */
     cpuid = g_malloc0(sizeof(*cpuid) + 2 * sizeof(*cpuid->entries));
     cpuid->nent = 2;
@@ -1218,12 +1226,15 @@  static void hyperv_expand_features(CPUState *cs, Error **errp)
     if (!hyperv_enabled(cpu))
         return;
 
-    if (kvm_check_extension(cs->kvm_state, KVM_CAP_HYPERV_CPUID) > 0) {
+    if (kvm_check_extension(kvm_state, KVM_CAP_HYPERV_CPUID) > 0) {
         cpuid = get_supported_hv_cpuid(cs);
     } else {
         cpuid = get_supported_hv_cpuid_legacy(cs);
     }
 
+    if (!cpuid)
+        return;
+
     if (cpu->hyperv_passthrough) {
         c = cpuid_find_entry(cpuid, HV_CPUID_VENDOR_AND_MAX_FUNCTIONS, 0);
         if (c) {