Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: nVMX: sync vmcs02 segment regs prior to vmx_set_cr0

Segment registers must be synchronized prior to any code that may
trigger a call to emulation_required()/guest_state_valid(), e.g.
vmx_set_cr0(). Because preparing vmcs02 writes segmentation fields
directly, i.e. doesn't use vmx_set_segment(), emulation_required
will not be re-evaluated when synchronizing the segment registers,
which can result in L0 incorrectly starting emulation of L2.

Fixes: 8665c3f97320 ("KVM: nVMX: initialize descriptor cache fields in prepare_vmcs02_full")
Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
[Move all of prepare_vmcs02_full earlier, not just segment registers. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

authored by

Sean Christopherson and committed by
Paolo Bonzini
9d1887ef e13c2ac5

+5 -5
+5 -5
arch/x86/kvm/vmx.c
··· 10704 10704 struct vcpu_vmx *vmx = to_vmx(vcpu); 10705 10705 u32 exec_control, vmcs12_exec_ctrl; 10706 10706 10707 + if (vmx->nested.dirty_vmcs12) { 10708 + prepare_vmcs02_full(vcpu, vmcs12, from_vmentry); 10709 + vmx->nested.dirty_vmcs12 = false; 10710 + } 10711 + 10707 10712 /* 10708 10713 * First, the fields that are shadowed. This must be kept in sync 10709 10714 * with vmx_shadow_fields.h. ··· 10945 10940 vcpu->arch.efer &= ~(EFER_LMA | EFER_LME); 10946 10941 /* Note: modifies VM_ENTRY/EXIT_CONTROLS and GUEST/HOST_IA32_EFER */ 10947 10942 vmx_set_efer(vcpu, vcpu->arch.efer); 10948 - 10949 - if (vmx->nested.dirty_vmcs12) { 10950 - prepare_vmcs02_full(vcpu, vmcs12, from_vmentry); 10951 - vmx->nested.dirty_vmcs12 = false; 10952 - } 10953 10943 10954 10944 /* Shadow page tables on either EPT or shadow page tables. */ 10955 10945 if (nested_vmx_load_cr3(vcpu, vmcs12->guest_cr3, nested_cpu_has_ept(vmcs12),