OSDN Git Service

selftests: kvm: Properly set Hyper-V CPUIDs in evmcs_test
authorVitaly Kuznetsov <vkuznets@redhat.com>
Tue, 26 Jan 2021 13:48:03 +0000 (14:48 +0100)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 9 Feb 2021 13:17:10 +0000 (08:17 -0500)
Generally, when Hyper-V emulation is enabled, VMM is supposed to set
Hyper-V CPUID identifications so the guest knows that Hyper-V features
are available. evmcs_test doesn't currently do that but so far Hyper-V
emulation in KVM was enabled unconditionally. As we are about to change
that, proper Hyper-V CPUID identification should be set in selftests as
well.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Message-Id: <20210126134816.1880136-3-vkuznets@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
tools/testing/selftests/kvm/x86_64/evmcs_test.c

index 37b8a78..39a3cb2 100644 (file)
@@ -78,6 +78,42 @@ void guest_code(struct vmx_pages *vmx_pages)
        GUEST_ASSERT(vmlaunch());
 }
 
+struct kvm_cpuid2 *guest_get_cpuid(void)
+{
+       static struct kvm_cpuid2 *cpuid_full;
+       struct kvm_cpuid2 *cpuid_sys, *cpuid_hv;
+       int i, nent = 0;
+
+       if (cpuid_full)
+               return cpuid_full;
+
+       cpuid_sys = kvm_get_supported_cpuid();
+       cpuid_hv = kvm_get_supported_hv_cpuid();
+
+       cpuid_full = malloc(sizeof(*cpuid_full) +
+                           (cpuid_sys->nent + cpuid_hv->nent) *
+                           sizeof(struct kvm_cpuid_entry2));
+       if (!cpuid_full) {
+               perror("malloc");
+               abort();
+       }
+
+       /* Need to skip KVM CPUID leaves 0x400000xx */
+       for (i = 0; i < cpuid_sys->nent; i++) {
+               if (cpuid_sys->entries[i].function >= 0x40000000 &&
+                   cpuid_sys->entries[i].function < 0x40000100)
+                       continue;
+               cpuid_full->entries[nent] = cpuid_sys->entries[i];
+               nent++;
+       }
+
+       memcpy(&cpuid_full->entries[nent], cpuid_hv->entries,
+              cpuid_hv->nent * sizeof(struct kvm_cpuid_entry2));
+       cpuid_full->nent = nent + cpuid_hv->nent;
+
+       return cpuid_full;
+}
+
 int main(int argc, char *argv[])
 {
        vm_vaddr_t vmx_pages_gva = 0;
@@ -99,6 +135,7 @@ int main(int argc, char *argv[])
                exit(KSFT_SKIP);
        }
 
+       vcpu_set_cpuid(vm, VCPU_ID, guest_get_cpuid());
        vcpu_enable_evmcs(vm, VCPU_ID);
 
        run = vcpu_state(vm, VCPU_ID);
@@ -142,7 +179,7 @@ int main(int argc, char *argv[])
                /* Restore state in a new VM.  */
                kvm_vm_restart(vm, O_RDWR);
                vm_vcpu_add(vm, VCPU_ID);
-               vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid());
+               vcpu_set_cpuid(vm, VCPU_ID, guest_get_cpuid());
                vcpu_enable_evmcs(vm, VCPU_ID);
                vcpu_load_state(vm, VCPU_ID, state);
                run = vcpu_state(vm, VCPU_ID);