]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
vfio/mlx5: Fix unwind flows in mlx5vf_pci_save/resume_device_data()
authorYishai Hadas <yishaih@nvidia.com>
Thu, 14 Nov 2024 09:53:18 +0000 (11:53 +0200)
committerAlex Williamson <alex.williamson@redhat.com>
Thu, 14 Nov 2024 18:42:18 +0000 (11:42 -0700)
Fix unwind flows in mlx5vf_pci_save_device_data() and
mlx5vf_pci_resume_device_data() to avoid freeing the migf pointer at the
'end' label, as this will be handled by fput(migf->filp) through
mlx5vf_release_file().

To ensure mlx5vf_release_file() functions correctly, move the
initialization of migf fields (such as migf->lock) to occur before any
potential unwind flow, as these fields may be accessed within
mlx5vf_release_file().

Fixes: 9945a67ea4b3 ("vfio/mlx5: Refactor PD usage")
Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/20241114095318.16556-3-yishaih@nvidia.com
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
drivers/vfio/pci/mlx5/main.c

index 242c23eef452e81da871891b977c36df7d5255c9..8833e60d42f566a1369ce768ec319e409ba851b9 100644 (file)
@@ -640,14 +640,11 @@ mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev, bool track)
                                        O_RDONLY);
        if (IS_ERR(migf->filp)) {
                ret = PTR_ERR(migf->filp);
-               goto end;
+               kfree(migf);
+               return ERR_PTR(ret);
        }
 
        migf->mvdev = mvdev;
-       ret = mlx5vf_cmd_alloc_pd(migf);
-       if (ret)
-               goto out_free;
-
        stream_open(migf->filp->f_inode, migf->filp);
        mutex_init(&migf->lock);
        init_waitqueue_head(&migf->poll_wait);
@@ -663,6 +660,11 @@ mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev, bool track)
        INIT_LIST_HEAD(&migf->buf_list);
        INIT_LIST_HEAD(&migf->avail_list);
        spin_lock_init(&migf->list_lock);
+
+       ret = mlx5vf_cmd_alloc_pd(migf);
+       if (ret)
+               goto out;
+
        ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &length, &full_size, 0);
        if (ret)
                goto out_pd;
@@ -692,10 +694,8 @@ out_save:
        mlx5vf_free_data_buffer(buf);
 out_pd:
        mlx5fv_cmd_clean_migf_resources(migf);
-out_free:
+out:
        fput(migf->filp);
-end:
-       kfree(migf);
        return ERR_PTR(ret);
 }
 
@@ -1016,13 +1016,19 @@ mlx5vf_pci_resume_device_data(struct mlx5vf_pci_core_device *mvdev)
                                        O_WRONLY);
        if (IS_ERR(migf->filp)) {
                ret = PTR_ERR(migf->filp);
-               goto end;
+               kfree(migf);
+               return ERR_PTR(ret);
        }
 
+       stream_open(migf->filp->f_inode, migf->filp);
+       mutex_init(&migf->lock);
+       INIT_LIST_HEAD(&migf->buf_list);
+       INIT_LIST_HEAD(&migf->avail_list);
+       spin_lock_init(&migf->list_lock);
        migf->mvdev = mvdev;
        ret = mlx5vf_cmd_alloc_pd(migf);
        if (ret)
-               goto out_free;
+               goto out;
 
        buf = mlx5vf_alloc_data_buffer(migf, 0, DMA_TO_DEVICE);
        if (IS_ERR(buf)) {
@@ -1041,20 +1047,13 @@ mlx5vf_pci_resume_device_data(struct mlx5vf_pci_core_device *mvdev)
        migf->buf_header[0] = buf;
        migf->load_state = MLX5_VF_LOAD_STATE_READ_HEADER;
 
-       stream_open(migf->filp->f_inode, migf->filp);
-       mutex_init(&migf->lock);
-       INIT_LIST_HEAD(&migf->buf_list);
-       INIT_LIST_HEAD(&migf->avail_list);
-       spin_lock_init(&migf->list_lock);
        return migf;
 out_buf:
        mlx5vf_free_data_buffer(migf->buf[0]);
 out_pd:
        mlx5vf_cmd_dealloc_pd(migf);
-out_free:
+out:
        fput(migf->filp);
-end:
-       kfree(migf);
        return ERR_PTR(ret);
 }