On Thu, 2018-09-13 at 00:00 +0300, Liran Alon wrote: > 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: 8fcc4b5923af ("kvm: nVMX: Introduce KVM_CAP_NESTED_STATE") > > Reviewed-by: Mark Kanda <mark.kanda@xxxxxxxxxx> > Signed-off-by: Liran Alon <liran.alon@xxxxxxxxxx> Reviewed-by: Patrick Colp <patrick.colp@xxxxxxxxxx> > --- > arch/x86/kvm/x86.c | 21 +++++++++++++-------- > 1 file changed, 13 insertions(+), 8 deletions(-) > > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index 805c1df7c77e..8f3acdae8b14 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -4007,19 +4007,22 @@ long kvm_arch_vcpu_ioctl(struct file *filp, > break; > > BUILD_BUG_ON(sizeof(user_data_size) != > sizeof(user_kvm_nested_state->size)); > + r = -EFAULT; > if (get_user(user_data_size, &user_kvm_nested_state- > >size)) > - return -EFAULT; > + break; > > r = kvm_x86_ops->get_nested_state(vcpu, > user_kvm_nested_state, > user_data_size); > if (r < 0) > - return r; > + break; > > if (r > user_data_size) { > + r = -E2BIG; > if (put_user(r, &user_kvm_nested_state->size)) > - return -EFAULT; > - return -E2BIG; > + r = -EFAULT; > + break; > } > + > r = 0; > break; > } > @@ -4031,19 +4034,21 @@ long kvm_arch_vcpu_ioctl(struct file *filp, > if (!kvm_x86_ops->set_nested_state) > break; > > + r = -EFAULT; > if (copy_from_user(&kvm_state, user_kvm_nested_state, > sizeof(kvm_state))) > - return -EFAULT; > + break; > > + r = -EINVAL; > if (kvm_state.size < sizeof(kvm_state)) > - return -EINVAL; > + break; > > if (kvm_state.flags & > ~(KVM_STATE_NESTED_RUN_PENDING | > KVM_STATE_NESTED_GUEST_MODE)) > - return -EINVAL; > + break; > > /* nested_run_pending implies guest_mode. */ > if (kvm_state.flags == KVM_STATE_NESTED_RUN_PENDING) > - return -EINVAL; > + break; > > r = kvm_x86_ops->set_nested_state(vcpu, > user_kvm_nested_state, &kvm_state); > break;