All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Ben Gardon <bgardon@google.com>
Cc: David Matlack <dmatlack@google.com>, kvm <kvm@vger.kernel.org>,
	Joerg Roedel <joro@8bytes.org>, Jim Mattson <jmattson@google.com>,
	Wanpeng Li <wanpengli@tencent.com>,
	Vitaly Kuznetsov <vkuznets@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Junaid Shahid <junaids@google.com>,
	Andrew Jones <drjones@redhat.com>,
	Matthew Wilcox <willy@infradead.org>, Yu Zhao <yuzhao@google.com>,
	David Hildenbrand <david@redhat.com>,
	Andrew Morton <akpm@linux-foundation.org>
Subject: Re: [PATCH v2 4/6] KVM: x86/mmu: fast_page_fault support for the TDP MMU
Date: Mon, 12 Jul 2021 21:03:11 +0000	[thread overview]
Message-ID: <YOyuD7UJXHpNnXA2@google.com> (raw)
In-Reply-To: <CANgfPd_Ew2AcwegRxcwr+M_myVjyjq2UVz=pHqVuy-UnPWY_ew@mail.gmail.com>

On Mon, Jul 12, 2021, Ben Gardon wrote:
> > diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
> > index c6fa8d00bf9f..2c9e0ed71fa0 100644
> > --- a/arch/x86/kvm/mmu/tdp_mmu.c
> > +++ b/arch/x86/kvm/mmu/tdp_mmu.c
> > @@ -527,6 +527,10 @@ static inline bool tdp_mmu_set_spte_atomic_no_dirty_log(struct kvm *kvm,
> >         if (is_removed_spte(iter->old_spte))
> >                 return false;
> >
> > +       /*
> > +        * TDP MMU sptes can also be concurrently cmpxchg'd in
> > +        * fast_pf_fix_direct_spte as part of fast_page_fault.
> > +        */

The cmpxchg64 part isn't what's interesting, it's just the means to the end.
Maybe reword slightly to focus on modifying SPTEs without holding mmu_lock, e.g.

	/*
	 * Note, fast_pf_fix_direct_spte() can also modify TDP MMU SPTEs outside
	 * of mmu_lock.
	 */

> >         if (cmpxchg64(rcu_dereference(iter->sptep), iter->old_spte,
> >                       new_spte) != iter->old_spte)
> >                 return false;
> 
> I'm a little nervous about not going through the handle_changed_spte
> flow for the TDP MMU, but as things are now, I think it's safe.

Ya, it would be nice to flow through the TDP MMU proper as we could also "restore"
__rcu.  That said, the fast #PF fix flow is unique and specific enough that I don't
think it's worth going out of our way to force the issue.

> > @@ -1546,3 +1550,35 @@ int kvm_tdp_mmu_get_walk_lockless(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes,
> >
> >         return leaf;
> >  }
> > +
> > +/*
> > + * Must be called between kvm_tdp_mmu_walk_shadow_page_lockless_{begin,end}.
> > + *
> > + * The returned sptep must not be used after
> > + * kvm_tdp_mmu_walk_shadow_page_lockless_end.
> > + */
> > +u64 *kvm_tdp_mmu_get_last_sptep_lockless(struct kvm_vcpu *vcpu, u64 addr,
> > +                                        u64 *spte)
> > +{
> > +       struct tdp_iter iter;
> > +       struct kvm_mmu *mmu = vcpu->arch.mmu;
> > +       gfn_t gfn = addr >> PAGE_SHIFT;
> > +       tdp_ptep_t sptep = NULL;
> > +
> > +       tdp_mmu_for_each_pte(iter, mmu, gfn, gfn + 1) {
> > +               *spte = iter.old_spte;
> > +               sptep = iter.sptep;
> > +       }
> > +
> > +       if (sptep)

This check is unnecessary, even when using rcu_dereference.

> > +               /*
> > +                * Perform the rcu dereference here since we are passing the
> > +                * sptep up to the generic MMU code which does not know the
> > +                * synchronization details of the TDP MMU. This is safe as long
> > +                * as the caller obeys the contract that the sptep is not used
> > +                * after kvm_tdp_mmu_walk_shadow_page_lockless_end.
> > +                */
> 
> There's a little more to this contract:
> 1. The caller should only modify the SPTE using an atomic cmpxchg with
> the returned spte value.
> 2. The caller should not modify the mapped PFN or present <-> not
> present state of the SPTE.
> 3. There are other bits the caller can't modify too. (lpage, mt, etc.)
> 
> If the comments on this function don't document all the constraints on
> how the returned sptep can be used, it might be safer to specify that
> this is only meant to be used as part of the fast page fault handler.

Or maybe a less specific, but more scary comment?

> 
> > +               return rcu_dereference(sptep);

I still vote to use "(__force u64 *)" instead of rcu_dereference() to make it
clear we're cheating in order to share code with the legacy MMU.

	/*
	 * Squash the __rcu annotation, the legacy MMU doesn't rely on RCU to
	 * protect its page tables and so the common MMU code doesn't preserve
	 * the annotation.
	 *
	 * It goes without saying, but the caller must honor all TDP MMU
	 * contracts for accessing/modifying SPTEs outside of mmu_lock.
	 */
	return (__force u64 *)sptep;
	
> > +       return NULL;
> > +}
> > diff --git a/arch/x86/kvm/mmu/tdp_mmu.h b/arch/x86/kvm/mmu/tdp_mmu.h
> > index e9dde5f9c0ef..508a23bdf7da 100644
> > --- a/arch/x86/kvm/mmu/tdp_mmu.h
> > +++ b/arch/x86/kvm/mmu/tdp_mmu.h
> > @@ -81,6 +81,8 @@ void kvm_tdp_mmu_walk_lockless_begin(void);
> >  void kvm_tdp_mmu_walk_lockless_end(void);
> >  int kvm_tdp_mmu_get_walk_lockless(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes,
> >                                   int *root_level);
> > +u64 *kvm_tdp_mmu_get_last_sptep_lockless(struct kvm_vcpu *vcpu, u64 addr,
> > +                                        u64 *spte);
> >
> >  #ifdef CONFIG_X86_64
> >  bool kvm_mmu_init_tdp_mmu(struct kvm *kvm);
> > --
> > 2.32.0.93.g670b81a890-goog
> >

  parent reply	other threads:[~2021-07-12 21:03 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-30 21:47 [PATCH v2 0/6] KVM: x86/mmu: Fast page fault support for the TDP MMU David Matlack
2021-06-30 21:47 ` [PATCH v2 1/6] KVM: x86/mmu: Rename cr2_or_gpa to gpa in fast_page_fault David Matlack
2021-07-12 20:01   ` Sean Christopherson
2021-06-30 21:47 ` [PATCH v2 2/6] KVM: x86/mmu: Fix use of enums in trace_fast_page_fault David Matlack
2021-07-12 16:14   ` Ben Gardon
2021-07-12 18:11     ` David Matlack
2021-07-12 19:53       ` Sean Christopherson
2021-07-12 20:38         ` David Matlack
2021-06-30 21:47 ` [PATCH v2 3/6] KVM: x86/mmu: Make walk_shadow_page_lockless_{begin,end} interoperate with the TDP MMU David Matlack
2021-07-12 17:02   ` Ben Gardon
2021-07-12 18:11     ` David Matlack
2021-07-12 20:20       ` Sean Christopherson
2021-07-12 20:23   ` Sean Christopherson
2021-06-30 21:48 ` [PATCH v2 4/6] KVM: x86/mmu: fast_page_fault support for " David Matlack
2021-07-01  2:54   ` kernel test robot
2021-07-01  2:54     ` kernel test robot
2021-07-01  4:27   ` kernel test robot
2021-07-01  4:27     ` kernel test robot
2021-07-01 18:27     ` David Matlack
2021-07-01 18:27       ` David Matlack
2021-07-09 18:45   ` David Matlack
2021-07-12 17:49   ` Ben Gardon
2021-07-12 18:20     ` David Matlack
2021-07-12 21:03     ` Sean Christopherson [this message]
2021-07-12 21:24       ` David Matlack
2021-06-30 21:48 ` [PATCH v2 5/6] KVM: selftests: Fix missing break in dirty_log_perf_test arg parsing David Matlack
2021-06-30 21:48 ` [PATCH v2 6/6] KVM: selftests: Introduce access_tracking_perf_test David Matlack
2021-07-01  1:15 ` [PATCH v2 0/6] KVM: x86/mmu: Fast page fault support for the TDP MMU Matthew Wilcox
     [not found]   ` <CABgObfZUFWCAvKoxDzGjmksFnwZgbnpX9GuC+nhiVLa-Fhwj6A@mail.gmail.com>
2021-07-01 12:08     ` Matthew Wilcox
2021-07-01 16:50       ` David Matlack
2021-07-01 17:00 ` David Hildenbrand
2021-07-01 22:11   ` David Matlack
2021-07-02  7:53     ` David Hildenbrand

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=YOyuD7UJXHpNnXA2@google.com \
    --to=seanjc@google.com \
    --cc=akpm@linux-foundation.org \
    --cc=bgardon@google.com \
    --cc=david@redhat.com \
    --cc=dmatlack@google.com \
    --cc=drjones@redhat.com \
    --cc=jmattson@google.com \
    --cc=joro@8bytes.org \
    --cc=junaids@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=vkuznets@redhat.com \
    --cc=wanpengli@tencent.com \
    --cc=willy@infradead.org \
    --cc=yuzhao@google.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.