linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] KVM: x86/mmu: Misc cleanups, mostly TDP MMU
@ 2021-02-26  1:03 Sean Christopherson
  2021-02-26  1:03 ` [PATCH 1/5] KVM: x86/mmu: Remove spurious TLB flush from TDP MMU's change_pte() hook Sean Christopherson
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Sean Christopherson @ 2021-02-26  1:03 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li, Jim Mattson,
	Joerg Roedel, kvm, linux-kernel, Ben Gardon

Effectively belated code review of a few pieces of the TDP MMU.

Sean Christopherson (5):
  KVM: x86/mmu: Remove spurious TLB flush from TDP MMU's change_pte()
    hook
  KVM: x86/mmu: WARN if TDP MMU's set_tdp_spte() sees multiple GFNs
  KVM: x86/mmu: Use 'end' param in TDP MMU's test_age_gfn()
  KVM: x86/mmu: Add typedefs for rmap/iter handlers
  KVM: x86/mmu: Add convenience wrapper for acting on single hva in TDP
    MMU

 arch/x86/kvm/mmu/mmu.c     | 27 +++++++------------
 arch/x86/kvm/mmu/tdp_mmu.c | 54 ++++++++++++++++++++++----------------
 2 files changed, 41 insertions(+), 40 deletions(-)

-- 
2.30.1.766.gb4fecdf3b7-goog


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/5] KVM: x86/mmu: Remove spurious TLB flush from TDP MMU's change_pte() hook
  2021-02-26  1:03 [PATCH 0/5] KVM: x86/mmu: Misc cleanups, mostly TDP MMU Sean Christopherson
@ 2021-02-26  1:03 ` Sean Christopherson
  2021-02-26  1:03 ` [PATCH 2/5] KVM: x86/mmu: WARN if TDP MMU's set_tdp_spte() sees multiple GFNs Sean Christopherson
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Sean Christopherson @ 2021-02-26  1:03 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li, Jim Mattson,
	Joerg Roedel, kvm, linux-kernel, Ben Gardon

Remove an unnecessary remote TLB flush from set_tdp_spte(), the TDP MMu's
hook for handling change_pte() invocations from the MMU notifier.  If
the new host PTE is writable, the flush is completely redundant as there
are no futher changes to the SPTE before the post-loop flush.  If the
host PTE is read-only, then the primary MMU is responsible for ensuring
that the contents of the old and new pages are identical, thus it's safe
to let the guest continue reading both the old and new pages.  KVM must
only ensure the old page cannot be referenced after returning from its
callback; this is handled by the post-loop flush.

Fixes: 1d8dd6b3f12b ("kvm: x86/mmu: Support changed pte notifier in tdp MMU")
Cc: Ben Gardon <bgardon@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/mmu/tdp_mmu.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index c926c6b899a1..3290e53fb850 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -1044,10 +1044,14 @@ static int set_tdp_spte(struct kvm *kvm, struct kvm_memory_slot *slot,
 		if (!is_shadow_present_pte(iter.old_spte))
 			break;
 
+		/*
+		 * Note, when changing a read-only SPTE, it's not strictly
+		 * necessary to zero the SPTE before setting the new PFN, but
+		 * doing so preserves the invariant that the PFN of a present
+		 * leaf SPTE can never change.  See __handle_changed_spte().
+		 */
 		tdp_mmu_set_spte(kvm, &iter, 0);
 
-		kvm_flush_remote_tlbs_with_address(kvm, iter.gfn, 1);
-
 		if (!pte_write(*ptep)) {
 			new_spte = kvm_mmu_changed_pte_notifier_make_spte(
 					iter.old_spte, new_pfn);
-- 
2.30.1.766.gb4fecdf3b7-goog


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/5] KVM: x86/mmu: WARN if TDP MMU's set_tdp_spte() sees multiple GFNs
  2021-02-26  1:03 [PATCH 0/5] KVM: x86/mmu: Misc cleanups, mostly TDP MMU Sean Christopherson
  2021-02-26  1:03 ` [PATCH 1/5] KVM: x86/mmu: Remove spurious TLB flush from TDP MMU's change_pte() hook Sean Christopherson
@ 2021-02-26  1:03 ` Sean Christopherson
  2021-02-26  1:03 ` [PATCH 3/5] KVM: x86/mmu: Use 'end' param in TDP MMU's test_age_gfn() Sean Christopherson
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Sean Christopherson @ 2021-02-26  1:03 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li, Jim Mattson,
	Joerg Roedel, kvm, linux-kernel, Ben Gardon

