18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _ASM_X86_KVM_PAGE_TRACK_H
38c2ecf20Sopenharmony_ci#define _ASM_X86_KVM_PAGE_TRACK_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_cienum kvm_page_track_mode {
68c2ecf20Sopenharmony_ci	KVM_PAGE_TRACK_WRITE,
78c2ecf20Sopenharmony_ci	KVM_PAGE_TRACK_MAX,
88c2ecf20Sopenharmony_ci};
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci/*
118c2ecf20Sopenharmony_ci * The notifier represented by @kvm_page_track_notifier_node is linked into
128c2ecf20Sopenharmony_ci * the head which will be notified when guest is triggering the track event.
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci * Write access on the head is protected by kvm->mmu_lock, read access
158c2ecf20Sopenharmony_ci * is protected by track_srcu.
168c2ecf20Sopenharmony_ci */
178c2ecf20Sopenharmony_cistruct kvm_page_track_notifier_head {
188c2ecf20Sopenharmony_ci	struct srcu_struct track_srcu;
198c2ecf20Sopenharmony_ci	struct hlist_head track_notifier_list;
208c2ecf20Sopenharmony_ci};
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_cistruct kvm_page_track_notifier_node {
238c2ecf20Sopenharmony_ci	struct hlist_node node;
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	/*
268c2ecf20Sopenharmony_ci	 * It is called when guest is writing the write-tracked page
278c2ecf20Sopenharmony_ci	 * and write emulation is finished at that time.
288c2ecf20Sopenharmony_ci	 *
298c2ecf20Sopenharmony_ci	 * @vcpu: the vcpu where the write access happened.
308c2ecf20Sopenharmony_ci	 * @gpa: the physical address written by guest.
318c2ecf20Sopenharmony_ci	 * @new: the data was written to the address.
328c2ecf20Sopenharmony_ci	 * @bytes: the written length.
338c2ecf20Sopenharmony_ci	 * @node: this node
348c2ecf20Sopenharmony_ci	 */
358c2ecf20Sopenharmony_ci	void (*track_write)(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new,
368c2ecf20Sopenharmony_ci			    int bytes, struct kvm_page_track_notifier_node *node);
378c2ecf20Sopenharmony_ci	/*
388c2ecf20Sopenharmony_ci	 * It is called when memory slot is being moved or removed
398c2ecf20Sopenharmony_ci	 * users can drop write-protection for the pages in that memory slot
408c2ecf20Sopenharmony_ci	 *
418c2ecf20Sopenharmony_ci	 * @kvm: the kvm where memory slot being moved or removed
428c2ecf20Sopenharmony_ci	 * @slot: the memory slot being moved or removed
438c2ecf20Sopenharmony_ci	 * @node: this node
448c2ecf20Sopenharmony_ci	 */
458c2ecf20Sopenharmony_ci	void (*track_flush_slot)(struct kvm *kvm, struct kvm_memory_slot *slot,
468c2ecf20Sopenharmony_ci			    struct kvm_page_track_notifier_node *node);
478c2ecf20Sopenharmony_ci};
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ciint kvm_page_track_init(struct kvm *kvm);
508c2ecf20Sopenharmony_civoid kvm_page_track_cleanup(struct kvm *kvm);
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_civoid kvm_page_track_free_memslot(struct kvm_memory_slot *slot);
538c2ecf20Sopenharmony_ciint kvm_page_track_create_memslot(struct kvm_memory_slot *slot,
548c2ecf20Sopenharmony_ci				  unsigned long npages);
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_civoid kvm_slot_page_track_add_page(struct kvm *kvm,
578c2ecf20Sopenharmony_ci				  struct kvm_memory_slot *slot, gfn_t gfn,
588c2ecf20Sopenharmony_ci				  enum kvm_page_track_mode mode);
598c2ecf20Sopenharmony_civoid kvm_slot_page_track_remove_page(struct kvm *kvm,
608c2ecf20Sopenharmony_ci				     struct kvm_memory_slot *slot, gfn_t gfn,
618c2ecf20Sopenharmony_ci				     enum kvm_page_track_mode mode);
628c2ecf20Sopenharmony_cibool kvm_page_track_is_active(struct kvm_vcpu *vcpu, gfn_t gfn,
638c2ecf20Sopenharmony_ci			      enum kvm_page_track_mode mode);
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_civoid
668c2ecf20Sopenharmony_cikvm_page_track_register_notifier(struct kvm *kvm,
678c2ecf20Sopenharmony_ci				 struct kvm_page_track_notifier_node *n);
688c2ecf20Sopenharmony_civoid
698c2ecf20Sopenharmony_cikvm_page_track_unregister_notifier(struct kvm *kvm,
708c2ecf20Sopenharmony_ci				   struct kvm_page_track_notifier_node *n);
718c2ecf20Sopenharmony_civoid kvm_page_track_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new,
728c2ecf20Sopenharmony_ci			  int bytes);
738c2ecf20Sopenharmony_civoid kvm_page_track_flush_slot(struct kvm *kvm, struct kvm_memory_slot *slot);
748c2ecf20Sopenharmony_ci#endif
75