Skip to content

Commit ff806cb

Browse files
jgunthorpeawilliam
authored andcommitted
vfio/pci: Remove vfio_device_get_from_dev()
The last user of this function is in PCI callbacks that want to convert their struct pci_dev to a vfio_device. Instead of searching use the vfio_device available trivially through the drvdata. When a callback in the device_driver is called, the caller must hold the device_lock() on dev. The purpose of the device_lock is to prevent remove() from being called (see __device_release_driver), and allow the driver to safely interact with its drvdata without races. The PCI core correctly follows this and holds the device_lock() when calling error_detected (see report_error_detected) and sriov_configure (see sriov_numvfs_store). Further, since the drvdata holds a positive refcount on the vfio_device any access of the drvdata, under the device_lock(), from a driver callback needs no further protection or refcounting. Thus the remark in the vfio_device_get_from_dev() comment does not apply here, VFIO PCI drivers all call vfio_unregister_group_dev() from their remove callbacks under the device_lock() and cannot race with the remaining callers. Reviewed-by: Kevin Tian <[email protected]> Reviewed-by: Shameer Kolothum <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alex Williamson <[email protected]>
1 parent 91be0bd commit ff806cb

File tree

5 files changed

+12
-70
lines changed

5 files changed

+12
-70
lines changed

drivers/vfio/pci/vfio_pci.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,12 @@ static void vfio_pci_remove(struct pci_dev *pdev)
174174

175175
static int vfio_pci_sriov_configure(struct pci_dev *pdev, int nr_virtfn)
176176
{
177+
struct vfio_pci_core_device *vdev = dev_get_drvdata(&pdev->dev);
178+
177179
if (!enable_sriov)
178180
return -ENOENT;
179181

180-
return vfio_pci_core_sriov_configure(pdev, nr_virtfn);
182+
return vfio_pci_core_sriov_configure(vdev, nr_virtfn);
181183
}
182184

