Skip to content

Commit

Permalink
KVM: nVMX: Clear nested_run_pending if setting nested state fails
Browse files Browse the repository at this point in the history
VMX's nested_run_pending flag is subtly consumed when stuffing state to
enter guest mode, i.e. needs to be set according before KVM knows if
setting guest state is successful.  If setting guest state fails, clear
the flag as a nested run is obviously not pending.

Reported-by: Aaron Lewis <aaronlewis@google.com>
Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
Sean Christopherson authored and Paolo Bonzini committed May 24, 2019
1 parent db80927 commit 21be4ca
Showing 1 changed file with 17 additions and 12 deletions.
29 changes: 17 additions & 12 deletions arch/x86/kvm/vmx/nested.c
Original file line number Diff line number Diff line change
Expand Up @@ -5423,39 +5423,44 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu,
if (!(kvm_state->flags & KVM_STATE_NESTED_GUEST_MODE))
return 0;

vmx->nested.nested_run_pending =
!!(kvm_state->flags & KVM_STATE_NESTED_RUN_PENDING);

ret = -EINVAL;
if (nested_cpu_has_shadow_vmcs(vmcs12) &&
vmcs12->vmcs_link_pointer != -1ull) {
struct vmcs12 *shadow_vmcs12 = get_shadow_vmcs12(vcpu);

if (kvm_state->size < sizeof(*kvm_state) + VMCS12_SIZE + sizeof(*vmcs12))
return -EINVAL;
goto error_guest_mode;

if (copy_from_user(shadow_vmcs12,
user_kvm_nested_state->data + VMCS12_SIZE,
sizeof(*vmcs12)))
return -EFAULT;
sizeof(*vmcs12))) {
ret = -EFAULT;
goto error_guest_mode;
}

if (shadow_vmcs12->hdr.revision_id != VMCS12_REVISION ||
!shadow_vmcs12->hdr.shadow_vmcs)
return -EINVAL;
goto error_guest_mode;
}

if (nested_vmx_check_controls(vcpu, vmcs12) ||
nested_vmx_check_host_state(vcpu, vmcs12) ||
nested_vmx_check_guest_state(vcpu, vmcs12, &exit_qual))
return -EINVAL;
goto error_guest_mode;

vmx->nested.dirty_vmcs12 = true;
vmx->nested.nested_run_pending =
!!(kvm_state->flags & KVM_STATE_NESTED_RUN_PENDING);

ret = nested_vmx_enter_non_root_mode(vcpu, false);
if (ret) {
vmx->nested.nested_run_pending = 0;
return -EINVAL;
}
if (ret)
goto error_guest_mode;

return 0;

error_guest_mode:
vmx->nested.nested_run_pending = 0;
return ret;
}

void nested_vmx_vcpu_setup(void)
Expand Down

0 comments on commit 21be4ca

Please sign in to comment.