Commit 729ce7e1 authored by Roman Kagan's avatar Roman Kagan Committed by Paolo Bonzini
Browse files

hyperv:synic: split capability testing and setting



Put a bit more consistency into handling KVM_CAP_HYPERV_SYNIC capability,
by checking its availability and determining the feasibility of hv-synic
property first, and enabling it later.

Signed-off-by: default avatarRoman Kagan <rkagan@virtuozzo.com>
Message-Id: <20180921082217.29481-2-rkagan@virtuozzo.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 8417442a
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -735,8 +735,9 @@ static int hyperv_handle_properties(CPUState *cs)
    }
    if (cpu->hyperv_synic) {
        if (!has_msr_hv_synic ||
            kvm_vcpu_enable_cap(cs, KVM_CAP_HYPERV_SYNIC, 0)) {
            fprintf(stderr, "Hyper-V SynIC is not supported by kernel\n");
            !kvm_check_extension(cs->kvm_state, KVM_CAP_HYPERV_SYNIC)) {
            fprintf(stderr, "Hyper-V SynIC (requested by 'hv-synic' cpu flag) "
                    "is not supported by kernel\n");
            return -ENOSYS;
        }

@@ -754,12 +755,14 @@ static int hyperv_handle_properties(CPUState *cs)

static int hyperv_init_vcpu(X86CPU *cpu)
{
    CPUState *cs = CPU(cpu);
    int ret;

    if (cpu->hyperv_vpindex && !hv_vpindex_settable) {
        /*
         * the kernel doesn't support setting vp_index; assert that its value
         * is in sync
         */
        int ret;
        struct {
            struct kvm_msrs info;
            struct kvm_msr_entry entries[1];
@@ -768,7 +771,7 @@ static int hyperv_init_vcpu(X86CPU *cpu)
            .entries[0].index = HV_X64_MSR_VP_INDEX,
        };

        ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, &msr_data);
        ret = kvm_vcpu_ioctl(cs, KVM_GET_MSRS, &msr_data);
        if (ret < 0) {
            return ret;
        }
@@ -780,6 +783,15 @@ static int hyperv_init_vcpu(X86CPU *cpu)
        }
    }

    if (cpu->hyperv_synic) {
        ret = kvm_vcpu_enable_cap(cs, KVM_CAP_HYPERV_SYNIC, 0);
        if (ret < 0) {
            error_report("failed to turn on HyperV SynIC in KVM: %s",
                         strerror(-ret));
            return ret;
        }
    }

    return 0;
}