From: Mihai Donțu <mdo...@bitdefender.com>

This is used to add page access notifications as soon as a slot appears.

Signed-off-by: Mihai Donțu <mdo...@bitdefender.com>
Signed-off-by: Adalbert Lazăr <ala...@bitdefender.com>
---
 arch/x86/include/asm/kvm_page_track.h | 13 ++++++++++++-
 arch/x86/kvm/mmu/page_track.c         | 16 +++++++++++++++-
 arch/x86/kvm/x86.c                    |  7 ++++---
 3 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/kvm_page_track.h 
b/arch/x86/include/asm/kvm_page_track.h
index 9a261e463eb3..00a66c4d4d3c 100644
--- a/arch/x86/include/asm/kvm_page_track.h
+++ b/arch/x86/include/asm/kvm_page_track.h
@@ -36,6 +36,17 @@ struct kvm_page_track_notifier_node {
        void (*track_write)(struct kvm_vcpu *vcpu, gpa_t gpa, gva_t gva,
                            const u8 *new, int bytes,
                            struct kvm_page_track_notifier_node *node);
+       /*
+        * It is called when memory slot is being created
+        *
+        * @kvm: the kvm where memory slot being moved or removed
+        * @slot: the memory slot being moved or removed
+        * @npages: the number of pages
+        * @node: this node
+        */
+       void (*track_create_slot)(struct kvm *kvm, struct kvm_memory_slot *slot,
+                                 unsigned long npages,
+                                 struct kvm_page_track_notifier_node *node);
        /*
         * It is called when memory slot is being moved or removed
         * users can drop write-protection for the pages in that memory slot
@@ -52,7 +63,7 @@ void kvm_page_track_init(struct kvm *kvm);
 void kvm_page_track_cleanup(struct kvm *kvm);
 
 void kvm_page_track_free_memslot(struct kvm_memory_slot *slot);
-int kvm_page_track_create_memslot(struct kvm_memory_slot *slot,
+int kvm_page_track_create_memslot(struct kvm *kvm, struct kvm_memory_slot 
*slot,
                                  unsigned long npages);
 
 void kvm_slot_page_track_add_page(struct kvm *kvm,
diff --git a/arch/x86/kvm/mmu/page_track.c b/arch/x86/kvm/mmu/page_track.c
index 9642af1b2c21..02759b81a04c 100644
--- a/arch/x86/kvm/mmu/page_track.c
+++ b/arch/x86/kvm/mmu/page_track.c
@@ -28,9 +28,12 @@ void kvm_page_track_free_memslot(struct kvm_memory_slot 
*slot)
        }
 }
 
-int kvm_page_track_create_memslot(struct kvm_memory_slot *slot,
+int kvm_page_track_create_memslot(struct kvm *kvm, struct kvm_memory_slot 
*slot,
                                  unsigned long npages)
 {
+       struct kvm_page_track_notifier_head *head;
+       struct kvm_page_track_notifier_node *n;
+       int idx;
        int  i;
 
        for (i = 0; i < KVM_PAGE_TRACK_MAX; i++) {
@@ -41,6 +44,17 @@ int kvm_page_track_create_memslot(struct kvm_memory_slot 
*slot,
                        goto track_free;
        }
 
+       head = &kvm->arch.track_notifier_head;
+
+       if (hlist_empty(&head->track_notifier_list))
+               return 0;
+
+       idx = srcu_read_lock(&head->track_srcu);
+       hlist_for_each_entry_rcu(n, &head->track_notifier_list, node)
+               if (n->track_create_slot)
+                       n->track_create_slot(kvm, slot, npages, n);
+       srcu_read_unlock(&head->track_srcu, idx);
+
        return 0;
 
 track_free:
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index a59c935f4bbe..83424339ea9d 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -10070,7 +10070,8 @@ void kvm_arch_free_memslot(struct kvm *kvm, struct 
kvm_memory_slot *slot)
        kvm_page_track_free_memslot(slot);
 }
 
-static int kvm_alloc_memslot_metadata(struct kvm_memory_slot *slot,
+static int kvm_alloc_memslot_metadata(struct kvm *kvm,
+                                     struct kvm_memory_slot *slot,
                                      unsigned long npages)
 {
        int i;
@@ -10122,7 +10123,7 @@ static int kvm_alloc_memslot_metadata(struct 
kvm_memory_slot *slot,
                }
        }
 
-       if (kvm_page_track_create_memslot(slot, npages))
+       if (kvm_page_track_create_memslot(kvm, slot, npages))
                goto out_free;
 
        return 0;
@@ -10162,7 +10163,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
                                enum kvm_mr_change change)
 {
        if (change == KVM_MR_CREATE || change == KVM_MR_MOVE)
-               return kvm_alloc_memslot_metadata(memslot,
+               return kvm_alloc_memslot_metadata(kvm, memslot,
                                                  mem->memory_size >> 
PAGE_SHIFT);
        return 0;
 }
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Reply via email to