Skip to content

Commit b5f5fdc

Browse files
chenxgggbonzini
authored andcommitted
KVM: x86: add track_flush_slot page track notifier
When a memory slot is being moved or removed users of page track can be notified. So users can drop write-protection for the pages in that memory slot. This notifier type is needed by KVMGT to sync up its shadow page table when memory slot is being moved or removed. Register the notifier type track_flush_slot to receive memslot move and remove event. Reviewed-by: Xiao Guangrong <[email protected]> Signed-off-by: Chen Xiaoguang <[email protected]> [Squashed commits to avoid bisection breakage and reworded the subject.] Signed-off-by: Radim Krčmář <[email protected]>
1 parent 2361133 commit b5f5fdc

File tree

4 files changed

+42
-1
lines changed

4 files changed

+42
-1
lines changed

arch/x86/include/asm/kvm_page_track.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ struct kvm_page_track_notifier_node {
3232
*/
3333
void (*track_write)(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new,
3434
int bytes);
35+
/*
36+
* It is called when memory slot is being moved or removed
37+
* users can drop write-protection for the pages in that memory slot
38+
*
39+
* @kvm: the kvm where memory slot being moved or removed
40+
* @slot: the memory slot being moved or removed
41+
*/
42+
void (*track_flush_slot)(struct kvm *kvm, struct kvm_memory_slot *slot);
3543
};
3644

3745
void kvm_page_track_init(struct kvm *kvm);
@@ -58,4 +66,5 @@ kvm_page_track_unregister_notifier(struct kvm *kvm,
5866
struct kvm_page_track_notifier_node *n);
5967
void kvm_page_track_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new,
6068
int bytes);
69+
void kvm_page_track_flush_slot(struct kvm *kvm, struct kvm_memory_slot *slot);
6170
#endif

arch/x86/kvm/mmu.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4609,11 +4609,18 @@ void kvm_mmu_setup(struct kvm_vcpu *vcpu)
46094609
init_kvm_mmu(vcpu);
46104610
}
46114611

4612+
static void kvm_mmu_invalidate_zap_pages_in_memslot(struct kvm *kvm,
4613+
struct kvm_memory_slot *slot)
4614+
{
4615+
kvm_mmu_invalidate_zap_all_pages(kvm);
4616+
}
4617+
46124618
void kvm_mmu_init_vm(struct kvm *kvm)
46134619
{
46144620
struct kvm_page_track_notifier_node *node = &kvm->arch.mmu_sp_tracker;
46154621

46164622
node->track_write = kvm_mmu_pte_write;
4623+
node->track_flush_slot = kvm_mmu_invalidate_zap_pages_in_memslot;
46174624
kvm_page_track_register_notifier(kvm, node);
46184625
}
46194626

arch/x86/kvm/page_track.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,28 @@ void kvm_page_track_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new,
225225
n->track_write(vcpu, gpa, new, bytes);
226226
srcu_read_unlock(&head->track_srcu, idx);
227227
}
228+
229+
/*
230+
* Notify the node that memory slot is being removed or moved so that it can
231+
* drop write-protection for the pages in the memory slot.
232+
*
233+
* The node should figure out it has any write-protected pages in this slot
234+
* by itself.
235+
*/
236+
void kvm_page_track_flush_slot(struct kvm *kvm, struct kvm_memory_slot *slot)
237+
{
238+
struct kvm_page_track_notifier_head *head;
239+
struct kvm_page_track_notifier_node *n;
240+
int idx;
241+
242+
head = &kvm->arch.track_notifier_head;
243+
244+
if (hlist_empty(&head->track_notifier_list))
245+
return;
246+
247+
idx = srcu_read_lock(&head->track_srcu);
248+
hlist_for_each_entry_rcu(n, &head->track_notifier_list, node)
249+
if (n->track_flush_slot)
250+
n->track_flush_slot(kvm, slot);
251+
srcu_read_unlock(&head->track_srcu, idx);
252+
}

arch/x86/kvm/x86.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8155,7 +8155,7 @@ void kvm_arch_flush_shadow_all(struct kvm *kvm)
81558155
void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
81568156
struct kvm_memory_slot *slot)
81578157
{
8158-
kvm_mmu_invalidate_zap_all_pages(kvm);
8158+
kvm_page_track_flush_slot(kvm, slot);
81598159
}
81608160

81618161
static inline bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu)

0 commit comments

Comments
 (0)