diff options
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r-- | virt/kvm/kvm_main.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index e4d358195e54..9a56ca2fa257 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -822,6 +822,8 @@ int __kvm_set_memory_region(struct kvm *kvm, | |||
822 | old_memslots = kvm->memslots; | 822 | old_memslots = kvm->memslots; |
823 | rcu_assign_pointer(kvm->memslots, slots); | 823 | rcu_assign_pointer(kvm->memslots, slots); |
824 | synchronize_srcu_expedited(&kvm->srcu); | 824 | synchronize_srcu_expedited(&kvm->srcu); |
825 | /* slot was deleted or moved, clear iommu mapping */ | ||
826 | kvm_iommu_unmap_pages(kvm, &old); | ||
825 | /* From this point no new shadow pages pointing to a deleted, | 827 | /* From this point no new shadow pages pointing to a deleted, |
826 | * or moved, memslot will be created. | 828 | * or moved, memslot will be created. |
827 | * | 829 | * |
@@ -837,20 +839,19 @@ int __kvm_set_memory_region(struct kvm *kvm, | |||
837 | if (r) | 839 | if (r) |
838 | goto out_free; | 840 | goto out_free; |
839 | 841 | ||
840 | /* map/unmap the pages in iommu page table */ | ||
841 | if (npages) { | ||
842 | r = kvm_iommu_map_pages(kvm, &new); | ||
843 | if (r) | ||
844 | goto out_free; | ||
845 | } else | ||
846 | kvm_iommu_unmap_pages(kvm, &old); | ||
847 | |||
848 | r = -ENOMEM; | 842 | r = -ENOMEM; |
849 | slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots), | 843 | slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots), |
850 | GFP_KERNEL); | 844 | GFP_KERNEL); |
851 | if (!slots) | 845 | if (!slots) |
852 | goto out_free; | 846 | goto out_free; |
853 | 847 | ||
848 | /* map new memory slot into the iommu */ | ||
849 | if (npages) { | ||
850 | r = kvm_iommu_map_pages(kvm, &new); | ||
851 | if (r) | ||
852 | goto out_slots; | ||
853 | } | ||
854 | |||
854 | /* actual memory is freed via old in kvm_free_physmem_slot below */ | 855 | /* actual memory is freed via old in kvm_free_physmem_slot below */ |
855 | if (!npages) { | 856 | if (!npages) { |
856 | new.dirty_bitmap = NULL; | 857 | new.dirty_bitmap = NULL; |
@@ -869,6 +870,8 @@ int __kvm_set_memory_region(struct kvm *kvm, | |||
869 | 870 | ||
870 | return 0; | 871 | return 0; |
871 | 872 | ||
873 | out_slots: | ||
874 | kfree(slots); | ||
872 | out_free: | 875 | out_free: |
873 | kvm_free_physmem_slot(&new, &old); | 876 | kvm_free_physmem_slot(&new, &old); |
874 | out: | 877 | out: |