Skip to content

Commit 26b471c

Browse files
Liran Alonbonzini
authored andcommitted
KVM: nVMX: Fix bad cleanup on error of get/set nested state IOCTLs
The handlers of IOCTLs in kvm_arch_vcpu_ioctl() are expected to set their return value in "r" local var and break out of switch block when they encounter some error. This is because vcpu_load() is called before the switch block which have a proper cleanup of vcpu_put() afterwards. However, KVM_{GET,SET}_NESTED_STATE IOCTLs handlers just return immediately on error without performing above mentioned cleanup. Thus, change these handlers to behave as expected. Fixes: 8fcc4b5 ("kvm: nVMX: Introduce KVM_CAP_NESTED_STATE") Reviewed-by: Mark Kanda <mark.kanda@oracle.com> Reviewed-by: Patrick Colp <patrick.colp@oracle.com> Signed-off-by: Liran Alon <liran.alon@oracle.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 8b56ee9 commit 26b471c

File tree

1 file changed

+14
-8
lines changed

1 file changed

+14
-8
lines changed

arch/x86/kvm/x86.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4010,19 +4010,23 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
40104010
break;
40114011

40124012
BUILD_BUG_ON(sizeof(user_data_size) != sizeof(user_kvm_nested_state->size));
4013+
r = -EFAULT;
40134014
if (get_user(user_data_size, &user_kvm_nested_state->size))
4014-
return -EFAULT;
4015+
break;
40154016

40164017
r = kvm_x86_ops->get_nested_state(vcpu, user_kvm_nested_state,
40174018
user_data_size);
40184019
if (r < 0)
4019-
return r;
4020+
break;
40204021

40214022
if (r > user_data_size) {
40224023
if (put_user(r, &user_kvm_nested_state->size))
4023-
return -EFAULT;
4024-
return -E2BIG;
4024+
r = -EFAULT;
4025+
else
4026+
r = -E2BIG;
4027+
break;
40254028
}
4029+
40264030
r = 0;
40274031
break;
40284032
}
@@ -4034,19 +4038,21 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
40344038
if (!kvm_x86_ops->set_nested_state)
40354039
break;
40364040

4041+
r = -EFAULT;
40374042
if (copy_from_user(&kvm_state, user_kvm_nested_state, sizeof(kvm_state)))
4038-
return -EFAULT;
4043+
break;
40394044

4045+
r = -EINVAL;
40404046
if (kvm_state.size < sizeof(kvm_state))
4041-
return -EINVAL;
4047+
break;
40424048

40434049
if (kvm_state.flags &
40444050
~(KVM_STATE_NESTED_RUN_PENDING | KVM_STATE_NESTED_GUEST_MODE))
4045-
return -EINVAL;
4051+
break;
40464052

40474053
/* nested_run_pending implies guest_mode. */
40484054
if (kvm_state.flags == KVM_STATE_NESTED_RUN_PENDING)
4049-
return -EINVAL;
4055+
break;
40504056

40514057
r = kvm_x86_ops->set_nested_state(vcpu, user_kvm_nested_state, &kvm_state);
40524058
break;

0 commit comments

Comments
 (0)