Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp3481302pxv; Mon, 19 Jul 2021 00:49:46 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx/MLMGE+QqytARQttg65LIqeNiqvO5EswVf+t6Z7LHA6REhflh8vpnbwwTto0aza61euJK X-Received: by 2002:aa7:c7c2:: with SMTP id o2mr33194909eds.166.1626680986404; Mon, 19 Jul 2021 00:49:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626680986; cv=none; d=google.com; s=arc-20160816; b=DxJXITYCBy5dSlCRgmqjr8fxzyGRLpv0uyu3k1PCuJlZeQw1qFlkwU4bth3Ne0Xd2J yx4GHINgh7nwub6cwl5b4Wd1MV1GpHiaCZUyjs1d/WanOXbeIdYFBL/0/JlSIHVlmCtM 5B9fMU5/nmtN21jdoyaR0AVKEt7b6w8m+qSJYGO5nAiSqIrGGt/glYdwnVn9yNAcE84h AyGRf4vA/kag2LrkjJHJRLEEXsnUsHiV2iw4dhUwsaGytgIKfCN3e8X3R+PeFXAut0Jk Zx38RKtkAs+lcrxGo5jEMNWKmjQkDsQC4gImxhoXGLBWTK+W37+Q97hjQkKGYqaxKuhz izdw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:message-id:date:references :in-reply-to:subject:cc:to:from:dkim-signature; bh=aQyY2LkoWEws2okKALivBeq9d7IHNBUboUUbi3JwfRU=; b=GnrEjsfNaLsJmegaPDDeH0jzjUiLQh0g4z2MBTyU/FKCdVV/wdzAHKaReU0r/DNDLT hp2XR/PYTfsB2Ibq+lOnmqOdg2jtfdYBNVFOsrKDm0Lupz41wbdx2nm3gvBBgeP9378H DoIc8sthBCxN2+MQo6dYYoSVPmeZe5T0mMURYolB6HZBfki9ExZJe5ssWYK89oodwFHu ZFzYnRy5Kir4aI0z14vJUSoMqYyKrhM5h9ebnIOlu9OXtBeGaPlZ22J1IAZena0ynLkE HFH18I/3YvUj7cl7Max/v0jYTAE13M16b2VAh+G9ZiOW+rHLFwg7gPwTAkfGaomfYRKF XZRw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=gpjlUZUh; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id j7si24986244ejm.492.2021.07.19.00.49.23; Mon, 19 Jul 2021 00:49:46 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=gpjlUZUh; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235052AbhGSHur (ORCPT + 99 others); Mon, 19 Jul 2021 03:50:47 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:34724 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235027AbhGSHuo (ORCPT ); Mon, 19 Jul 2021 03:50:44 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1626680864; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=aQyY2LkoWEws2okKALivBeq9d7IHNBUboUUbi3JwfRU=; b=gpjlUZUhjySz5oDQ5+9asDmYocOWXtOM568UALLybfr4Z2YtmVb+jdAPfsic0oVCVqAj7n ndtJR50kTj/BGLwnZaaY5+RgnQ+SVtQv0zYmDdL0Su+DouHIcpZBi84Z7erl8i3WbsNThJ fHs1cHP0oxdOzmSnU4kEBZsjtWoEYW8= Received: from mail-ej1-f69.google.com (mail-ej1-f69.google.com [209.85.218.69]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-195-oavhDqFAN5SI544hQvTwag-1; Mon, 19 Jul 2021 03:47:43 -0400 X-MC-Unique: oavhDqFAN5SI544hQvTwag-1 Received: by mail-ej1-f69.google.com with SMTP id kf3-20020a17090776c3b0290536d9b62eb6so3554613ejc.2 for ; Mon, 19 Jul 2021 00:47:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:in-reply-to:references:date :message-id:mime-version; bh=aQyY2LkoWEws2okKALivBeq9d7IHNBUboUUbi3JwfRU=; b=QSzzEZNdG81gzIiBl4kwFOhXazGoYb7c36zaCZ2RNZJW9We7SeEA4A1YT5NPGb4hg3 KZL9i27gtZPsRLvbklrrj2/N7gPHisclZU56pkNJpGehexjTFH7zscvOIGGwTRUmEI13 3LCBPRStf1u4rHiCbOMqDVYmK76FwiuTUxmgPwQZthNduttyNYCcK1Hd/MM1HddDAC/B JTICGJYz99uKPyv9uysqPoSFSCudnTYRaLEnNMnvLUCJFWA/GBQ0sxlfQe1Zbv7hFeOl tythoKDPqrq6v71CRuLzOXVQVMWJXeUf9Cu2oiD6m129pJ4pQJSxQuUectTbs2x1sYfy SxVg== X-Gm-Message-State: AOAM532hRiqGfj5KsK7hPiYA6QAFWe9hS/2dGrWT11o2pDJY1Fls085t NCLx/9L8SRrULdxU0Sqobl9KbwarRDOmuPYKKy+pjLPuJAGQi4vForGO/dRjvo/oQrBXc4WZfPQ GaGryM5vfCSxXpThrJ7lnZMPF X-Received: by 2002:a17:906:a019:: with SMTP id p25mr26004923ejy.483.1626680862030; Mon, 19 Jul 2021 00:47:42 -0700 (PDT) X-Received: by 2002:a17:906:a019:: with SMTP id p25mr26004911ejy.483.1626680861815; Mon, 19 Jul 2021 00:47:41 -0700 (PDT) Received: from vitty.brq.redhat.com (g-server-2.ign.cz. [91.219.240.2]) by smtp.gmail.com with ESMTPSA id m15sm7362181edp.73.2021.07.19.00.47.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Jul 2021 00:47:41 -0700 (PDT) From: Vitaly Kuznetsov To: Maxim Levitsky , kvm@vger.kernel.org Cc: "open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)" , Jim Mattson , Joerg Roedel , Borislav Petkov , Wanpeng Li , Paolo Bonzini , Thomas Gleixner , "H. Peter Anvin" , Ingo Molnar , "maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT)" , Sean Christopherson Subject: Re: [PATCH v2 8/8] KVM: x86: hyper-v: Deactivate APICv only when AutoEOI feature is in use In-Reply-To: References: <20210713142023.106183-1-mlevitsk@redhat.com> <20210713142023.106183-9-mlevitsk@redhat.com> Date: Mon, 19 Jul 2021 09:47:40 +0200 Message-ID: <87wnpmzqw3.fsf@vitty.brq.redhat.com> MIME-Version: 1.0 Content-Type: text/plain Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Maxim Levitsky writes: > On Tue, 2021-07-13 at 17:20 +0300, Maxim Levitsky wrote: >> From: Vitaly Kuznetsov >> >> APICV_INHIBIT_REASON_HYPERV is currently unconditionally forced upon >> SynIC activation as SynIC's AutoEOI is incompatible with APICv/AVIC. It is, >> however, possible to track whether the feature was actually used by the >> guest and only inhibit APICv/AVIC when needed. >> >> TLFS suggests a dedicated 'HV_DEPRECATING_AEOI_RECOMMENDED' flag to let >> Windows know that AutoEOI feature should be avoided. While it's up to >> KVM userspace to set the flag, KVM can help a bit by exposing global >> APICv/AVIC enablement: in case APICv/AVIC usage is impossible, AutoEOI >> is still preferred. > >> >> Maxim: >> - added SRCU lock drop around call to kvm_request_apicv_update >> - always set HV_DEPRECATING_AEOI_RECOMMENDED in kvm_get_hv_cpuid, >> since this feature can be used regardless of AVIC >> >> Signed-off-by: Vitaly Kuznetsov >> Signed-off-by: Maxim Levitsky >> --- >> arch/x86/include/asm/kvm_host.h | 3 +++ >> arch/x86/kvm/hyperv.c | 34 +++++++++++++++++++++++++++------ >> 2 files changed, 31 insertions(+), 6 deletions(-) >> >> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h >> index e11d64aa0bcd..f900dca58af8 100644 >> --- a/arch/x86/include/asm/kvm_host.h >> +++ b/arch/x86/include/asm/kvm_host.h >> @@ -956,6 +956,9 @@ struct kvm_hv { >> /* How many vCPUs have VP index != vCPU index */ >> atomic_t num_mismatched_vp_indexes; >> >> + /* How many SynICs use 'AutoEOI' feature */ >> + atomic_t synic_auto_eoi_used; >> + >> struct hv_partition_assist_pg *hv_pa_pg; >> struct kvm_hv_syndbg hv_syndbg; >> }; >> diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c >> index b07592ca92f0..6bf47a583d0e 100644 >> --- a/arch/x86/kvm/hyperv.c >> +++ b/arch/x86/kvm/hyperv.c >> @@ -85,9 +85,22 @@ static bool synic_has_vector_auto_eoi(struct kvm_vcpu_hv_synic *synic, >> return false; >> } >> >> + >> +static void synic_toggle_avic(struct kvm_vcpu *vcpu, bool activate) >> +{ >> + srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); >> + kvm_request_apicv_update(vcpu->kvm, activate, >> + APICV_INHIBIT_REASON_HYPERV); >> + vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); >> +} > > Well turns out that this patch still doesn't work (on this > weekend I found out that all my AVIC enabled VMs hang on reboot). > > I finally found out what prompted me back then to make srcu lock drop > in synic_update_vector conditional on whether the write was done > by the host. > > Turns out that while KVM_SET_MSRS does take the kvm->srcu lock, > it stores the returned srcu index in a local variable and not > in vcpu->srcu_idx, thus the lock drop in synic_toggle_avic > doesn't work. > > So it is likely that I have seen it not work, and blamed > KVM_SET_MSRS for not taking the srcu lock which was a wrong assumption. > > I am more inclined to fix this by just tracking if we hold the srcu > lock on each VCPU manually, just as we track the srcu index anyway, > and then kvm_request_apicv_update can use this to drop the srcu > lock when needed. > Would it be possible to use some magic value in 'vcpu->srcu_idx' and not introduce a new 'srcu_ls_locked' flag? > >> + >> static void synic_update_vector(struct kvm_vcpu_hv_synic *synic, >> int vector) >> { >> + struct kvm_vcpu *vcpu = hv_synic_to_vcpu(synic); >> + struct kvm_hv *hv = to_kvm_hv(vcpu->kvm); >> + int auto_eoi_old, auto_eoi_new; >> + >> if (vector < HV_SYNIC_FIRST_VALID_VECTOR) >> return; >> >> @@ -96,10 +109,23 @@ static void synic_update_vector(struct kvm_vcpu_hv_synic *synic, >> else >> __clear_bit(vector, synic->vec_bitmap); >> >> + auto_eoi_old = bitmap_weight(synic->auto_eoi_bitmap, 256); >> + >> if (synic_has_vector_auto_eoi(synic, vector)) >> __set_bit(vector, synic->auto_eoi_bitmap); >> else >> __clear_bit(vector, synic->auto_eoi_bitmap); >> + >> + auto_eoi_new = bitmap_weight(synic->auto_eoi_bitmap, 256); >> + >> + /* Hyper-V SynIC auto EOI SINTs are not compatible with APICV */ >> + if (!auto_eoi_old && auto_eoi_new) { >> + if (atomic_inc_return(&hv->synic_auto_eoi_used) == 1) >> + synic_toggle_avic(vcpu, false); >> + } else if (!auto_eoi_new && auto_eoi_old) { >> + if (atomic_dec_return(&hv->synic_auto_eoi_used) == 0) >> + synic_toggle_avic(vcpu, true); >> + } >> } >> >> static int synic_set_sint(struct kvm_vcpu_hv_synic *synic, int sint, >> @@ -933,12 +959,6 @@ int kvm_hv_activate_synic(struct kvm_vcpu *vcpu, bool dont_zero_synic_pages) >> >> synic = to_hv_synic(vcpu); >> >> - /* >> - * Hyper-V SynIC auto EOI SINT's are >> - * not compatible with APICV, so request >> - * to deactivate APICV permanently. >> - */ >> - kvm_request_apicv_update(vcpu->kvm, false, APICV_INHIBIT_REASON_HYPERV); >> synic->active = true; >> synic->dont_zero_synic_pages = dont_zero_synic_pages; >> synic->control = HV_SYNIC_CONTROL_ENABLE; >> @@ -2466,6 +2486,8 @@ int kvm_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, >> ent->eax |= HV_X64_ENLIGHTENED_VMCS_RECOMMENDED; >> if (!cpu_smt_possible()) >> ent->eax |= HV_X64_NO_NONARCH_CORESHARING; >> + >> + ent->eax |= HV_DEPRECATING_AEOI_RECOMMENDED; > > Vitally, I would like to hear your opinion on this change I also made to your code. > I think that we should always expose HV_DEPRECATING_AEOI_RECOMMENDED as a supported > HV cpuid bit regardless of AVIC, so that qemu could set it regardless of AVIC > in the kernel, even if this is not optimal. Generally, I'm OK with the change. The meaning of the bit changes slightly depending on whether we expose it conditionally or not. If HV_DEPRECATING_AEOI_RECOMMENDED is always exposed it just means that the patch in question is in, nothing else. VMM has to figure out if APICv/AVIC is supported by some other means. If HV_DEPRECATING_AEOI_RECOMMENDED is exposed conditionally, then VMM can be stupid and solely rely on this information by just copying the bit to user visible CPUIDs (e.g. QEMU's 'hv-passthrough' mode). -- Vitaly