183185
static const struct pci_device_id vfio_pci_table[] = {

drivers/vfio/pci/vfio_pci_core.c

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1894,9 +1894,7 @@ EXPORT_SYMBOL_GPL(vfio_pci_core_register_device);
18941894

18951895
void vfio_pci_core_unregister_device(struct vfio_pci_core_device *vdev)
18961896
{
1897-
struct pci_dev *pdev = vdev->pdev;
1898-
1899-
vfio_pci_core_sriov_configure(pdev, 0);
1897+
vfio_pci_core_sriov_configure(vdev, 0);
19001898

19011899
vfio_unregister_group_dev(&vdev->vdev);
19021900

@@ -1911,14 +1909,7 @@ EXPORT_SYMBOL_GPL(vfio_pci_core_unregister_device);
19111909
pci_ers_result_t vfio_pci_core_aer_err_detected(struct pci_dev *pdev,
19121910
pci_channel_state_t state)
19131911
{
1914-
struct vfio_pci_core_device *vdev;
1915-
struct vfio_device *device;
1916-
1917-
device = vfio_device_get_from_dev(&pdev->dev);
1918-
if (device == NULL)
1919-
return PCI_ERS_RESULT_DISCONNECT;
1920-
1921-
vdev = container_of(device, struct vfio_pci_core_device, vdev);
1912+
struct vfio_pci_core_device *vdev = dev_get_drvdata(&pdev->dev);
19221913

19231914
mutex_lock(&vdev->igate);
19241915

@@ -1927,26 +1918,18 @@ pci_ers_result_t vfio_pci_core_aer_err_detected(struct pci_dev *pdev,
19271918

19281919
mutex_unlock(&vdev->igate);
19291920

1930-
vfio_device_put(device);
1931-
19321921
return PCI_ERS_RESULT_CAN_RECOVER;
19331922
}
19341923
EXPORT_SYMBOL_GPL(vfio_pci_core_aer_err_detected);
19351924

1936-
int vfio_pci_core_sriov_configure(struct pci_dev *pdev, int nr_virtfn)
1925+
int vfio_pci_core_sriov_configure(struct vfio_pci_core_device *vdev,
1926+
int nr_virtfn)
19371927
{
1938-
struct vfio_pci_core_device *vdev;
1939-
struct vfio_device *device;
1928+
struct pci_dev *pdev = vdev->pdev;
19401929
int ret = 0;
19411930

19421931
device_lock_assert(&pdev->dev);
19431932

1944-
device = vfio_device_get_from_dev(&pdev->dev);
1945-
if (!device)
1946-
return -ENODEV;
1947-
1948-
vdev = container_of(device, struct vfio_pci_core_device, vdev);
1949-
19501933
if (nr_virtfn) {
19511934
mutex_lock(&vfio_pci_sriov_pfs_mutex);
19521935
/*
@@ -1964,8 +1947,7 @@ int vfio_pci_core_sriov_configure(struct pci_dev *pdev, int nr_virtfn)
19641947
ret = pci_enable_sriov(pdev, nr_virtfn);
19651948
if (ret)
19661949
goto out_del;
1967-
ret = nr_virtfn;
1968-
goto out_put;
1950+
return nr_virtfn;
19691951
}
19701952

19711953
pci_disable_sriov(pdev);
@@ -1975,8 +1957,6 @@ int vfio_pci_core_sriov_configure(struct pci_dev *pdev, int nr_virtfn)
19751957
list_del_init(&vdev->sriov_pfs_item);
19761958
out_unlock:
19771959
mutex_unlock(&vfio_pci_sriov_pfs_mutex);
1978-
out_put:
1979-
vfio_device_put(device);
19801960
return ret;
19811961
}
19821962
EXPORT_SYMBOL_GPL(vfio_pci_core_sriov_configure);

drivers/vfio/vfio.c

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -473,31 +473,15 @@ static void vfio_group_get(struct vfio_group *group)
473473
refcount_inc(&group->users);
474474
}
475475

476-
static struct vfio_group *vfio_group_get_from_dev(struct device *dev)
477-
{
478-
struct iommu_group *iommu_group;
479-
struct vfio_group *group;
480-
481-
iommu_group = iommu_group_get(dev);
482-
if (!iommu_group)
483-
return NULL;
484-
485-
group = vfio_group_get_from_iommu(iommu_group);
486-
iommu_group_put(iommu_group);
487-
488-
return group;
489-
}
490-
491476
/*
492477
* Device objects - create, release, get, put, search
493478
*/
494479
/* Device reference always implies a group reference */
495-
void vfio_device_put(struct vfio_device *device)
480+
static void vfio_device_put(struct vfio_device *device)
496481
{
497482
if (refcount_dec_and_test(&device->refcount))
498483
complete(&device->comp);
499484
}
500-
EXPORT_SYMBOL_GPL(vfio_device_put);
501485

502486
static bool vfio_device_try_get(struct vfio_device *device)
503487
{
@@ -831,29 +815,6 @@ int vfio_register_emulated_iommu_dev(struct vfio_device *device)
831815
}
832816
EXPORT_SYMBOL_GPL(vfio_register_emulated_iommu_dev);
833817

834-
/*
835-
* Get a reference to the vfio_device for a device. Even if the
836-
* caller thinks they own the device, they could be racing with a
837-
* release call path, so we can't trust drvdata for the shortcut.
838-
* Go the long way around, from the iommu_group to the vfio_group
839-
* to the vfio_device.
840-
*/
841-
struct vfio_device *vfio_device_get_from_dev(struct device *dev)
842-
{
843-
struct vfio_group *group;
844-
struct vfio_device *device;
845-
846-
group = vfio_group_get_from_dev(dev);
847-
if (!group)
848-
return NULL;
849-
850-
device = vfio_group_get_device(group, dev);
851-
vfio_group_put(group);
852-
853-
return device;
854-
}
855-
EXPORT_SYMBOL_GPL(vfio_device_get_from_dev);
856-
857818
static struct vfio_device *vfio_device_get_from_name(struct vfio_group *group,
858819
char *buf)
859820
{

include/linux/vfio.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,6 @@ void vfio_uninit_group_dev(struct vfio_device *device);
125125
int vfio_register_group_dev(struct vfio_device *device);
126126
int vfio_register_emulated_iommu_dev(struct vfio_device *device);
127127
void vfio_unregister_group_dev(struct vfio_device *device);
128-
extern struct vfio_device *vfio_device_get_from_dev(struct device *dev);
129-
extern void vfio_device_put(struct vfio_device *device);
130128

131129
int vfio_assign_device_set(struct vfio_device *device, void *set_id);
132130

include/linux/vfio_pci_core.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,9 @@ void vfio_pci_core_init_device(struct vfio_pci_core_device *vdev,
227227
int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev);
228228
void vfio_pci_core_uninit_device(struct vfio_pci_core_device *vdev);
229229
void vfio_pci_core_unregister_device(struct vfio_pci_core_device *vdev);
230-
int vfio_pci_core_sriov_configure(struct pci_dev *pdev, int nr_virtfn);
231230
extern const struct pci_error_handlers vfio_pci_core_err_handlers;
231+
int vfio_pci_core_sriov_configure(struct vfio_pci_core_device *vdev,
232+
int nr_virtfn);
232233
long vfio_pci_core_ioctl(struct vfio_device *core_vdev, unsigned int cmd,
233234
unsigned long arg);
234235
int vfio_pci_core_ioctl_feature(struct vfio_device *device, u32 flags,

0 commit comments

Comments
 (0)