Commit 07d47b42 authored by Jason Gunthorpe's avatar Jason Gunthorpe Committed by Alex Williamson

vfio/pci: Replace uses of vfio_device_data() with container_of

This tidies a few confused places that think they can have a refcount on
the vfio_device but the device_data could be NULL, that isn't possible by
design.

Most of the change falls out when struct vfio_devices is updated to just
store the struct vfio_pci_device itself. This wasn't possible before
because there was no easy way to get from the 'struct vfio_pci_device' to
the 'struct vfio_device' to put back the refcount.
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarKevin Tian <kevin.tian@intel.com>
Reviewed-by: default avatarCornelia Huck <cohuck@redhat.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Message-Id: <13-v3-225de1400dfc+4e074-vfio1_jgg@nvidia.com>
Signed-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
parent 6df62c5b
...@@ -517,30 +517,29 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev) ...@@ -517,30 +517,29 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev)
static struct pci_driver vfio_pci_driver; static struct pci_driver vfio_pci_driver;
static struct vfio_pci_device *get_pf_vdev(struct vfio_pci_device *vdev, static struct vfio_pci_device *get_pf_vdev(struct vfio_pci_device *vdev)
struct vfio_device **pf_dev)
{ {
struct pci_dev *physfn = pci_physfn(vdev->pdev); struct pci_dev *physfn = pci_physfn(vdev->pdev);
struct vfio_device *pf_dev;
if (!vdev->pdev->is_virtfn) if (!vdev->pdev->is_virtfn)
return NULL; return NULL;
*pf_dev = vfio_device_get_from_dev(&physfn->dev); pf_dev = vfio_device_get_from_dev(&physfn->dev);
if (!*pf_dev) if (!pf_dev)
return NULL; return NULL;
if (pci_dev_driver(physfn) != &vfio_pci_driver) { if (pci_dev_driver(physfn) != &vfio_pci_driver) {
vfio_device_put(*pf_dev); vfio_device_put(pf_dev);
return NULL; return NULL;
} }
return vfio_device_data(*pf_dev); return container_of(pf_dev, struct vfio_pci_device, vdev);
} }
static void vfio_pci_vf_token_user_add(struct vfio_pci_device *vdev, int val) static void vfio_pci_vf_token_user_add(struct vfio_pci_device *vdev, int val)
{ {
struct vfio_device *pf_dev; struct vfio_pci_device *pf_vdev = get_pf_vdev(vdev);
struct vfio_pci_device *pf_vdev = get_pf_vdev(vdev, &pf_dev);
if (!pf_vdev) if (!pf_vdev)
return; return;
...@@ -550,7 +549,7 @@ static void vfio_pci_vf_token_user_add(struct vfio_pci_device *vdev, int val) ...@@ -550,7 +549,7 @@ static void vfio_pci_vf_token_user_add(struct vfio_pci_device *vdev, int val)
WARN_ON(pf_vdev->vf_token->users < 0); WARN_ON(pf_vdev->vf_token->users < 0);
mutex_unlock(&pf_vdev->vf_token->lock); mutex_unlock(&pf_vdev->vf_token->lock);
vfio_device_put(pf_dev); vfio_device_put(&pf_vdev->vdev);
} }
static void vfio_pci_release(struct vfio_device *core_vdev) static void vfio_pci_release(struct vfio_device *core_vdev)
...@@ -794,7 +793,7 @@ int vfio_pci_register_dev_region(struct vfio_pci_device *vdev, ...@@ -794,7 +793,7 @@ int vfio_pci_register_dev_region(struct vfio_pci_device *vdev,
} }
struct vfio_devices { struct vfio_devices {
struct vfio_device **devices; struct vfio_pci_device **devices;
int cur_index; int cur_index;
int max_index; int max_index;
}; };
...@@ -1283,9 +1282,7 @@ static long vfio_pci_ioctl(struct vfio_device *core_vdev, ...@@ -1283,9 +1282,7 @@ static long vfio_pci_ioctl(struct vfio_device *core_vdev,
goto hot_reset_release; goto hot_reset_release;
for (; mem_idx < devs.cur_index; mem_idx++) { for (; mem_idx < devs.cur_index; mem_idx++) {
struct vfio_pci_device *tmp; struct vfio_pci_device *tmp = devs.devices[mem_idx];
tmp = vfio_device_data(devs.devices[mem_idx]);
ret = down_write_trylock(&tmp->memory_lock); ret = down_write_trylock(&tmp->memory_lock);
if (!ret) { if (!ret) {
...@@ -1300,17 +1297,13 @@ static long vfio_pci_ioctl(struct vfio_device *core_vdev, ...@@ -1300,17 +1297,13 @@ static long vfio_pci_ioctl(struct vfio_device *core_vdev,
hot_reset_release: hot_reset_release:
for (i = 0; i < devs.cur_index; i++) { for (i = 0; i < devs.cur_index; i++) {
struct vfio_device *device; struct vfio_pci_device *tmp = devs.devices[i];
struct vfio_pci_device *tmp;
device = devs.devices[i];
tmp = vfio_device_data(device);
if (i < mem_idx) if (i < mem_idx)
up_write(&tmp->memory_lock); up_write(&tmp->memory_lock);
else else
mutex_unlock(&tmp->vma_lock); mutex_unlock(&tmp->vma_lock);
vfio_device_put(device); vfio_device_put(&tmp->vdev);
} }
kfree(devs.devices); kfree(devs.devices);
...@@ -1777,8 +1770,7 @@ static int vfio_pci_validate_vf_token(struct vfio_pci_device *vdev, ...@@ -1777,8 +1770,7 @@ static int vfio_pci_validate_vf_token(struct vfio_pci_device *vdev,
return 0; /* No VF token provided or required */ return 0; /* No VF token provided or required */
if (vdev->pdev->is_virtfn) { if (vdev->pdev->is_virtfn) {
struct vfio_device *pf_dev; struct vfio_pci_device *pf_vdev = get_pf_vdev(vdev);
struct vfio_pci_device *pf_vdev = get_pf_vdev(vdev, &pf_dev);
bool match; bool match;
if (!pf_vdev) { if (!pf_vdev) {
...@@ -1791,7 +1783,7 @@ static int vfio_pci_validate_vf_token(struct vfio_pci_device *vdev, ...@@ -1791,7 +1783,7 @@ static int vfio_pci_validate_vf_token(struct vfio_pci_device *vdev,
} }
if (!vf_token) { if (!vf_token) {
vfio_device_put(pf_dev); vfio_device_put(&pf_vdev->vdev);
pci_info_ratelimited(vdev->pdev, pci_info_ratelimited(vdev->pdev,
"VF token required to access device\n"); "VF token required to access device\n");
return -EACCES; return -EACCES;
...@@ -1801,7 +1793,7 @@ static int vfio_pci_validate_vf_token(struct vfio_pci_device *vdev, ...@@ -1801,7 +1793,7 @@ static int vfio_pci_validate_vf_token(struct vfio_pci_device *vdev,
match = uuid_equal(uuid, &pf_vdev->vf_token->uuid); match = uuid_equal(uuid, &pf_vdev->vf_token->uuid);
mutex_unlock(&pf_vdev->vf_token->lock); mutex_unlock(&pf_vdev->vf_token->lock);
vfio_device_put(pf_dev); vfio_device_put(&pf_vdev->vdev);
if (!match) { if (!match) {
pci_info_ratelimited(vdev->pdev, pci_info_ratelimited(vdev->pdev,
...@@ -2122,11 +2114,7 @@ static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev, ...@@ -2122,11 +2114,7 @@ static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev,
if (device == NULL) if (device == NULL)
return PCI_ERS_RESULT_DISCONNECT; return PCI_ERS_RESULT_DISCONNECT;
vdev = vfio_device_data(device); vdev = container_of(device, struct vfio_pci_device, vdev);
if (vdev == NULL) {
vfio_device_put(device);
return PCI_ERS_RESULT_DISCONNECT;
}
mutex_lock(&vdev->igate); mutex_lock(&vdev->igate);
...@@ -2142,7 +2130,6 @@ static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev, ...@@ -2142,7 +2130,6 @@ static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev,
static int vfio_pci_sriov_configure(struct pci_dev *pdev, int nr_virtfn) static int vfio_pci_sriov_configure(struct pci_dev *pdev, int nr_virtfn)
{ {
struct vfio_pci_device *vdev;
struct vfio_device *device; struct vfio_device *device;
int ret = 0; int ret = 0;
...@@ -2155,12 +2142,6 @@ static int vfio_pci_sriov_configure(struct pci_dev *pdev, int nr_virtfn) ...@@ -2155,12 +2142,6 @@ static int vfio_pci_sriov_configure(struct pci_dev *pdev, int nr_virtfn)
if (!device) if (!device)
return -ENODEV; return -ENODEV;
vdev = vfio_device_data(device);
if (!vdev) {
vfio_device_put(device);
return -ENODEV;
}
if (nr_virtfn == 0) if (nr_virtfn == 0)
pci_disable_sriov(pdev); pci_disable_sriov(pdev);
else else
...@@ -2220,7 +2201,7 @@ static int vfio_pci_reflck_find(struct pci_dev *pdev, void *data) ...@@ -2220,7 +2201,7 @@ static int vfio_pci_reflck_find(struct pci_dev *pdev, void *data)
return 0; return 0;
} }
vdev = vfio_device_data(device); vdev = container_of(device, struct vfio_pci_device, vdev);
if (vdev->reflck) { if (vdev->reflck) {
vfio_pci_reflck_get(vdev->reflck); vfio_pci_reflck_get(vdev->reflck);
...@@ -2282,7 +2263,7 @@ static int vfio_pci_get_unused_devs(struct pci_dev *pdev, void *data) ...@@ -2282,7 +2263,7 @@ static int vfio_pci_get_unused_devs(struct pci_dev *pdev, void *data)
return -EBUSY; return -EBUSY;
} }
vdev = vfio_device_data(device); vdev = container_of(device, struct vfio_pci_device, vdev);
/* Fault if the device is not unused */ /* Fault if the device is not unused */
if (vdev->refcnt) { if (vdev->refcnt) {
...@@ -2290,7 +2271,7 @@ static int vfio_pci_get_unused_devs(struct pci_dev *pdev, void *data) ...@@ -2290,7 +2271,7 @@ static int vfio_pci_get_unused_devs(struct pci_dev *pdev, void *data)
return -EBUSY; return -EBUSY;
} }
devs->devices[devs->cur_index++] = device; devs->devices[devs->cur_index++] = vdev;
return 0; return 0;
} }
...@@ -2312,7 +2293,7 @@ static int vfio_pci_try_zap_and_vma_lock_cb(struct pci_dev *pdev, void *data) ...@@ -2312,7 +2293,7 @@ static int vfio_pci_try_zap_and_vma_lock_cb(struct pci_dev *pdev, void *data)
return -EBUSY; return -EBUSY;
} }
vdev = vfio_device_data(device); vdev = container_of(device, struct vfio_pci_device, vdev);
/* /*
* Locking multiple devices is prone to deadlock, runaway and * Locking multiple devices is prone to deadlock, runaway and
...@@ -2323,7 +2304,7 @@ static int vfio_pci_try_zap_and_vma_lock_cb(struct pci_dev *pdev, void *data) ...@@ -2323,7 +2304,7 @@ static int vfio_pci_try_zap_and_vma_lock_cb(struct pci_dev *pdev, void *data)
return -EBUSY; return -EBUSY;
} }
devs->devices[devs->cur_index++] = device; devs->devices[devs->cur_index++] = vdev;
return 0; return 0;
} }
...@@ -2371,7 +2352,7 @@ static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev) ...@@ -2371,7 +2352,7 @@ static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev)
/* Does at least one need a reset? */ /* Does at least one need a reset? */
for (i = 0; i < devs.cur_index; i++) { for (i = 0; i < devs.cur_index; i++) {
tmp = vfio_device_data(devs.devices[i]); tmp = devs.devices[i];
if (tmp->needs_reset) { if (tmp->needs_reset) {
ret = pci_reset_bus(vdev->pdev); ret = pci_reset_bus(vdev->pdev);
break; break;
...@@ -2380,7 +2361,7 @@ static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev) ...@@ -2380,7 +2361,7 @@ static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev)
put_devs: put_devs:
for (i = 0; i < devs.cur_index; i++) { for (i = 0; i < devs.cur_index; i++) {
tmp = vfio_device_data(devs.devices[i]); tmp = devs.devices[i];
/* /*
* If reset was successful, affected devices no longer need * If reset was successful, affected devices no longer need
...@@ -2396,7 +2377,7 @@ static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev) ...@@ -2396,7 +2377,7 @@ static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev)
vfio_pci_set_power_state(tmp, PCI_D3hot); vfio_pci_set_power_state(tmp, PCI_D3hot);
} }
vfio_device_put(devs.devices[i]); vfio_device_put(&tmp->vdev);
} }
kfree(devs.devices); kfree(devs.devices);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment