From: Sean Christopherson <seanjc@google.com>
To: Jeremi Piotrowski <jpiotrowski@linux.microsoft.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
Vitaly Kuznetsov <vkuznets@redhat.com>,
Tianyu Lan <ltykernel@gmail.com>,
Michael Kelley <mikelley@microsoft.com>
Subject: Re: [PATCH] KVM: SVM: Disable TDP MMU when running on Hyper-V
Date: Wed, 8 Mar 2023 11:20:27 -0800 [thread overview]
Message-ID: <ZAjf+8D5/HhZxGyR@google.com> (raw)
In-Reply-To: <c940389f-c086-9d0e-7150-f57b3866ae82@linux.microsoft.com>
On Wed, Mar 08, 2023, Jeremi Piotrowski wrote:
> On 08/03/2023 16:55, Jeremi Piotrowski wrote:
> >
> >
> > On 08/03/2023 01:39, Sean Christopherson wrote:
> >> On Wed, Mar 08, 2023, Paolo Bonzini wrote:
> >>> On Tue, Mar 7, 2023 at 6:36 PM Sean Christopherson <seanjc@google.com> wrote:
> >>>> Thinking about this more, I would rather revert commit 1e0c7d40758b ("KVM: SVM:
> >>>> hyper-v: Remote TLB flush for SVM") or fix the thing properly straitaway. KVM
> >>>> doesn't magically handle the flushes correctly for the shadow/legacy MMU, KVM just
> >>>> happens to get lucky and not run afoul of the underlying bugs.
> >>>
> >>> I don't think it's about luck---the legacy MMU's zapping/invalidation
> >>> seems to invoke the flush hypercall correctly:
> >>
> >> ...for the paths that Jeremi has exercised, and for which a stale TLB entry is
> >> fatal to L2. E.g. kvm_unmap_gfn_range() does not have a range-based TLB flush
> >> in its path and fully relies on the buggy kvm_flush_remote_tlbs().
> >>
> >
> > Why do you say "buggy kvm_flush_remote_tlbs"? kvm_flush_remote_tlbs calls the hypercall
> > that is needed, I don't see how this might be an issue of a missing "range-based TLB flush".
> >
> > kvm_unmap_gfn_range is called from kvm_mmu_notifier_invalidate_range_start and 'flush_on_ret=true'
> > is set, so it is followed by kvm_flush_remote_tlbs which calls hv_remote_flush_tlb.
> >
> >> In other words, KVM is getting lucky :-)
> >>
> >>> Jeremi, did you ever track the call stack where
> >>> hyperv_nested_flush_guest_mapping is triggered?
> >>
> >> I don't think it matters. As above, it only takes one path where KVM is fully
> >> relying on kvm_flush_remote_tlbs() for the whole thing to fall apart
>
> Slowly I'm starting to understand what we've been talking about, thank you :)
>
> Paolo/Sean, what do you think about smth like the following, except I would make
> it SVM only, and I'd need to think about what to do with the return.
> I believe this accurately reflects what the optimization is about. hv_track_root_tdp
> is called from kvm_mmu_load_pgd, which covers both kvm_mmu_load and kvm_mmu_new_pgd
> (which requests KVM_REQ_LOAD_MMU_PGD).
It's close, but KVM doesn't *always* need to flush when loading a root. KVM needs
to flush when loading a brand spanking new root, which is the kvm_mmu_load() path.
But when KVM loads a root via KVM_REQ_LOAD_MMU_PGD/kvm_mmu_new_pgd(), a flush may
or may not be necessary, e.g. if KVM reuses an old, but still valid, root (each
vCPU has a 3-entry root cache) and a TLB flush isn't architecturally required, then
there is no need to flush.
And as mentioned in the other tendril of this thread, I'd really like to fix
svm_flush_tlb_current() since it's technically broken, even though it's highly
unlikely (maybe even impossible?) to cause issues in practice.
> diff --git a/arch/x86/kvm/kvm_onhyperv.c b/arch/x86/kvm/kvm_onhyperv.c
> index 482d6639ef88..6a5bd3cbace8 100644
> --- a/arch/x86/kvm/kvm_onhyperv.c
> +++ b/arch/x86/kvm/kvm_onhyperv.c
> @@ -29,6 +29,18 @@ static inline int hv_remote_flush_root_tdp(hpa_t root_tdp,
> return hyperv_flush_guest_mapping(root_tdp);
> }
>
> +static int hv_vcpu_flush_tlb_current(struct kvm_vcpu *vcpu)
> +{
> + struct kvm_arch *kvm_arch = &vcpu->kvm->arch;
> + hpa_t root_tdp = vcpu->arch.hv_root_tdp;
> + int ret;
> +
> + ret = hyperv_flush_guest_mapping(root_tdp);
> + if (!ret)
> + kvm_arch->hv_root_tdp = root_tdp;
> + return ret;
> +}
> +
> int hv_remote_flush_tlb_with_range(struct kvm *kvm,
> struct kvm_tlb_range *range)
> {
> @@ -101,8 +113,10 @@ void hv_track_root_tdp(struct kvm_vcpu *vcpu, hpa_t root_tdp)
> if (kvm_x86_ops.tlb_remote_flush == hv_remote_flush_tlb) {
> spin_lock(&kvm_arch->hv_root_tdp_lock);
> vcpu->arch.hv_root_tdp = root_tdp;
> - if (root_tdp != kvm_arch->hv_root_tdp)
> + if (root_tdp != kvm_arch->hv_root_tdp) {
> kvm_arch->hv_root_tdp = INVALID_PAGE;
> + hv_vcpu_flush_tlb_current(vcpu);
> + }
> spin_unlock(&kvm_arch->hv_root_tdp_lock);
> }
> }
>
next prev parent reply other threads:[~2023-03-08 19:20 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-27 17:17 [PATCH] KVM: SVM: Disable TDP MMU when running on Hyper-V Jeremi Piotrowski
2023-03-06 17:52 ` Vitaly Kuznetsov
2023-03-06 18:31 ` Jeremi Piotrowski
2023-03-07 10:07 ` Vitaly Kuznetsov
2023-03-08 15:42 ` Jeremi Piotrowski
2023-03-07 17:36 ` Sean Christopherson
2023-03-08 0:00 ` Paolo Bonzini
2023-03-08 0:39 ` Sean Christopherson
2023-03-08 15:55 ` Jeremi Piotrowski
2023-03-08 17:22 ` Jeremi Piotrowski
2023-03-08 19:20 ` Sean Christopherson [this message]
2023-03-08 19:11 ` Sean Christopherson
2023-03-09 17:58 ` Jeremi Piotrowski
2023-03-12 17:42 ` Alexander Grest
2023-03-08 15:48 ` Jeremi Piotrowski
2023-04-05 16:43 ` Jeremi Piotrowski
2023-04-10 23:25 ` Sean Christopherson
2023-04-11 14:22 ` Jeremi Piotrowski
2023-04-11 16:02 ` Sean Christopherson
2023-04-13 9:53 ` Jeremi Piotrowski
2023-04-13 17:24 ` Sean Christopherson
2023-04-13 18:49 ` Sean Christopherson
2023-04-13 19:09 ` Sean Christopherson
2023-04-13 20:21 ` David Matlack
2023-04-13 20:58 ` Sean Christopherson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZAjf+8D5/HhZxGyR@google.com \
--to=seanjc@google.com \
--cc=jpiotrowski@linux.microsoft.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ltykernel@gmail.com \
--cc=mikelley@microsoft.com \
--cc=pbonzini@redhat.com \
--cc=vkuznets@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.