162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _ASM_X86_KVM_PAGE_TRACK_H 362306a36Sopenharmony_ci#define _ASM_X86_KVM_PAGE_TRACK_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/kvm_types.h> 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#ifdef CONFIG_KVM_EXTERNAL_WRITE_TRACKING 862306a36Sopenharmony_ci/* 962306a36Sopenharmony_ci * The notifier represented by @kvm_page_track_notifier_node is linked into 1062306a36Sopenharmony_ci * the head which will be notified when guest is triggering the track event. 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * Write access on the head is protected by kvm->mmu_lock, read access 1362306a36Sopenharmony_ci * is protected by track_srcu. 1462306a36Sopenharmony_ci */ 1562306a36Sopenharmony_cistruct kvm_page_track_notifier_head { 1662306a36Sopenharmony_ci struct srcu_struct track_srcu; 1762306a36Sopenharmony_ci struct hlist_head track_notifier_list; 1862306a36Sopenharmony_ci}; 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistruct kvm_page_track_notifier_node { 2162306a36Sopenharmony_ci struct hlist_node node; 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci /* 2462306a36Sopenharmony_ci * It is called when guest is writing the write-tracked page 2562306a36Sopenharmony_ci * and write emulation is finished at that time. 2662306a36Sopenharmony_ci * 2762306a36Sopenharmony_ci * @gpa: the physical address written by guest. 2862306a36Sopenharmony_ci * @new: the data was written to the address. 2962306a36Sopenharmony_ci * @bytes: the written length. 3062306a36Sopenharmony_ci * @node: this node 3162306a36Sopenharmony_ci */ 3262306a36Sopenharmony_ci void (*track_write)(gpa_t gpa, const u8 *new, int bytes, 3362306a36Sopenharmony_ci struct kvm_page_track_notifier_node *node); 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci /* 3662306a36Sopenharmony_ci * Invoked when a memory region is removed from the guest. Or in KVM 3762306a36Sopenharmony_ci * terms, when a memslot is deleted. 3862306a36Sopenharmony_ci * 3962306a36Sopenharmony_ci * @gfn: base gfn of the region being removed 4062306a36Sopenharmony_ci * @nr_pages: number of pages in the to-be-removed region 4162306a36Sopenharmony_ci * @node: this node 4262306a36Sopenharmony_ci */ 4362306a36Sopenharmony_ci void (*track_remove_region)(gfn_t gfn, unsigned long nr_pages, 4462306a36Sopenharmony_ci struct kvm_page_track_notifier_node *node); 4562306a36Sopenharmony_ci}; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ciint kvm_page_track_register_notifier(struct kvm *kvm, 4862306a36Sopenharmony_ci struct kvm_page_track_notifier_node *n); 4962306a36Sopenharmony_civoid kvm_page_track_unregister_notifier(struct kvm *kvm, 5062306a36Sopenharmony_ci struct kvm_page_track_notifier_node *n); 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ciint kvm_write_track_add_gfn(struct kvm *kvm, gfn_t gfn); 5362306a36Sopenharmony_ciint kvm_write_track_remove_gfn(struct kvm *kvm, gfn_t gfn); 5462306a36Sopenharmony_ci#else 5562306a36Sopenharmony_ci/* 5662306a36Sopenharmony_ci * Allow defining a node in a structure even if page tracking is disabled, e.g. 5762306a36Sopenharmony_ci * to play nice with testing headers via direct inclusion from the command line. 5862306a36Sopenharmony_ci */ 5962306a36Sopenharmony_cistruct kvm_page_track_notifier_node {}; 6062306a36Sopenharmony_ci#endif /* CONFIG_KVM_EXTERNAL_WRITE_TRACKING */ 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci#endif 63