Skip to content

Commit 0819769

Browse files
committed
KVM: x86/mmu: Flush remote TLBs iff MMU-writable flag is cleared from RO SPTE
Don't force a remote TLB flush if KVM happens to effectively "refresh" a read-only SPTE that is still MMU-Writable, as KVM allows MMU-Writable SPTEs to have Writable TLB entries, even if the SPTE is !Writable. Remote TLBs need to be flushed only when creating a read-only SPTE for write-tracking, i.e. when installing a !MMU-Writable SPTE. In practice, especially now that KVM doesn't overwrite existing SPTEs when prefetching, KVM will rarely "refresh" a read-only, MMU-Writable SPTE, i.e. this is unlikely to eliminate many, if any, TLB flushes. But, more precisely flushing makes it easier to understand exactly when KVM does and doesn't need to flush. Note, x86 architecturally requires relevant TLB entries to be invalidated on a page fault, i.e. there is no risk of putting a vCPU into an infinite loop of read-only page faults. Cc: Yan Zhao <yan.y.zhao@intel.com> Link: https://lore.kernel.org/r/20241011021051.1557902-2-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 5cb1659 commit 0819769

File tree

2 files changed

+7
-11
lines changed

2 files changed

+7
-11
lines changed

arch/x86/kvm/mmu/mmu.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -514,9 +514,12 @@ static u64 mmu_spte_update_no_track(u64 *sptep, u64 new_spte)
514514
/* Rules for using mmu_spte_update:
515515
* Update the state bits, it means the mapped pfn is not changed.
516516
*
517-
* Whenever an MMU-writable SPTE is overwritten with a read-only SPTE, remote
518-
* TLBs must be flushed. Otherwise rmap_write_protect will find a read-only
519-
* spte, even though the writable spte might be cached on a CPU's TLB.
517+
* If the MMU-writable flag is cleared, i.e. the SPTE is write-protected for
518+
* write-tracking, remote TLBs must be flushed, even if the SPTE was read-only,
519+
* as KVM allows stale Writable TLB entries to exist. When dirty logging, KVM
520+
* flushes TLBs based on whether or not dirty bitmap/ring entries were reaped,
521+
* not whether or not SPTEs were modified, i.e. only the write-tracking case
522+
* needs to flush at the time the SPTEs is modified, before dropping mmu_lock.
520523
*
521524
* Returns true if the TLB needs to be flushed
522525
*/
@@ -533,8 +536,7 @@ static bool mmu_spte_update(u64 *sptep, u64 new_spte)
533536
* we always atomically update it, see the comments in
534537
* spte_has_volatile_bits().
535538
*/
536-
if (is_mmu_writable_spte(old_spte) &&
537-
!is_writable_pte(new_spte))
539+
if (is_mmu_writable_spte(old_spte) && !is_mmu_writable_spte(new_spte))
538540
flush = true;
539541

540542
/*

arch/x86/kvm/mmu/spte.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,6 @@ static bool kvm_is_mmio_pfn(kvm_pfn_t pfn)
133133
*/
134134
bool spte_has_volatile_bits(u64 spte)
135135
{
136-
/*
137-
* Always atomically update spte if it can be updated
138-
* out of mmu-lock, it can ensure dirty bit is not lost,
139-
* also, it can help us to get a stable is_writable_pte()
140-
* to ensure tlb flush is not missed.
141-
*/
142136
if (!is_writable_pte(spte) && is_mmu_writable_spte(spte))
143137
return true;
144138

0 commit comments

Comments
 (0)