Commit 9da27466 authored by zhenwei pi's avatar zhenwei pi Committed by Herbert Xu

crypto: virtio - handle config changed by work queue

MST pointed out: config change callback is also handled incorrectly
in this driver, it takes a mutex from interrupt context.

Handle config changed by work queue instead.

Cc: Gonglei (Arei) <arei.gonglei@huawei.com>
Cc: Halil Pasic <pasic@linux.ibm.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarzhenwei pi <pizhenwei@bytedance.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 5b90073d
......@@ -35,6 +35,9 @@ struct virtio_crypto {
struct virtqueue *ctrl_vq;
struct data_queue *data_vq;
/* Work struct for config space updates */
struct work_struct config_work;
/* To protect the vq operations for the controlq */
spinlock_t ctrl_lock;
......
......@@ -335,6 +335,14 @@ static void virtcrypto_del_vqs(struct virtio_crypto *vcrypto)
virtcrypto_free_queues(vcrypto);
}
static void vcrypto_config_changed_work(struct work_struct *work)
{
struct virtio_crypto *vcrypto =
container_of(work, struct virtio_crypto, config_work);
virtcrypto_update_status(vcrypto);
}
static int virtcrypto_probe(struct virtio_device *vdev)
{
int err = -EFAULT;
......@@ -454,6 +462,8 @@ static int virtcrypto_probe(struct virtio_device *vdev)
if (err)
goto free_engines;
INIT_WORK(&vcrypto->config_work, vcrypto_config_changed_work);
return 0;
free_engines:
......@@ -490,6 +500,7 @@ static void virtcrypto_remove(struct virtio_device *vdev)
dev_info(&vdev->dev, "Start virtcrypto_remove.\n");
flush_work(&vcrypto->config_work);
if (virtcrypto_dev_started(vcrypto))
virtcrypto_dev_stop(vcrypto);
virtio_reset_device(vdev);
......@@ -504,7 +515,7 @@ static void virtcrypto_config_changed(struct virtio_device *vdev)
{
struct virtio_crypto *vcrypto = vdev->priv;
virtcrypto_update_status(vcrypto);
schedule_work(&vcrypto->config_work);
}
#ifdef CONFIG_PM_SLEEP
......@@ -512,6 +523,7 @@ static int virtcrypto_freeze(struct virtio_device *vdev)
{
struct virtio_crypto *vcrypto = vdev->priv;
flush_work(&vcrypto->config_work);
virtio_reset_device(vdev);
virtcrypto_free_unused_reqs(vcrypto);
if (virtcrypto_dev_started(vcrypto))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment