--- /dev/null
+From e40f193f5bb022e927a57a4f5d5194e4f12ddb74 Mon Sep 17 00:00:00 2001
+From: Alex Williamson <alex.williamson@redhat.com>
+Date: Mon, 10 Dec 2012 10:32:57 -0700
+Subject: KVM: Fix iommu map/unmap to handle memory slot moves
+
+From: Alex Williamson <alex.williamson@redhat.com>
+
+commit e40f193f5bb022e927a57a4f5d5194e4f12ddb74 upstream.
+
+The iommu integration into memory slots expects memory slots to be
+added or removed and doesn't handle the move case. We can unmap
+slots from the iommu after we mark them invalid and map them before
+installing the final memslot array. Also re-order the kmemdup vs
+map so we don't leave iommu mappings if we get ENOMEM.
+
+Reviewed-by: Gleb Natapov <gleb@redhat.com>
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
+Cc: Luis Henriques <luis.henriques@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ virt/kvm/kvm_main.c | 19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -790,6 +790,8 @@ int __kvm_set_memory_region(struct kvm *
+ old_memslots = kvm->memslots;
+ rcu_assign_pointer(kvm->memslots, slots);
+ synchronize_srcu_expedited(&kvm->srcu);
++ /* slot was deleted or moved, clear iommu mapping */
++ kvm_iommu_unmap_pages(kvm, &old);
+ /* From this point no new shadow pages pointing to a deleted,
+ * or moved, memslot will be created.
+ *
+@@ -805,20 +807,19 @@ int __kvm_set_memory_region(struct kvm *
+ if (r)
+ goto out_free;
+
+- /* map/unmap the pages in iommu page table */
+- if (npages) {
+- r = kvm_iommu_map_pages(kvm, &new);
+- if (r)
+- goto out_free;
+- } else
+- kvm_iommu_unmap_pages(kvm, &old);
+-
+ r = -ENOMEM;
+ slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots),
+ GFP_KERNEL);
+ if (!slots)
+ goto out_free;
+
++ /* map new memory slot into the iommu */
++ if (npages) {
++ r = kvm_iommu_map_pages(kvm, &new);
++ if (r)
++ goto out_slots;
++ }
++
+ /* actual memory is freed via old in kvm_free_physmem_slot below */
+ if (!npages) {
+ new.rmap = NULL;
+@@ -845,6 +846,8 @@ int __kvm_set_memory_region(struct kvm *
+
+ return 0;
+
++out_slots:
++ kfree(slots);
+ out_free:
+ kvm_free_physmem_slot(&new, &old);
+ out:
--- /dev/null
+From 12d6e7538e2d418c08f082b1b44ffa5fb7270ed8 Mon Sep 17 00:00:00 2001
+From: Marcelo Tosatti <mtosatti@redhat.com>
+Date: Fri, 24 Aug 2012 15:54:58 -0300
+Subject: KVM: perform an invalid memslot step for gpa base change
+
+From: Marcelo Tosatti <mtosatti@redhat.com>
+
+commit 12d6e7538e2d418c08f082b1b44ffa5fb7270ed8 upstream.
+
+PPC must flush all translations before the new memory slot
+is visible.
+
+Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
+Signed-off-by: Avi Kivity <avi@redhat.com>
+Cc: Luis Henriques <luis.henriques@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ virt/kvm/kvm_main.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -774,7 +774,7 @@ int __kvm_set_memory_region(struct kvm *
+ /* destroy any largepage mappings for dirty tracking */
+ }
+
+- if (!npages) {
++ if (!npages || base_gfn != old.base_gfn) {
+ struct kvm_memory_slot *slot;
+
+ r = -ENOMEM;
+@@ -790,8 +790,8 @@ int __kvm_set_memory_region(struct kvm *
+ old_memslots = kvm->memslots;
+ rcu_assign_pointer(kvm->memslots, slots);
+ synchronize_srcu_expedited(&kvm->srcu);
+- /* From this point no new shadow pages pointing to a deleted
+- * memslot will be created.
++ /* From this point no new shadow pages pointing to a deleted,
++ * or moved, memslot will be created.
+ *
+ * validation of sp->gfn happens in:
+ * - gfn_to_hva (kvm_read_guest, gfn_to_pfn)