Query guest_memfd for private/shared status if those guest_memfds track private/shared status. With this patch, Coco VMs can use guest_memfd for both shared and private memory. If Coco VMs choose to use guest_memfd for both shared and private memory, by creating guest_memfd with the GUEST_MEMFD_FLAG_SUPPORT_SHARED flag, guest_memfd will be used to provide the private/shared status of the memory, instead of kvm->mem_attr_array. Change-Id: I8f23d7995c12242aa4e09ccf5ec19360e9c9ed83 Signed-off-by: Ackerley Tng <ackerleytng@xxxxxxxxxx> --- include/linux/kvm_host.h | 19 ++++++++++++------- virt/kvm/guest_memfd.c | 22 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index b317392453a5..91279e05e010 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -2508,12 +2508,22 @@ static inline void kvm_prepare_memory_fault_exit(struct kvm_vcpu *vcpu, } #ifdef CONFIG_KVM_GMEM_SHARED_MEM + bool kvm_gmem_memslot_supports_shared(const struct kvm_memory_slot *slot); +bool kvm_gmem_is_private(struct kvm_memory_slot *slot, gfn_t gfn); + #else + static inline bool kvm_gmem_memslot_supports_shared(const struct kvm_memory_slot *slot) { return false; } + +static inline bool kvm_gmem_is_private(struct kvm_memory_slot *slot, gfn_t gfn) +{ + return false; +} + #endif /* CONFIG_KVM_GMEM_SHARED_MEM */ #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES @@ -2544,13 +2554,8 @@ static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn) return false; slot = gfn_to_memslot(kvm, gfn); - if (kvm_slot_has_gmem(slot) && kvm_gmem_memslot_supports_shared(slot)) { - /* - * For now, memslots only support in-place shared memory if the - * host is allowed to mmap memory (i.e., non-Coco VMs). - */ - return false; - } + if (kvm_slot_has_gmem(slot) && kvm_gmem_memslot_supports_shared(slot)) + return kvm_gmem_is_private(slot, gfn); return kvm_get_memory_attributes(kvm, gfn) & KVM_MEMORY_ATTRIBUTE_PRIVATE; } diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 6f6c4d298f8f..853e989bdcb2 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -865,6 +865,28 @@ bool kvm_gmem_memslot_supports_shared(const struct kvm_memory_slot *slot) } EXPORT_SYMBOL_GPL(kvm_gmem_memslot_supports_shared); +bool kvm_gmem_is_private(struct kvm_memory_slot *slot, gfn_t gfn) +{ + struct inode *inode; + struct file *file; + pgoff_t index; + bool ret; + + file = kvm_gmem_get_file(slot); + if (!file) + return false; + + index = kvm_gmem_get_index(slot, gfn); + inode = file_inode(file); + + filemap_invalidate_lock_shared(inode->i_mapping); + ret = kvm_gmem_shareability_get(inode, index) == SHAREABILITY_GUEST; + filemap_invalidate_unlock_shared(inode->i_mapping); + + fput(file); + return ret; +} + #else #define kvm_gmem_mmap NULL #endif /* CONFIG_KVM_GMEM_SHARED_MEM */ -- 2.49.0.1045.g170613ef41-goog