Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5a8eb242 authored by Alexander Duyck's avatar Alexander Duyck Committed by Jeff Kirsher
Browse files

pci: Add SRIOV helper function to determine if VFs are assigned to guest



This function is meant to add a helper function that will determine if a PF
has any VFs that are currently assigned to a guest.  We currently have been
implementing this function per driver, and going forward I would like to avoid
that by making this function generic and using this helper.

v2: Removed extern from declaration of pci_vfs_assigned in pci.h and return
    0 if SR-IOV is disabled with is inline with other PCI SRIOV functions.

Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Acked-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent d44e7a9a
Loading
Loading
Loading
Loading
+41 −0
Original line number Original line Diff line number Diff line
@@ -728,6 +728,47 @@ int pci_num_vf(struct pci_dev *dev)
}
}
EXPORT_SYMBOL_GPL(pci_num_vf);
EXPORT_SYMBOL_GPL(pci_num_vf);


/**
 * pci_vfs_assigned - returns number of VFs are assigned to a guest
 * @dev: the PCI device
 *
 * Returns number of VFs belonging to this device that are assigned to a guest.
 * If device is not a physical function returns -ENODEV.
 */
int pci_vfs_assigned(struct pci_dev *dev)
{
	struct pci_dev *vfdev;
	unsigned int vfs_assigned = 0;
	unsigned short dev_id;

	/* only search if we are a PF */
	if (!dev->is_physfn)
		return 0;

	/*
	 * determine the device ID for the VFs, the vendor ID will be the
	 * same as the PF so there is no need to check for that one
	 */
	pci_read_config_word(dev, dev->sriov->pos + PCI_SRIOV_VF_DID, &dev_id);

	/* loop through all the VFs to see if we own any that are assigned */
	vfdev = pci_get_device(dev->vendor, dev_id, NULL);
	while (vfdev) {
		/*
		 * It is considered assigned if it is a virtual function with
		 * our dev as the physical function and the assigned bit is set
		 */
		if (vfdev->is_virtfn && (vfdev->physfn == dev) &&
		    (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED))
			vfs_assigned++;

		vfdev = pci_get_device(dev->vendor, dev_id, vfdev);
	}

	return vfs_assigned;
}
EXPORT_SYMBOL_GPL(pci_vfs_assigned);

/**
/**
 * pci_sriov_set_totalvfs -- reduce the TotalVFs available
 * pci_sriov_set_totalvfs -- reduce the TotalVFs available
 * @dev: the PCI PF device
 * @dev: the PCI PF device
+5 −0
Original line number Original line Diff line number Diff line
@@ -1644,6 +1644,7 @@ extern int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn);
extern void pci_disable_sriov(struct pci_dev *dev);
extern void pci_disable_sriov(struct pci_dev *dev);
extern irqreturn_t pci_sriov_migration(struct pci_dev *dev);
extern irqreturn_t pci_sriov_migration(struct pci_dev *dev);
extern int pci_num_vf(struct pci_dev *dev);
extern int pci_num_vf(struct pci_dev *dev);
int pci_vfs_assigned(struct pci_dev *dev);
extern int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs);
extern int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs);
extern int pci_sriov_get_totalvfs(struct pci_dev *dev);
extern int pci_sriov_get_totalvfs(struct pci_dev *dev);
#else
#else
@@ -1662,6 +1663,10 @@ static inline int pci_num_vf(struct pci_dev *dev)
{
{
	return 0;
	return 0;
}
}
static inline int pci_vfs_assigned(struct pci_dev *dev)
{
	return 0;
}
static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs)
static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs)
{
{
	return 0;
	return 0;