Skip to content

Commit 13ea525

Browse files
Sean Christophersonbonzini
authored andcommitted
KVM: Reinstall old memslots if arch preparation fails
Reinstall the old memslots if preparing the new memory region fails after invalidating a to-be-{re}moved memslot. Remove the superfluous 'old_memslots' variable so that it's somewhat clear that the error handling path needs to free the unused memslots, not simply the 'old' memslots. Fixes: bc6678a ("KVM: introduce kvm->srcu and convert kvm_set_memory_region to SRCU update") Reviewed-by: Christoffer Dall <christoffer.dall@arm.com> Reviewed-by: Peter Xu <peterx@redhat.com> Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent edd4fa3 commit 13ea525

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

virt/kvm/kvm_main.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
999999
unsigned long npages;
10001000
struct kvm_memory_slot *slot;
10011001
struct kvm_memory_slot old, new;
1002-
struct kvm_memslots *slots = NULL, *old_memslots;
1002+
struct kvm_memslots *slots;
10031003
int as_id, id;
10041004
enum kvm_mr_change change;
10051005

@@ -1107,7 +1107,13 @@ int __kvm_set_memory_region(struct kvm *kvm,
11071107
slot = id_to_memslot(slots, id);
11081108
slot->flags |= KVM_MEMSLOT_INVALID;
11091109

1110-
old_memslots = install_new_memslots(kvm, as_id, slots);
1110+
/*
1111+
* We can re-use the old memslots, the only difference from the
1112+
* newly installed memslots is the invalid flag, which will get
1113+
* dropped by update_memslots anyway. We'll also revert to the
1114+
* old memslots if preparing the new memory region fails.
1115+
*/
1116+
slots = install_new_memslots(kvm, as_id, slots);
11111117

11121118
/* From this point no new shadow pages pointing to a deleted,
11131119
* or moved, memslot will be created.
@@ -1117,13 +1123,6 @@ int __kvm_set_memory_region(struct kvm *kvm,
11171123
* - kvm_is_visible_gfn (mmu_check_root)
11181124
*/
11191125
kvm_arch_flush_shadow_memslot(kvm, slot);
1120-
1121-
/*
1122-
* We can re-use the old_memslots from above, the only difference
1123-
* from the currently installed memslots is the invalid flag. This
1124-
* will get overwritten by update_memslots anyway.
1125-
*/
1126-
slots = old_memslots;
11271126
}
11281127

11291128
r = kvm_arch_prepare_memory_region(kvm, &new, mem, change);
@@ -1137,15 +1136,17 @@ int __kvm_set_memory_region(struct kvm *kvm,
11371136
}
11381137

11391138
update_memslots(slots, &new, change);
1140-
old_memslots = install_new_memslots(kvm, as_id, slots);
1139+
slots = install_new_memslots(kvm, as_id, slots);
11411140

11421141
kvm_arch_commit_memory_region(kvm, mem, &old, &new, change);
11431142

11441143
kvm_free_memslot(kvm, &old, &new);
1145-
kvfree(old_memslots);
1144+
kvfree(slots);
11461145
return 0;
11471146

11481147
out_slots:
1148+
if (change == KVM_MR_DELETE || change == KVM_MR_MOVE)
1149+
slots = install_new_memslots(kvm, as_id, slots);
11491150
kvfree(slots);
11501151
out_free:
11511152
kvm_free_memslot(kvm, &new, &old);

0 commit comments

Comments
 (0)