WARN if set_tdp_spte() is invoked with multipel GFNs.  It is specifically
a callback to handle a single host PTE being changed.  Consuming the
@end parameter also eliminates the confusing 'unused' parameter.

Cc: Ben Gardon <bgardon@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/mmu/tdp_mmu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index 3290e53fb850..020f2e573f44 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -1022,7 +1022,7 @@ int kvm_tdp_mmu_test_age_hva(struct kvm *kvm, unsigned long hva)
  * Returns non-zero if a flush is needed before releasing the MMU lock.
  */
 static int set_tdp_spte(struct kvm *kvm, struct kvm_memory_slot *slot,
-			struct kvm_mmu_page *root, gfn_t gfn, gfn_t unused,
+			struct kvm_mmu_page *root, gfn_t gfn, gfn_t end,
 			unsigned long data)
 {
 	struct tdp_iter iter;
@@ -1033,7 +1033,7 @@ static int set_tdp_spte(struct kvm *kvm, struct kvm_memory_slot *slot,
 
 	rcu_read_lock();
 
-	WARN_ON(pte_huge(*ptep));
+	WARN_ON(pte_huge(*ptep) || (gfn + 1) != end);
 
 	new_pfn = pte_pfn(*ptep);
 
-- 
2.30.1.766.gb4fecdf3b7-goog


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/5] KVM: x86/mmu: Use 'end' param in TDP MMU's test_age_gfn()
  2021-02-26  1:03 [PATCH 0/5] KVM: x86/mmu: Misc cleanups, mostly TDP MMU Sean Christopherson
  2021-02-26  1:03 ` [PATCH 1/5] KVM: x86/mmu: Remove spurious TLB flush from TDP MMU's change_pte() hook Sean Christopherson
  2021-02-26  1:03 ` [PATCH 2/5] KVM: x86/mmu: WARN if TDP MMU's set_tdp_spte() sees multiple GFNs Sean Christopherson
@ 2021-02-26  1:03 ` Sean Christopherson
  2021-02-26  1:03 ` [PATCH 4/5] KVM: x86/mmu: Add typedefs for rmap/iter handlers Sean Christopherson
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Sean Christopherson @ 2021-02-26  1:03 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li, Jim Mattson,
	Joerg Roedel, kvm, linux-kernel, Ben Gardon

Use the @end param when aging a GFN instead of hardcoding the walk to a
single GFN.  Unlike tdp_set_spte(), which simply cannot work with more
than one GFN, aging multiple GFNs would not break, though admittedly it
would be weird.  Be nice to the casual reader and don't make them puzzle
out why the end GFN is unused.

No functional change intended.

Cc: Ben Gardon <bgardon@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/mmu/tdp_mmu.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index 020f2e573f44..9ce8d226b621 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -997,12 +997,12 @@ int kvm_tdp_mmu_age_hva_range(struct kvm *kvm, unsigned long start,
 }
 
 static int test_age_gfn(struct kvm *kvm, struct kvm_memory_slot *slot,
-			struct kvm_mmu_page *root, gfn_t gfn, gfn_t unused,
-			unsigned long unused2)
+			struct kvm_mmu_page *root, gfn_t gfn, gfn_t end,
+			unsigned long unused)
 {
 	struct tdp_iter iter;
 
-	tdp_root_for_each_leaf_pte(iter, root, gfn, gfn + 1)
+	tdp_root_for_each_leaf_pte(iter, root, gfn, end)
 		if (is_accessed_spte(iter.old_spte))
 			return 1;
 
-- 
2.30.1.766.gb4fecdf3b7-goog


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/5] KVM: x86/mmu: Add typedefs for rmap/iter handlers
  2021-02-26  1:03 [PATCH 0/5] KVM: x86/mmu: Misc cleanups, mostly TDP MMU Sean Christopherson
                   ` (2 preceding siblings ...)
  2021-02-26  1:03 ` [PATCH 3/5] KVM: x86/mmu: Use 'end' param in TDP MMU's test_age_gfn() Sean Christopherson
