diff options
author | Sean Christopherson <sean.j.christopherson@intel.com> | 2018-03-05 12:33:27 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2018-03-23 13:26:21 -0400 |
commit | 9d1887ef3252a45f4e692525d04e23ce8091c17c (patch) | |
tree | 82d2700fa857f56446dc28d5e9d0746818b25cd6 | |
parent | e13c2ac512373d7b108ca534249b76e0da1e3334 (diff) |
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>
-rw-r--r-- | arch/x86/kvm/vmx.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 051dab74e4e9..f0fd50ba284c 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -10704,6 +10704,11 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, | |||
10704 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 10704 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
10705 | u32 exec_control, vmcs12_exec_ctrl; | 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 | * First, the fields that are shadowed. This must be kept in sync | 10713 | * First, the fields that are shadowed. This must be kept in sync |
10709 | * with vmx_shadow_fields.h. | 10714 | * with vmx_shadow_fields.h. |
@@ -10941,11 +10946,6 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, | |||
10941 | /* Note: modifies VM_ENTRY/EXIT_CONTROLS and GUEST/HOST_IA32_EFER */ | 10946 | /* Note: modifies VM_ENTRY/EXIT_CONTROLS and GUEST/HOST_IA32_EFER */ |
10942 | vmx_set_efer(vcpu, vcpu->arch.efer); | 10947 | vmx_set_efer(vcpu, vcpu->arch.efer); |
10943 | 10948 | ||
10944 | if (vmx->nested.dirty_vmcs12) { | ||
10945 | prepare_vmcs02_full(vcpu, vmcs12, from_vmentry); | ||
10946 | vmx->nested.dirty_vmcs12 = false; | ||
10947 | } | ||
10948 | |||
10949 | /* Shadow page tables on either EPT or shadow page tables. */ | 10949 | /* Shadow page tables on either EPT or shadow page tables. */ |
10950 | if (nested_vmx_load_cr3(vcpu, vmcs12->guest_cr3, nested_cpu_has_ept(vmcs12), | 10950 | if (nested_vmx_load_cr3(vcpu, vmcs12->guest_cr3, nested_cpu_has_ept(vmcs12), |
10951 | entry_failure_code)) | 10951 | entry_failure_code)) |