From: Junaid Shahid <junaids@xxxxxxxxxx> This change uses a lighter-weight function instead of mmu_spte_update() in the common case in spte_write_protect(). This helps speed up the get_dirty_log IOCTL. Performance: dirty_log_perf_test with 32 GB VM size Avg IOCTL time over 10 passes Haswell: ~0.23s vs ~0.4s IvyBridge: ~0.8s vs 1s Signed-off-by: Venkatesh Srinivas <venkateshs@xxxxxxxxxxxx> Signed-off-by: Junaid Shahid <junaids@xxxxxxxxxx> --- arch/x86/kvm/mmu/mmu.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index efe5a3dca1e0..a6db9dfaf7c3 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -1151,6 +1151,22 @@ static void drop_large_spte(struct kvm_vcpu *vcpu, u64 *sptep) } } +static bool spte_test_and_clear_writable(u64 *sptep) +{ + u64 spte = *sptep; + + if (spte & PT_WRITABLE_MASK) { + clear_bit(PT_WRITABLE_SHIFT, (unsigned long *)sptep); + + if (!spte_ad_enabled(spte)) + kvm_set_pfn_dirty(spte_to_pfn(spte)); + + return true; + } + + return false; +} + /* * Write-protect on the specified @sptep, @pt_protect indicates whether * spte write-protection is caused by protecting shadow page table. @@ -1174,11 +1190,11 @@ static bool spte_write_protect(u64 *sptep, bool pt_protect) rmap_printk("spte %p %llx\n", sptep, *sptep); - if (pt_protect) - spte &= ~shadow_mmu_writable_mask; - spte = spte & ~PT_WRITABLE_MASK; - - return mmu_spte_update(sptep, spte); + if (pt_protect) { + spte &= ~(shadow_mmu_writable_mask | PT_WRITABLE_MASK); + return mmu_spte_update(sptep, spte); + } + return spte_test_and_clear_writable(sptep); } static bool rmap_write_protect(struct kvm_rmap_head *rmap_head, -- 2.36.1.124.g0e6072fb45-goog