mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Kevin Loughlin <kevinloughlin@google.com>
To: linux-kernel@vger.kernel.org
Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
	 dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com,
	seanjc@google.com,  pbonzini@redhat.com,
	kevinloughlin@google.com,  kirill.shutemov@linux.intel.com,
	kai.huang@intel.com, ubizjak@gmail.com,  dave.jiang@intel.com,
	jgross@suse.com, kvm@vger.kernel.org,  thomas.lendacky@amd.com,
	pgonda@google.com, sidtelang@google.com,  mizhang@google.com,
	rientjes@google.com, szy0127@sjtu.edu.cn
Subject: [PATCH v2 2/2] KVM: SEV: Prefer WBNOINVD over WBINVD for cache maintenance efficiency
Date: Thu,  9 Jan 2025 22:55:33 +0000	[thread overview]
Message-ID: <20250109225533.1841097-3-kevinloughlin@google.com> (raw)
In-Reply-To: <20250109225533.1841097-1-kevinloughlin@google.com>

AMD CPUs currently execute WBINVD in the host when unregistering SEV
guest memory or when deactivating SEV guests. Such cache maintenance is
performed to prevent data corruption, wherein the encrypted (C=1)
version of a dirty cache line might otherwise only be written back
after the memory is written in a different context (ex: C=0), yielding
corruption. However, WBINVD is performance-costly, especially because
it invalidates processor caches.

Strictly-speaking, unless the SEV ASID is being recycled (meaning all
existing cache lines with the recycled ASID must be flushed), the
cache invalidation triggered by WBINVD is unnecessary; only the
writeback is needed to prevent data corruption in remaining scenarios.

To improve performance in these scenarios, use WBNOINVD when available
instead of WBINVD. WBNOINVD still writes back all dirty lines
(preventing host data corruption by SEV guests) but does *not*
invalidate processor caches.

Signed-off-by: Kevin Loughlin <kevinloughlin@google.com>
---
 arch/x86/kvm/svm/sev.c | 35 ++++++++++++++++++++++-------------
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index fe6cc763fd51..a413b2299d30 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -116,6 +116,7 @@ static int sev_flush_asids(unsigned int min_asid, unsigned int max_asid)
 	 */
 	down_write(&sev_deactivate_lock);
 
+	/* Use WBINVD for ASID recycling. */
 	wbinvd_on_all_cpus();
 
 	if (sev_snp_enabled)
@@ -710,6 +711,14 @@ static void sev_clflush_pages(struct page *pages[], unsigned long npages)
 	}
 }
 
+static void sev_wb_on_all_cpus(void)
+{
+	if (boot_cpu_has(X86_FEATURE_WBNOINVD))
+		wbnoinvd_on_all_cpus();
+	else
+		wbinvd_on_all_cpus();
+}
+
 static unsigned long get_num_contig_pages(unsigned long idx,
 				struct page **inpages, unsigned long npages)
 {
@@ -2774,11 +2783,11 @@ int sev_mem_enc_unregister_region(struct kvm *kvm,
 	}
 
 	/*
-	 * Ensure that all guest tagged cache entries are flushed before
-	 * releasing the pages back to the system for use. CLFLUSH will
-	 * not do this, so issue a WBINVD.
+	 * Ensure that all dirty guest tagged cache entries are written back
+	 * before releasing the pages back to the system for use. CLFLUSH will
+	 * not do this without SME_COHERENT, so issue a WB[NO]INVD.
 	 */
-	wbinvd_on_all_cpus();
+	sev_wb_on_all_cpus();
 
 	__unregister_enc_region_locked(kvm, region);
 
@@ -2900,11 +2909,11 @@ void sev_vm_destroy(struct kvm *kvm)
 	}
 
 	/*
-	 * Ensure that all guest tagged cache entries are flushed before
-	 * releasing the pages back to the system for use. CLFLUSH will
-	 * not do this, so issue a WBINVD.
+	 * Ensure that all dirty guest tagged cache entries are written back
+	 * before releasing the pages back to the system for use. CLFLUSH will
+	 * not do this without SME_COHERENT, so issue a WB[NO]INVD.
 	 */
-	wbinvd_on_all_cpus();
+	sev_wb_on_all_cpus();
 
 	/*
 	 * if userspace was terminated before unregistering the memory regions
@@ -3130,12 +3139,12 @@ static void sev_flush_encrypted_page(struct kvm_vcpu *vcpu, void *va)
 	 * by leaving stale encrypted data in the cache.
 	 */
 	if (WARN_ON_ONCE(wrmsrl_safe(MSR_AMD64_VM_PAGE_FLUSH, addr | asid)))
-		goto do_wbinvd;
+		goto do_wb_on_all_cpus;
 
 	return;
 
-do_wbinvd:
-	wbinvd_on_all_cpus();
+do_wb_on_all_cpus:
+	sev_wb_on_all_cpus();
 }
 
 void sev_guest_memory_reclaimed(struct kvm *kvm)
@@ -3149,7 +3158,7 @@ void sev_guest_memory_reclaimed(struct kvm *kvm)
 	if (!sev_guest(kvm) || sev_snp_guest(kvm))
 		return;
 
-	wbinvd_on_all_cpus();
+	sev_wb_on_all_cpus();
 }
 
 void sev_free_vcpu(struct kvm_vcpu *vcpu)
@@ -3858,7 +3867,7 @@ static int __sev_snp_update_protected_guest_state(struct kvm_vcpu *vcpu)
 		 * guest-mapped page rather than the initial one allocated
 		 * by KVM in svm->sev_es.vmsa. In theory, svm->sev_es.vmsa
 		 * could be free'd and cleaned up here, but that involves
-		 * cleanups like wbinvd_on_all_cpus() which would ideally
+		 * cleanups like sev_wb_on_all_cpus() which would ideally
 		 * be handled during teardown rather than guest boot.
 		 * Deferring that also allows the existing logic for SEV-ES
 		 * VMSAs to be re-used with minimal SNP-specific changes.
-- 
2.47.1.688.g23fc6f90ad-goog


  parent reply	other threads:[~2025-01-09 22:56 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-09 22:55 [PATCH v2 0/2] " Kevin Loughlin
2025-01-09 22:55 ` [PATCH v2 1/2] x86, lib: Add WBNOINVD helper functions Kevin Loughlin
2025-01-09 22:55 ` Kevin Loughlin [this message]
2025-01-10  8:23   ` [PATCH v2 2/2] KVM: SEV: Prefer WBNOINVD over WBINVD for cache maintenance efficiency Kirill A. Shutemov
2025-01-13 18:47     ` Kevin Loughlin
2025-01-14  7:50       ` Kirill A. Shutemov
2025-01-14 16:12         ` Sean Christopherson
2025-01-17 22:20           ` Kevin Loughlin
2025-01-13 21:46   ` Mingwei Zhang
2025-01-22  0:13 ` [PATCH v3 0/2] " Kevin Loughlin
2025-01-22  0:13   ` [PATCH v3 1/2] x86, lib: Add WBNOINVD helper functions Kevin Loughlin
2025-01-22  0:30     ` Dave Hansen
2025-01-22  0:30       ` Dave Hansen
2025-01-22  1:14       ` Kevin Loughlin
2025-01-22  0:13   ` [PATCH v3 2/2] KVM: SEV: Prefer WBNOINVD over WBINVD for cache maintenance efficiency Kevin Loughlin
2025-01-22  1:34   ` [PATCH v4 0/2] " Kevin Loughlin
2025-01-22  1:34     ` [PATCH v4 1/2] x86, lib: Add WBNOINVD helper functions Kevin Loughlin
2025-01-22  7:32       ` Kirill A. Shutemov
2025-01-22 19:39         ` Tom Lendacky
2025-01-22 23:16           ` Dave Hansen
2025-01-23  0:06             ` Kevin Loughlin
2025-01-23  0:33               ` Dave Hansen
2025-01-23  0:58                 ` Kevin Loughlin
2025-01-23  1:17                   ` Kevin Loughlin
2025-01-22  1:34     ` [PATCH v4 2/2] KVM: SEV: Prefer WBNOINVD over WBINVD for cache maintenance efficiency Kevin Loughlin
2025-01-23  0:24     ` [PATCH v5 0/2] " Kevin Loughlin
2025-01-23  0:24       ` [PATCH v5 1/2] x86, lib: Add WBNOINVD helper functions Kevin Loughlin
2025-01-23  0:36         ` Dave Hansen
2025-01-23  0:55           ` Kevin Loughlin
2025-01-23  0:24       ` [PATCH v5 2/2] KVM: SEV: Prefer WBNOINVD over WBINVD for cache maintenance efficiency Kevin Loughlin
2025-02-26  1:30         ` Sean Christopherson
2025-02-01  0:02       ` [PATCH v6 0/2] " Kevin Loughlin
2025-02-01  0:02         ` [PATCH v6 1/2] x86, lib: Add WBNOINVD helper functions Kevin Loughlin
2025-02-04 16:59           ` Tom Lendacky
2025-02-26  1:26           ` Sean Christopherson
2025-02-26 14:22             ` Borislav Petkov
2025-02-01  0:02         ` [PATCH v6 2/2] KVM: SEV: Prefer WBNOINVD over WBINVD for cache maintenance efficiency Kevin Loughlin
2025-02-04 17:00           ` Tom Lendacky
2025-02-26  1:35       ` [PATCH v5 0/2] " Sean Christopherson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250109225533.1841097-3-kevinloughlin@google.com \
    --to=kevinloughlin@google.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=dave.jiang@intel.com \
    --cc=hpa@zytor.com \
    --cc=jgross@suse.com \
    --cc=kai.huang@intel.com \
    --cc=kirill.shutemov@linux.intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=mizhang@google.com \
    --cc=pbonzini@redhat.com \
    --cc=pgonda@google.com \
    --cc=rientjes@google.com \
    --cc=seanjc@google.com \
    --cc=sidtelang@google.com \
    --cc=szy0127@sjtu.edu.cn \
    --cc=tglx@linutronix.de \
    --cc=thomas.lendacky@amd.com \
    --cc=ubizjak@gmail.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®