Skip to content

Commit 9b51a63

Browse files
Kai Huangbonzini
authored andcommitted
KVM: MMU: Explicitly set D-bit for writable spte.
This patch avoids unnecessary dirty GPA logging to PML buffer in EPT violation path by setting D-bit manually prior to the occurrence of the write from guest. We only set D-bit manually in set_spte, and leave fast_page_fault path unchanged, as fast_page_fault is very unlikely to happen in case of PML. For the hva <-> pa change case, the spte is updated to either read-only (host pte is read-only) or be dropped (host pte is writeable), and both cases will be handled by above changes, therefore no change is necessary. Signed-off-by: Kai Huang <[email protected]> Reviewed-by: Xiao Guangrong <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent f4b4b18 commit 9b51a63

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

arch/x86/kvm/mmu.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2597,8 +2597,10 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
25972597
}
25982598
}
25992599

2600-
if (pte_access & ACC_WRITE_MASK)
2600+
if (pte_access & ACC_WRITE_MASK) {
26012601
mark_page_dirty(vcpu->kvm, gfn);
2602+
spte |= shadow_dirty_mask;
2603+
}
26022604

26032605
set_pte:
26042606
if (mmu_spte_update(sptep, spte))
@@ -2914,6 +2916,18 @@ fast_pf_fix_direct_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
29142916
*/
29152917
gfn = kvm_mmu_page_get_gfn(sp, sptep - sp->spt);
29162918

2919+
/*
2920+
* Theoretically we could also set dirty bit (and flush TLB) here in
2921+
* order to eliminate unnecessary PML logging. See comments in
2922+
* set_spte. But fast_page_fault is very unlikely to happen with PML
2923+
* enabled, so we do not do this. This might result in the same GPA
2924+
* to be logged in PML buffer again when the write really happens, and
2925+
* eventually to be called by mark_page_dirty twice. But it's also no
2926+
* harm. This also avoids the TLB flush needed after setting dirty bit
2927+
* so non-PML cases won't be impacted.
2928+
*
2929+
* Compare with set_spte where instead shadow_dirty_mask is set.
2930+
*/
29172931
if (cmpxchg64(sptep, spte, spte | PT_WRITABLE_MASK) == spte)
29182932
mark_page_dirty(vcpu->kvm, gfn);
29192933

0 commit comments

Comments
 (0)