All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Leonardo Bras <leonardo@linux.ibm.com>
Cc: "Paul Mackerras" <paulus@ozlabs.org>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Radim Krčmář" <rkrcmar@redhat.com>,
	kvm-ppc@vger.kernel.org, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] KVM: Add separate helper for putting borrowed reference to kvm
Date: Tue, 26 Nov 2019 17:14:16 +0000	[thread overview]
Message-ID: <20191126171416.GA22233@linux.intel.com> (raw)
In-Reply-To: <de313d549a5ae773aad6bbf04c20b395bea7811f.camel@linux.ibm.com>

On Tue, Nov 26, 2019 at 01:44:14PM -0300, Leonardo Bras wrote:
> On Mon, 2019-10-21 at 15:58 -0700, Sean Christopherson wrote:

...

> > 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);
> 
> Hello,
> 
> I see what are you solving here, but would not this behavior cause the
> refcount to reach negative values?
>
> If so, is not there a problem? I mean, in some archs (powerpc included)
> refcount_dec_and_test() will decrement and then test if the value is
> equal 0. If we ever reach a negative value, this will cause that memory
> to never be released. 
>
> An example is that refcount_dec_and_test(), on other archs than x86,
> will call atomic_dec_and_test(), which on include/linux/atomic-
> fallback.h will do:
> 
> return atomic_dec_return(v) = 0;
> 
> To change this behavior, it would mean change the whole atomic_*_test
> behavior, or do a copy function in order to change this '= 0' to 
> '<= 0'. 
> 
> Does it make sense? Do you need any help on this?

I don't think so.  refcount_dec_and_test() will WARN on an underflow when
the kernel is built with CONFIG_REFCOUNT_FULL=y.  I see no value in
duplicating those sanity checks in KVM.

This new helper and WARN is to explicitly catch @users_count unexpectedly
hitting zero, which is orthogonal to an underflow (although odds are good
that a bug that triggers the WARN in kvm_put_kvm_no_destroy() will also
lead to an underflow).  Leaking the memory is deliberate as the alternative
is a guaranteed use-after-free, i.e. kvm_put_kvm_no_destroy() is intended
to be used when users_count is guaranteed to be valid after it is
decremented.

WARNING: multiple messages have this Message-ID (diff)
From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Leonardo Bras <leonardo@linux.ibm.com>
Cc: "Paul Mackerras" <paulus@ozlabs.org>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Radim Krčmář" <rkrcmar@redhat.com>,
	kvm-ppc@vger.kernel.org, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] KVM: Add separate helper for putting borrowed reference to kvm
Date: Tue, 26 Nov 2019 09:14:16 -0800	[thread overview]
Message-ID: <20191126171416.GA22233@linux.intel.com> (raw)
In-Reply-To: <de313d549a5ae773aad6bbf04c20b395bea7811f.camel@linux.ibm.com>

On Tue, Nov 26, 2019 at 01:44:14PM -0300, Leonardo Bras wrote:
> On Mon, 2019-10-21 at 15:58 -0700, Sean Christopherson wrote:

...

> > 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);
> 
> Hello,
> 
> I see what are you solving here, but would not this behavior cause the
> refcount to reach negative values?
>
> If so, is not there a problem? I mean, in some archs (powerpc included)
> refcount_dec_and_test() will decrement and then test if the value is
> equal 0. If we ever reach a negative value, this will cause that memory
> to never be released. 
>
> An example is that refcount_dec_and_test(), on other archs than x86,
> will call atomic_dec_and_test(), which on include/linux/atomic-
> fallback.h will do:
> 
> return atomic_dec_return(v) == 0;
> 
> To change this behavior, it would mean change the whole atomic_*_test
> behavior, or do a copy function in order to change this '== 0' to 
> '<= 0'. 
> 
> Does it make sense? Do you need any help on this?

I don't think so.  refcount_dec_and_test() will WARN on an underflow when
the kernel is built with CONFIG_REFCOUNT_FULL=y.  I see no value in
duplicating those sanity checks in KVM.

This new helper and WARN is to explicitly catch @users_count unexpectedly
hitting zero, which is orthogonal to an underflow (although odds are good
that a bug that triggers the WARN in kvm_put_kvm_no_destroy() will also
lead to an underflow).  Leaking the memory is deliberate as the alternative
is a guaranteed use-after-free, i.e. kvm_put_kvm_no_destroy() is intended
to be used when users_count is guaranteed to be valid after it is
decremented.

  reply	other threads:[~2019-11-26 17:14 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-21 22:58 [PATCH] KVM: Add separate helper for putting borrowed reference to kvm Sean Christopherson
2019-10-21 22:58 ` Sean Christopherson
2019-10-22 13:49 ` Paolo Bonzini
2019-10-22 13:49   ` Paolo Bonzini
2019-11-26 16:44 ` Leonardo Bras
2019-11-26 16:44   ` Leonardo Bras
2019-11-26 17:14   ` Sean Christopherson [this message]
2019-11-26 17:14     ` Sean Christopherson
2019-11-26 17:53     ` Leonardo Bras
2019-11-26 17:53       ` Leonardo Bras
2019-11-27 16:38       ` Paolo Bonzini
2019-11-27 16:38         ` Paolo Bonzini
2019-11-27 18:24         ` Leonardo Bras
2019-11-27 18:24           ` Leonardo Bras
2019-11-27 18:32           ` Paolo Bonzini
2019-11-27 18:32             ` Paolo Bonzini
2019-11-27 19:25             ` Leonardo Bras
2019-11-27 19:25               ` Leonardo Bras
2019-11-27 19:47               ` Sean Christopherson
2019-11-27 19:47                 ` Sean Christopherson
2019-11-27 20:15                 ` Leonardo Bras
2019-11-27 20:15                   ` Leonardo Bras
2019-11-27 21:57                   ` Leonardo Bras
2019-11-27 21:57                     ` Leonardo Bras
2019-11-28  1:00                     ` Sean Christopherson
2019-11-28  1:00                       ` Sean Christopherson
2019-11-28 16:29                       ` Leonardo Bras
2019-11-28 16:29                         ` Leonardo Bras
2019-11-28 13:49                     ` Paolo Bonzini
2019-11-28 13:49                       ` Paolo Bonzini
2019-11-28 16:04                       ` Leonardo Bras
2019-11-28 16:04                         ` Leonardo Bras
2019-11-26 17:57     ` Leonardo Bras
2019-11-26 17:57       ` Leonardo Bras

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191126171416.GA22233@linux.intel.com \
    --to=sean.j.christopherson@intel.com \
    --cc=kvm-ppc@vger.kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=leonardo@linux.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=paulus@ozlabs.org \
    --cc=pbonzini@redhat.com \
    --cc=rkrcmar@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.