97 lines
2.7 KiB
Diff
97 lines
2.7 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Pawel Furtak <pawel.furtak@intel.com>
|
|
Date: Tue, 5 Mar 2019 09:19:19 +0100
|
|
Subject: [PATCH] ASoC: Intel: Skl: Virt: Fix panic during tplg initialization
|
|
|
|
Timeout during topology request may lead to not initialized
|
|
topology buffer. This patch adds additional checks and cleanups
|
|
to avoid access fo not initialized/freed memory.
|
|
|
|
Change-Id: I1a4eec1c04d41566e04a58fd88e4307c01a39664
|
|
Tracked-On: OAM-76719
|
|
Signed-off-by: Pawel Furtak <pawel.furtak@intel.com>
|
|
Signed-off-by: Wojciech Jablonski <wojciech.jablonski@intel.com>
|
|
---
|
|
.../soc/intel/skylake/virtio/skl-virtio-fe.c | 27 +++++++++++++------
|
|
1 file changed, 19 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/sound/soc/intel/skylake/virtio/skl-virtio-fe.c b/sound/soc/intel/skylake/virtio/skl-virtio-fe.c
|
|
index 8b54d08..17d5e3d 100644
|
|
--- a/sound/soc/intel/skylake/virtio/skl-virtio-fe.c
|
|
+++ b/sound/soc/intel/skylake/virtio/skl-virtio-fe.c
|
|
@@ -282,7 +282,6 @@ static void vfe_cmd_handle_rx(struct virtqueue *vq)
|
|
|
|
vfe = vq->vdev->priv;
|
|
|
|
-
|
|
spin_lock_irqsave(&vfe->substream_info_lock, irq_flags);
|
|
list_for_each_entry_safe(substr_info, tmp,
|
|
&vfe->substr_info_list, list) {
|
|
@@ -414,7 +413,11 @@ static void vfe_handle_tplg(struct snd_skl_vfe *vfe,
|
|
tplg_data->offset, tplg_data->chunk_size);
|
|
|
|
mutex_lock(&vfe->tplg.tplg_lock);
|
|
- data_ptr = vfe->tplg.tplg_data.data + tplg_data->offset;
|
|
+
|
|
+ if (!vfe->tplg.tplg_data.data)
|
|
+ goto err_handler;
|
|
+
|
|
+ data_ptr = (u8 *)vfe->tplg.tplg_data.data + tplg_data->offset;
|
|
memcpy(data_ptr, tplg_data->data, tplg_data->chunk_size);
|
|
vfe->tplg.data_ready += tplg_data->chunk_size;
|
|
|
|
@@ -423,6 +426,7 @@ static void vfe_handle_tplg(struct snd_skl_vfe *vfe,
|
|
wake_up(&vfe->tplg.waitq);
|
|
}
|
|
|
|
+err_handler:
|
|
mutex_unlock(&vfe->tplg.tplg_lock);
|
|
}
|
|
|
|
@@ -1018,7 +1022,7 @@ static int vfe_skl_init(struct virtio_device *vdev)
|
|
|
|
err = vfe_init_tplg(vfe, skl);
|
|
if (err < 0)
|
|
- return err;
|
|
+ goto error;
|
|
|
|
err = vfe_platform_register(vfe, &vdev->dev);
|
|
if (err < 0)
|
|
@@ -1087,8 +1091,10 @@ static int vfe_init(struct virtio_device *vdev)
|
|
int ret;
|
|
|
|
vfe = devm_kzalloc(&vdev->dev, sizeof(*vfe), GFP_KERNEL);
|
|
- if (!vfe)
|
|
- goto no_mem;
|
|
+ if (!vfe) {
|
|
+ ret = -ENOMEM;
|
|
+ goto err;
|
|
+ }
|
|
|
|
skl_vfe = vfe;
|
|
vfe->vdev = vdev;
|
|
@@ -1123,12 +1129,17 @@ static int vfe_init(struct virtio_device *vdev)
|
|
|
|
ret = vfe_skl_init(vdev);
|
|
if (ret < 0)
|
|
- goto err;
|
|
+ goto skl_err;
|
|
|
|
return 0;
|
|
|
|
-no_mem:
|
|
- ret = -ENOMEM;
|
|
+skl_err:
|
|
+ virtqueue_disable_cb(vfe->ipc_not_tx_vq);
|
|
+ virtqueue_disable_cb(vfe->ipc_not_rx_vq);
|
|
+ cancel_work_sync(&vfe->msg_timeout_work);
|
|
+ cancel_work_sync(&vfe->message_loop_work);
|
|
+ vdev->config->reset(vdev);
|
|
+ vdev->config->del_vqs(vdev);
|
|
err:
|
|
vdev->priv = NULL;
|
|
return ret;
|
|
--
|
|
https://clearlinux.org
|
|
|