diff mbox series

[RFC,08/42] KVM: Add a helper to notify importers that KVM exported TDP is flushed

Message ID 20231202091850.13890-1-yan.y.zhao@intel.com (mailing list archive)
State New, archived
Headers show
Series Sharing KVM TDP to IOMMU | expand

Commit Message

Yan Zhao Dec. 2, 2023, 9:18 a.m. UTC
Introduce a helper in KVM TDP FD to notify importers that TDP page tables
are invalidated. This helper will be called by arch code (e.g. VMX specific
code).

Currently, the helper will notify all importers of all KVM exported TDPs.

Signed-off-by: Yan Zhao <yan.y.zhao@intel.com>
---
 include/linux/kvm_host.h |  3 +++
 virt/kvm/tdp_fd.c        | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)
diff mbox series

Patch

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index b76919eec9b72..a8af95194767f 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -2366,5 +2366,8 @@  static inline int kvm_arch_fault_exported_tdp(struct kvm_exported_tdp *tdp,
 }
 #endif /* __KVM_HAVE_ARCH_EXPORTED_TDP */
 
+void kvm_tdp_fd_flush_notify(struct kvm *kvm, unsigned long gfn, unsigned long npages);
+
 #endif /* CONFIG_HAVE_KVM_EXPORTED_TDP */
+
 #endif
diff --git a/virt/kvm/tdp_fd.c b/virt/kvm/tdp_fd.c
index 02c9066391ebe..8c16af685a061 100644
--- a/virt/kvm/tdp_fd.c
+++ b/virt/kvm/tdp_fd.c
@@ -304,3 +304,41 @@  void kvm_tdp_fd_put(struct kvm_tdp_fd *tdp_fd)
 	fput(tdp_fd->file);
 }
 EXPORT_SYMBOL_GPL(kvm_tdp_fd_put);
+
+static void kvm_tdp_fd_flush(struct kvm_exported_tdp *tdp, unsigned long gfn,
+			     unsigned long npages)
+{
+#define INVALID_NPAGES (-1UL)
+	bool all = (gfn == 0) && (npages == INVALID_NPAGES);
+	struct kvm_tdp_importer *importer;
+	unsigned long start, size;
+
+	if (all) {
+		start = 0;
+		size = -1UL;
+	} else {
+		start = gfn << PAGE_SHIFT;
+		size = npages << PAGE_SHIFT;
+	}
+
+	spin_lock(&tdp->importer_lock);
+
+	list_for_each_entry(importer, &tdp->importers, node) {
+		if (!importer->ops->invalidate)
+			continue;
+
+		importer->ops->invalidate(importer->data, start, size);
+	}
+	spin_unlock(&tdp->importer_lock);
+}
+
+void kvm_tdp_fd_flush_notify(struct kvm *kvm, unsigned long gfn, unsigned long npages)
+{
+	struct kvm_exported_tdp *tdp;
+
+	spin_lock(&kvm->exported_tdplist_lock);
+	list_for_each_entry(tdp, &kvm->exported_tdp_list, list_node)
+		kvm_tdp_fd_flush(tdp, gfn, npages);
+	spin_unlock(&kvm->exported_tdplist_lock);
+}
+EXPORT_SYMBOL_GPL(kvm_tdp_fd_flush_notify);