From 8d46c7de2d5294404b8f3e2334b4856a0bd0d29d Mon Sep 17 00:00:00 2001 From: Stephen Cheng Date: Tue, 27 Oct 2026 09:00:49 +0100 Subject: [PATCH] x86/nSVM: Ignore bits 11:0 of MSRPM_BASE_PA in L1's VMCB for L2 VMRUN ignores bits 11:0 of MSRPM_BASE_PA (APM volume 2, 24593 Rev. 3.44, section 15.11 "MSR Intercepts"). On L1's VMRUN of L2, nsvm_vmrun_permissionmap() copies the MSR permission map which L1 set up for L2 from MSRPM_BASE_PA exactly as L1 wrote it. With any of those bits set, the copy starts at the wrong offset, so both the map L0 runs L2 with and the intercept check on #VMEXIT use the wrong bits: L1 can miss intercepts it set or see ones it didn't, and the copy may run into the following page, giving a spurious VMEXIT_INVALID if that isn't RAM. Mask the address before copying. Fixes: 9a779e4fc161 ("Implement SVM specific part for Nested Virtualization") Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Stephen Cheng Reviewed-by: Ross Lagerwall Acked-by: Jan Beulich --- xen/arch/x86/hvm/svm/nestedsvm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c index 2b998e26bc..56d0f0fa4d 100644 --- a/xen/arch/x86/hvm/svm/nestedsvm.c +++ b/xen/arch/x86/hvm/svm/nestedsvm.c @@ -309,8 +309,10 @@ static int nsvm_vmrun_permissionmap(struct vcpu *v) ns_msrpm_ptr = (unsigned long *)svm->ns_cached_msrpm; + /* VMRUN ignores bits 11:0 of MSRPM_BASE_PA. */ ret = hvm_copy_from_guest_phys(svm->ns_cached_msrpm, - ns_vmcb->_msrpm_base_pa, MSRPM_SIZE); + ns_vmcb->_msrpm_base_pa & PAGE_MASK, + MSRPM_SIZE); if ( ret != HVMTRANS_okay ) { gdprintk(XENLOG_ERR, "hvm_copy_from_guest_phys msrpm %u\n", ret);