@@ -2346,6 +2346,8 @@ struct kvm_exported_tdp {
#ifdef __KVM_HAVE_ARCH_EXPORTED_TDP
int kvm_arch_exported_tdp_init(struct kvm *kvm, struct kvm_exported_tdp *tdp);
void kvm_arch_exported_tdp_destroy(struct kvm_exported_tdp *tdp);
+int kvm_arch_fault_exported_tdp(struct kvm_exported_tdp *tdp, unsigned long gfn,
+ struct kvm_tdp_fault_type type);
#else
static inline int kvm_arch_exported_tdp_init(struct kvm *kvm,
struct kvm_exported_tdp *tdp)
@@ -2355,6 +2357,13 @@ static inline int kvm_arch_exported_tdp_init(struct kvm *kvm,
static inline void kvm_arch_exported_tdp_destroy(struct kvm_exported_tdp *tdp)
{
}
+
+static inline int kvm_arch_fault_exported_tdp(struct kvm_exported_tdp *tdp,
+ unsigned long gfn,
+ struct kvm_tdp_fault_type type)
+{
+ return -EOPNOTSUPP;
+}
#endif /* __KVM_HAVE_ARCH_EXPORTED_TDP */
#endif /* CONFIG_HAVE_KVM_EXPORTED_TDP */
@@ -223,7 +223,33 @@ static void *kvm_tdp_get_metadata(struct kvm_tdp_fd *tdp_fd)
static int kvm_tdp_fault(struct kvm_tdp_fd *tdp_fd, struct mm_struct *mm,
unsigned long gfn, struct kvm_tdp_fault_type type)
{
- return -EOPNOTSUPP;
+ bool kthread = current->mm == NULL;
+ int ret = -EINVAL;
+
+ if (!tdp_fd || !tdp_fd->priv || !tdp_fd->priv->kvm)
+ return -EINVAL;
+
+ if (!type.read && !type.write && !type.exec)
+ return -EINVAL;
+
+ if (!mm || tdp_fd->priv->kvm->mm != mm)
+ return -EINVAL;
+
+ if (!mmget_not_zero(mm))
+ return -EPERM;
+
+ if (kthread)
+ kthread_use_mm(mm);
+ else if (current->mm != mm)
+ goto out;
+
+ ret = kvm_arch_fault_exported_tdp(tdp_fd->priv, gfn, type);
+
+ if (kthread)
+ kthread_unuse_mm(mm);
+out:
+ mmput(mm);
+ return ret;
}
static const struct kvm_exported_tdp_ops exported_tdp_ops = {
Implement .fault op of KVM TDP FD object and pass page fault requests from importers of KVM TDP FD to KVM arch specific code. Since the thread for importers to call .fault op is not vCPU thread and could be a kernel thread, thread "mm" is checked and kthread_use_mm() are called when necessary. Signed-off-by: Yan Zhao <yan.y.zhao@intel.com> --- include/linux/kvm_host.h | 9 +++++++++ virt/kvm/tdp_fd.c | 28 +++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-)