i386: Implement pseudo 'hv-avic' ('hv-apicv') enlightenment

The enlightenment allows to use Hyper-V SynIC with hardware APICv/AVIC
enabled. Normally, Hyper-V SynIC disables these hardware features and
suggests the guest to use paravirtualized AutoEOI feature. Linux-4.15
gains support for conditional APICv/AVIC disablement, the feature
stays on until the guest tries to use AutoEOI feature with SynIC. With
'HV_DEPRECATING_AEOI_RECOMMENDED' bit exposed, modern enough Windows/
Hyper-V versions should follow the recommendation and not use the
(unwanted) feature.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Message-Id: <20210902093530.345756-7-vkuznets@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Vitaly Kuznetsov 2021-09-02 11:35:28 +02:00 committed by Paolo Bonzini
parent 050716292a
commit e1f9a8e8c9
5 changed files with 24 additions and 2 deletions

View file

@ -189,7 +189,15 @@ enabled.
Requires: hv-vpindex, hv-synic, hv-time, hv-stimer
3.17. hv-no-nonarch-coresharing=on/off/auto
3.18. hv-avic (hv-apicv)
=======================
The enlightenment allows to use Hyper-V SynIC with hardware APICv/AVIC enabled.
Normally, Hyper-V SynIC disables these hardware feature and suggests the guest
to use paravirtualized AutoEOI feature.
Note: enabling this feature on old hardware (without APICv/AVIC support) may
have negative effect on guest's performace.
3.19. hv-no-nonarch-coresharing=on/off/auto
===========================================
This enlightenment tells guest OS that virtual processors will never share a
physical core unless they are reported as sibling SMT threads. This information

View file

@ -6644,6 +6644,8 @@ static void x86_cpu_initfn(Object *obj)
object_property_add_alias(obj, "sse4_1", obj, "sse4.1");
object_property_add_alias(obj, "sse4_2", obj, "sse4.2");
object_property_add_alias(obj, "hv-apicv", obj, "hv-avic");
if (xcc->model) {
x86_cpu_load_model(cpu, xcc->model);
}
@ -6831,6 +6833,8 @@ static Property x86_cpu_properties[] = {
HYPERV_FEAT_IPI, 0),
DEFINE_PROP_BIT64("hv-stimer-direct", X86CPU, hyperv_features,
HYPERV_FEAT_STIMER_DIRECT, 0),
DEFINE_PROP_BIT64("hv-avic", X86CPU, hyperv_features,
HYPERV_FEAT_AVIC, 0),
DEFINE_PROP_ON_OFF_AUTO("hv-no-nonarch-coresharing", X86CPU,
hyperv_no_nonarch_cs, ON_OFF_AUTO_OFF),
DEFINE_PROP_BOOL("hv-passthrough", X86CPU, hyperv_passthrough, false),

View file

@ -1056,6 +1056,7 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
#define HYPERV_FEAT_EVMCS 12
#define HYPERV_FEAT_IPI 13
#define HYPERV_FEAT_STIMER_DIRECT 14
#define HYPERV_FEAT_AVIC 15
#ifndef HYPERV_SPINLOCK_NEVER_NOTIFY
#define HYPERV_SPINLOCK_NEVER_NOTIFY 0xFFFFFFFF

View file

@ -66,6 +66,7 @@
#define HV_APIC_ACCESS_RECOMMENDED (1u << 3)
#define HV_SYSTEM_RESET_RECOMMENDED (1u << 4)
#define HV_RELAXED_TIMING_RECOMMENDED (1u << 5)
#define HV_DEPRECATING_AEOI_RECOMMENDED (1u << 9)
#define HV_CLUSTER_IPI_RECOMMENDED (1u << 10)
#define HV_EX_PROCESSOR_MASKS_RECOMMENDED (1u << 11)
#define HV_ENLIGHTENED_VMCS_RECOMMENDED (1u << 14)

View file

@ -924,6 +924,13 @@ static struct {
},
.dependencies = BIT(HYPERV_FEAT_STIMER)
},
[HYPERV_FEAT_AVIC] = {
.desc = "AVIC/APICv support (hv-avic/hv-apicv)",
.flags = {
{.func = HV_CPUID_ENLIGHTMENT_INFO, .reg = R_EAX,
.bits = HV_DEPRECATING_AEOI_RECOMMENDED}
}
},
};
static struct kvm_cpuid2 *try_get_hv_cpuid(CPUState *cs, int max,
@ -1373,7 +1380,8 @@ static int hyperv_fill_cpuids(CPUState *cs,
c->eax = hv_build_cpuid_leaf(cs, HV_CPUID_ENLIGHTMENT_INFO, R_EAX);
c->ebx = cpu->hyperv_spinlock_attempts;
if (hyperv_feat_enabled(cpu, HYPERV_FEAT_VAPIC)) {
if (hyperv_feat_enabled(cpu, HYPERV_FEAT_VAPIC) &&
!hyperv_feat_enabled(cpu, HYPERV_FEAT_AVIC)) {
c->eax |= HV_APIC_ACCESS_RECOMMENDED;
}