unsigned long gfn);
 extern long kvmppc_hv_get_dirty_log_radix(struct kvm *kvm,
                        struct kvm_memory_slot *memslot, unsigned long *map);
+extern void kvmppc_radix_flush_memslot(struct kvm *kvm,
+                       const struct kvm_memory_slot *memslot);
 extern int kvmhv_get_rmmu_info(struct kvm *kvm, struct kvm_ppc_rmmu_info *info);
 
 /* XXX remove this export when load_last_inst() is generic */
 
 
        gfn = memslot->base_gfn;
        rmapp = memslot->arch.rmap;
+       if (kvm_is_radix(kvm)) {
+               kvmppc_radix_flush_memslot(kvm, memslot);
+               return;
+       }
+
        for (n = memslot->npages; n; --n, ++gfn) {
-               if (kvm_is_radix(kvm)) {
-                       kvm_unmap_radix(kvm, memslot, gfn);
-                       continue;
-               }
                /*
                 * Testing the present bit without locking is OK because
                 * the memslot has been marked invalid already, and hence
 
        return 0;
 }
 
+void kvmppc_radix_flush_memslot(struct kvm *kvm,
+                               const struct kvm_memory_slot *memslot)
+{
+       unsigned long n;
+       pte_t *ptep;
+       unsigned long gpa;
+       unsigned int shift;
+
+       gpa = memslot->base_gfn << PAGE_SHIFT;
+       spin_lock(&kvm->mmu_lock);
+       for (n = memslot->npages; n; --n) {
+               ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift);
+               if (ptep && pte_present(*ptep))
+                       kvmppc_unmap_pte(kvm, ptep, gpa, shift, memslot,
+                                        kvm->arch.lpid);
+               gpa += PAGE_SIZE;
+       }
+       spin_unlock(&kvm->mmu_lock);
+}
+
 static void add_rmmu_ap_encoding(struct kvm_ppc_rmmu_info *info,
                                 int psize, int *indexp)
 {
 
         */
        if (npages)
                atomic64_inc(&kvm->arch.mmio_update);
+
+       /*
+        * For change == KVM_MR_MOVE or KVM_MR_DELETE, higher levels
+        * have already called kvm_arch_flush_shadow_memslot() to
+        * flush shadow mappings.  For KVM_MR_CREATE we have no
+        * previous mappings.  So the only case to handle is
+        * KVM_MR_FLAGS_ONLY when the KVM_MEM_LOG_DIRTY_PAGES bit
+        * has been changed.
+        * For radix guests, we flush on setting KVM_MEM_LOG_DIRTY_PAGES
+        * to get rid of any THP PTEs in the partition-scoped page tables
+        * so we can track dirtiness at the page level; we flush when
+        * clearing KVM_MEM_LOG_DIRTY_PAGES so that we can go back to
+        * using THP PTEs.
+        */
+       if (change == KVM_MR_FLAGS_ONLY && kvm_is_radix(kvm) &&
+           ((new->flags ^ old->flags) & KVM_MEM_LOG_DIRTY_PAGES))
+               kvmppc_radix_flush_memslot(kvm, old);
 }
 
 /*