@ 2021-02-26  1:03 ` Sean Christopherson
  2021-02-26  1:03 ` [PATCH 5/5] KVM: x86/mmu: Add convenience wrapper for acting on single hva in TDP MMU Sean Christopherson
  2021-02-26  9:27 ` [PATCH 0/5] KVM: x86/mmu: Misc cleanups, mostly " Paolo Bonzini
  5 siblings, 0 replies; 7+ messages in thread
From: Sean Christopherson @ 2021-02-26  1:03 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li, Jim Mattson,
	Joerg Roedel, kvm, linux-kernel, Ben Gardon

Add typedefs for the MMU handlers that are invoked when walking the MMU
SPTEs (rmaps in legacy MMU) to act on a host virtual address range.

No functional change intended.

Cc: Ben Gardon <bgardon@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/mmu/mmu.c     | 27 ++++++++++-----------------
 arch/x86/kvm/mmu/tdp_mmu.c | 20 +++++++++-----------
 2 files changed, 19 insertions(+), 28 deletions(-)

diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index d75524bc8423..1ee01ca196bd 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -1424,17 +1424,15 @@ static void slot_rmap_walk_next(struct slot_rmap_walk_iterator *iterator)
 	     slot_rmap_walk_okay(_iter_);				\
 	     slot_rmap_walk_next(_iter_))
 
-static __always_inline int
-kvm_handle_hva_range(struct kvm *kvm,
-		     unsigned long start,
-		     unsigned long end,
-		     unsigned long data,
-		     int (*handler)(struct kvm *kvm,
-				    struct kvm_rmap_head *rmap_head,
-				    struct kvm_memory_slot *slot,
-				    gfn_t gfn,
-				    int level,
-				    unsigned long data))
+typedef int (*rmap_handler_t)(struct kvm *kvm, struct kvm_rmap_head *rmap_head,
+			      struct kvm_memory_slot *slot, gfn_t gfn,
+			      int level, unsigned long data);
+
+static __always_inline int kvm_handle_hva_range(struct kvm *kvm,
+						unsigned long start,
+						unsigned long end,
+						unsigned long data,
+						rmap_handler_t handler)
 {
 	struct kvm_memslots *slots;
 	struct kvm_memory_slot *memslot;
@@ -1473,12 +1471,7 @@ kvm_handle_hva_range(struct kvm *kvm,
 }
 
 static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
-			  unsigned long data,
-			  int (*handler)(struct kvm *kvm,
-					 struct kvm_rmap_head *rmap_head,
-					 struct kvm_memory_slot *slot,
-					 gfn_t gfn, int level,
-					 unsigned long data))
+			  unsigned long data, rmap_handler_t handler)
 {
 	return kvm_handle_hva_range(kvm, hva, hva + 1, data, handler);
 }
diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index 9ce8d226b621..b6f829b58e67 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -879,17 +879,15 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code,
 	return ret;
 }
 
-static __always_inline int
-kvm_tdp_mmu_handle_hva_range(struct kvm *kvm,
-			     unsigned long start,
-			     unsigned long end,
-			     unsigned long data,
-			     int (*handler)(struct kvm *kvm,
-					    struct kvm_memory_slot *slot,
-					    struct kvm_mmu_page *root,
-					    gfn_t start,
-					    gfn_t end,
-					    unsigned long data))
+typedef int (*tdp_handler_t)(struct kvm *kvm, struct kvm_memory_slot *slot,
+			     struct kvm_mmu_page *root, gfn_t start, gfn_t end,
+			     unsigned long data);
+
+static __always_inline int kvm_tdp_mmu_handle_hva_range(struct kvm *kvm,
+							unsigned long start,
+							unsigned long end,
+							unsigned long data,
+							tdp_handler_t handler)
 {
 	struct kvm_memslots *slots;
 	struct kvm_memory_slot *memslot;
-- 
2.30.1.766.gb4fecdf3b7-goog


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 5/5] KVM: x86/mmu: Add convenience wrapper for acting on single hva in TDP MMU
  2021-02-26  1:03 [PATCH 0/5] KVM: x86/mmu: Misc cleanups, mostly TDP MMU Sean Christopherson
                   ` (3 preceding siblings ...)
  2021-02-26  1:03 ` [PATCH 4/5] KVM: x86/mmu: Add typedefs for rmap/iter handlers Sean Christopherson
@ 2021-02-26  1:03 ` Sean Christopherson
  2021-02-26  9:27 ` [PATCH 0/5] KVM: x86/mmu: Misc cleanups, mostly " Paolo Bonzini
  5 siblings, 0 replies; 7+ messages in thread
From: Sean Christopherson @ 2021-02-26  1:03 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li, Jim Mattson,
	Joerg Roedel, kvm, linux-kernel, Ben Gardon

Add a TDP MMU helper to handle a single HVA hook, the name is a nice
reminder that the flow in question is operating on a single HVA.

No functional change intended.

Cc: Ben Gardon <bgardon@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/mmu/tdp_mmu.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index b6f829b58e67..c0c09ec07c53 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -922,6 +922,14 @@ static __always_inline int kvm_tdp_mmu_handle_hva_range(struct kvm *kvm,
 	return ret;
 }
 
+static __always_inline int kvm_tdp_mmu_handle_hva(struct kvm *kvm,
+						  unsigned long addr,
+						  unsigned long data,
+						  tdp_handler_t handler)
+{
+	return kvm_tdp_mmu_handle_hva_range(kvm, addr, addr + 1, data, handler);
+}
+
 static int zap_gfn_range_hva_wrapper(struct kvm *kvm,
 				     struct kvm_memory_slot *slot,
 				     struct kvm_mmu_page *root, gfn_t start,
@@ -1009,8 +1017,7 @@ static int test_age_gfn(struct kvm *kvm, struct kvm_memory_slot *slot,
 
 int kvm_tdp_mmu_test_age_hva(struct kvm *kvm, unsigned long hva)
 {
-	return kvm_tdp_mmu_handle_hva_range(kvm, hva, hva + 1, 0,
-					    test_age_gfn);
+	return kvm_tdp_mmu_handle_hva(kvm, hva, 0, test_age_gfn);
 }
 
 /*
@@ -1071,9 +1078,8 @@ static int set_tdp_spte(struct kvm *kvm, struct kvm_memory_slot *slot,
 int kvm_tdp_mmu_set_spte_hva(struct kvm *kvm, unsigned long address,
 			     pte_t *host_ptep)
 {
-	return kvm_tdp_mmu_handle_hva_range(kvm, address, address + 1,
-					    (unsigned long)host_ptep,
-					    set_tdp_spte);
+	return kvm_tdp_mmu_handle_hva(kvm, address, (unsigned long)host_ptep,
+				      set_tdp_spte);
 }
 
 /*
-- 
2.30.1.766.gb4fecdf3b7-goog


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/5] KVM: x86/mmu: Misc cleanups, mostly TDP MMU
  2021-02-26  1:03 [PATCH 0/5] KVM: x86/mmu: Misc cleanups, mostly TDP MMU Sean Christopherson
                   ` (4 preceding siblings ...)
  2021-02-26  1:03 ` [PATCH 5/5] KVM: x86/mmu: Add convenience wrapper for acting on single hva in TDP MMU Sean Christopherson
@ 2021-02-26  9:27 ` Paolo Bonzini
  5 siblings, 0 replies; 7+ messages in thread
