Commit c6861930 authored by Vitaly Kuznetsov's avatar Vitaly Kuznetsov Committed by Paolo Bonzini
Browse files

i386/kvm: hv-stimer requires hv-time and hv-synic



Synthetic timers operate in hv-time time and Windows won't use these
without SynIC.

Add .dependencies field to kvm_hyperv_properties[] and a generic mechanism
to check dependencies between features.

Signed-off-by: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
Message-Id: <20190517141924.19024-7-vkuznets@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent e48ddcc6
Loading
Loading
Loading
Loading
+19 −4
Original line number Diff line number Diff line
@@ -689,6 +689,7 @@ static struct {
        uint32_t fw;
        uint32_t bits;
    } flags[2];
    uint64_t dependencies;
} kvm_hyperv_properties[] = {
    [HYPERV_FEAT_RELAXED] = {
        .desc = "relaxed timing (hv-relaxed)",
@@ -756,7 +757,8 @@ static struct {
        .flags = {
            {.fw = FEAT_HYPERV_EAX,
             .bits = HV_SYNTIMERS_AVAILABLE}
        }
        },
        .dependencies = BIT(HYPERV_FEAT_SYNIC) | BIT(HYPERV_FEAT_TIME)
    },
    [HYPERV_FEAT_FREQUENCIES] = {
        .desc = "frequency MSRs (hv-frequencies)",
@@ -986,12 +988,25 @@ static int hv_cpuid_check_and_set(CPUState *cs, struct kvm_cpuid2 *cpuid,
    X86CPU *cpu = X86_CPU(cs);
    CPUX86State *env = &cpu->env;
    uint32_t r, fw, bits;
    int i;
    uint64_t deps;
    int i, dep_feat = 0;

    if (!hyperv_feat_enabled(cpu, feature) && !cpu->hyperv_passthrough) {
        return 0;
    }

    deps = kvm_hyperv_properties[feature].dependencies;
    while ((dep_feat = find_next_bit(&deps, 64, dep_feat)) < 64) {
        if (!(hyperv_feat_enabled(cpu, dep_feat))) {
                fprintf(stderr,
                        "Hyper-V %s requires Hyper-V %s\n",
                        kvm_hyperv_properties[feature].desc,
                        kvm_hyperv_properties[dep_feat].desc);
                return 1;
        }
        dep_feat++;
    }

    for (i = 0; i < ARRAY_SIZE(kvm_hyperv_properties[feature].flags); i++) {
        fw = kvm_hyperv_properties[feature].flags[i].fw;
        bits = kvm_hyperv_properties[feature].flags[i].bits;
@@ -1107,11 +1122,11 @@ static int hyperv_handle_properties(CPUState *cs,
    r |= hv_cpuid_check_and_set(cs, cpuid, HYPERV_FEAT_EVMCS);
    r |= hv_cpuid_check_and_set(cs, cpuid, HYPERV_FEAT_IPI);

    /* Dependencies */
    /* Additional dependencies not covered by kvm_hyperv_properties[] */
    if (hyperv_feat_enabled(cpu, HYPERV_FEAT_SYNIC) &&
        !cpu->hyperv_synic_kvm_only &&
        !hyperv_feat_enabled(cpu, HYPERV_FEAT_VPINDEX)) {
        fprintf(stderr, "Hyper-V %s requires %s\n",
        fprintf(stderr, "Hyper-V %s requires Hyper-V %s\n",
                kvm_hyperv_properties[HYPERV_FEAT_SYNIC].desc,
                kvm_hyperv_properties[HYPERV_FEAT_VPINDEX].desc);
        r |= 1;