From 3fea597f75dac7a1c6f9de35a596a1754f305398 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Mon, 30 Aug 2021 15:21:29 -0400 Subject: [PATCH] Fixes for 4.4 Signed-off-by: Sasha Levin --- queue-4.4/series | 2 + ...q-broken-access-to-avoid-any-compile.patch | 58 +++++++++++++++++++ ...used-to-check-for-read-write-desc-or.patch | 50 ++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 queue-4.4/virtio-improve-vq-broken-access-to-avoid-any-compile.patch create mode 100644 queue-4.4/vringh-use-wiov-used-to-check-for-read-write-desc-or.patch diff --git a/queue-4.4/series b/queue-4.4/series index b860a713f4d..38bd93485c6 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -3,3 +3,5 @@ revert-usb-serial-ch341-fix-character-loss-at-high-transfer-rates.patch usb-serial-option-add-new-vid-pid-to-support-fibocom-fg150.patch e1000e-fix-the-max-snoop-no-snoop-latency-for-10m.patch net-marvell-fix-mvneta_tx_in_prgrs-bit-number.patch +virtio-improve-vq-broken-access-to-avoid-any-compile.patch +vringh-use-wiov-used-to-check-for-read-write-desc-or.patch diff --git a/queue-4.4/virtio-improve-vq-broken-access-to-avoid-any-compile.patch b/queue-4.4/virtio-improve-vq-broken-access-to-avoid-any-compile.patch new file mode 100644 index 00000000000..8c1d725df8e --- /dev/null +++ b/queue-4.4/virtio-improve-vq-broken-access-to-avoid-any-compile.patch @@ -0,0 +1,58 @@ +From f9a214d92d394faf1330e04cbd40aad715f3d7cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Jul 2021 17:26:45 +0300 +Subject: virtio: Improve vq->broken access to avoid any compiler optimization + +From: Parav Pandit + +[ Upstream commit 60f0779862e4ab943810187752c462e85f5fa371 ] + +Currently vq->broken field is read by virtqueue_is_broken() in busy +loop in one context by virtnet_send_command(). + +vq->broken is set to true in other process context by +virtio_break_device(). Reader and writer are accessing it without any +synchronization. This may lead to a compiler optimization which may +result to optimize reading vq->broken only once. + +Hence, force reading vq->broken on each invocation of +virtqueue_is_broken() and also force writing it so that such +update is visible to the readers. + +It is a theoretical fix that isn't yet encountered in the field. + +Signed-off-by: Parav Pandit +Link: https://lore.kernel.org/r/20210721142648.1525924-2-parav@nvidia.com +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + drivers/virtio/virtio_ring.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c +index 6b3565feddb2..b15c24c4d91f 100644 +--- a/drivers/virtio/virtio_ring.c ++++ b/drivers/virtio/virtio_ring.c +@@ -840,7 +840,7 @@ bool virtqueue_is_broken(struct virtqueue *_vq) + { + struct vring_virtqueue *vq = to_vvq(_vq); + +- return vq->broken; ++ return READ_ONCE(vq->broken); + } + EXPORT_SYMBOL_GPL(virtqueue_is_broken); + +@@ -854,7 +854,9 @@ void virtio_break_device(struct virtio_device *dev) + + list_for_each_entry(_vq, &dev->vqs, list) { + struct vring_virtqueue *vq = to_vvq(_vq); +- vq->broken = true; ++ ++ /* Pairs with READ_ONCE() in virtqueue_is_broken(). */ ++ WRITE_ONCE(vq->broken, true); + } + } + EXPORT_SYMBOL_GPL(virtio_break_device); +-- +2.30.2 + diff --git a/queue-4.4/vringh-use-wiov-used-to-check-for-read-write-desc-or.patch b/queue-4.4/vringh-use-wiov-used-to-check-for-read-write-desc-or.patch new file mode 100644 index 00000000000..b2162dc59b1 --- /dev/null +++ b/queue-4.4/vringh-use-wiov-used-to-check-for-read-write-desc-or.patch @@ -0,0 +1,50 @@ +From 40a7686c90f252cff203bbd150ede0aac3bc6948 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Jun 2021 08:55:02 +0530 +Subject: vringh: Use wiov->used to check for read/write desc order + +From: Neeraj Upadhyay + +[ Upstream commit e74cfa91f42c50f7f649b0eca46aa049754ccdbd ] + +As __vringh_iov() traverses a descriptor chain, it populates +each descriptor entry into either read or write vring iov +and increments that iov's ->used member. So, as we iterate +over a descriptor chain, at any point, (riov/wriov)->used +value gives the number of descriptor enteries available, +which are to be read or written by the device. As all read +iovs must precede the write iovs, wiov->used should be zero +when we are traversing a read descriptor. Current code checks +for wiov->i, to figure out whether any previous entry in the +current descriptor chain was a write descriptor. However, +iov->i is only incremented, when these vring iovs are consumed, +at a later point, and remain 0 in __vringh_iov(). So, correct +the check for read and write descriptor order, to use +wiov->used. + +Acked-by: Jason Wang +Reviewed-by: Stefano Garzarella +Signed-off-by: Neeraj Upadhyay +Link: https://lore.kernel.org/r/1624591502-4827-1-git-send-email-neeraju@codeaurora.org +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + drivers/vhost/vringh.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c +index d56736655dec..da47542496cc 100644 +--- a/drivers/vhost/vringh.c ++++ b/drivers/vhost/vringh.c +@@ -329,7 +329,7 @@ __vringh_iov(struct vringh *vrh, u16 i, + iov = wiov; + else { + iov = riov; +- if (unlikely(wiov && wiov->i)) { ++ if (unlikely(wiov && wiov->used)) { + vringh_bad("Readable desc %p after writable", + &descs[i]); + err = -EINVAL; +-- +2.30.2 + -- 2.47.3