Skip to content

Commit 3d3a04f

Browse files
Fuad Tabbabonzini
authored andcommitted
KVM: Allow and advertise support for host mmap() on guest_memfd files
Now that all the x86 and arm64 plumbing for mmap() on guest_memfd is in place, allow userspace to set GUEST_MEMFD_FLAG_MMAP and advertise support via a new capability, KVM_CAP_GUEST_MEMFD_MMAP. The availability of this capability is determined per architecture, and its enablement for a specific guest_memfd instance is controlled by the GUEST_MEMFD_FLAG_MMAP flag at creation time. Update the KVM API documentation to detail the KVM_CAP_GUEST_MEMFD_MMAP capability, the associated GUEST_MEMFD_FLAG_MMAP, and provide essential information regarding support for mmap in guest_memfd. Reviewed-by: David Hildenbrand <david@redhat.com> Reviewed-by: Gavin Shan <gshan@redhat.com> Reviewed-by: Shivank Garg <shivankg@amd.com> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com> Signed-off-by: Fuad Tabba <tabba@google.com> Signed-off-by: Sean Christopherson <seanjc@google.com> Message-ID: <20250729225455.670324-22-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 32e200b commit 3d3a04f

4 files changed

Lines changed: 19 additions & 1 deletion

File tree

Documentation/virt/kvm/api.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6414,6 +6414,15 @@ most one mapping per page, i.e. binding multiple memory regions to a single
64146414
guest_memfd range is not allowed (any number of memory regions can be bound to
64156415
a single guest_memfd file, but the bound ranges must not overlap).
64166416

6417+
When the capability KVM_CAP_GUEST_MEMFD_MMAP is supported, the 'flags' field
6418+
supports GUEST_MEMFD_FLAG_MMAP. Setting this flag on guest_memfd creation
6419+
enables mmap() and faulting of guest_memfd memory to host userspace.
6420+
6421+
When the KVM MMU performs a PFN lookup to service a guest fault and the backing
6422+
guest_memfd has the GUEST_MEMFD_FLAG_MMAP set, then the fault will always be
6423+
consumed from guest_memfd, regardless of whether it is a shared or a private
6424+
fault.
6425+
64176426
See KVM_SET_USER_MEMORY_REGION2 for additional details.
64186427

64196428
4.143 KVM_PRE_FAULT_MEMORY

include/uapi/linux/kvm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,7 @@ struct kvm_enable_cap {
962962
#define KVM_CAP_ARM_EL2_E2H0 241
963963
#define KVM_CAP_RISCV_MP_STATE_RESET 242
964964
#define KVM_CAP_ARM_CACHEABLE_PFNMAP_SUPPORTED 243
965+
#define KVM_CAP_GUEST_MEMFD_MMAP 244
965966

966967
struct kvm_irq_routing_irqchip {
967968
__u32 irqchip;
@@ -1598,6 +1599,7 @@ struct kvm_memory_attributes {
15981599
#define KVM_MEMORY_ATTRIBUTE_PRIVATE (1ULL << 3)
15991600

16001601
#define KVM_CREATE_GUEST_MEMFD _IOWR(KVMIO, 0xd4, struct kvm_create_guest_memfd)
1602+
#define GUEST_MEMFD_FLAG_MMAP (1ULL << 0)
16011603

16021604
struct kvm_create_guest_memfd {
16031605
__u64 size;

virt/kvm/guest_memfd.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,9 @@ static pgoff_t kvm_gmem_get_index(struct kvm_memory_slot *slot, gfn_t gfn)
314314

315315
static bool kvm_gmem_supports_mmap(struct inode *inode)
316316
{
317-
return false;
317+
const u64 flags = (u64)inode->i_private;
318+
319+
return flags & GUEST_MEMFD_FLAG_MMAP;
318320
}
319321

320322
static vm_fault_t kvm_gmem_fault_user_mapping(struct vm_fault *vmf)
@@ -522,6 +524,9 @@ int kvm_gmem_create(struct kvm *kvm, struct kvm_create_guest_memfd *args)
522524
u64 flags = args->flags;
523525
u64 valid_flags = 0;
524526

527+
if (kvm_arch_supports_gmem_mmap(kvm))
528+
valid_flags |= GUEST_MEMFD_FLAG_MMAP;
529+
525530
if (flags & ~valid_flags)
526531
return -EINVAL;
527532

virt/kvm/kvm_main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4918,6 +4918,8 @@ static int kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg)
49184918
#ifdef CONFIG_KVM_GUEST_MEMFD
49194919
case KVM_CAP_GUEST_MEMFD:
49204920
return 1;
4921+
case KVM_CAP_GUEST_MEMFD_MMAP:
4922+
return !kvm || kvm_arch_supports_gmem_mmap(kvm);
49214923
#endif
49224924
default:
49234925
break;

0 commit comments

Comments
 (0)