David Hildenbrand <david@xxxxxxxxxx> writes: > On 30.04.25 18:56, 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. >> >> This patch introduces the configuration option KVM_GMEM_SHARED_MEM, >> which enables support for in-place shared memory. >> >> It also introduces the KVM capability KVM_CAP_GMEM_SHARED_MEM, which >> indicates that the host can create VMs that support shared memory. >> Supporting shared memory implies that memory can be mapped when shared >> with the host. >> >> Signed-off-by: Fuad Tabba <tabba@xxxxxxxxxx> >> --- >> include/linux/kvm_host.h | 15 ++++++- >> include/uapi/linux/kvm.h | 1 + >> virt/kvm/Kconfig | 5 +++ >> virt/kvm/guest_memfd.c | 92 ++++++++++++++++++++++++++++++++++++++++ >> virt/kvm/kvm_main.c | 4 ++ >> 5 files changed, 116 insertions(+), 1 deletion(-) >> >> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h >> index 9419fb99f7c2..f3af6bff3232 100644 >> --- a/include/linux/kvm_host.h >> +++ b/include/linux/kvm_host.h >> @@ -729,6 +729,17 @@ static inline bool kvm_arch_supports_gmem(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_GMEM_SHARED_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) >> { >> @@ -2516,7 +2527,9 @@ static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn) >> >> static inline bool kvm_mem_from_gmem(struct kvm *kvm, gfn_t gfn) >> { >> - /* For now, only private memory gets consumed from guest_memfd. */ >> + if (kvm_arch_gmem_supports_shared_mem(kvm)) >> + return true; > > After our discussion yesterday, am I correct that we will not be > querying the KVM capability, but instead the "SHARED_TRACKING" (or > however that flag is called) on the underlying guest_memfd instead? > > I assume the function would then look something like > > if (!kvm_supports_gmem(kvm)) > return false; > if (kvm_arch_gmem_supports_shared_mem(kvm)) > return .. TBD, test the gmem flag for the slot via gfn > return kvm_mem_is_private(kvm, gfn); > Yes, I believe we're aligned here. I added a patch that will do this, but it depends on other parts of the patch series and I think it's better if you review it altogether when Fuad posts it (as opposed to reviewing a snippet I drop here. >> + >> return kvm_mem_is_private(kvm, gfn); >> } >> >> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h >> index b6ae8ad8934b..8bc8046c7f3a 100644 >> --- a/include/uapi/linux/kvm.h >> +++ b/include/uapi/linux/kvm.h >> @@ -930,6 +930,7 @@ struct kvm_enable_cap { >> #define KVM_CAP_X86_APIC_BUS_CYCLES_NS 237 >> #define KVM_CAP_X86_GUEST_MODE 238 >> #define KVM_CAP_ARM_WRITABLE_IMP_ID_REGS 239 >> +#define KVM_CAP_GMEM_SHARED_MEM 240 >> >> struct kvm_irq_routing_irqchip { >> __u32 irqchip; >> diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig >> index 559c93ad90be..f4e469a62a60 100644 >> --- a/virt/kvm/Kconfig >> +++ b/virt/kvm/Kconfig >> @@ -128,3 +128,8 @@ config HAVE_KVM_ARCH_GMEM_PREPARE >> config HAVE_KVM_ARCH_GMEM_INVALIDATE >> bool >> depends on KVM_GMEM >> + >> +config KVM_GMEM_SHARED_MEM >> + select KVM_GMEM >> + bool >> + prompt "Enables in-place shared memory for guest_memfd" >> diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c >> index 6db515833f61..8bc8fc991d58 100644 >> --- a/virt/kvm/guest_memfd.c >> +++ b/virt/kvm/guest_memfd.c >> @@ -312,7 +312,99 @@ 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 >> +/* >> + * Returns true if the folio is shared with the host and the guest. >> + */ >> +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); > > Similar here: likely we want to check the guest_memfd flag. > > -- > Cheers, > > David / dhildenb