@@ -10140,41 +10140,65 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
10140
10140
}
10141
10141
10142
10142
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 )
10144
10146
{
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 ))
10147
10152
return ;
10148
10153
10149
10154
/*
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.
10163
10161
*
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.
10166
10165
*
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.
10168
10177
*
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.
10170
10184
*
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.
10172
10187
*
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.
10176
10194
*
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.
10177
10198
* 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.
10178
10202
*/
10179
10203
if (new -> flags & KVM_MEM_LOG_DIRTY_PAGES ) {
10180
10204
if (kvm_x86_ops .slot_enable_log_dirty ) {
@@ -10211,39 +10235,9 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
10211
10235
kvm_mmu_calculate_default_mmu_pages (kvm ));
10212
10236
10213
10237
/*
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
- *
10243
10238
* FIXME: const-ify all uses of struct kvm_memory_slot.
10244
10239
*/
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 );
10247
10241
10248
10242
/* Free the arrays associated with the old memslot. */
10249
10243
if (change == KVM_MR_MOVE )
0 commit comments