• Paolo Bonzini's avatar
    KVM: guest_memfd: delay kvm_gmem_prepare_folio() until the memory is passed to the guest · b8552431
    Paolo Bonzini authored
    Initializing the contents of the folio on fallocate() is unnecessarily
    restrictive.  It means that the page is registered with the firmware and
    then it cannot be touched anymore.  In particular, this loses the
    possibility of using fallocate() to pre-allocate the page for SEV-SNP
    guests, because kvm_arch_gmem_prepare() then fails.
    
    It's only when the guest actually accesses the page (and therefore
    kvm_gmem_get_pfn() is called) that the page must be cleared from any
    stale host data and registered with the firmware.  The up-to-date flag
    is clear if this has to be done (i.e. it is the first access and
    kvm_gmem_populate() has not been called).
    
    All in all, there are enough differences between kvm_gmem_get_pfn() and
    kvm_gmem_populate(), that it's better to separate the two flows completely.
    Extract the bulk of kvm_gmem_get_folio(), which take a folio and end up
    setting its up-to-date flag, to a new function kvm_gmem_prepare_folio();
    these are now done only by the non-__-prefixed kvm_gmem_get_pfn().
    As a bonus, __kvm_gmem_get_pfn() loses its ugly "bool prepare" argument.
    
    One difference is that fallocate(PUNCH_HOLE) can now race with a
    page fault.  Potentially this causes a page to be prepared and into the
    filemap even after fallocate(PUNCH_HOLE).  This is harmless, as it can be
    fixed by another hole punching operation, and can be avoided by clearing
    the private-page attribute prior to invoking fallocate(PUNCH_HOLE).
    This way, the page fault will cause an exit to user space.
    
    The previous semantics, where fallocate() could be used to prepare
    the pages in advance of running the guest, can be accessed with
    KVM_PRE_FAULT_MEMORY.
    
    For now, accessing a page in one VM will attempt to call
    kvm_arch_gmem_prepare() in all of those that have bound the guest_memfd.
    Cleaning this up is left to a separate patch.
    Suggested-by: default avatarSean Christopherson <seanjc@google.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    b8552431
guest_memfd.c 16.6 KB