1
0
Fork 0
forked from nuttx/nuttx-update

virtio-rpmb.c: add spin lock for virtqueue add/get buffer

Virtqueeus are used in both user thread and interrupt, so add spinlock
to proetect them.

Signed-off-by: wangyongrong <wangyongrong@xiaomi.com>
This commit is contained in:
wangyongrong 2024-06-13 09:51:16 +08:00 committed by Xiang Xiao
parent e8a8052a8a
commit 377f184019

View file

@ -29,6 +29,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/fs/ioctl.h>
#include <nuttx/semaphore.h>
#include <nuttx/spinlock.h>
#include <nuttx/mmcsd.h>
#include <nuttx/virtio/virtio.h>
@ -49,6 +50,7 @@ struct virtio_rpmb_priv_s
/* The virtio device we're associated with */
FAR struct virtio_device *vdev;
spinlock_t lock;
};
struct virtio_rpmb_cookie_s
@ -101,12 +103,21 @@ static const struct file_operations g_virtio_rpmb_ops =
static void virtio_rpmb_done(FAR struct virtqueue *vq)
{
FAR struct virtio_rpmb_priv_s *priv = vq->vq_dev->priv;
FAR struct virtio_rpmb_cookie_s *cookie;
irqstate_t flags;
uint32_t len;
cookie = virtqueue_get_buffer(vq, &len, NULL);
if (cookie != NULL)
for (; ; )
{
flags = spin_lock_irqsave(&priv->lock);
cookie = virtqueue_get_buffer(vq, &len, NULL);
spin_unlock_irqrestore(&priv->lock, flags);
if (cookie == NULL)
{
break;
}
/* Assign the return length */
cookie->len = len;
@ -128,6 +139,7 @@ static int virtio_rpmb_transact(FAR struct virtio_rpmb_priv_s *priv,
{
FAR struct virtqueue *vq = priv->vdev->vrings_info[0].vq;
struct virtio_rpmb_cookie_s cookie;
irqstate_t flags;
int ret;
/* Init the cookie */
@ -139,15 +151,18 @@ static int virtio_rpmb_transact(FAR struct virtio_rpmb_priv_s *priv,
* cookie. (virtqueue_get_buffer() will return cookie).
*/
flags = spin_lock_irqsave(&priv->lock);
ret = virtqueue_add_buffer(vq, vb, out, in, &cookie);
if (ret < 0)
{
spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}
/* Notify the other side to process the added virtqueue buffer */
virtqueue_kick(vq);
spin_unlock_irqrestore(&priv->lock, flags);
/* Wait fot completion */
@ -189,6 +204,7 @@ static int virtio_rpmb_init(FAR struct virtio_rpmb_priv_s *priv,
priv->vdev = vdev;
vdev->priv = priv;
spin_lock_init(&priv->lock);
/* Initialize the virtio device */