From: Stephen Cheng <stephen.cheng@citrix.com>
To: xen-devel@lists.xenproject.org
Cc: "Ross Lagerwall" <ross.lagerwall@citrix.com>,
"Stephen Cheng" <stephen.cheng@citrix.com>,
"Jan Beulich" <jbeulich@suse.com>,
"Andrew Cooper" <andrew.cooper3@citrix.com>,
"Roger Pau Monné" <roger@xenproject.org>,
"Jason Andryuk" <jason.andryuk@amd.com>,
"Teddy Astie" <teddy.astie@vates.tech>
Subject: [PATCH] x86/nSVM: Don't zero the l1 guest's N_CR3 on #VMEXIT
Date: Mon, 21 Sep 2026 12:31:48 +0800 [thread overview]
Message-ID: <20260921043148.562181-1-stephen.cheng@citrix.com> (raw)
Xen's emulated #VMEXIT writes a VMCB field that a real #VMEXIT leaves alone.
nsvm_vmcb_prepare4vmexit() zeroes ns_vmcb->_h_cr3 when the l1 guest runs its
l2 guest with nested paging off. Hardware writes back guest state and the
exit-information fields (AMD APM vol 2 rev 3.44 section 15.6); N_CR3 is
neither, and section 15.25.4 says so by name: "nCR3 is not saved back into
the VMCB". An l1 guest that sets N_CR3 once and reuses the VMCB finds it
zeroed.
The comment defending it - the guest "is not allowed to set" h_cr3,
"otherwise (security hole!)" - is wrong. ns_vmcb is a live mapping of l1
guest memory, so the guest can write the field again before the next VMRUN.
Drop both assignments and that comment.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Stephen Cheng <stephen.cheng@citrix.com>
---
xen/arch/x86/hvm/svm/nestedsvm.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c
index a8b15d6eae..54c62d1474 100644
--- a/xen/arch/x86/hvm/svm/nestedsvm.c
+++ b/xen/arch/x86/hvm/svm/nestedsvm.c
@@ -1023,7 +1023,10 @@ nsvm_vmcb_prepare4vmexit(struct vcpu *v, struct cpu_user_regs *regs)
ns_vmcb->event_inj.raw = 0;
- /* Nested paging mode */
+ /*
+ * Nested paging mode. ns_vmcb->_h_cr3 is left alone: hardware does not
+ * save N_CR3 back into the VMCB on #VMEXIT.
+ */
if ( nestedhvm_paging_mode_hap(v) )
{
/* host nested paging + guest nested paging. */
@@ -1037,9 +1040,6 @@ nsvm_vmcb_prepare4vmexit(struct vcpu *v, struct cpu_user_regs *regs)
{
/* host nested paging + guest shadow paging. */
vmcb_set_np(ns_vmcb, false);
- /* Throw h_cr3 away. Guest is not allowed to set it or
- * it can break out, otherwise (security hole!) */
- ns_vmcb->_h_cr3 = 0x0;
/* Stop intercepting #PF (already done above
* by restoring cached intercepts). */
ns_vmcb->_cr3 = n2vmcb->_cr3;
@@ -1048,7 +1048,6 @@ nsvm_vmcb_prepare4vmexit(struct vcpu *v, struct cpu_user_regs *regs)
{
/* host shadow paging + guest shadow paging. */
vmcb_set_np(ns_vmcb, false);
- ns_vmcb->_h_cr3 = 0x0;
/* The vmcb->_cr3 is the shadowed cr3. The original
* unshadowed guest cr3 is kept in ns_vmcb->_cr3,
* hence we keep the ns_vmcb->_cr3 value. */
--
2.49.0
next reply other threads:[~2026-09-21 4:32 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-21 4:31 Stephen Cheng [this message]
2026-09-21 5:42 ` [PATCH] x86/nSVM: Don't zero the l1 guest's N_CR3 on #VMEXIT Stephen Cheng
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=20260921043148.562181-1-stephen.cheng@citrix.com \
--to=stephen.cheng@citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=jason.andryuk@amd.com \
--cc=jbeulich@suse.com \
--cc=roger@xenproject.org \
--cc=ross.lagerwall@citrix.com \
--cc=teddy.astie@vates.tech \
--cc=xen-devel@lists.xenproject.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.