|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] x86/nestedhvm: L2 reads its own CR0 and CR4 bits, not L1's shadow
At virtual VM entry load_shadow_guest_state() records L1's whole CR0 and
CR4 read shadows as what L2 reads. Once L2 changes a bit only L0 owns,
nvmx_set_cr_read_shadow() installs that record, so in the bits L0 masks
and L1 does not, L2's MOV from CR4 returns whatever L1 left in its read
shadow where L1's mask does not select it.
Fixes: ef17e127c411 ("Nested VMX: CR emulation fix up")
Signed-off-by: Mahmoud Abumandour <ma.mandourr@xxxxxxxxx>
---
Found using a VMX isolation fuzzer.
xen/arch/x86/hvm/vmx/vvmx.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c
index 29e48387a1..71cc9dd373 100644
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -1089,8 +1089,12 @@ static void load_shadow_guest_state(struct vcpu *v)
vvmcs_to_shadow_bulk(v, ARRAY_SIZE(vmcs_gstate_field),
vmcs_gstate_field);
- nvcpu->guest_cr[0] = get_vvmcs(v, CR0_READ_SHADOW);
- nvcpu->guest_cr[4] = get_vvmcs(v, CR4_READ_SHADOW);
+ nvcpu->guest_cr[0] =
+ (get_vvmcs(v, GUEST_CR0) & ~get_vvmcs(v, CR0_GUEST_HOST_MASK)) |
+ (get_vvmcs(v, CR0_READ_SHADOW) & get_vvmcs(v, CR0_GUEST_HOST_MASK));
+ nvcpu->guest_cr[4] =
+ (get_vvmcs(v, GUEST_CR4) & ~get_vvmcs(v, CR4_GUEST_HOST_MASK)) |
+ (get_vvmcs(v, CR4_READ_SHADOW) & get_vvmcs(v, CR4_GUEST_HOST_MASK));
rc = hvm_set_cr4(get_vvmcs(v, GUEST_CR4), true);
if ( rc == X86EMUL_EXCEPTION )
--
2.25.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |