mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
KVM: guest_memfd: Always fault from guest_memfd if in-place conversion is enabled
If a guest_memfd memslot is created but the guest_memfd does not have the GUEST_MEMFD_FLAG_MMAP set, KVM still fulfils guest faults by looking up the memslot's userspace_addr. Set KVM_MEMSLOT_GMEM_ONLY if in-place conversion is enabled so that the guest_memfd's memory will be used for both shared and private memory. With in-place conversion, guest_memfd will be the only backing memory for the memslot. No validation is performed to require userspace_addr to be a mapping from the associated guest_memfd because even after validation, userspace is free to remap something else at the provided userspace_addr. userspace_addr will still be used by functions like kvm_read_guest(), and if userspace_addr does not match up with the corresponding memory in the memslot's guest_memfd (whether userspace_addr points to the wrong offset or some non-guest_memfd memory, etc), that is a user error. Requiring both shared and private memory to come from the only associated guest_memfd simplifies invalidation in stage 2 page tables. On a PUNCH_HOLE operation on a guest_memfd, the invalidation is now guaranteed to be invalidating only memory mapped from the given guest_memfd. Suggested-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Ackerley Tng <ackerleytng@google.com> Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev> Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com> Reviewed-by: David Hildenbrand (Arm) <david@kernel.org> Tested-by: Yan Zhao <yan.y.zhao@intel.com> Link: https://patch.msgid.link/20260910-gmem-inplace-conversion-v13-12-dd6fbf94f4e1@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
This commit is contained in:
parent
e088c7f86b
commit
2e646bcfcf
|
|
@ -6381,10 +6381,16 @@ mapping for userspace_addr is not required to be valid/populated at the time of
|
|||
KVM_SET_USER_MEMORY_REGION2, e.g. shared memory can be lazily mapped/allocated
|
||||
on-demand.
|
||||
|
||||
When mapping a gfn into the guest, KVM selects shared vs. private, i.e. consumes
|
||||
userspace_addr vs. guest_memfd, based on the state in guest_memfd, which is the
|
||||
sole authority on private vs. shared memory. See :ref:`KVM_CREATE_GUEST_MEMFD`
|
||||
to find out more about the creation-time shared/private status.
|
||||
When mapping a gfn into the guest, guest faults are always serviced from
|
||||
guest_memfd regardless of whether memory is shared or private. KVM determines
|
||||
shared vs. private based on the state in guest_memfd, which is the sole
|
||||
authority on private vs. shared memory. See :ref:`KVM_CREATE_GUEST_MEMFD` to
|
||||
find out more about the creation-time shared/private status.
|
||||
|
||||
userspace_addr is expected to be the mmap()-ed address corresponding to the
|
||||
right offset within the guest_memfd. Any mismatch between userspace_addr and
|
||||
guest_memfd is not validated and is a user error. userspace_addr is only used
|
||||
for host-side guest accesses such as kvm_read_guest().
|
||||
|
||||
If in-place conversion is disabled, KVM selects shared vs. private based on the
|
||||
gfn's KVM_MEMORY_ATTRIBUTE_PRIVATE state. At VM creation time, all memory is
|
||||
|
|
@ -6490,10 +6496,10 @@ specified via KVM_CREATE_GUEST_MEMFD. Currently defined flags:
|
|||
page tables. Private memory cannot.
|
||||
============================ ================================================
|
||||
|
||||
When the KVM MMU performs a PFN lookup to service a guest fault and the backing
|
||||
guest_memfd has the GUEST_MEMFD_FLAG_MMAP set, then the fault will always be
|
||||
consumed from guest_memfd, regardless of whether it is a shared or a private
|
||||
fault.
|
||||
When the KVM MMU performs a PFN lookup to service a guest fault, the fault will
|
||||
always be consumed from guest_memfd, regardless of whether it is a shared or a
|
||||
private fault (unless in-place conversion is disabled and the backing
|
||||
guest_memfd does not have the GUEST_MEMFD_FLAG_MMAP flag set).
|
||||
|
||||
See KVM_SET_USER_MEMORY_REGION2 for additional details.
|
||||
|
||||
|
|
|
|||
|
|
@ -775,7 +775,7 @@ int kvm_gmem_prepare_memory_region(struct kvm *kvm, struct kvm_memory_slot *slot
|
|||
*/
|
||||
slot->gmem.file = file;
|
||||
slot->gmem.pgoff = offset >> PAGE_SHIFT;
|
||||
if (kvm_gmem_supports_mmap(inode))
|
||||
if (gmem_in_place_conversion || kvm_gmem_supports_mmap(inode))
|
||||
slot->flags |= KVM_MEMSLOT_GMEM_ONLY;
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user