Skip to content

Commit 7e066cb

Browse files
Ge Yangsean-jc
authored andcommitted
KVM: SEV: Use long-term pin when registering encrypted memory regions
When registering an encrypted memory region for SEV-MEM/SEV-ES guests, pin the pages with FOLL_TERM so that the pages are migrated out of MIGRATE_CMA/ZONE_MOVABLE. Failure to do so violates the CMA/MOVABLE mechanisms and can result in fragmentation due to unmovable pages, e.g. can make CMA allocations fail. Signed-off-by: Ge Yang <[email protected]> Reviewed-by: Tom Lendacky <[email protected]> Acked-by: David Hildenbrand <[email protected]> Link: https://lore.kernel.org/r/[email protected] [sean: massage changelog, make @flags an unsigned int] Signed-off-by: Sean Christopherson <[email protected]>
1 parent a613666 commit 7e066cb

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

arch/x86/kvm/svm/sev.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
619619

620620
static struct page **sev_pin_memory(struct kvm *kvm, unsigned long uaddr,
621621
unsigned long ulen, unsigned long *n,
622-
int write)
622+
unsigned int flags)
623623
{
624624
struct kvm_sev_info *sev = to_kvm_sev_info(kvm);
625625
unsigned long npages, size;
@@ -660,7 +660,7 @@ static struct page **sev_pin_memory(struct kvm *kvm, unsigned long uaddr,
660660
return ERR_PTR(-ENOMEM);
661661

662662
/* Pin the user virtual address. */
663-
npinned = pin_user_pages_fast(uaddr, npages, write ? FOLL_WRITE : 0, pages);
663+
npinned = pin_user_pages_fast(uaddr, npages, flags, pages);
664664
if (npinned != npages) {
665665
pr_err("SEV: Failure locking %lu pages.\n", npages);
666666
ret = -ENOMEM;
@@ -745,7 +745,7 @@ static int sev_launch_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp)
745745
vaddr_end = vaddr + size;
746746

747747
/* Lock the user memory. */
748-
inpages = sev_pin_memory(kvm, vaddr, size, &npages, 1);
748+
inpages = sev_pin_memory(kvm, vaddr, size, &npages, FOLL_WRITE);
749749
if (IS_ERR(inpages))
750750
return PTR_ERR(inpages);
751751

@@ -1240,7 +1240,7 @@ static int sev_dbg_crypt(struct kvm *kvm, struct kvm_sev_cmd *argp, bool dec)
12401240
if (IS_ERR(src_p))
12411241
return PTR_ERR(src_p);
12421242

1243-
dst_p = sev_pin_memory(kvm, dst_vaddr & PAGE_MASK, PAGE_SIZE, &n, 1);
1243+
dst_p = sev_pin_memory(kvm, dst_vaddr & PAGE_MASK, PAGE_SIZE, &n, FOLL_WRITE);
12441244
if (IS_ERR(dst_p)) {
12451245
sev_unpin_memory(kvm, src_p, n);
12461246
return PTR_ERR(dst_p);
@@ -1305,7 +1305,7 @@ static int sev_launch_secret(struct kvm *kvm, struct kvm_sev_cmd *argp)
13051305
if (copy_from_user(&params, u64_to_user_ptr(argp->data), sizeof(params)))
13061306
return -EFAULT;
13071307

1308-
pages = sev_pin_memory(kvm, params.guest_uaddr, params.guest_len, &n, 1);
1308+
pages = sev_pin_memory(kvm, params.guest_uaddr, params.guest_len, &n, FOLL_WRITE);
13091309
if (IS_ERR(pages))
13101310
return PTR_ERR(pages);
13111311

@@ -1779,7 +1779,7 @@ static int sev_receive_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp)
17791779

17801780
/* Pin guest memory */
17811781
guest_page = sev_pin_memory(kvm, params.guest_uaddr & PAGE_MASK,
1782-
PAGE_SIZE, &n, 1);
1782+
PAGE_SIZE, &n, FOLL_WRITE);
17831783
if (IS_ERR(guest_page)) {
17841784
ret = PTR_ERR(guest_page);
17851785
goto e_free_trans;
@@ -2675,7 +2675,8 @@ int sev_mem_enc_register_region(struct kvm *kvm,
26752675
return -ENOMEM;
26762676

26772677
mutex_lock(&kvm->lock);
2678-
region->pages = sev_pin_memory(kvm, range->addr, range->size, &region->npages, 1);
2678+
region->pages = sev_pin_memory(kvm, range->addr, range->size, &region->npages,
2679+
FOLL_WRITE | FOLL_LONGTERM);
26792680
if (IS_ERR(region->pages)) {
26802681
ret = PTR_ERR(region->pages);
26812682
mutex_unlock(&kvm->lock);

0 commit comments

Comments
 (0)