]> git.ipfire.org Git - thirdparty/kernel/stable.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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 5 Dec 2024 12:53:55 +0000 (13:53 +0100)
[ Upstream commit cb04444c243c001fc27f275e84792ff1c2b96867 ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/vfio/pci/mlx5/main.c

index 61d9b0f9146d1b23c38194bc95aac4c533ed2fc3..8de6037c88194b54f8197750c683b6f5e6af8550 100644 (file)
@@ -641,14 +641,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);
@@ -664,6 +661,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;
@@ -693,10 +695,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);
 }
 
@@ -1018,13 +1018,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)) {
@@ -1043,20 +1049,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);
 }