Skip to content

Commit b548786

Browse files
committed
KVM: guest_memfd: move check for already-populated page to common code
JIRA: https://issues.redhat.com/browse/RHEL-32435 Do not allow populating the same page twice with startup data. In the case of SEV-SNP, for example, the firmware does not allow it anyway, since the launch-update operation is only possible on pages that are still shared in the RMP. Even if it worked, kvm_gmem_populate()'s callback is meant to have side effects such as updating launch measurements, and updating the same page twice is unlikely to have the desired results. Races between calls to the ioctl are not possible because kvm_gmem_populate() holds slots_lock and the VM should not be running. But again, even if this worked on other confidential computing technology, it doesn't matter to guest_memfd.c whether this is something fishy such as missing synchronization in userspace, or rather something intentional. One of the racers wins, and the page is initialized by either kvm_gmem_prepare_folio() or kvm_gmem_populate(). Anyway, out of paranoia, adjust sev_gmem_post_populate() anyway to use the same errno that kvm_gmem_populate() is using. Reviewed-by: Michael Roth <michael.roth@amd.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> (cherry picked from commit de80252) Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 1edd270 commit b548786

File tree

2 files changed

+8
-1
lines changed

2 files changed

+8
-1
lines changed

arch/x86/kvm/svm/sev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2213,7 +2213,7 @@ static int sev_gmem_post_populate(struct kvm *kvm, gfn_t gfn_start, kvm_pfn_t pf
22132213
if (ret || assigned) {
22142214
pr_debug("%s: Failed to ensure GFN 0x%llx RMP entry is initial shared state, ret: %d assigned: %d\n",
22152215
__func__, gfn, ret, assigned);
2216-
ret = -EINVAL;
2216+
ret = ret ? -EINVAL : -EEXIST;
22172217
goto err;
22182218
}
22192219

virt/kvm/guest_memfd.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,13 @@ long kvm_gmem_populate(struct kvm *kvm, gfn_t start_gfn, void __user *src, long
657657
break;
658658
}
659659

660+
if (folio_test_uptodate(folio)) {
661+
folio_unlock(folio);
662+
folio_put(folio);
663+
ret = -EEXIST;
664+
break;
665+
}
666+
660667
folio_unlock(folio);
661668
if (!IS_ALIGNED(gfn, (1 << max_order)) ||
662669
(npages - i) < (1 << max_order))

0 commit comments

Comments
 (0)