Merge tag 'kvm-x86-mmu-6.10' of https://github.com/kvm-x86/linux into HEAD
authorPaolo Bonzini <pbonzini@redhat.com>
Sun, 12 May 2024 07:18:30 +0000 (03:18 -0400)
committerPaolo Bonzini <pbonzini@redhat.com>
Sun, 12 May 2024 07:18:30 +0000 (03:18 -0400)
KVM x86 MMU changes for 6.10:

 - Process TDP MMU SPTEs that are are zapped while holding mmu_lock for read
   after replacing REMOVED_SPTE with '0' and flushing remote TLBs, which allows
   vCPU tasks to repopulate the zapped region while the zapper finishes tearing
   down the old, defunct page tables.

 - Fix a longstanding, likely benign-in-practice race where KVM could fail to
   detect a write from kvm_mmu_track_write() to a shadowed GPTE if the GPTE is
   first page table being shadowed.

1  2 
arch/x86/kvm/mmu/mmu.c
arch/x86/kvm/mmu/tdp_mmu.c

Simple merge
index b5be7e949bd8c5981757f147497a30b0b5fa0744,afd00f79e741be342300592a33df1cfc8cdebfd4..1259dd63defc8e92ed2eb49e291db5a96d7623c9
@@@ -599,12 -614,20 +614,20 @@@ static inline int tdp_mmu_zap_spte_atom
        /*
         * No other thread can overwrite the removed SPTE as they must either
         * wait on the MMU lock or use tdp_mmu_set_spte_atomic() which will not
-        * overwrite the special removed SPTE value. No bookkeeping is needed
-        * here since the SPTE is going from non-present to non-present.  Use
-        * the raw write helper to avoid an unnecessary check on volatile bits.
+        * overwrite the special removed SPTE value. Use the raw write helper to
+        * avoid an unnecessary check on volatile bits.
         */
 -      __kvm_tdp_mmu_write_spte(iter->sptep, 0);
 +      __kvm_tdp_mmu_write_spte(iter->sptep, SHADOW_NONPRESENT_VALUE);
  
+       /*
+        * Process the zapped SPTE after flushing TLBs, and after replacing
+        * REMOVED_SPTE with 0. This minimizes the amount of time vCPUs are
+        * blocked by the REMOVED_SPTE and reduces contention on the child
+        * SPTEs.
+        */
+       handle_changed_spte(kvm, iter->as_id, iter->gfn, iter->old_spte,
+                           0, iter->level, true);
        return 0;
  }