}
 
 int kvm_arch_prepare_memory_region(struct kvm *kvm,
-                                  struct kvm_memory_slot *memslot,
                                   const struct kvm_userspace_memory_region *mem,
+                                  const struct kvm_memory_slot *old,
+                                  struct kvm_memory_slot *new,
                                   enum kvm_mr_change change)
 {
        hva_t hva = mem->userspace_addr;
         * Prevent userspace from creating a memory region outside of the IPA
         * space addressable by the KVM guest IPA space.
         */
-       if ((memslot->base_gfn + memslot->npages) > (kvm_phys_size(kvm) >> PAGE_SHIFT))
+       if ((new->base_gfn + new->npages) > (kvm_phys_size(kvm) >> PAGE_SHIFT))
                return -EFAULT;
 
        mmap_read_lock(current->mm);
 
                if (vma->vm_flags & VM_PFNMAP) {
                        /* IO region dirty page logging not allowed */
-                       if (memslot->flags & KVM_MEM_LOG_DIRTY_PAGES) {
+                       if (new->flags & KVM_MEM_LOG_DIRTY_PAGES) {
                                ret = -EINVAL;
                                break;
                        }
 
 }
 
 int kvm_arch_prepare_memory_region(struct kvm *kvm,
-                                  struct kvm_memory_slot *memslot,
                                   const struct kvm_userspace_memory_region *mem,
+                                  const struct kvm_memory_slot *old,
+                                  struct kvm_memory_slot *new,
                                   enum kvm_mr_change change)
 {
        return 0;
 
 extern void kvmppc_core_free_memslot(struct kvm *kvm,
                                     struct kvm_memory_slot *slot);
 extern int kvmppc_core_prepare_memory_region(struct kvm *kvm,
-                               struct kvm_memory_slot *memslot,
                                const struct kvm_userspace_memory_region *mem,
+                               const struct kvm_memory_slot *old,
+                               struct kvm_memory_slot *new,
                                enum kvm_mr_change change);
 extern void kvmppc_core_commit_memory_region(struct kvm *kvm,
                                const struct kvm_userspace_memory_region *mem,
-                               const struct kvm_memory_slot *old,
+                               struct kvm_memory_slot *old,
                                const struct kvm_memory_slot *new,
                                enum kvm_mr_change change);
 extern int kvm_vm_ioctl_get_smmu_info(struct kvm *kvm,
        int (*get_dirty_log)(struct kvm *kvm, struct kvm_dirty_log *log);
        void (*flush_memslot)(struct kvm *kvm, struct kvm_memory_slot *memslot);
        int (*prepare_memory_region)(struct kvm *kvm,
-                                    struct kvm_memory_slot *memslot,
                                     const struct kvm_userspace_memory_region *mem,
+                                    const struct kvm_memory_slot *old,
+                                    struct kvm_memory_slot *new,
                                     enum kvm_mr_change change);
        void (*commit_memory_region)(struct kvm *kvm,
                                     const struct kvm_userspace_memory_region *mem,
-                                    const struct kvm_memory_slot *old,
+                                    struct kvm_memory_slot *old,
                                     const struct kvm_memory_slot *new,
                                     enum kvm_mr_change change);
        bool (*unmap_gfn_range)(struct kvm *kvm, struct kvm_gfn_range *range);
 
 }
 
 int kvmppc_core_prepare_memory_region(struct kvm *kvm,
-                               struct kvm_memory_slot *memslot,
-                               const struct kvm_userspace_memory_region *mem,
-                               enum kvm_mr_change change)
+                                     const struct kvm_userspace_memory_region *mem,
+                                     const struct kvm_memory_slot *old,
+                                     struct kvm_memory_slot *new,
+                                     enum kvm_mr_change change)
 {
-       return kvm->arch.kvm_ops->prepare_memory_region(kvm, memslot, mem,
-                                                       change);
+       return kvm->arch.kvm_ops->prepare_memory_region(kvm, mem, old, new, change);
 }
 
 void kvmppc_core_commit_memory_region(struct kvm *kvm,
                                const struct kvm_userspace_memory_region *mem,
-                               const struct kvm_memory_slot *old,
+                               struct kvm_memory_slot *old,
                                const struct kvm_memory_slot *new,
                                enum kvm_mr_change change)
 {
 
 }
 
 static int kvmppc_core_prepare_memory_region_hv(struct kvm *kvm,
-                                       struct kvm_memory_slot *slot,
-                                       const struct kvm_userspace_memory_region *mem,
-                                       enum kvm_mr_change change)
+                               const struct kvm_userspace_memory_region *mem,
+                               const struct kvm_memory_slot *old,
+                               struct kvm_memory_slot *new,
+                               enum kvm_mr_change change)
 {
        unsigned long npages = mem->memory_size >> PAGE_SHIFT;
 
        if (change == KVM_MR_CREATE) {
-               slot->arch.rmap = vzalloc(array_size(npages,
-                                         sizeof(*slot->arch.rmap)));
-               if (!slot->arch.rmap)
+               new->arch.rmap = vzalloc(array_size(npages,
+                                         sizeof(*new->arch.rmap)));
+               if (!new->arch.rmap)
                        return -ENOMEM;
+       } else if (change != KVM_MR_DELETE) {
+               new->arch.rmap = old->arch.rmap;
        }
 
        return 0;
 
 static void kvmppc_core_commit_memory_region_hv(struct kvm *kvm,
                                const struct kvm_userspace_memory_region *mem,
-                               const struct kvm_memory_slot *old,
+                               struct kvm_memory_slot *old,
                                const struct kvm_memory_slot *new,
                                enum kvm_mr_change change)
 {
 
 }
 
 static int kvmppc_core_prepare_memory_region_pr(struct kvm *kvm,
-                                       struct kvm_memory_slot *memslot,
-                                       const struct kvm_userspace_memory_region *mem,
-                                       enum kvm_mr_change change)
+                               const struct kvm_userspace_memory_region *mem,
+                               const struct kvm_memory_slot *old,
+                               struct kvm_memory_slot *new,
+                               enum kvm_mr_change change)
 {
        return 0;
 }
 
 static void kvmppc_core_commit_memory_region_pr(struct kvm *kvm,
                                const struct kvm_userspace_memory_region *mem,
-                               const struct kvm_memory_slot *old,
+                               struct kvm_memory_slot *old,
                                const struct kvm_memory_slot *new,
                                enum kvm_mr_change change)
 {
 
 }
 
 int kvmppc_core_prepare_memory_region(struct kvm *kvm,
-                                     struct kvm_memory_slot *memslot,
                                      const struct kvm_userspace_memory_region *mem,
+                                     const struct kvm_memory_slot *old,
+                                     struct kvm_memory_slot *new,
                                      enum kvm_mr_change change)
 {
        return 0;
 
 void kvmppc_core_commit_memory_region(struct kvm *kvm,
                                const struct kvm_userspace_memory_region *mem,
-                               const struct kvm_memory_slot *old,
+                               struct kvm_memory_slot *old,
                                const struct kvm_memory_slot *new,
                                enum kvm_mr_change change)
 {
 
 }
 
 int kvm_arch_prepare_memory_region(struct kvm *kvm,
-                                  struct kvm_memory_slot *memslot,
                                   const struct kvm_userspace_memory_region *mem,
+                                  const struct kvm_memory_slot *old,
+                                  struct kvm_memory_slot *new,
                                   enum kvm_mr_change change)
 {
-       return kvmppc_core_prepare_memory_region(kvm, memslot, mem, change);
+       return kvmppc_core_prepare_memory_region(kvm, mem, old, new, change);
 }
 
 void kvm_arch_commit_memory_region(struct kvm *kvm,
 
 }
 
 int kvm_arch_prepare_memory_region(struct kvm *kvm,
-                               struct kvm_memory_slot *memslot,
                                const struct kvm_userspace_memory_region *mem,
+                               const struct kvm_memory_slot *old,
+                               struct kvm_memory_slot *new,
                                enum kvm_mr_change change)
 {
        hva_t hva = mem->userspace_addr;
         * Prevent userspace from creating a memory region outside of the GPA
         * space addressable by the KVM guest GPA space.
         */
-       if ((memslot->base_gfn + memslot->npages) >=
+       if ((new->base_gfn + new->npages) >=
            (stage2_gpa_size >> PAGE_SHIFT))
                return -EFAULT;
 
                        pa += vm_start - vma->vm_start;
 
                        /* IO region dirty page logging not allowed */
-                       if (memslot->flags & KVM_MEM_LOG_DIRTY_PAGES) {
+                       if (new->flags & KVM_MEM_LOG_DIRTY_PAGES) {
                                ret = -EINVAL;
                                goto out;
                        }
 
 
 /* Section: memory related */
 int kvm_arch_prepare_memory_region(struct kvm *kvm,
-                                  struct kvm_memory_slot *memslot,
                                   const struct kvm_userspace_memory_region *mem,
+                                  const struct kvm_memory_slot *old,
+                                  struct kvm_memory_slot *new,
                                   enum kvm_mr_change change)
 {
        /* A few sanity checks. We can have memory slots which have to be
 
 }
 
 int kvm_arch_prepare_memory_region(struct kvm *kvm,
-                               struct kvm_memory_slot *memslot,
-                               const struct kvm_userspace_memory_region *mem,
-                               enum kvm_mr_change change)
+                                  const struct kvm_userspace_memory_region *mem,
+                                  const struct kvm_memory_slot *old,
+                                  struct kvm_memory_slot *new,
+                                  enum kvm_mr_change change)
 {
        if (change == KVM_MR_CREATE || change == KVM_MR_MOVE)
-               return kvm_alloc_memslot_metadata(kvm, memslot,
+               return kvm_alloc_memslot_metadata(kvm, new,
                                                  mem->memory_size >> PAGE_SHIFT);
+
+       if (change == KVM_MR_FLAGS_ONLY)
+               memcpy(&new->arch, &old->arch, sizeof(old->arch));
+       else if (WARN_ON_ONCE(change != KVM_MR_DELETE))
+               return -EIO;
+
        return 0;
 }
 
 
 void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot);
 void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen);
 int kvm_arch_prepare_memory_region(struct kvm *kvm,
-                               struct kvm_memory_slot *memslot,
                                const struct kvm_userspace_memory_region *mem,
+                               const struct kvm_memory_slot *old,
+                               struct kvm_memory_slot *new,
                                enum kvm_mr_change change);
 void kvm_arch_commit_memory_region(struct kvm *kvm,
                                const struct kvm_userspace_memory_region *mem,
 
                old.as_id = new->as_id;
        }
 
-       /* Copy the arch-specific data, again after (re)acquiring slots_arch_lock. */
-       memcpy(&new->arch, &old.arch, sizeof(old.arch));
-
-       r = kvm_arch_prepare_memory_region(kvm, new, mem, change);
+       r = kvm_arch_prepare_memory_region(kvm, mem, &old, new, change);
        if (r)
                goto out_slots;