Skip to content

Commit 3741679

Browse files
Anthony Yznagabonzini
authored andcommitted
KVM: x86: minor code refactor and comments fixup around dirty logging
Consolidate the code and correct the comments to show that the actions taken to update existing mappings to disable or enable dirty logging are not necessary when creating, moving, or deleting a memslot. Signed-off-by: Anthony Yznaga <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 4b44295 commit 3741679

File tree

1 file changed

+49
-55
lines changed

1 file changed

+49
-55
lines changed

arch/x86/kvm/x86.c

Lines changed: 49 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -10140,41 +10140,65 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
1014010140
}
1014110141

1014210142
static void kvm_mmu_slot_apply_flags(struct kvm *kvm,
10143-
struct kvm_memory_slot *new)
10143+
struct kvm_memory_slot *old,
10144+
struct kvm_memory_slot *new,
10145+
enum kvm_mr_change change)
1014410146
{
10145-
/* Nothing to do for RO slots */
10146-
if (new->flags & KVM_MEM_READONLY)
10147+
/*
10148+
* Nothing to do for RO slots or CREATE/MOVE/DELETE of a slot.
10149+
* See comments below.
10150+
*/
10151+
if ((change != KVM_MR_FLAGS_ONLY) || (new->flags & KVM_MEM_READONLY))
1014710152
return;
1014810153

1014910154
/*
10150-
* Call kvm_x86_ops dirty logging hooks when they are valid.
10151-
*
10152-
* kvm_x86_ops.slot_disable_log_dirty is called when:
10153-
*
10154-
* - KVM_MR_CREATE with dirty logging is disabled
10155-
* - KVM_MR_FLAGS_ONLY with dirty logging is disabled in new flag
10156-
*
10157-
* The reason is, in case of PML, we need to set D-bit for any slots
10158-
* with dirty logging disabled in order to eliminate unnecessary GPA
10159-
* logging in PML buffer (and potential PML buffer full VMEXIT). This
10160-
* guarantees leaving PML enabled during guest's lifetime won't have
10161-
* any additional overhead from PML when guest is running with dirty
10162-
* logging disabled for memory slots.
10155+
* Dirty logging tracks sptes in 4k granularity, meaning that large
10156+
* sptes have to be split. If live migration is successful, the guest
10157+
* in the source machine will be destroyed and large sptes will be
10158+
* created in the destination. However, if the guest continues to run
10159+
* in the source machine (for example if live migration fails), small
10160+
* sptes will remain around and cause bad performance.
1016310161
*
10164-
* kvm_x86_ops.slot_enable_log_dirty is called when switching new slot
10165-
* to dirty logging mode.
10162+
* Scan sptes if dirty logging has been stopped, dropping those
10163+
* which can be collapsed into a single large-page spte. Later
10164+
* page faults will create the large-page sptes.
1016610165
*
10167-
* If kvm_x86_ops dirty logging hooks are invalid, use write protect.
10166+
* There is no need to do this in any of the following cases:
10167+
* CREATE: No dirty mappings will already exist.
10168+
* MOVE/DELETE: The old mappings will already have been cleaned up by
10169+
* kvm_arch_flush_shadow_memslot()
10170+
*/
10171+
if ((old->flags & KVM_MEM_LOG_DIRTY_PAGES) &&
10172+
!(new->flags & KVM_MEM_LOG_DIRTY_PAGES))
10173+
kvm_mmu_zap_collapsible_sptes(kvm, new);
10174+
10175+
/*
10176+
* Enable or disable dirty logging for the slot.
1016810177
*
10169-
* In case of write protect:
10178+
* For KVM_MR_DELETE and KVM_MR_MOVE, the shadow pages of the old
10179+
* slot have been zapped so no dirty logging updates are needed for
10180+
* the old slot.
10181+
* For KVM_MR_CREATE and KVM_MR_MOVE, once the new slot is visible
10182+
* any mappings that might be created in it will consume the
10183+
* properties of the new slot and do not need to be updated here.
1017010184
*
10171-
* Write protect all pages for dirty logging.
10185+
* When PML is enabled, the kvm_x86_ops dirty logging hooks are
10186+
* called to enable/disable dirty logging.
1017210187
*
10173-
* All the sptes including the large sptes which point to this
10174-
* slot are set to readonly. We can not create any new large
10175-
* spte on this slot until the end of the logging.
10188+
* When disabling dirty logging with PML enabled, the D-bit is set
10189+
* for sptes in the slot in order to prevent unnecessary GPA
10190+
* logging in the PML buffer (and potential PML buffer full VMEXIT).
10191+
* This guarantees leaving PML enabled for the guest's lifetime
10192+
* won't have any additional overhead from PML when the guest is
10193+
* running with dirty logging disabled.
1017610194
*
10195+
* When enabling dirty logging, large sptes are write-protected
10196+
* so they can be split on first write. New large sptes cannot
10197+
* be created for this slot until the end of the logging.
1017710198
* See the comments in fast_page_fault().
10199+
* For small sptes, nothing is done if the dirty log is in the
10200+
* initial-all-set state. Otherwise, depending on whether pml
10201+
* is enabled the D-bit or the W-bit will be cleared.
1017810202
*/
1017910203
if (new->flags & KVM_MEM_LOG_DIRTY_PAGES) {
1018010204
if (kvm_x86_ops.slot_enable_log_dirty) {
@@ -10211,39 +10235,9 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
1021110235
kvm_mmu_calculate_default_mmu_pages(kvm));
1021210236

1021310237
/*
10214-
* Dirty logging tracks sptes in 4k granularity, meaning that large
10215-
* sptes have to be split. If live migration is successful, the guest
10216-
* in the source machine will be destroyed and large sptes will be
10217-
* created in the destination. However, if the guest continues to run
10218-
* in the source machine (for example if live migration fails), small
10219-
* sptes will remain around and cause bad performance.
10220-
*
10221-
* Scan sptes if dirty logging has been stopped, dropping those
10222-
* which can be collapsed into a single large-page spte. Later
10223-
* page faults will create the large-page sptes.
10224-
*
10225-
* There is no need to do this in any of the following cases:
10226-
* CREATE: No dirty mappings will already exist.
10227-
* MOVE/DELETE: The old mappings will already have been cleaned up by
10228-
* kvm_arch_flush_shadow_memslot()
10229-
*/
10230-
if (change == KVM_MR_FLAGS_ONLY &&
10231-
(old->flags & KVM_MEM_LOG_DIRTY_PAGES) &&
10232-
!(new->flags & KVM_MEM_LOG_DIRTY_PAGES))
10233-
kvm_mmu_zap_collapsible_sptes(kvm, new);
10234-
10235-
/*
10236-
* Set up write protection and/or dirty logging for the new slot.
10237-
*
10238-
* For KVM_MR_DELETE and KVM_MR_MOVE, the shadow pages of old slot have
10239-
* been zapped so no dirty logging staff is needed for old slot. For
10240-
* KVM_MR_FLAGS_ONLY, the old slot is essentially the same one as the
10241-
* new and it's also covered when dealing with the new slot.
10242-
*
1024310238
* FIXME: const-ify all uses of struct kvm_memory_slot.
1024410239
*/
10245-
if (change == KVM_MR_FLAGS_ONLY)
10246-
kvm_mmu_slot_apply_flags(kvm, (struct kvm_memory_slot *) new);
10240+
kvm_mmu_slot_apply_flags(kvm, old, (struct kvm_memory_slot *) new, change);
1024710241

1024810242
/* Free the arrays associated with the old memslot. */
1024910243
if (change == KVM_MR_MOVE)

0 commit comments

Comments
 (0)