From b5fadd35f8c2bc6a456d7669b295587910b59b85 Mon Sep 17 00:00:00 2001 From: Lin Liu Date: Wed, 30 Sep 2026 08:49:03 +0200 Subject: [PATCH] x86/nSVM: Save L2's CR0, CR4 and EFER on #VMEXIT, not Xen's nsvm_vmcb_prepare4vmexit() copies CR0, CR4 and EFER out of the shadow VMCB, but Xen does not run L2 with L2's own values: svm_update_guest_cr() ORs in HVM_CR4_HOST_MASK and, under shadow paging, CR0.PG|WP, and svm_update_guest_efer() forces EFER.SVME. Hardware writes back what L2 ran with, so L1 reads Xen's bits back as L2's. Save the shadowed values instead. CR4 leaks CR4.MCE under HAP. EFER is observable on a VMRUN rejected for SVME=0: L1 gets back a VMCB with the bit it deliberately cleared. CR0 is a no-op today, since nested virt requires HAP, and is changed for consistency. Fixes: 9a779e4fc161 ("Implement SVM specific part for Nested Virtualization") Assisted-by: Claude:claude-opus-5 Signed-off-by: Lin Liu Acked-by: Jan Beulich --- xen/arch/x86/hvm/svm/nestedsvm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c index 81579370b8..2e3b70345b 100644 --- a/xen/arch/x86/hvm/svm/nestedsvm.c +++ b/xen/arch/x86/hvm/svm/nestedsvm.c @@ -1079,11 +1079,11 @@ nsvm_vmcb_prepare4vmexit(struct vcpu *v, struct cpu_user_regs *regs) ns_vmcb->_cpl = n2vmcb->_cpl; /* EFER */ - ns_vmcb->_efer = n2vmcb->_efer; + ns_vmcb->_efer = v->arch.hvm.guest_efer; /* CRn */ - ns_vmcb->_cr4 = n2vmcb->_cr4; - ns_vmcb->_cr0 = n2vmcb->_cr0; + ns_vmcb->_cr4 = v->arch.hvm.guest_cr[4]; + ns_vmcb->_cr0 = v->arch.hvm.guest_cr[0]; /* DRn */ ns_vmcb->_dr7 = n2vmcb->_dr7;