From: Sean Christopherson <seanjc@google.com>
To: David Matlack <dmatlack@google.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
Vitaly Kuznetsov <vkuznets@redhat.com>,
Wanpeng Li <wanpengli@tencent.com>,
Jim Mattson <jmattson@google.com>, Joerg Roedel <joro@8bytes.org>,
Ben Gardon <bgardon@google.com>,
kvm@vger.kernel.org
Subject: Re: [PATCH v2 4/4] KVM: x86/mmu: Improve TLB flush comment in kvm_mmu_slot_remove_write_access()
Date: Fri, 14 Jan 2022 23:58:32 +0000 [thread overview]
Message-ID: <YeIOKLxBF/MPmxbP@google.com> (raw)
In-Reply-To: <20220113233020.3986005-5-dmatlack@google.com>
On Thu, Jan 13, 2022, David Matlack wrote:
> Rewrite the comment in kvm_mmu_slot_remove_write_access() that explains
> why it is safe to flush TLBs outside of the MMU lock after
> write-protecting SPTEs for dirty logging. The current comment is a long
> run-on sentence that was difficult to understand. In addition it was
> specific to the shadow MMU (mentioning mmu_spte_update()) when the TDP
> MMU has to handle this as well.
>
> The new comment explains:
> - Why the TLB flush is necessary at all.
> - Why it is desirable to do the TLB flush outside of the MMU lock.
> - Why it is safe to do the TLB flush outside of the MMU lock.
>
> No functional change intended.
>
> Signed-off-by: David Matlack <dmatlack@google.com>
One nit below,
Reviewed-by: Sean Christopherson <seanjc@google.com>
> ---
> arch/x86/kvm/mmu/mmu.c | 31 ++++++++++++++++++++++---------
> 1 file changed, 22 insertions(+), 9 deletions(-)
>
> diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
> index 1d275e9d76b5..8ed2b42a7aa3 100644
> --- a/arch/x86/kvm/mmu/mmu.c
> +++ b/arch/x86/kvm/mmu/mmu.c
> @@ -5756,6 +5756,7 @@ static bool __kvm_zap_rmaps(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end)
> continue;
>
> flush = slot_handle_level_range(kvm, memslot, kvm_zap_rmapp,
> +
> PG_LEVEL_4K, KVM_MAX_HUGEPAGE_LEVEL,
> start, end - 1, true, flush);
> }
> @@ -5825,15 +5826,27 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm,
> }
>
> /*
> - * We can flush all the TLBs out of the mmu lock without TLB
> - * corruption since we just change the spte from writable to
> - * readonly so that we only need to care the case of changing
> - * spte from present to present (changing the spte from present
> - * to nonpresent will flush all the TLBs immediately), in other
> - * words, the only case we care is mmu_spte_update() where we
> - * have checked Host-writable | MMU-writable instead of
> - * PT_WRITABLE_MASK, that means it does not depend on PT_WRITABLE_MASK
> - * anymore.
> + * Flush TLBs if any SPTEs had to be write-protected to ensure that
> + * guest writes are reflected in the dirty bitmap before the memslot
> + * update completes, i.e. before enabling dirty logging is visible to
> + * userspace.
> + *
> + * Perform the TLB flush outside the mmu_lock to reduce the amount of
> + * time the lock is held. However, this does mean that another CPU can
> + * now grab the mmu_lock and encounter an SPTE that is write-protected
> + * while CPUs still have writable versions of that SPTE in their TLB.
Uber nit on "SPTE in their TLB". Maybe this?
* now grab mmu_lock and encounter a write-protected SPTE while CPUs
* still have a writable mapping for the associated GFN in their TLB.
> + *
> + * This is safe but requires KVM to be careful when making decisions
> + * based on the write-protection status of an SPTE. Specifically, KVM
> + * also write-protects SPTEs to monitor changes to guest page tables
> + * during shadow paging, and must guarantee no CPUs can write to those
> + * page before the lock is dropped. As mentioned in the previous
> + * paragraph, a write-protected SPTE is no guarantee that CPU cannot
> + * perform writes. So to determine if a TLB flush is truly required, KVM
> + * will clear a separate software-only bit (MMU-writable) and skip the
> + * flush if-and-only-if this bit was already clear.
> + *
> + * See DEFAULT_SPTE_MMU_WRITEABLE for more details.
> */
> if (flush)
> kvm_arch_flush_remote_tlbs_memslot(kvm, memslot);
> --
> 2.34.1.703.g22d0c6ccf7-goog
>
next prev parent reply other threads:[~2022-01-14 23:58 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-13 23:30 [PATCH v2 0/4] KVM: x86/mmu: Fix write-protection bug in the TDP MMU David Matlack
2022-01-13 23:30 ` [PATCH v2 1/4] KVM: x86/mmu: Fix write-protection of PTs mapped by " David Matlack
2022-01-14 23:38 ` Sean Christopherson
2022-01-13 23:30 ` [PATCH v2 2/4] KVM: x86/mmu: Clear MMU-writable during changed_pte notifier David Matlack
2022-01-14 23:41 ` Sean Christopherson
2022-01-13 23:30 ` [PATCH v2 3/4] KVM: x86/mmu: Document and enforce MMU-writable and Host-writable invariants David Matlack
2022-01-14 22:29 ` Sean Christopherson
2022-01-18 17:45 ` David Matlack
2022-01-13 23:30 ` [PATCH v2 4/4] KVM: x86/mmu: Improve TLB flush comment in kvm_mmu_slot_remove_write_access() David Matlack
2022-01-14 23:58 ` Sean Christopherson [this message]
2022-01-17 17:59 ` [PATCH v2 0/4] KVM: x86/mmu: Fix write-protection bug in the TDP MMU Paolo Bonzini
2022-01-18 17:38 ` David Matlack
2022-01-18 17:41 ` Paolo Bonzini
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=YeIOKLxBF/MPmxbP@google.com \
--to=seanjc@google.com \
--cc=bgardon@google.com \
--cc=dmatlack@google.com \
--cc=jmattson@google.com \
--cc=joro@8bytes.org \
--cc=kvm@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=vkuznets@redhat.com \
--cc=wanpengli@tencent.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.