From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jan Kiszka Subject: [PATCH] KVM: Clean up error handling during VCPU creation Date: Sun, 17 Apr 2011 13:01:02 +0200 Message-ID: <4DAAC86E.1060904@web.de> References: <4DA4E128.8070401@web.de> <4DAAAFD4.3030900@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Cc: Marcelo Tosatti , kvm To: Avi Kivity Return-path: Received: from fmmailgate02.web.de ([217.72.192.227]:58759 "EHLO fmmailgate02.web.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752490Ab1DQLBM (ORCPT ); Sun, 17 Apr 2011 07:01:12 -0400 In-Reply-To: <4DAAAFD4.3030900@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: On 2011-04-17 11:16, Avi Kivity wrote: > On 04/13/2011 02:32 AM, Jan Kiszka wrote: >> From: Jan Kiszka >> >> If kvm_arch_vcpu_setup failed, we leaked the allocated VCPU structure so >> far. > >> @@ -1609,18 +1609,18 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm >> *kvm, u32 id) >> >> r = kvm_arch_vcpu_setup(vcpu); >> if (r) >> - return r; >> + goto vcpu_destroy; >> > > kvm_arch_vcpu_setup() (at least x86's) does a vcpu->free() on failure. > I think the current code is correct (if confusing). Right. How about cleaning this inconsistency up? It looks like there is no problem calling kvm_arch_vcpu_destroy even if kvm_arch_vcpu_setup bailed out early. Jan ------8<------ From: Jan Kiszka So far kvm_arch_vcpu_setup is responsible for freeing the vcpu struct if it fails. Move this confusing resonsibility back into the hands of kvm_vm_ioctl_create_vcpu. Only kvm_arch_vcpu_setup of x86 is affected, all other archs cannot fail. Signed-off-by: Jan Kiszka --- arch/x86/kvm/x86.c | 5 ----- virt/kvm/kvm_main.c | 11 ++++++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 1d5a7f4..9826d5d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -6002,12 +6002,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) if (r == 0) r = kvm_mmu_setup(vcpu); vcpu_put(vcpu); - if (r < 0) - goto free_vcpu; - return 0; -free_vcpu: - kvm_x86_ops->vcpu_free(vcpu); return r; } diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 5814645..57b173c 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1609,18 +1609,18 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id) r = kvm_arch_vcpu_setup(vcpu); if (r) - return r; + goto vcpu_destroy; mutex_lock(&kvm->lock); if (atomic_read(&kvm->online_vcpus) == KVM_MAX_VCPUS) { r = -EINVAL; - goto vcpu_destroy; + goto unlock_vcpu_destroy; } kvm_for_each_vcpu(r, v, kvm) if (v->vcpu_id == id) { r = -EEXIST; - goto vcpu_destroy; + goto unlock_vcpu_destroy; } BUG_ON(kvm->vcpus[atomic_read(&kvm->online_vcpus)]); @@ -1630,7 +1630,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id) r = create_vcpu_fd(vcpu); if (r < 0) { kvm_put_kvm(kvm); - goto vcpu_destroy; + goto unlock_vcpu_destroy; } kvm->vcpus[atomic_read(&kvm->online_vcpus)] = vcpu; @@ -1644,8 +1644,9 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id) mutex_unlock(&kvm->lock); return r; -vcpu_destroy: +unlock_vcpu_destroy: mutex_unlock(&kvm->lock); +vcpu_destroy: kvm_arch_vcpu_destroy(vcpu); return r; } -- 1.7.1