1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
221ebbedaSXiao Guangrong #ifndef _ASM_X86_KVM_PAGE_TRACK_H
321ebbedaSXiao Guangrong #define _ASM_X86_KVM_PAGE_TRACK_H
421ebbedaSXiao Guangrong 
558ea7cf7SSean Christopherson #include <linux/kvm_types.h>
658ea7cf7SSean Christopherson 
7e998fb1aSSean Christopherson #ifdef CONFIG_KVM_EXTERNAL_WRITE_TRACKING
80eb05bf2SXiao Guangrong /*
90eb05bf2SXiao Guangrong  * The notifier represented by @kvm_page_track_notifier_node is linked into
100eb05bf2SXiao Guangrong  * the head which will be notified when guest is triggering the track event.
110eb05bf2SXiao Guangrong  *
120eb05bf2SXiao Guangrong  * Write access on the head is protected by kvm->mmu_lock, read access
130eb05bf2SXiao Guangrong  * is protected by track_srcu.
140eb05bf2SXiao Guangrong  */
150eb05bf2SXiao Guangrong struct kvm_page_track_notifier_head {
160eb05bf2SXiao Guangrong 	struct srcu_struct track_srcu;
170eb05bf2SXiao Guangrong 	struct hlist_head track_notifier_list;
180eb05bf2SXiao Guangrong };
190eb05bf2SXiao Guangrong 
200eb05bf2SXiao Guangrong struct kvm_page_track_notifier_node {
210eb05bf2SXiao Guangrong 	struct hlist_node node;
220eb05bf2SXiao Guangrong 
230eb05bf2SXiao Guangrong 	/*
240eb05bf2SXiao Guangrong 	 * It is called when guest is writing the write-tracked page
250eb05bf2SXiao Guangrong 	 * and write emulation is finished at that time.
260eb05bf2SXiao Guangrong 	 *
270eb05bf2SXiao Guangrong 	 * @gpa: the physical address written by guest.
280eb05bf2SXiao Guangrong 	 * @new: the data was written to the address.
290eb05bf2SXiao Guangrong 	 * @bytes: the written length.
30d126363dSJike Song 	 * @node: this node
310eb05bf2SXiao Guangrong 	 */
32b271e17dSSean Christopherson 	void (*track_write)(gpa_t gpa, const u8 *new, int bytes,
33b271e17dSSean Christopherson 			    struct kvm_page_track_notifier_node *node);
34b83ab124SYan Zhao 
35b83ab124SYan Zhao 	/*
36b83ab124SYan Zhao 	 * Invoked when a memory region is removed from the guest.  Or in KVM
37b83ab124SYan Zhao 	 * terms, when a memslot is deleted.
38b83ab124SYan Zhao 	 *
39b83ab124SYan Zhao 	 * @gfn:       base gfn of the region being removed
40b83ab124SYan Zhao 	 * @nr_pages:  number of pages in the to-be-removed region
41b83ab124SYan Zhao 	 * @node:      this node
42b83ab124SYan Zhao 	 */
43b83ab124SYan Zhao 	void (*track_remove_region)(gfn_t gfn, unsigned long nr_pages,
44b83ab124SYan Zhao 				    struct kvm_page_track_notifier_node *node);
450eb05bf2SXiao Guangrong };
460eb05bf2SXiao Guangrong 
47*f22b1e85SSean Christopherson int kvm_page_track_register_notifier(struct kvm *kvm,
480eb05bf2SXiao Guangrong 				     struct kvm_page_track_notifier_node *n);
49*f22b1e85SSean Christopherson void kvm_page_track_unregister_notifier(struct kvm *kvm,
500eb05bf2SXiao Guangrong 					struct kvm_page_track_notifier_node *n);
51*f22b1e85SSean Christopherson 
5296316a06SSean Christopherson int kvm_write_track_add_gfn(struct kvm *kvm, gfn_t gfn);
5396316a06SSean Christopherson int kvm_write_track_remove_gfn(struct kvm *kvm, gfn_t gfn);
54e998fb1aSSean Christopherson #else
55e998fb1aSSean Christopherson /*
56e998fb1aSSean Christopherson  * Allow defining a node in a structure even if page tracking is disabled, e.g.
57e998fb1aSSean Christopherson  * to play nice with testing headers via direct inclusion from the command line.
58e998fb1aSSean Christopherson  */
59e998fb1aSSean Christopherson struct kvm_page_track_notifier_node {};
60e998fb1aSSean Christopherson #endif /* CONFIG_KVM_EXTERNAL_WRITE_TRACKING */
61c70934e0SSean Christopherson 
6221ebbedaSXiao Guangrong #endif
63