]> git.hungrycats.org Git - linux/commitdiff
KVM: SEV: Drop FOLL_WRITE for encrypted region registration
authorPankaj Gupta <pankaj.gupta@amd.com>
Wed, 15 Jul 2026 06:36:26 +0000 (01:36 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 2 Sep 2026 12:31:48 +0000 (14:31 +0200)
commit ee1a586dd1fa2f245b3b753a3e44d9263a49240b upstream.

When pinning SEV guest memory, drop FOLL_WRITE and rely on FOLL_LONGTERM
to break CoW, as *KVM* doesn't actually to the memory using the GUP'd
pages.  Omitting FOLL_WRITE fixes a regression when using file-backed guest
memory that was introduced when KVM (correctly) added FOLL_LONG (e.g. to
ensure anonymous memory is migrated out of MIGRATE_CMA/ZONE_MOVABLE before
a long term pin).

Unfortunately, as of commits:

  8ac268436e6d ("mm/gup: disallow FOLL_LONGTERM GUP-nonfast writing to file-backed mappings")
  a6e79df92e4a ("mm/gup: disallow FOLL_LONGTERM GUP-fast writing to file-backed mappings")

GUP uses FOLL_LONGTERM as a canary of sorts to detect pins that are likely
to be problematic, and disallows WRITE+LONGTERM pins for file-backed memory.
As a result, backing SEV+ guests with file-backed memory, e.g. virtio-pmem,
fails due to the disallowed FOLL_LONGTERM+FOLL_WRITE combination.

Note, in the past, FOLL_WRITE was required to trigger CoW unsharing, to
prevent replacing the page in the (primary MMU's) page tables during a
later write fault after already having pinned a (shared) page in
MAP_PRIVATE mappings.  FOLL_LONGTERM does that nowadays, even without
FOLL_WRITE (see gup_must_unshare()).

Fixes: 7e066cb9b71a ("KVM: SEV: Use long-term pin when registering encrypted memory regions")
Cc: stable@vger.kernel.org
Suggested-by: "David Hildenbrand (Arm)" <david@kernel.org>
Link: https://lore.kernel.org/all/ad784f05-b36c-4e91-9f17-4c5b826735d0@kernel.org/
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Link: https://patch.msgid.link/20260715063626.65899-1-pankaj.gupta@amd.com
[sean: massage changelog, add comment about CoW unsharing]
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/kvm/svm/sev.c

index e836d082a57804f474b65628f4048bbedbf27e8a..606fad42ee82c756c7b864d48fee10346db0467f 100644 (file)
@@ -2727,8 +2727,12 @@ int sev_mem_enc_register_region(struct kvm *kvm,
        if (!region)
                return -ENOMEM;
 
+       /*
+        * Do NOT specify FOLL_WRITE, as KVM isn't using the pinned pages to
+        * write memory, and FOLL_LONGTERM itself triggers CoW unshare.
+        */
        region->pages = sev_pin_memory(kvm, range->addr, range->size, &region->npages,
-                                      FOLL_WRITE | FOLL_LONGTERM);
+                                      FOLL_LONGTERM);
        if (IS_ERR(region->pages)) {
                ret = PTR_ERR(region->pages);
                goto e_free;