Received: by 2002:a25:d7c1:0:0:0:0:0 with SMTP id o184csp4861833ybg; Mon, 21 Oct 2019 15:59:25 -0700 (PDT) X-Google-Smtp-Source: APXvYqxrvF/ktSmydS3UChcdl/Qemr6fVI8fvFNF2cNSCY9OfmQ4+VgbT0LyOWplAF8bGV5DSvUk X-Received: by 2002:a05:6402:3072:: with SMTP id bs18mr9223357edb.120.1571698765204; Mon, 21 Oct 2019 15:59:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1571698765; cv=none; d=google.com; s=arc-20160816; b=d3diBX0HHpRwJF3ctZH5dBI71pasTupJoKonUkppkYB3B8O/IwN+qDBlbiyccjIcw3 ZQM3nTknv/0SoBI+s81VUau6m8Hf03wZtJ+f8qz+Wr4xGmPu4EaMujxxF8JZM+1t8grq drZBS0SOSC9riTqkjbpkMlPjnTZwrDks0OR2PY+4Obn6jzSTb2oJ7ikWPzEvsizlcXXE Q5NsoCWLUApdB2fodaYH4/GxVZoIJGpTf4G9ZCTsW75qvqbEQcAkdl12SB2brCJ4+EqY dxSsdZCytpmBX9qOEmZWwl4ux0hhwYZ5NTIbBjmBuLwwiJzLj+N3lwHoNgequQhhXwhy fEvQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=kyLLtAJdNqy/YK/NyJ9jMG0f8EEZrfYanM7xjBMEpEk=; b=JhwV05JLXyd53JgbeMVsOD+IsHGevaksw+Gbrey31874CVPR3dig6lxPOZSqRxir57 mJ9VtQPoecNEnLhIPRDCYfOnuo+AV0lsZRkndJi+0F7zGmQbGhY+URZlX2pfE6x1WalY Db6Zn7cTgrRNUNnxlnyWTZ+Fo6NWyeeQXzf+cKzySMQ1UEVablXSD/3iWc045qL+ot7w DzdVZp+GaBV+OFA56AuvrwlJOsN1BiZG6bhlr3nEnfCBRkZYHsbcuKGHGk7NsLJWg2wu yPsciNjEdnftGEhFSnxnsCVxSIl+LRsxY3JD6GR0E9uth4vXpmgtHnrFlCXytGsZEI3H nDNg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h23si9917933ejc.1.2019.10.21.15.59.01; Mon, 21 Oct 2019 15:59:25 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730518AbfJUW6o (ORCPT + 99 others); Mon, 21 Oct 2019 18:58:44 -0400 Received: from mga14.intel.com ([192.55.52.115]:50811 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730405AbfJUW6n (ORCPT ); Mon, 21 Oct 2019 18:58:43 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 Oct 2019 15:58:43 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,325,1566889200"; d="scan'208";a="209539352" Received: from sjchrist-coffee.jf.intel.com ([10.54.74.41]) by fmsmga001.fm.intel.com with ESMTP; 21 Oct 2019 15:58:43 -0700 From: Sean Christopherson To: Paul Mackerras , Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] KVM: Add separate helper for putting borrowed reference to kvm Date: Mon, 21 Oct 2019 15:58:42 -0700 Message-Id: <20191021225842.23941-1-sean.j.christopherson@intel.com> X-Mailer: git-send-email 2.22.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add a new helper, kvm_put_kvm_no_destroy(), to handle putting a borrowed reference[*] to the VM when installing a new file descriptor fails. KVM expects the refcount to remain valid in this case, as the in-progress ioctl() has an explicit reference to the VM. The primary motiviation for the helper is to document that the 'kvm' pointer is still valid after putting the borrowed reference, e.g. to document that doing mutex(&kvm->lock) immediately after putting a ref to kvm isn't broken. [*] When exposing a new object to userspace via a file descriptor, e.g. a new vcpu, KVM grabs a reference to itself (the VM) prior to making the object visible to userspace to avoid prematurely freeing the VM in the scenario where userspace immediately closes file descriptor. Signed-off-by: Sean Christopherson --- arch/powerpc/kvm/book3s_64_mmu_hv.c | 2 +- arch/powerpc/kvm/book3s_64_vio.c | 2 +- include/linux/kvm_host.h | 1 + virt/kvm/kvm_main.c | 16 ++++++++++++++-- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 9a75f0e1933b..68678e31c84c 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -2000,7 +2000,7 @@ int kvm_vm_ioctl_get_htab_fd(struct kvm *kvm, struct kvm_get_htab_fd *ghf) ret = anon_inode_getfd("kvm-htab", &kvm_htab_fops, ctx, rwflag | O_CLOEXEC); if (ret < 0) { kfree(ctx); - kvm_put_kvm(kvm); + kvm_put_kvm_no_destroy(kvm); return ret; } diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c index 5834db0a54c6..883a66e76638 100644 --- a/arch/powerpc/kvm/book3s_64_vio.c +++ b/arch/powerpc/kvm/book3s_64_vio.c @@ -317,7 +317,7 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, if (ret >= 0) list_add_rcu(&stt->list, &kvm->arch.spapr_tce_tables); else - kvm_put_kvm(kvm); + kvm_put_kvm_no_destroy(kvm); mutex_unlock(&kvm->lock); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 719fc3e15ea4..90a2102605ef 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -622,6 +622,7 @@ void kvm_exit(void); void kvm_get_kvm(struct kvm *kvm); void kvm_put_kvm(struct kvm *kvm); +void kvm_put_kvm_no_destroy(struct kvm *kvm); static inline struct kvm_memslots *__kvm_memslots(struct kvm *kvm, int as_id) { diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 67ef3f2e19e8..b8534c6b8cf6 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -772,6 +772,18 @@ void kvm_put_kvm(struct kvm *kvm) } EXPORT_SYMBOL_GPL(kvm_put_kvm); +/* + * Used to put a reference that was taken on behalf of an object associated + * with a user-visible file descriptor, e.g. a vcpu or device, if installation + * of the new file descriptor fails and the reference cannot be transferred to + * its final owner. In such cases, the caller is still actively using @kvm and + * will fail miserably if the refcount unexpectedly hits zero. + */ +void kvm_put_kvm_no_destroy(struct kvm *kvm) +{ + WARN_ON(refcount_dec_and_test(&kvm->users_count)); +} +EXPORT_SYMBOL_GPL(kvm_put_kvm_no_destroy); static int kvm_vm_release(struct inode *inode, struct file *filp) { @@ -2679,7 +2691,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id) kvm_get_kvm(kvm); r = create_vcpu_fd(vcpu); if (r < 0) { - kvm_put_kvm(kvm); + kvm_put_kvm_no_destroy(kvm); goto unlock_vcpu_destroy; } @@ -3117,7 +3129,7 @@ static int kvm_ioctl_create_device(struct kvm *kvm, kvm_get_kvm(kvm); ret = anon_inode_getfd(ops->name, &kvm_device_fops, dev, O_RDWR | O_CLOEXEC); if (ret < 0) { - kvm_put_kvm(kvm); + kvm_put_kvm_no_destroy(kvm); mutex_lock(&kvm->lock); list_del(&dev->vm_node); mutex_unlock(&kvm->lock); -- 2.22.0