On Wed, 4 May 2022 16:01:47 -0300 Jason Gunthorpe <jgg@xxxxxxxxxx> wrote: > Having a consistent pointer in the drvdata will allow the next patch to > make use of the drvdata from some of the core code helpers. > > Use a WARN_ON inside vfio_pci_core_enable() to detect drivers that miss > this. > > Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxx> > --- > drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 14 +++++++++++--- > drivers/vfio/pci/mlx5/main.c | 14 +++++++++++--- > drivers/vfio/pci/vfio_pci_core.c | 4 ++++ > 3 files changed, 26 insertions(+), 6 deletions(-) > > diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c > index 767b5d47631a49..665691967a030c 100644 > --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c > +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c > @@ -337,6 +337,14 @@ static int vf_qm_cache_wb(struct hisi_qm *qm) > return 0; > } > > +static struct hisi_acc_vf_core_device *hssi_acc_drvdata(struct pci_dev *pdev) > +{ > + struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev); > + > + return container_of(core_device, struct hisi_acc_vf_core_device, > + core_device); > +} > + > static void vf_qm_fun_reset(struct hisi_acc_vf_core_device *hisi_acc_vdev, > struct hisi_qm *qm) > { > @@ -962,7 +970,7 @@ hisi_acc_vfio_pci_get_device_state(struct vfio_device *vdev, > > static void hisi_acc_vf_pci_aer_reset_done(struct pci_dev *pdev) > { > - struct hisi_acc_vf_core_device *hisi_acc_vdev = dev_get_drvdata(&pdev->dev); > + struct hisi_acc_vf_core_device *hisi_acc_vdev = hssi_acc_drvdata(pdev); > > if (hisi_acc_vdev->core_device.vdev.migration_flags != > VFIO_MIGRATION_STOP_COPY) > @@ -1278,7 +1286,7 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device > if (ret) > goto out_free; > > - dev_set_drvdata(&pdev->dev, hisi_acc_vdev); > + dev_set_drvdata(&pdev->dev, &hisi_acc_vdev->core_device); > return 0; > > out_free: > @@ -1289,7 +1297,7 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device > > static void hisi_acc_vfio_pci_remove(struct pci_dev *pdev) > { > - struct hisi_acc_vf_core_device *hisi_acc_vdev = dev_get_drvdata(&pdev->dev); > + struct hisi_acc_vf_core_device *hisi_acc_vdev = hssi_acc_drvdata(pdev); > > vfio_pci_core_unregister_device(&hisi_acc_vdev->core_device); > vfio_pci_core_uninit_device(&hisi_acc_vdev->core_device); > diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c > index bbec5d288fee97..3391f965abd9f0 100644 > --- a/drivers/vfio/pci/mlx5/main.c > +++ b/drivers/vfio/pci/mlx5/main.c > @@ -39,6 +39,14 @@ struct mlx5vf_pci_core_device { > struct mlx5_vf_migration_file *saving_migf; > }; > > +static struct mlx5vf_pci_core_device *mlx5vf_drvdata(struct pci_dev *pdev) > +{ > + struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev); > + > + return container_of(core_device, struct mlx5vf_pci_core_device, > + core_device); > +} > + > static struct page * > mlx5vf_get_migration_page(struct mlx5_vf_migration_file *migf, > unsigned long offset) > @@ -505,7 +513,7 @@ static int mlx5vf_pci_get_device_state(struct vfio_device *vdev, > > static void mlx5vf_pci_aer_reset_done(struct pci_dev *pdev) > { > - struct mlx5vf_pci_core_device *mvdev = dev_get_drvdata(&pdev->dev); > + struct mlx5vf_pci_core_device *mvdev = mlx5vf_drvdata(pdev); > > if (!mvdev->migrate_cap) > return; > @@ -618,7 +626,7 @@ static int mlx5vf_pci_probe(struct pci_dev *pdev, > if (ret) > goto out_free; > > - dev_set_drvdata(&pdev->dev, mvdev); > + dev_set_drvdata(&pdev->dev, &mvdev->core_device); > return 0; > > out_free: > @@ -629,7 +637,7 @@ static int mlx5vf_pci_probe(struct pci_dev *pdev, > > static void mlx5vf_pci_remove(struct pci_dev *pdev) > { > - struct mlx5vf_pci_core_device *mvdev = dev_get_drvdata(&pdev->dev); > + struct mlx5vf_pci_core_device *mvdev = mlx5vf_drvdata(pdev); > > vfio_pci_core_unregister_device(&mvdev->core_device); > vfio_pci_core_uninit_device(&mvdev->core_device); > diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c > index 06b6f3594a1316..53ad39d617653d 100644 > --- a/drivers/vfio/pci/vfio_pci_core.c > +++ b/drivers/vfio/pci/vfio_pci_core.c > @@ -262,6 +262,10 @@ int vfio_pci_core_enable(struct vfio_pci_core_device *vdev) > u16 cmd; > u8 msix_pos; > > + /* Drivers must set the vfio_pci_core_device to their drvdata */ > + if (WARN_ON(vdev != dev_get_drvdata(&vdev->pdev->dev))) > + return -EINVAL; > + The ordering seems off, if we only validate in the core enable function then we can only guarantee drvdata is correct once the user has opened the device. However, we start invoking power management controls, which Abhishek proposes moving to runtime pm, from the core register device function. Therefore we've not validated drvdata for anything we might do in the background, not under the direction of the user. I'd also rather see the variant driver fail to register with the core than to see a failure opening the device an arbitrary time later. Thanks, Alex > vfio_pci_set_power_state(vdev, PCI_D0); > > /* Don't allow our initial saved state to include busmaster */