if (KVM_BUG_ON(!kvm_page_track_write_tracking_enabled(kvm), kvm)) return;
update_gfn_write_track(slot, gfn, -1);
/* * allow large page mapping for the tracked page * after the tracker is gone.
*/
kvm_mmu_gfn_allow_lpage(slot, gfn);
}
/* * check if the corresponding access on the specified guest page is tracked.
*/ bool kvm_gfn_is_write_tracked(struct kvm *kvm, conststruct kvm_memory_slot *slot, gfn_t gfn)
{ int index;
if (!slot) returnfalse;
if (!kvm_page_track_write_tracking_enabled(kvm)) returnfalse;
index = gfn_to_index(gfn, slot->base_gfn, PG_LEVEL_4K); return !!READ_ONCE(slot->arch.gfn_write_track[index]);
}
head = &kvm->arch.track_notifier_head;
cleanup_srcu_struct(&head->track_srcu);
}
int kvm_page_track_init(struct kvm *kvm)
{ struct kvm_page_track_notifier_head *head;
head = &kvm->arch.track_notifier_head;
INIT_HLIST_HEAD(&head->track_notifier_list); return init_srcu_struct(&head->track_srcu);
}
staticint kvm_enable_external_write_tracking(struct kvm *kvm)
{ struct kvm_memslots *slots; struct kvm_memory_slot *slot; int r = 0, i, bkt;
if (kvm->arch.vm_type == KVM_X86_TDX_VM) return -EOPNOTSUPP;
mutex_lock(&kvm->slots_arch_lock);
/* * Check for *any* write tracking user (not just external users) under * lock. This avoids unnecessary work, e.g. if KVM itself is using * write tracking, or if two external users raced when registering.
*/ if (kvm_page_track_write_tracking_enabled(kvm)) goto out_success;
for (i = 0; i < kvm_arch_nr_memslot_as_ids(kvm); i++) {
slots = __kvm_memslots(kvm, i);
kvm_for_each_memslot(slot, bkt, slots) { /* * Intentionally do NOT free allocations on failure to * avoid having to track which allocations were made * now versus when the memslot was created. The * metadata is guaranteed to be freed when the slot is * freed, and will be kept/used if userspace retries * the failed ioctl() instead of killing the VM.
*/
r = kvm_page_track_write_tracking_alloc(slot); if (r) goto out_unlock;
}
}
out_success: /* * Ensure that external_write_tracking_enabled becomes true strictly * after all the related pointers are set.
*/
smp_store_release(&kvm->arch.external_write_tracking_enabled, true);
out_unlock:
mutex_unlock(&kvm->slots_arch_lock); return r;
}
/* * register the notifier so that event interception for the tracked guest * pages can be received.
*/ int kvm_page_track_register_notifier(struct kvm *kvm, struct kvm_page_track_notifier_node *n)
{ struct kvm_page_track_notifier_head *head; int r;
if (!kvm || kvm->mm != current->mm) return -ESRCH;
if (!kvm_external_write_tracking_enabled(kvm)) {
r = kvm_enable_external_write_tracking(kvm); if (r) return r;
}
/* * Notify the node that write access is intercepted and write emulation is * finished at this time. * * The node should figure out if the written page is the one that node is * interested in by itself.
*/ void __kvm_page_track_write(struct kvm *kvm, gpa_t gpa, const u8 *new, int bytes)
{ struct kvm_page_track_notifier_head *head; struct kvm_page_track_notifier_node *n; int idx;
head = &kvm->arch.track_notifier_head;
if (hlist_empty(&head->track_notifier_list)) return;
/* * Notify external page track nodes that a memory region is being removed from * the VM, e.g. so that users can free any associated metadata.
*/ void kvm_page_track_delete_slot(struct kvm *kvm, struct kvm_memory_slot *slot)
{ struct kvm_page_track_notifier_head *head; struct kvm_page_track_notifier_node *n; int idx;
head = &kvm->arch.track_notifier_head;
if (hlist_empty(&head->track_notifier_list)) return;
/* * add guest page to the tracking pool so that corresponding access on that * page will be intercepted. * * @kvm: the guest instance we are interested in. * @gfn: the guest page.
*/ int kvm_write_track_add_gfn(struct kvm *kvm, gfn_t gfn)
{ struct kvm_memory_slot *slot; int idx;
/* * remove the guest page from the tracking pool which stops the interception * of corresponding access on that page. * * @kvm: the guest instance we are interested in. * @gfn: the guest page.
*/ int kvm_write_track_remove_gfn(struct kvm *kvm, gfn_t gfn)
{ struct kvm_memory_slot *slot; int idx;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.