Skip to content

Commit

Permalink
KVM: Reinstall old memslots if arch preparation fails
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Peter Xu <[email protected]>
Signed-off-by: Sean Christopherson <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
  • Loading branch information
Sean Christopherson authored and bonzini committed Mar 16, 2020
1 parent edd4fa3 commit 13ea525
Showing 1 changed file with 12 additions and 11 deletions.
23 changes: 12 additions & 11 deletions virt/kvm/kvm_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -999,7 +999,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
unsigned long npages;
struct kvm_memory_slot *slot;
struct kvm_memory_slot old, new;
struct kvm_memslots *slots = NULL, *old_memslots;
struct kvm_memslots *slots;
int as_id, id;
enum kvm_mr_change change;

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

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

/* From this point no new shadow pages pointing to a deleted,
* or moved, memslot will be created.
Expand All @@ -1117,13 +1123,6 @@ int __kvm_set_memory_region(struct kvm *kvm,
* - kvm_is_visible_gfn (mmu_check_root)
*/
kvm_arch_flush_shadow_memslot(kvm, slot);

/*
* We can re-use the old_memslots from above, the only difference
* from the currently installed memslots is the invalid flag. This
* will get overwritten by update_memslots anyway.
*/
slots = old_memslots;
}

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

update_memslots(slots, &new, change);
old_memslots = install_new_memslots(kvm, as_id, slots);
slots = install_new_memslots(kvm, as_id, slots);

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

kvm_free_memslot(kvm, &old, &new);
kvfree(old_memslots);
kvfree(slots);
return 0;

out_slots:
if (change == KVM_MR_DELETE || change == KVM_MR_MOVE)
slots = install_new_memslots(kvm, as_id, slots);
kvfree(slots);
out_free:
kvm_free_memslot(kvm, &new, &old);
Expand Down

0 comments on commit 13ea525

Please sign in to comment.