mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 05:49:47 -04:00
vsock/virtio: read virtqueues under worker locks
Commitbd50c5dc18("vsock/virtio: add support for device suspend/resume") made the *_run flags transition from false to true when restore installs replacement virtqueues. The RX, TX and event workers read their virtqueue before locking and checking the corresponding flag, so a worker delayed across freeze and restore can observe the replacement queue's running state while retaining a pointer to the deleted queue. Read each virtqueue under its mutex after checking the run flag, keeping the pointer and state in the same queue generation. Fixes:bd50c5dc18("vsock/virtio: add support for device suspend/resume") Cc: stable@vger.kernel.org Reported-by: Xiang Mei <xmei5@asu.edu> Link: https://lore.kernel.org/r/20260727035804.1860862-1-bestswngs@gmail.com Signed-off-by: Weiming Shi <bestswngs@gmail.com> Reviewed-by: Bobby Eshleman <bobbyeshleman@meta.com> Link: https://patch.msgid.link/e79f68ad9284c983364fc3ac46904b6d9ef50231.1785352330.git.bestswngs@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
d1000fd799
commit
ebac8f6b1e
@@ -346,12 +346,13 @@ static void virtio_transport_tx_work(struct work_struct *work)
|
||||
struct virtqueue *vq;
|
||||
bool added = false;
|
||||
|
||||
vq = vsock->vqs[VSOCK_VQ_TX];
|
||||
mutex_lock(&vsock->tx_lock);
|
||||
|
||||
if (!vsock->tx_run)
|
||||
goto out;
|
||||
|
||||
vq = vsock->vqs[VSOCK_VQ_TX];
|
||||
|
||||
do {
|
||||
struct sk_buff *skb;
|
||||
unsigned int len;
|
||||
@@ -451,13 +452,13 @@ static void virtio_transport_event_work(struct work_struct *work)
|
||||
container_of(work, struct virtio_vsock, event_work);
|
||||
struct virtqueue *vq;
|
||||
|
||||
vq = vsock->vqs[VSOCK_VQ_EVENT];
|
||||
|
||||
mutex_lock(&vsock->event_lock);
|
||||
|
||||
if (!vsock->event_run)
|
||||
goto out;
|
||||
|
||||
vq = vsock->vqs[VSOCK_VQ_EVENT];
|
||||
|
||||
do {
|
||||
struct virtio_vsock_event *event;
|
||||
unsigned int len;
|
||||
@@ -634,13 +635,13 @@ static void virtio_transport_rx_work(struct work_struct *work)
|
||||
container_of(work, struct virtio_vsock, rx_work);
|
||||
struct virtqueue *vq;
|
||||
|
||||
vq = vsock->vqs[VSOCK_VQ_RX];
|
||||
|
||||
mutex_lock(&vsock->rx_lock);
|
||||
|
||||
if (!vsock->rx_run)
|
||||
goto out;
|
||||
|
||||
vq = vsock->vqs[VSOCK_VQ_RX];
|
||||
|
||||
do {
|
||||
virtqueue_disable_cb(vq);
|
||||
for (;;) {
|
||||
|
||||
Reference in New Issue
Block a user