|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] x86/nSVM: Ignore bits 11:0 of L1's MSRPM base address
VMRUN ignores bits 11:0 of MSRPM_BASE_PA (APM volume 2, 24593 Rev. 3.44,
section 15.11), but nsvm_vmrun_permissionmap() copies L1's MSR permission
map from the address exactly as L1 wrote it. With any of those bits set,
the copy starts at the wrong offset, so both the merged map 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 <stephen.cheng@xxxxxxxxxx>
---
Notes:
To reproduce, in L1: set MSR_PROT, set only FS_BASE's read bit in a
page-aligned MSRPM, point MSRPM_BASE_PA at the map + 0x800, and run L2
doing RDMSR of FS_BASE. L1 should get VMEXIT_MSR; without this patch the
RDMSR completes in L2 instead.
The IOPM base, handled in the same function, doesn't need the same fix:
all of its users convert it to a frame number first.
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);
base-commit: 4e3c0eeac5761c505f8229e82d265eb29957ca5c
--
2.49.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |