All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Gunthorpe <jgg@nvidia.com>
To: Alex Williamson <alex.williamson@redhat.com>
Cc: Cornelia Huck <cohuck@redhat.com>,
	kvm@vger.kernel.org, Max Gurtovoy <mgurtovoy@nvidia.com>,
	Yishai Hadas <yishaih@nvidia.com>
Subject: Re: [PATCH] vfio/pci: Fix vf_token mechanism when device-specific VF drivers are used
Date: Fri, 8 Apr 2022 14:08:39 -0300	[thread overview]
Message-ID: <20220408170839.GA2120790@nvidia.com> (raw)
In-Reply-To: <20220408105305.1ee00b44.alex.williamson@redhat.com>

On Fri, Apr 08, 2022 at 10:53:05AM -0600, Alex Williamson wrote:
> On Fri,  8 Apr 2022 12:10:15 -0300
> Jason Gunthorpe <jgg@nvidia.com> wrote:
> 
> > get_pf_vdev() tries to check if a PF is a VFIO PF by looking at the driver:
> > 
> >        if (pci_dev_driver(physfn) != pci_dev_driver(vdev->pdev)) {
> > 
> > However now that we have multiple VF and PF drivers this is no longer
> > reliable.
> > 
> > This means that security tests realted to vf_token can be skipped by
> > mixing and matching different VFIO PCI drivers.
> > 
> > Instead of trying to use the driver core to find the PF devices maintain a
> > linked list of all PF vfio_pci_core_device's that we have called
> > pci_enable_sriov() on.
> > 
> > When registering a VF just search the list to see if the PF is present and
> > record the match permanently in the struct. PCI core locking prevents a PF
> > from passing pci_disable_sriov() while VF drivers are attached so the VFIO
> > owned PF becomes a static property of the VF.
> > 
> > In common cases where vfio does not own the PF the global list remains
> > empty and the VF's pointer is statically NULL.
> > 
> > This also fixes a lockdep splat from recursive locking of the
> > vfio_group::device_lock between vfio_device_get_from_name() and
> > vfio_device_get_from_dev(). If the VF and PF share the same group this
> > would deadlock.
> > 
> > Fixes: ff53edf6d6ab ("vfio/pci: Split the pci_driver code out of vfio_pci_core.c")
> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> >  drivers/vfio/pci/vfio_pci_core.c | 109 ++++++++++++++++---------------
> >  include/linux/vfio_pci_core.h    |   2 +
> >  2 files changed, 60 insertions(+), 51 deletions(-)
> > 
> > This is probably for the rc cycle since it only became a problem when the
> > migration drivers were merged.
> ...  
> > @@ -1942,14 +1935,28 @@ int vfio_pci_core_sriov_configure(struct pci_dev *pdev, int nr_virtfn)
> >  	if (!device)
> >  		return -ENODEV;
> >  
> > -	if (nr_virtfn == 0)
> > -		pci_disable_sriov(pdev);
> > -	else
> > +	vdev = container_of(device, struct vfio_pci_core_device, vdev);
> > +
> > +	if (nr_virtfn) {
> > +		mutex_lock(&vfio_pci_sriov_pfs_mutex);
> > +		list_add_tail(&vdev->sriov_pfs_item, &vfio_pci_sriov_pfs);
> > +		mutex_unlock(&vfio_pci_sriov_pfs_mutex);
> >  		ret = pci_enable_sriov(pdev, nr_virtfn);
> > +		if (ret)
> > +			goto out_del;
> > +		ret = nr_virtfn;
> > +		goto out_put;
> > +	}
> 
> If a user were to do:
> 
> 	# echo 1 > sriov_numvfs
> 	# echo 2 > sriov_numvfs
> 
> Don't we have a problem that we've botched the list and the PF still
> exists with 1 VF?  Thanks,

Yes, that is a mistake. We need to do the list_add before the
pci_enable_sriov because the probe() will inspect the
vfio_pci_sriov_pfs list.

But since pci_enable_sriov can only be called once we can just gaurd
directly against that.

I fixed it like this:

		mutex_lock(&vfio_pci_sriov_pfs_mutex);
		/*
		 * The thread that adds the vdev to the list is the only thread
		 * that gets to call pci_enable_sriov() and we will only allow
		 * it to be called once without going through
		 * pci_disable_sriov()
		 */
		if (!list_empty(&vdev->sriov_pfs_item)) {
			ret = -EINVAL;
			goto out_unlock;
		}
		list_add_tail(&vdev->sriov_pfs_item, &vfio_pci_sriov_pfs);
		mutex_unlock(&vfio_pci_sriov_pfs_mutex);
		ret = pci_enable_sriov(pdev, nr_virtfn);
		if (ret)
			goto out_del;

Let me know if you have any other notes and I will fix them before
resending

Thanks,
Jason

  reply	other threads:[~2022-04-08 17:08 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-08 15:10 [PATCH] vfio/pci: Fix vf_token mechanism when device-specific VF drivers are used Jason Gunthorpe
2022-04-08 16:53 ` Alex Williamson
2022-04-08 17:08   ` Jason Gunthorpe [this message]
2022-04-08 17:17     ` Alex Williamson

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=20220408170839.GA2120790@nvidia.com \
    --to=jgg@nvidia.com \
    --cc=alex.williamson@redhat.com \
    --cc=cohuck@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=mgurtovoy@nvidia.com \
    --cc=yishaih@nvidia.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.