[PATCH] vdpa/vdpa_sim: guard partial device teardown

Xiong Weimin <[email protected]>
Newsgroups gmane.linux.kernel
Message-ID <[email protected]>
vdpasim_create() unwinds early allocation failures with put_device(),
which invokes the vdpa free callback even when the worker, virtqueues or
IOTLB arrays have not all been initialized.  vdpasim_free() currently
assumes the fully initialized path and can dereference NULL or ERR_PTR
state during those failures.

Make the free callback tolerate partially initialized simulator devices
before destroying the worker or walking optional arrays.

Signed-off-by: Xiong Weimin <[email protected]>
---
 drivers/vdpa/vdpa_sim/vdpa_sim.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.c b/drivers/vdpa/vdpa_sim/vdpa_sim.c
index 8cb1cc2ea..77966e957 100644
--- a/drivers/vdpa/vdpa_sim/vdpa_sim.c
+++ b/drivers/vdpa/vdpa_sim/vdpa_sim.c
@@ -743,17 +743,22 @@ static void vdpasim_free(struct vdpa_device *vdpa)
 	int i;
 
 	kthread_cancel_work_sync(&vdpasim->work);
-	kthread_destroy_worker(vdpasim->worker);
+	if (!IS_ERR_OR_NULL(vdpasim->worker))
+		kthread_destroy_worker(vdpasim->worker);
 
-	for (i = 0; i < vdpasim->dev_attr.nvqs; i++) {
-		vringh_kiov_cleanup(&vdpasim->vqs[i].out_iov);
-		vringh_kiov_cleanup(&vdpasim->vqs[i].in_iov);
+	if (vdpasim->vqs) {
+		for (i = 0; i < vdpasim->dev_attr.nvqs; i++) {
+			vringh_kiov_cleanup(&vdpasim->vqs[i].out_iov);
+			vringh_kiov_cleanup(&vdpasim->vqs[i].in_iov);
+		}
 	}
 
 	vdpasim->dev_attr.free(vdpasim);
 
-	for (i = 0; i < vdpasim->dev_attr.nas; i++)
-		vhost_iotlb_reset(&vdpasim->iommu[i]);
+	if (vdpasim->iommu) {
+		for (i = 0; i < vdpasim->dev_attr.nas; i++)
+			vhost_iotlb_reset(&vdpasim->iommu[i]);
+	}
 	kfree(vdpasim->iommu);
 	kfree(vdpasim->iommu_pt);
 	kfree(vdpasim->vqs);
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.