]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.19
authorSasha Levin <sashal@kernel.org>
Mon, 30 Aug 2021 19:21:27 +0000 (15:21 -0400)
committerSasha Levin <sashal@kernel.org>
Mon, 30 Aug 2021 19:21:27 +0000 (15:21 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.19/drm-copy-drm_wait_vblank-to-user-before-returning.patch [new file with mode: 0644]
queue-4.19/drm-nouveau-disp-power-down-unused-dp-links-during-i.patch [new file with mode: 0644]
queue-4.19/net-rds-dma_map_sg-is-entitled-to-merge-entries.patch [new file with mode: 0644]
queue-4.19/opp-remove-warn-when-no-valid-opps-remain.patch [new file with mode: 0644]
queue-4.19/qed-fix-null-pointer-dereference-in-qed_rdma_create_.patch [new file with mode: 0644]
queue-4.19/qed-qed-ll2-race-condition-fixes.patch [new file with mode: 0644]
queue-4.19/series
queue-4.19/virtio-improve-vq-broken-access-to-avoid-any-compile.patch [new file with mode: 0644]
queue-4.19/virtio_pci-support-surprise-removal-of-virtio-pci-de.patch [new file with mode: 0644]
queue-4.19/vringh-use-wiov-used-to-check-for-read-write-desc-or.patch [new file with mode: 0644]

diff --git a/queue-4.19/drm-copy-drm_wait_vblank-to-user-before-returning.patch b/queue-4.19/drm-copy-drm_wait_vblank-to-user-before-returning.patch
new file mode 100644 (file)
index 0000000..cbe80ea
--- /dev/null
@@ -0,0 +1,70 @@
+From 7ffb76c215d428424bb8c4e8f11ef2c14eaa1c49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Aug 2021 15:49:17 -0400
+Subject: drm: Copy drm_wait_vblank to user before returning
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mark Yacoub <markyacoub@google.com>
+
+[ Upstream commit fa0b1ef5f7a694f48e00804a391245f3471aa155 ]
+
+[Why]
+Userspace should get back a copy of drm_wait_vblank that's been modified
+even when drm_wait_vblank_ioctl returns a failure.
+
+Rationale:
+drm_wait_vblank_ioctl modifies the request and expects the user to read
+it back. When the type is RELATIVE, it modifies it to ABSOLUTE and updates
+the sequence to become current_vblank_count + sequence (which was
+RELATIVE), but now it became ABSOLUTE.
+drmWaitVBlank (in libdrm) expects this to be the case as it modifies
+the request to be Absolute so it expects the sequence to would have been
+updated.
+
+The change is in compat_drm_wait_vblank, which is called by
+drm_compat_ioctl. This change of copying the data back regardless of the
+return number makes it en par with drm_ioctl, which always copies the
+data before returning.
+
+[How]
+Return from the function after everything has been copied to user.
+
+Fixes IGT:kms_flip::modeset-vs-vblank-race-interruptible
+Tested on ChromeOS Trogdor(msm)
+
+Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
+Signed-off-by: Mark Yacoub <markyacoub@chromium.org>
+Signed-off-by: Sean Paul <seanpaul@chromium.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210812194917.1703356-1-markyacoub@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_ioc32.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c
+index ab8847c7dd96..87e13bcd7a67 100644
+--- a/drivers/gpu/drm/drm_ioc32.c
++++ b/drivers/gpu/drm/drm_ioc32.c
+@@ -855,8 +855,6 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
+       req.request.sequence = req32.request.sequence;
+       req.request.signal = req32.request.signal;
+       err = drm_ioctl_kernel(file, drm_wait_vblank_ioctl, &req, DRM_UNLOCKED);
+-      if (err)
+-              return err;
+       req32.reply.type = req.reply.type;
+       req32.reply.sequence = req.reply.sequence;
+@@ -865,7 +863,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
+       if (copy_to_user(argp, &req32, sizeof(req32)))
+               return -EFAULT;
+-      return 0;
++      return err;
+ }
+ #if defined(CONFIG_X86)
+-- 
+2.30.2
+
diff --git a/queue-4.19/drm-nouveau-disp-power-down-unused-dp-links-during-i.patch b/queue-4.19/drm-nouveau-disp-power-down-unused-dp-links-during-i.patch
new file mode 100644 (file)
index 0000000..0ef7398
--- /dev/null
@@ -0,0 +1,81 @@
+From 77c013fe39b115c9bd54468078c605ecb333f925 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Aug 2021 16:40:48 +1000
+Subject: drm/nouveau/disp: power down unused DP links during init
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+[ Upstream commit 6eaa1f3c59a707332e921e32782ffcad49915c5e ]
+
+When booted with multiple displays attached, the EFI GOP driver on (at
+least) Ampere, can leave DP links powered up that aren't being used to
+display anything.  This confuses our tracking of SOR routing, with the
+likely result being a failed modeset and display engine hang.
+
+Fix this by (ab?)using the DisableLT IED script to power-down the link,
+restoring HW to a state the driver expects.
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Reviewed-by: Lyude Paul <lyude@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c   | 2 +-
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h   | 1 +
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c | 9 +++++++++
+ 3 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
+index 818d21bd28d3..1d2837c5a8f2 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
+@@ -419,7 +419,7 @@ nvkm_dp_train(struct nvkm_dp *dp, u32 dataKBps)
+       return ret;
+ }
+-static void
++void
+ nvkm_dp_disable(struct nvkm_outp *outp, struct nvkm_ior *ior)
+ {
+       struct nvkm_dp *dp = nvkm_dp(outp);
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h
+index 495f665a0ee6..12d6ff4cfa95 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h
+@@ -32,6 +32,7 @@ struct nvkm_dp {
+ int nvkm_dp_new(struct nvkm_disp *, int index, struct dcb_output *,
+               struct nvkm_outp **);
++void nvkm_dp_disable(struct nvkm_outp *, struct nvkm_ior *);
+ /* DPCD Receiver Capabilities */
+ #define DPCD_RC00_DPCD_REV                                              0x00000
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
+index c62030c96fba..4b1c72fd8f03 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
+@@ -22,6 +22,7 @@
+  * Authors: Ben Skeggs
+  */
+ #include "outp.h"
++#include "dp.h"
+ #include "ior.h"
+ #include <subdev/bios.h>
+@@ -216,6 +217,14 @@ nvkm_outp_init_route(struct nvkm_outp *outp)
+       if (!ior->arm.head || ior->arm.proto != proto) {
+               OUTP_DBG(outp, "no heads (%x %d %d)", ior->arm.head,
+                        ior->arm.proto, proto);
++
++              /* The EFI GOP driver on Ampere can leave unused DP links routed,
++               * which we don't expect.  The DisableLT IED script *should* get
++               * us back to where we need to be.
++               */
++              if (ior->func->route.get && !ior->arm.head && outp->info.type == DCB_OUTPUT_DP)
++                      nvkm_dp_disable(outp, ior);
++
+               return;
+       }
+-- 
+2.30.2
+
diff --git a/queue-4.19/net-rds-dma_map_sg-is-entitled-to-merge-entries.patch b/queue-4.19/net-rds-dma_map_sg-is-entitled-to-merge-entries.patch
new file mode 100644 (file)
index 0000000..10758b0
--- /dev/null
@@ -0,0 +1,49 @@
+From 40cda404deda36a56d5be31409183db8d1185c91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Aug 2021 10:04:37 -0700
+Subject: net/rds: dma_map_sg is entitled to merge entries
+
+From: Gerd Rausch <gerd.rausch@oracle.com>
+
+[ Upstream commit fb4b1373dcab086d0619c29310f0466a0b2ceb8a ]
+
+Function "dma_map_sg" is entitled to merge adjacent entries
+and return a value smaller than what was passed as "nents".
+
+Subsequently "ib_map_mr_sg" needs to work with this value ("sg_dma_len")
+rather than the original "nents" parameter ("sg_len").
+
+This old RDS bug was exposed and reliably causes kernel panics
+(using RDMA operations "rds-stress -D") on x86_64 starting with:
+commit c588072bba6b ("iommu/vt-d: Convert intel iommu driver to the iommu ops")
+
+Simply put: Linux 5.11 and later.
+
+Signed-off-by: Gerd Rausch <gerd.rausch@oracle.com>
+Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
+Link: https://lore.kernel.org/r/60efc69f-1f35-529d-a7ef-da0549cad143@oracle.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/ib_frmr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/rds/ib_frmr.c b/net/rds/ib_frmr.c
+index 6431a023ac89..46988c009a3e 100644
+--- a/net/rds/ib_frmr.c
++++ b/net/rds/ib_frmr.c
+@@ -111,9 +111,9 @@ static int rds_ib_post_reg_frmr(struct rds_ib_mr *ibmr)
+               cpu_relax();
+       }
+-      ret = ib_map_mr_sg_zbva(frmr->mr, ibmr->sg, ibmr->sg_len,
++      ret = ib_map_mr_sg_zbva(frmr->mr, ibmr->sg, ibmr->sg_dma_len,
+                               &off, PAGE_SIZE);
+-      if (unlikely(ret != ibmr->sg_len))
++      if (unlikely(ret != ibmr->sg_dma_len))
+               return ret < 0 ? ret : -EINVAL;
+       /* Perform a WR for the fast_reg_mr. Each individual page
+-- 
+2.30.2
+
diff --git a/queue-4.19/opp-remove-warn-when-no-valid-opps-remain.patch b/queue-4.19/opp-remove-warn-when-no-valid-opps-remain.patch
new file mode 100644 (file)
index 0000000..f36ba44
--- /dev/null
@@ -0,0 +1,41 @@
+From 74baabf0efcea1b3e973b3c3c28e15e3ce25eca0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jul 2021 10:30:56 +0200
+Subject: opp: remove WARN when no valid OPPs remain
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michał Mirosław <mirq-linux@rere.qmqm.pl>
+
+[ Upstream commit 335ffab3ef864539e814b9a2903b0ae420c1c067 ]
+
+This WARN can be triggered per-core and the stack trace is not useful.
+Replace it with plain dev_err(). Fix a comment while at it.
+
+Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/opp/of.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/opp/of.c b/drivers/opp/of.c
+index d64a13d7881b..a53123356697 100644
+--- a/drivers/opp/of.c
++++ b/drivers/opp/of.c
+@@ -423,8 +423,9 @@ static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np)
+               }
+       }
+-      /* There should be one of more OPP defined */
+-      if (WARN_ON(!count)) {
++      /* There should be one or more OPPs defined */
++      if (!count) {
++              dev_err(dev, "%s: no supported OPPs", __func__);
+               ret = -ENOENT;
+               goto put_opp_table;
+       }
+-- 
+2.30.2
+
diff --git a/queue-4.19/qed-fix-null-pointer-dereference-in-qed_rdma_create_.patch b/queue-4.19/qed-fix-null-pointer-dereference-in-qed_rdma_create_.patch
new file mode 100644 (file)
index 0000000..e45b826
--- /dev/null
@@ -0,0 +1,40 @@
+From e93ce64228783562b7e7904390519d879e00c770 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Aug 2021 14:06:39 +0300
+Subject: qed: Fix null-pointer dereference in qed_rdma_create_qp()
+
+From: Shai Malin <smalin@marvell.com>
+
+[ Upstream commit d33d19d313d3466abdf8b0428be7837aff767802 ]
+
+Fix a possible null-pointer dereference in qed_rdma_create_qp().
+
+Changes from V2:
+- Revert checkpatch fixes.
+
+Reported-by: TOTE Robot <oslab@tsinghua.edu.cn>
+Signed-off-by: Ariel Elior <aelior@marvell.com>
+Signed-off-by: Shai Malin <smalin@marvell.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qlogic/qed/qed_rdma.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.c b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
+index 909422d93903..3392982ff374 100644
+--- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
+@@ -1244,8 +1244,7 @@ qed_rdma_create_qp(void *rdma_cxt,
+       if (!rdma_cxt || !in_params || !out_params ||
+           !p_hwfn->p_rdma_info->active) {
+-              DP_ERR(p_hwfn->cdev,
+-                     "qed roce create qp failed due to NULL entry (rdma_cxt=%p, in=%p, out=%p, roce_info=?\n",
++              pr_err("qed roce create qp failed due to NULL entry (rdma_cxt=%p, in=%p, out=%p, roce_info=?\n",
+                      rdma_cxt, in_params, out_params);
+               return NULL;
+       }
+-- 
+2.30.2
+
diff --git a/queue-4.19/qed-qed-ll2-race-condition-fixes.patch b/queue-4.19/qed-qed-ll2-race-condition-fixes.patch
new file mode 100644 (file)
index 0000000..5627d76
--- /dev/null
@@ -0,0 +1,90 @@
+From 58152ee9784b50318aad5b626f17bffc1e2b0c3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Aug 2021 14:05:08 +0300
+Subject: qed: qed ll2 race condition fixes
+
+From: Shai Malin <smalin@marvell.com>
+
+[ Upstream commit 37110237f31105d679fc0aa7b11cdec867750ea7 ]
+
+Avoiding qed ll2 race condition and NULL pointer dereference as part
+of the remove and recovery flows.
+
+Changes form V1:
+- Change (!p_rx->set_prod_addr).
+- qed_ll2.c checkpatch fixes.
+
+Change from V2:
+- Revert "qed_ll2.c checkpatch fixes".
+
+Signed-off-by: Ariel Elior <aelior@marvell.com>
+Signed-off-by: Shai Malin <smalin@marvell.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qlogic/qed/qed_ll2.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
+index 2847509a183d..cb3569ac85f7 100644
+--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
+@@ -354,6 +354,9 @@ static int qed_ll2_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie)
+       unsigned long flags;
+       int rc = -EINVAL;
++      if (!p_ll2_conn)
++              return rc;
++
+       spin_lock_irqsave(&p_tx->lock, flags);
+       if (p_tx->b_completing_packet) {
+               rc = -EBUSY;
+@@ -527,7 +530,16 @@ static int qed_ll2_rxq_completion(struct qed_hwfn *p_hwfn, void *cookie)
+       unsigned long flags = 0;
+       int rc = 0;
++      if (!p_ll2_conn)
++              return rc;
++
+       spin_lock_irqsave(&p_rx->lock, flags);
++
++      if (!QED_LL2_RX_REGISTERED(p_ll2_conn)) {
++              spin_unlock_irqrestore(&p_rx->lock, flags);
++              return 0;
++      }
++
+       cq_new_idx = le16_to_cpu(*p_rx->p_fw_cons);
+       cq_old_idx = qed_chain_get_cons_idx(&p_rx->rcq_chain);
+@@ -848,6 +860,9 @@ static int qed_ll2_lb_rxq_completion(struct qed_hwfn *p_hwfn, void *p_cookie)
+       struct qed_ll2_info *p_ll2_conn = (struct qed_ll2_info *)p_cookie;
+       int rc;
++      if (!p_ll2_conn)
++              return 0;
++
+       if (!QED_LL2_RX_REGISTERED(p_ll2_conn))
+               return 0;
+@@ -871,6 +886,9 @@ static int qed_ll2_lb_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie)
+       u16 new_idx = 0, num_bds = 0;
+       int rc;
++      if (!p_ll2_conn)
++              return 0;
++
+       if (!QED_LL2_TX_REGISTERED(p_ll2_conn))
+               return 0;
+@@ -1628,6 +1646,8 @@ int qed_ll2_post_rx_buffer(void *cxt,
+       if (!p_ll2_conn)
+               return -EINVAL;
+       p_rx = &p_ll2_conn->rx_queue;
++      if (!p_rx->set_prod_addr)
++              return -EIO;
+       spin_lock_irqsave(&p_rx->lock, flags);
+       if (!list_empty(&p_rx->free_descq))
+-- 
+2.30.2
+
index 3ee9be354043f7dd7c0ce5544b4e287fd30af63e..7d374c31deb78964ecbcd30526ff233cf5a454ee 100644 (file)
@@ -17,3 +17,12 @@ xgene-v2-fix-a-resource-leak-in-the-error-handling-p.patch
 net-marvell-fix-mvneta_tx_in_prgrs-bit-number.patch
 net-hns3-fix-get-wrong-pfc_en-when-query-pfc-configu.patch
 usb-gadget-u_audio-fix-race-condition-on-endpoint-st.patch
+opp-remove-warn-when-no-valid-opps-remain.patch
+virtio-improve-vq-broken-access-to-avoid-any-compile.patch
+virtio_pci-support-surprise-removal-of-virtio-pci-de.patch
+vringh-use-wiov-used-to-check-for-read-write-desc-or.patch
+qed-qed-ll2-race-condition-fixes.patch
+qed-fix-null-pointer-dereference-in-qed_rdma_create_.patch
+drm-copy-drm_wait_vblank-to-user-before-returning.patch
+drm-nouveau-disp-power-down-unused-dp-links-during-i.patch
+net-rds-dma_map_sg-is-entitled-to-merge-entries.patch
diff --git a/queue-4.19/virtio-improve-vq-broken-access-to-avoid-any-compile.patch b/queue-4.19/virtio-improve-vq-broken-access-to-avoid-any-compile.patch
new file mode 100644 (file)
index 0000000..b443cfa
--- /dev/null
@@ -0,0 +1,58 @@
+From f21dbe5e096bcb1d2aacb9c5b481e414db3d6129 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jul 2021 17:26:45 +0300
+Subject: virtio: Improve vq->broken access to avoid any compiler optimization
+
+From: Parav Pandit <parav@nvidia.com>
+
+[ 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 <parav@nvidia.com>
+Link: https://lore.kernel.org/r/20210721142648.1525924-2-parav@nvidia.com
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 df7980aef927..0cc0cfd3a3cb 100644
+--- a/drivers/virtio/virtio_ring.c
++++ b/drivers/virtio/virtio_ring.c
+@@ -1197,7 +1197,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);
+@@ -1211,7 +1211,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.19/virtio_pci-support-surprise-removal-of-virtio-pci-de.patch b/queue-4.19/virtio_pci-support-surprise-removal-of-virtio-pci-de.patch
new file mode 100644 (file)
index 0000000..beff1aa
--- /dev/null
@@ -0,0 +1,80 @@
+From 1b518f346f9655187b9950ed1cf4813903ef3348 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jul 2021 17:26:48 +0300
+Subject: virtio_pci: Support surprise removal of virtio pci device
+
+From: Parav Pandit <parav@nvidia.com>
+
+[ Upstream commit 43bb40c5b92659966bdf4bfe584fde0a3575a049 ]
+
+When a virtio pci device undergo surprise removal (aka async removal in
+PCIe spec), mark the device as broken so that any upper layer drivers can
+abort any outstanding operation.
+
+When a virtio net pci device undergo surprise removal which is used by a
+NetworkManager, a below call trace was observed.
+
+kernel:watchdog: BUG: soft lockup - CPU#1 stuck for 26s! [kworker/1:1:27059]
+watchdog: BUG: soft lockup - CPU#1 stuck for 52s! [kworker/1:1:27059]
+CPU: 1 PID: 27059 Comm: kworker/1:1 Tainted: G S      W I  L    5.13.0-hotplug+ #8
+Hardware name: Dell Inc. PowerEdge R640/0H28RR, BIOS 2.9.4 11/06/2020
+Workqueue: events linkwatch_event
+RIP: 0010:virtnet_send_command+0xfc/0x150 [virtio_net]
+Call Trace:
+ virtnet_set_rx_mode+0xcf/0x2a7 [virtio_net]
+ ? __hw_addr_create_ex+0x85/0xc0
+ __dev_mc_add+0x72/0x80
+ igmp6_group_added+0xa7/0xd0
+ ipv6_mc_up+0x3c/0x60
+ ipv6_find_idev+0x36/0x80
+ addrconf_add_dev+0x1e/0xa0
+ addrconf_dev_config+0x71/0x130
+ addrconf_notify+0x1f5/0xb40
+ ? rtnl_is_locked+0x11/0x20
+ ? __switch_to_asm+0x42/0x70
+ ? finish_task_switch+0xaf/0x2c0
+ ? raw_notifier_call_chain+0x3e/0x50
+ raw_notifier_call_chain+0x3e/0x50
+ netdev_state_change+0x67/0x90
+ linkwatch_do_dev+0x3c/0x50
+ __linkwatch_run_queue+0xd2/0x220
+ linkwatch_event+0x21/0x30
+ process_one_work+0x1c8/0x370
+ worker_thread+0x30/0x380
+ ? process_one_work+0x370/0x370
+ kthread+0x118/0x140
+ ? set_kthread_struct+0x40/0x40
+ ret_from_fork+0x1f/0x30
+
+Hence, add the ability to abort the command on surprise removal
+which prevents infinite loop and system lockup.
+
+Signed-off-by: Parav Pandit <parav@nvidia.com>
+Link: https://lore.kernel.org/r/20210721142648.1525924-5-parav@nvidia.com
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/virtio/virtio_pci_common.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
+index 45b04bc91f24..b7cc63f556ee 100644
+--- a/drivers/virtio/virtio_pci_common.c
++++ b/drivers/virtio/virtio_pci_common.c
+@@ -579,6 +579,13 @@ static void virtio_pci_remove(struct pci_dev *pci_dev)
+       struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
+       struct device *dev = get_device(&vp_dev->vdev.dev);
++      /*
++       * Device is marked broken on surprise removal so that virtio upper
++       * layers can abort any ongoing operation.
++       */
++      if (!pci_device_is_present(pci_dev))
++              virtio_break_device(&vp_dev->vdev);
++
+       pci_disable_sriov(pci_dev);
+       unregister_virtio_device(&vp_dev->vdev);
+-- 
+2.30.2
+
diff --git a/queue-4.19/vringh-use-wiov-used-to-check-for-read-write-desc-or.patch b/queue-4.19/vringh-use-wiov-used-to-check-for-read-write-desc-or.patch
new file mode 100644 (file)
index 0000000..ee0c1c6
--- /dev/null
@@ -0,0 +1,50 @@
+From 1969bb9dc0c090c377b908206ca8db5f0ba6ab78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Jun 2021 08:55:02 +0530
+Subject: vringh: Use wiov->used to check for read/write desc order
+
+From: Neeraj Upadhyay <neeraju@codeaurora.org>
+
+[ 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 <jasowang@redhat.com>
+Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
+Signed-off-by: Neeraj Upadhyay <neeraju@codeaurora.org>
+Link: https://lore.kernel.org/r/1624591502-4827-1-git-send-email-neeraju@codeaurora.org
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 59c61744dcc1..97aa9b87e572 100644
+--- a/drivers/vhost/vringh.c
++++ b/drivers/vhost/vringh.c
+@@ -330,7 +330,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
+