Hi Kirill, On Tue, 4 Mar 2025 at 08:58, Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> wrote: > > On Mon, Mar 03, 2025 at 05:10:07PM +0000, Fuad Tabba wrote: > > Add support for mmap() and fault() for guest_memfd backed memory > > in the host for VMs that support in-place conversion between > > shared and private. To that end, this patch adds the ability to > > check whether the VM type supports in-place conversion, and only > > allows mapping its memory if that's the case. > > > > Also add the KVM capability KVM_CAP_GMEM_SHARED_MEM, which > > indicates that the VM supports shared memory in guest_memfd, or > > that the host can create VMs that support shared memory. > > Supporting shared memory implies that memory can be mapped when > > shared with the host. > > > > This is controlled by the KVM_GMEM_SHARED_MEM configuration > > option. > > > > Signed-off-by: Fuad Tabba <tabba@xxxxxxxxxx> > > --- > > include/linux/kvm_host.h | 11 ++++ > > include/uapi/linux/kvm.h | 1 + > > virt/kvm/guest_memfd.c | 105 +++++++++++++++++++++++++++++++++++++++ > > virt/kvm/kvm_main.c | 4 ++ > > 4 files changed, 121 insertions(+) > > > > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h > > index 7788e3625f6d..2d025b8ee20e 100644 > > --- a/include/linux/kvm_host.h > > +++ b/include/linux/kvm_host.h > > @@ -728,6 +728,17 @@ static inline bool kvm_arch_has_private_mem(struct kvm *kvm) > > } > > #endif > > > > +/* > > + * Arch code must define kvm_arch_gmem_supports_shared_mem if support for > > + * private memory is enabled and it supports in-place shared/private conversion. > > + */ > > +#if !defined(kvm_arch_gmem_supports_shared_mem) && !IS_ENABLED(CONFIG_KVM_PRIVATE_MEM) > > Hm. Do we expect any caller for !CONFIG_KVM_PRIVATE_MEM? > > > +static inline bool kvm_arch_gmem_supports_shared_mem(struct kvm *kvm) > > +{ > > + return false; > > +} > > +#endif > > + > > #ifndef kvm_arch_has_readonly_mem > > static inline bool kvm_arch_has_readonly_mem(struct kvm *kvm) > > { > > ... > > > diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c > > index b2aa6bf24d3a..4291956b51ae 100644 > > --- a/virt/kvm/guest_memfd.c > > +++ b/virt/kvm/guest_memfd.c > > @@ -312,7 +312,112 @@ static pgoff_t kvm_gmem_get_index(struct kvm_memory_slot *slot, gfn_t gfn) > > return gfn - slot->base_gfn + slot->gmem.pgoff; > > } > > > > +#ifdef CONFIG_KVM_GMEM_SHARED_MEM > > +static bool kvm_gmem_offset_is_shared(struct file *file, pgoff_t index) > > +{ > > + struct kvm_gmem *gmem = file->private_data; > > + > > + /* For now, VMs that support shared memory share all their memory. */ > > + return kvm_arch_gmem_supports_shared_mem(gmem->kvm); > > +} > > + > > +static vm_fault_t kvm_gmem_fault(struct vm_fault *vmf) > > +{ > > + struct inode *inode = file_inode(vmf->vma->vm_file); > > + struct folio *folio; > > + vm_fault_t ret = VM_FAULT_LOCKED; > > + > > + filemap_invalidate_lock_shared(inode->i_mapping); > > + > > + folio = kvm_gmem_get_folio(inode, vmf->pgoff); > > + if (IS_ERR(folio)) { > > + switch (PTR_ERR(folio)) { > > + case -EAGAIN: > > + ret = VM_FAULT_RETRY; > > + break; > > + case -ENOMEM: > > + ret = VM_FAULT_OOM; > > + break; > > + default: > > + ret = VM_FAULT_SIGBUS; > > + break; > > + } > > + goto out_filemap; > > + } > > + > > + if (folio_test_hwpoison(folio)) { > > + ret = VM_FAULT_HWPOISON; > > + goto out_folio; > > + } > > + > > + /* Must be called with folio lock held, i.e., after kvm_gmem_get_folio() */ > > If this is a requirement, it would be cleaner to rename the function and > pass down the folio and check the lock state inside. Will do. Thanks, /fuad > -- > Kiryl Shutsemau / Kirill A. Shutemov