From: Paolo Bonzini @ 2021-02-26  9:27 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: Vitaly Kuznetsov, Wanpeng Li, Jim Mattson, Joerg Roedel, kvm,
	linux-kernel, Ben Gardon

On 26/02/21 02:03, Sean Christopherson wrote:
> Effectively belated code review of a few pieces of the TDP MMU.
> 
> Sean Christopherson (5):
>    KVM: x86/mmu: Remove spurious TLB flush from TDP MMU's change_pte()
>      hook
>    KVM: x86/mmu: WARN if TDP MMU's set_tdp_spte() sees multiple GFNs
>    KVM: x86/mmu: Use 'end' param in TDP MMU's test_age_gfn()
>    KVM: x86/mmu: Add typedefs for rmap/iter handlers
>    KVM: x86/mmu: Add convenience wrapper for acting on single hva in TDP
>      MMU
> 
>   arch/x86/kvm/mmu/mmu.c     | 27 +++++++------------
>   arch/x86/kvm/mmu/tdp_mmu.c | 54 ++++++++++++++++++++++----------------
>   2 files changed, 41 insertions(+), 40 deletions(-)
> 

Queued (for 5.13), thanks.

Paolo


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-02-26  9:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-26  1:03 [PATCH 0/5] KVM: x86/mmu: Misc cleanups, mostly TDP MMU Sean Christopherson
2021-02-26  1:03 ` [PATCH 1/5] KVM: x86/mmu: Remove spurious TLB flush from TDP MMU's change_pte() hook Sean Christopherson
2021-02-26  1:03 ` [PATCH 2/5] KVM: x86/mmu: WARN if TDP MMU's set_tdp_spte() sees multiple GFNs Sean Christopherson
2021-02-26  1:03 ` [PATCH 3/5] KVM: x86/mmu: Use 'end' param in TDP MMU's test_age_gfn() Sean Christopherson
2021-02-26  1:03 ` [PATCH 4/5] KVM: x86/mmu: Add typedefs for rmap/iter handlers Sean Christopherson
2021-02-26  1:03 ` [PATCH 5/5] KVM: x86/mmu: Add convenience wrapper for acting on single hva in TDP MMU Sean Christopherson
2021-02-26  9:27 ` [PATCH 0/5] KVM: x86/mmu: Misc cleanups, mostly " Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).