The ioctl populates guest_memfd with userspace-provided data. Signed-off-by: Nikita Kalyazin <kalyazin@xxxxxxxxxx> --- include/linux/kvm_host.h | 3 +++ include/uapi/linux/kvm.h | 9 +++++++++ virt/kvm/guest_memfd.c | 7 +++++++ virt/kvm/kvm_main.c | 10 ++++++++++ 4 files changed, 29 insertions(+) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index db567d26f7b9..5b0347783598 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -2505,6 +2505,9 @@ typedef int (*kvm_gmem_populate_cb)(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, long kvm_gmem_populate(struct kvm *kvm, gfn_t gfn, void __user *src, long npages, kvm_gmem_populate_cb post_populate, void *opaque); + +int kvm_gmem_guest_memfd_populate(struct kvm *kvm, + struct kvm_guest_memfd_populate *populate); #endif #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 637efc055145..5d8073de0d96 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1573,4 +1573,13 @@ struct kvm_pre_fault_memory { __u64 padding[5]; }; +struct kvm_guest_memfd_populate { + __u64 gpa; + __u64 size; + void __user *from; + __u64 flags; +}; + +#define KVM_GUEST_MEMFD_POPULATE _IOW(KVMIO, 0xd6, struct kvm_guest_memfd_populate) + #endif /* __LINUX_KVM_H */ diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 954312fac462..08630b87f0e3 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -720,4 +720,11 @@ long kvm_gmem_populate(struct kvm *kvm, gfn_t start_gfn, void __user *src, long return ret && !i ? ret : i; } EXPORT_SYMBOL_GPL(kvm_gmem_populate); + +int kvm_gmem_guest_memfd_populate(struct kvm *kvm, + struct kvm_guest_memfd_populate *populate) +{ + return kvm_gmem_populate(kvm, populate->gpa >> PAGE_SHIFT, populate->from, + populate->size >> PAGE_SHIFT, kvm_gmem_post_populate_generic, NULL); +} #endif diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 05cbb2548d99..e5bd2c0031bf 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -5383,6 +5383,16 @@ static long kvm_vm_ioctl(struct file *filp, r = kvm_gmem_create(kvm, &guest_memfd); break; } + case KVM_GUEST_MEMFD_POPULATE: { + struct kvm_guest_memfd_populate populate; + + r = -EFAULT; + if (copy_from_user(&populate, argp, sizeof(populate))) + goto out; + + r = kvm_gmem_guest_memfd_populate(kvm, &populate); + break; + } #endif default: r = kvm_arch_vm_ioctl(filp, ioctl, arg); -- 2.40.1