diff mbox series

[gmem] KVM: Relax guest_memfd restrictions on hugepages

Message ID 20231002133342.195882-1-michael.roth@amd.com (mailing list archive)
State New, archived
Headers show
Series [gmem] KVM: Relax guest_memfd restrictions on hugepages | expand

Commit Message

Michael Roth Oct. 2, 2023, 1:33 p.m. UTC
Rather than requiring an entire memslot's gmem binding to be
hugepage-aligned to make use of hugepages, relax the check to simply
ensure that a large folio is completely contained by the range the
memslot is bound to. Otherwise, userspace components like QEMU may
inadvertantly disable the use of hugepages depending on how they handle
splitting up regions of guest memory for legacy regions, ROMs, etc.

Cc: Sean Christopherson <seanjc@google.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 virt/kvm/guest_memfd.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

Comments

Sean Christopherson Oct. 6, 2023, 2:20 a.m. UTC | #1
On Mon, 02 Oct 2023 08:33:42 -0500, Michael Roth wrote:
> Rather than requiring an entire memslot's gmem binding to be
> hugepage-aligned to make use of hugepages, relax the check to simply
> ensure that a large folio is completely contained by the range the
> memslot is bound to. Otherwise, userspace components like QEMU may
> inadvertantly disable the use of hugepages depending on how they handle
> splitting up regions of guest memory for legacy regions, ROMs, etc.
> 
> [...]

Applied to kvm-x86 guest_memfd, thanks!

[1/1] KVM: Relax guest_memfd restrictions on hugepages
      https://github.com/kvm-x86/linux/commit/e7af8d17224a

--
https://github.com/kvm-x86/linux/tree/next
diff mbox series

Patch

diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
index 4d74b66cfbf7..de5d72e21d63 100644
--- a/virt/kvm/guest_memfd.c
+++ b/virt/kvm/guest_memfd.c
@@ -535,6 +535,7 @@  int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot,
 		     gfn_t gfn, kvm_pfn_t *pfn, int *max_order)
 {
 	pgoff_t index = gfn - slot->base_gfn + slot->gmem.pgoff;
+	pgoff_t huge_index;
 	struct kvm_gmem *gmem;
 	struct folio *folio;
 	struct page *page;
@@ -574,13 +575,12 @@  int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot,
 		goto success;
 
 	/*
-	 * For simplicity, allow mapping a hugepage if and only if the entire
-	 * binding is compatible, i.e. don't bother supporting mapping interior
-	 * sub-ranges with hugepages (unless userspace comes up with a *really*
-	 * strong use case for needing hugepages within unaligned bindings).
+	 * Only report the true order of the backing folio if it is fully
+	 * contained by the range this GFN's memslot is bound to.
 	 */
-	if (!IS_ALIGNED(slot->gmem.pgoff, 1ull << *max_order) ||
-	    !IS_ALIGNED(slot->npages, 1ull << *max_order))
+	huge_index = ALIGN(index, 1ull << *max_order);
+	if (huge_index < ALIGN(slot->gmem.pgoff, 1ull << *max_order) ||
+	    huge_index + (1ull << *max_order) > slot->gmem.pgoff + slot->npages)
 		*max_order = 0;
 success:
 	r = 0;