*/
        void (*track_write)(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new,
                            int bytes);
+       /*
+        * It is called when memory slot is being moved or removed
+        * users can drop write-protection for the pages in that memory slot
+        *
+        * @kvm: the kvm where memory slot being moved or removed
+        * @slot: the memory slot being moved or removed
+        */
+       void (*track_flush_slot)(struct kvm *kvm, struct kvm_memory_slot *slot);
 };
 
 void kvm_page_track_init(struct kvm *kvm);
                                   struct kvm_page_track_notifier_node *n);
 void kvm_page_track_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new,
                          int bytes);
+void kvm_page_track_flush_slot(struct kvm *kvm, struct kvm_memory_slot *slot);
 #endif
 
        init_kvm_mmu(vcpu);
 }
 
+static void kvm_mmu_invalidate_zap_pages_in_memslot(struct kvm *kvm,
+                       struct kvm_memory_slot *slot)
+{
+       kvm_mmu_invalidate_zap_all_pages(kvm);
+}
+
 void kvm_mmu_init_vm(struct kvm *kvm)
 {
        struct kvm_page_track_notifier_node *node = &kvm->arch.mmu_sp_tracker;
 
        node->track_write = kvm_mmu_pte_write;
+       node->track_flush_slot = kvm_mmu_invalidate_zap_pages_in_memslot;
        kvm_page_track_register_notifier(kvm, node);
 }
 
 
                        n->track_write(vcpu, gpa, new, bytes);
        srcu_read_unlock(&head->track_srcu, idx);
 }
+
+/*
+ * Notify the node that memory slot is being removed or moved so that it can
+ * drop write-protection for the pages in the memory slot.
+ *
+ * The node should figure out it has any write-protected pages in this slot
+ * by itself.
+ */
+void kvm_page_track_flush_slot(struct kvm *kvm, struct kvm_memory_slot *slot)
+{
+       struct kvm_page_track_notifier_head *head;
+       struct kvm_page_track_notifier_node *n;
+       int idx;
+
+       head = &kvm->arch.track_notifier_head;
+
+       if (hlist_empty(&head->track_notifier_list))
+               return;
+
+       idx = srcu_read_lock(&head->track_srcu);
+       hlist_for_each_entry_rcu(n, &head->track_notifier_list, node)
+               if (n->track_flush_slot)
+                       n->track_flush_slot(kvm, slot);
+       srcu_read_unlock(&head->track_srcu, idx);
+}
 
 void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
                                   struct kvm_memory_slot *slot)
 {
-       kvm_mmu_invalidate_zap_all_pages(kvm);
+       kvm_page_track_flush_slot(kvm, slot);
 }
 
 static inline bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu)