From: Ashish Kalra <Ashish.Kalra@amd.com>
To: <tglx@kernel.org>, <mingo@redhat.com>, <bp@alien8.de>,
<dave.hansen@linux.intel.com>, <x86@kernel.org>, <hpa@zytor.com>,
<seanjc@google.com>, <peterz@infradead.org>,
<thomas.lendacky@amd.com>, <herbert@gondor.apana.org.au>,
<davem@davemloft.net>, <ardb@kernel.org>
Cc: <pbonzini@redhat.com>, <aik@amd.com>, <Michael.Roth@amd.com>,
<KPrateek.Nayak@amd.com>, <Tycho.Andersen@amd.com>,
<Nathan.Fontenot@amd.com>, <ackerleytng@google.com>,
<jackyli@google.com>, <pgonda@google.com>, <rientjes@google.com>,
<jacobhxu@google.com>, <xin@zytor.com>,
<pawan.kumar.gupta@linux.intel.com>, <babu.moger@amd.com>,
<dyoung@redhat.com>, <nikunj@amd.com>, <darwi@linutronix.de>,
<linux-kernel@vger.kernel.org>, <linux-crypto@vger.kernel.org>,
<kvm@vger.kernel.org>, <linux-coco@lists.linux.dev>
Subject: [PATCH v13 5/5] x86/sev: Re-enable RMP optimizations on SNP guest shutdown
Date: Wed, 2 Sep 2026 21:29:21 +0000 [thread overview]
Message-ID: <e8a8d0ec63bda2db61cde7cf298a4ccb6a502c20.1788296083.git.ashish.kalra@amd.com> (raw)
In-Reply-To: <cover.1788296083.git.ashish.kalra@amd.com>
From: Ashish Kalra <ashish.kalra@amd.com>
The RMPOPT table is a per-CPU table which indicates whether 1GB regions
of physical memory are entirely hypervisor-owned.
When performing host memory accesses in hypervisor mode as well as
non-SNP guest mode, the processor may consult the RMPOPT table to
potentially skip an RMP access and improve performance.
Normal guest events disable RMP optimizations: pages are converted from
shared to private as SNP guests are launched, and large pages are split
and collapsed during guest operation -- both disable the RMPOPT
optimizations for the affected 1GB regions.
When guests are torn down, their pages are converted back to shared, so
those regions may become eligible for RMPOPT optimization again. Without
some intervention, all RMP optimizations would eventually be lost, so
re-optimize all of physical memory on SNP guest teardown.
Perform the re-optimization after a delay, using mod_delayed_work() so
that the delay timer is reset on each call. This batches multiple guest
terminations into a single pass: the re-optimization runs 10 seconds
after the *last* termination rather than after the first.
mod_delayed_work() also re-queues work that is already in-flight, so a
re-scan request during an active scan is not silently dropped.
Guest teardown is currently the only event that returns guest memory to
hypervisor ownership: SNP guests do not support ballooning or memory
hotplug, so pages freed during a guest's lifetime remain guest-owned.
It is therefore the only point at which memory becomes eligible for RMP
re-optimization, which is why re-optimization is driven by guest
teardown rather than by a periodic scan.
Reviewed-by: Ackerley Tng <ackerleytng@google.com>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
---
arch/x86/include/asm/sev.h | 2 ++
arch/x86/kvm/svm/sev.c | 10 ++++++++++
arch/x86/virt/svm/sev.c | 27 +++++++++++++++++++++++++++
3 files changed, 39 insertions(+)
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index 5638d09b5132..3235e171647d 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -662,6 +662,7 @@ static inline void snp_leak_pages(u64 pfn, unsigned int pages)
__snp_leak_pages(pfn, pages, true);
}
int snp_prepare(void);
+void snp_rmpopt_all_physmem(void);
void snp_setup_rmpopt(void);
void snp_shutdown(void);
#else
@@ -681,6 +682,7 @@ static inline void snp_leak_pages(u64 pfn, unsigned int npages) {}
static inline void kdump_sev_callback(void) { }
static inline void snp_fixup_e820_tables(void) {}
static inline int snp_prepare(void) { return -ENODEV; }
+static inline void snp_rmpopt_all_physmem(void) {}
static inline void snp_setup_rmpopt(void) {}
static inline void snp_shutdown(void) {}
#endif
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 5705723f1f41..0babf96e38c6 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -3032,6 +3032,16 @@ void sev_vm_destroy(struct kvm *kvm)
*/
if (snp_decommission_context(kvm))
return;
+
+ /*
+ * Perform RMP optimizations on memory freed by terminating
+ * guests. The scan is deferred, so it normally runs after
+ * sev_gmem_invalidate() has converted this guest's pages back to
+ * shared, and picks them up then. A very large guest whose
+ * conversion has not finished by then is picked up by a later
+ * teardown's scan.
+ */
+ snp_rmpopt_all_physmem();
} else {
sev_unbind_asid(kvm, sev->handle);
}
diff --git a/arch/x86/virt/svm/sev.c b/arch/x86/virt/svm/sev.c
index a4c0fe49b9ec..fb66a1aa6fc3 100644
--- a/arch/x86/virt/svm/sev.c
+++ b/arch/x86/virt/svm/sev.c
@@ -659,6 +659,33 @@ static void do_rmpopt_work(struct work_struct *work)
on_each_cpu_mask(cpu_primary_thread_mask, rmpopt_scan_range, NULL, true);
}
+/*
+ * Delay, in milliseconds, before the RMP re-optimization pass runs after an
+ * SNP guest is torn down. snp_rmpopt_all_physmem() re-arms the delayed work
+ * with mod_delayed_work() on each teardown, so the pass fires this long after
+ * the last teardown. This coalesces a burst of teardowns into a single scan
+ * and gives each guest's pages time to be converted back to the shared,
+ * hypervisor-owned state before the scan re-optimizes their 1GB regions. The
+ * 10 second value is a heuristic trading re-optimization latency against
+ * scanning too eagerly.
+ */
+#define RMPOPT_WORK_TIMEOUT (10 * MSEC_PER_SEC)
+
+void snp_rmpopt_all_physmem(void)
+{
+ if (!rmpopt_capable())
+ return;
+
+ guard(mutex)(&rmpopt_wq_mutex);
+
+ if (!rmpopt_wq)
+ return;
+
+ mod_delayed_work(rmpopt_wq, &rmpopt_delayed_work,
+ msecs_to_jiffies(RMPOPT_WORK_TIMEOUT));
+}
+EXPORT_SYMBOL_FOR_MODULES(snp_rmpopt_all_physmem, "kvm-amd");
+
void snp_setup_rmpopt(void)
{
u64 rmpopt_base;
--
2.43.0
next prev parent reply other threads:[~2026-09-02 21:29 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-02 21:27 [PATCH v13 0/5] Add RMPOPT support Ashish Kalra
2026-09-02 21:27 ` [PATCH v13 1/5] x86/cpufeatures: Add X86_FEATURE_RMPOPT feature flag Ashish Kalra
2026-09-02 21:28 ` [PATCH v13 2/5] x86/sev: Disable CPU hotplug while SNP is active Ashish Kalra
2026-09-02 21:28 ` [PATCH v13 3/5] x86/sev: Initialize RMPOPT configuration MSRs Ashish Kalra
2026-09-02 21:28 ` [PATCH v13 4/5] x86/sev: Add support to perform RMP optimizations asynchronously Ashish Kalra
2026-09-02 21:36 ` Dave Hansen
2026-09-05 1:29 ` Borislav Petkov
2026-09-08 20:21 ` Kalra, Ashish
2026-09-09 1:52 ` Borislav Petkov
2026-09-09 13:55 ` Kalra, Ashish
2026-09-02 21:29 ` Ashish Kalra [this message]
2026-09-02 21:37 ` [PATCH v13 5/5] x86/sev: Re-enable RMP optimizations on SNP guest shutdown Dave Hansen
2026-09-06 17:24 ` Borislav Petkov
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=e8a8d0ec63bda2db61cde7cf298a4ccb6a502c20.1788296083.git.ashish.kalra@amd.com \
--to=ashish.kalra@amd.com \
--cc=KPrateek.Nayak@amd.com \
--cc=Michael.Roth@amd.com \
--cc=Nathan.Fontenot@amd.com \
--cc=Tycho.Andersen@amd.com \
--cc=ackerleytng@google.com \
--cc=aik@amd.com \
--cc=ardb@kernel.org \
--cc=babu.moger@amd.com \
--cc=bp@alien8.de \
--cc=darwi@linutronix.de \
--cc=dave.hansen@linux.intel.com \
--cc=davem@davemloft.net \
--cc=dyoung@redhat.com \
--cc=herbert@gondor.apana.org.au \
--cc=hpa@zytor.com \
--cc=jackyli@google.com \
--cc=jacobhxu@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-coco@lists.linux.dev \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=nikunj@amd.com \
--cc=pawan.kumar.gupta@linux.intel.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=pgonda@google.com \
--cc=rientjes@google.com \
--cc=seanjc@google.com \
--cc=tglx@kernel.org \
--cc=thomas.lendacky@amd.com \
--cc=x86@kernel.org \
--cc=xin@zytor.com \
/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