Re: [PATCH] KVM: SEV: Pin SEV guest memory out of CMA area

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 10.01.25 09:48, yangge1116@xxxxxxx wrote:
From: yangge <yangge1116@xxxxxxx>

I would suggest the title to be something like

"KVM: SEV: fix wrong pinning of pages"

Then you can describe that without FOLL_LONGTERM, the pages will not get migrated out of MIGRATE_CMA/ZONE_MOVABLE, violating these mechanisms to avoid fragmentation with unmovable pages, for example making CMA allocations fail.

(CMA allocations failing is only one symptom of the missed usage of FOLL_LONGTERM)


When pin_user_pages_fast() pins SEV guest memory without the
FOLL_LONGTERM flag, the pinned pages may inadvertently end up in the
CMA (Contiguous Memory Allocator) area. This can subsequently cause
cma_alloc() to fail in allocating these pages, due to the fact that
the pinned pages are not migratable.

To address the aforementioned problem, we propose adding the
FOLL_LONGTERM flag to the pin_user_pages_fast() function. By doing
so, we ensure that the pages allocated will not occupy space within
the CMA area, thereby preventing potential allocation failures.

Signed-off-by: yangge <yangge1116@xxxxxxx>
---
  arch/x86/kvm/svm/sev.c | 5 ++++-
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 943bd07..35d0714 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -630,6 +630,7 @@ static struct page **sev_pin_memory(struct kvm *kvm, unsigned long uaddr,
  	unsigned long locked, lock_limit;
  	struct page **pages;
  	unsigned long first, last;
+	unsigned int flags = 0;

Why not set

unsigned int flags = FOLL_LONGTERM;

  	int ret;
lockdep_assert_held(&kvm->lock);
@@ -662,8 +663,10 @@ static struct page **sev_pin_memory(struct kvm *kvm, unsigned long uaddr,
  	if (!pages)
  		return ERR_PTR(-ENOMEM);
+ flags = write ? FOLL_WRITE : 0;


and here do

flags |= write ? FOLL_WRITE : 0;

+
  	/* Pin the user virtual address. */
-	npinned = pin_user_pages_fast(uaddr, npages, write ? FOLL_WRITE : 0, pages);
+	npinned = pin_user_pages_fast(uaddr, npages, flags | FOLL_LONGTERM, pages);
  	if (npinned != npages) {
  		pr_err("SEV: Failure locking %lu pages.\n", npages);
  		ret = -ENOMEM;


--
Cheers,

David / dhildenb





[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux