summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Christopherson <seanjc@google.com>2026-09-28 08:46:44 -0700
committerPaolo Bonzini <pbonzini@redhat.com>2026-09-28 17:11:49 -0400
commit973ea70393e885e540f714904e51bc6cac80e3d7 (patch)
treec65b2061b7d461b1697a1fe4956c53b25a5c4bfd
parent8abbc76120a74bfba1851bd97528099d715e45c6 (diff)
KVM: SEV: Do cache maintenance on the source VM *before* clearing SEV state
Explicitly flush caches after intra-host migration before clearing "SEV active" on the source VM, as doing cache maintenance afterwards creates a tiny window where memory reclaim could return memory to the host without performing a cache flush, e.g. as pointed out by Sashiko: CPU1 in sev_migrate_from(): src->active = false; CPU2 running concurrent unmap: Since active is false, the automatic cache flush in sev_guest_memory_reclaimed is skipped. The host frees and reallocates the page. CPU1 in sev_migrate_from(): sev_writeback_caches(src_kvm); Executes a hardware cache flush (wbnoinvd), which writes the guest's old dirty ciphertext over the new page owner's data. Fixes: 93de2a6a4b91 ("KVM: SEV: Do cache maintenance on the source VM during intra-host migration") Cc: stable@vger.kernel.org Reported-by: Sashiko Bot <sashiko-bot@kernel.org> Closes: https://lore.kernel.org/all/20260923165304.1662E1F000FF@smtp.kernel.org Signed-off-by: Sean Christopherson <seanjc@google.com> Message-ID: <20260928154644.2559454-3-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/kvm/svm/sev.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index d3a2e6a51efc..0c1ebb16cec6 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -2045,6 +2045,13 @@ static void sev_migrate_from(struct kvm *dst_kvm, struct kvm *src_kvm)
struct kvm_sev_info *mirror;
unsigned long i;
+ /*
+ * Do cache maintenance on the source VM *before* clearing "SEV active",
+ * as memory reclaim flows won't trigger cache maintenance on the VM
+ * once it's no longer an SEV VM.
+ */
+ sev_writeback_caches(src_kvm);
+
dst->active = true;
dst->asid = src->asid;
dst->handle = src->handle;
@@ -2058,12 +2065,6 @@ static void sev_migrate_from(struct kvm *dst_kvm, struct kvm *src_kvm)
src->pages_locked = 0;
src->es_active = false;
- /*
- * Do cache maintenance on the source VM as it is no longer an SEV VM,
- * i.e. memory reclaim flows won't trigger cache maintenance on the VM.
- */
- sev_writeback_caches(src_kvm);
-
list_cut_before(&dst->regions_list, &src->regions_list, &src->regions_list);
mutex_lock(&sev_mirror_lock);