From: Greg Kroah-Hartman Date: Sun, 6 May 2018 00:43:09 +0000 (-0700) Subject: 4.14-stable patches X-Git-Tag: v4.9.99~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=aa4d91039dc65bb81c3198a2cdca38f10672b7a3;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: drm-bridge-vga-dac-fix-edid-memory-leak.patch drm-vc4-make-sure-vc4_bo_-inc-dec-_usecnt-calls-are-balanced.patch drm-vmwgfx-fix-a-buffer-object-leak.patch geneve-update-skb-dst-pmtu-on-tx-path.patch ib-hfi1-fix-handling-of-fecn-marked-multicast-packet.patch ib-hfi1-fix-loss-of-becn-with-ahg.patch ib-hfi1-fix-null-pointer-dereference-when-invalid-num_vls-is-used.patch iw_cxgb4-atomically-flush-per-qp-hw-cqes.patch net-don-t-call-update_pmtu-unconditionally.patch test_firmware-fix-setting-old-custom-fw-path-back-on-exit-second-try.patch --- diff --git a/queue-4.14/drm-bridge-vga-dac-fix-edid-memory-leak.patch b/queue-4.14/drm-bridge-vga-dac-fix-edid-memory-leak.patch new file mode 100644 index 00000000000..e9622d3635c --- /dev/null +++ b/queue-4.14/drm-bridge-vga-dac-fix-edid-memory-leak.patch @@ -0,0 +1,42 @@ +From 49ceda9de2da4d1827941d06701f3017c27c1855 Mon Sep 17 00:00:00 2001 +From: Sean Paul +Date: Fri, 20 Apr 2018 14:59:59 -0400 +Subject: drm/bridge: vga-dac: Fix edid memory leak + +From: Sean Paul + +commit 49ceda9de2da4d1827941d06701f3017c27c1855 upstream. + +edid should be freed once it's finished being used. + +Fixes: 56fe8b6f4991 ("drm/bridge: Add RGB to VGA bridge support") +Cc: Rob Herring +Cc: Sean Paul +Cc: Maxime Ripard +Cc: Archit Taneja +Cc: Andrzej Hajda +Cc: Laurent Pinchart +Cc: # v4.9+ +Reviewed-by: Maxime Ripard +Reviewed-by: Laurent Pinchart +Signed-off-by: Sean Paul +Link: https://patchwork.freedesktop.org/patch/msgid/20180420190007.1572-1-seanpaul@chromium.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/bridge/dumb-vga-dac.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/bridge/dumb-vga-dac.c ++++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c +@@ -55,7 +55,9 @@ static int dumb_vga_get_modes(struct drm + } + + drm_mode_connector_update_edid_property(connector, edid); +- return drm_add_edid_modes(connector, edid); ++ ret = drm_add_edid_modes(connector, edid); ++ kfree(edid); ++ return ret; + + fallback: + /* diff --git a/queue-4.14/drm-vc4-make-sure-vc4_bo_-inc-dec-_usecnt-calls-are-balanced.patch b/queue-4.14/drm-vc4-make-sure-vc4_bo_-inc-dec-_usecnt-calls-are-balanced.patch new file mode 100644 index 00000000000..e23410a2287 --- /dev/null +++ b/queue-4.14/drm-vc4-make-sure-vc4_bo_-inc-dec-_usecnt-calls-are-balanced.patch @@ -0,0 +1,123 @@ +From f7aef1c207092770d06d0df21dceafdca2b49c39 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Mon, 30 Apr 2018 15:32:32 +0200 +Subject: drm/vc4: Make sure vc4_bo_{inc,dec}_usecnt() calls are balanced + +From: Boris Brezillon + +commit f7aef1c207092770d06d0df21dceafdca2b49c39 upstream. + +Commit b9f19259b84d ("drm/vc4: Add the DRM_IOCTL_VC4_GEM_MADVISE ioctl") +introduced a mechanism to mark some BOs as purgeable to allow the driver +to drop them under memory pressure. In order to implement this feature +we had to add a mechanism to mark BOs as currently used by a piece of +hardware which materialized through the ->usecnt counter. + +Plane code is supposed to increment usecnt when it attaches a BO to a +plane and decrement it when it's done with this BO, which was done in +the ->prepare_fb() and ->cleanup_fb() hooks. The problem is, async page +flip logic does not go through the regular atomic update path, and +->prepare_fb() and ->cleanup_fb() are not called in this case. + +Fix that by manually calling vc4_bo_{inc,dec}_usecnt() in the +async-page-flip path. + +Note that all this should go away as soon as we get generic async page +flip support in the core, in the meantime, this fix should do the +trick. + +Fixes: b9f19259b84d ("drm/vc4: Add the DRM_IOCTL_VC4_GEM_MADVISE ioctl") +Reported-by: Peter Robinson +Cc: +Signed-off-by: Boris Brezillon +Signed-off-by: Eric Anholt +Link: https://patchwork.freedesktop.org/patch/msgid/20180430133232.32457-1-boris.brezillon@bootlin.com +Link: https://patchwork.freedesktop.org/patch/msgid/20180430133232.32457-1-boris.brezillon@bootlin.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/vc4/vc4_crtc.c | 46 ++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 45 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/vc4/vc4_crtc.c ++++ b/drivers/gpu/drm/vc4/vc4_crtc.c +@@ -735,6 +735,7 @@ static irqreturn_t vc4_crtc_irq_handler( + struct vc4_async_flip_state { + struct drm_crtc *crtc; + struct drm_framebuffer *fb; ++ struct drm_framebuffer *old_fb; + struct drm_pending_vblank_event *event; + + struct vc4_seqno_cb cb; +@@ -764,6 +765,23 @@ vc4_async_page_flip_complete(struct vc4_ + + drm_crtc_vblank_put(crtc); + drm_framebuffer_put(flip_state->fb); ++ ++ /* Decrement the BO usecnt in order to keep the inc/dec calls balanced ++ * when the planes are updated through the async update path. ++ * FIXME: we should move to generic async-page-flip when it's ++ * available, so that we can get rid of this hand-made cleanup_fb() ++ * logic. ++ */ ++ if (flip_state->old_fb) { ++ struct drm_gem_cma_object *cma_bo; ++ struct vc4_bo *bo; ++ ++ cma_bo = drm_fb_cma_get_gem_obj(flip_state->old_fb, 0); ++ bo = to_vc4_bo(&cma_bo->base); ++ vc4_bo_dec_usecnt(bo); ++ drm_framebuffer_put(flip_state->old_fb); ++ } ++ + kfree(flip_state); + + up(&vc4->async_modeset); +@@ -788,9 +806,22 @@ static int vc4_async_page_flip(struct dr + struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0); + struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); + ++ /* Increment the BO usecnt here, so that we never end up with an ++ * unbalanced number of vc4_bo_{dec,inc}_usecnt() calls when the ++ * plane is later updated through the non-async path. ++ * FIXME: we should move to generic async-page-flip when it's ++ * available, so that we can get rid of this hand-made prepare_fb() ++ * logic. ++ */ ++ ret = vc4_bo_inc_usecnt(bo); ++ if (ret) ++ return ret; ++ + flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL); +- if (!flip_state) ++ if (!flip_state) { ++ vc4_bo_dec_usecnt(bo); + return -ENOMEM; ++ } + + drm_framebuffer_get(fb); + flip_state->fb = fb; +@@ -801,10 +832,23 @@ static int vc4_async_page_flip(struct dr + ret = down_interruptible(&vc4->async_modeset); + if (ret) { + drm_framebuffer_put(fb); ++ vc4_bo_dec_usecnt(bo); + kfree(flip_state); + return ret; + } + ++ /* Save the current FB before it's replaced by the new one in ++ * drm_atomic_set_fb_for_plane(). We'll need the old FB in ++ * vc4_async_page_flip_complete() to decrement the BO usecnt and keep ++ * it consistent. ++ * FIXME: we should move to generic async-page-flip when it's ++ * available, so that we can get rid of this hand-made cleanup_fb() ++ * logic. ++ */ ++ flip_state->old_fb = plane->state->fb; ++ if (flip_state->old_fb) ++ drm_framebuffer_get(flip_state->old_fb); ++ + WARN_ON(drm_crtc_vblank_get(crtc) != 0); + + /* Immediately update the plane's legacy fb pointer, so that later diff --git a/queue-4.14/drm-vmwgfx-fix-a-buffer-object-leak.patch b/queue-4.14/drm-vmwgfx-fix-a-buffer-object-leak.patch new file mode 100644 index 00000000000..3dfb51b553f --- /dev/null +++ b/queue-4.14/drm-vmwgfx-fix-a-buffer-object-leak.patch @@ -0,0 +1,33 @@ +From 13f149d47392782baafd96d54d4e65f3b5ca342f Mon Sep 17 00:00:00 2001 +From: Thomas Hellstrom +Date: Thu, 26 Apr 2018 09:59:30 +0200 +Subject: drm/vmwgfx: Fix a buffer object leak + +From: Thomas Hellstrom + +commit 13f149d47392782baafd96d54d4e65f3b5ca342f upstream. + +A buffer object leak was introduced when fixing a premature buffer +object release. Fix this. + +Cc: +Fixes: 73a88250b709 ("Fix a destoy-while-held mutex problem.") +Signed-off-by: Thomas Hellstrom +Reviewed-by: Deepak Rawat +Reviewed-by: Sinclair Yeh +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +@@ -2612,6 +2612,7 @@ void vmw_kms_helper_resource_finish(stru + vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf, + out_fence, NULL); + ++ vmw_dmabuf_unreference(&ctx->buf); + vmw_resource_unreserve(res, false, NULL, 0); + mutex_unlock(&res->dev_priv->cmdbuf_mutex); + } diff --git a/queue-4.14/geneve-update-skb-dst-pmtu-on-tx-path.patch b/queue-4.14/geneve-update-skb-dst-pmtu-on-tx-path.patch new file mode 100644 index 00000000000..a4b168c528f --- /dev/null +++ b/queue-4.14/geneve-update-skb-dst-pmtu-on-tx-path.patch @@ -0,0 +1,59 @@ +From 52a589d51f1008f62569bf89e95b26221ee76690 Mon Sep 17 00:00:00 2001 +From: Xin Long +Date: Mon, 25 Dec 2017 14:43:58 +0800 +Subject: geneve: update skb dst pmtu on tx path + +From: Xin Long + +commit 52a589d51f1008f62569bf89e95b26221ee76690 upstream. + +Commit a93bf0ff4490 ("vxlan: update skb dst pmtu on tx path") has fixed +a performance issue caused by the change of lower dev's mtu for vxlan. + +The same thing needs to be done for geneve as well. + +Note that geneve cannot adjust it's mtu according to lower dev's mtu +when creating it. The performance is very low later when netperfing +over it without fixing the mtu manually. This patch could also avoid +this issue. + +Signed-off-by: Xin Long +Signed-off-by: David S. Miller +Cc: Thomas Deutschmann +Cc: Eddie Chapman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/geneve.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/drivers/net/geneve.c ++++ b/drivers/net/geneve.c +@@ -825,6 +825,13 @@ static int geneve_xmit_skb(struct sk_buf + if (IS_ERR(rt)) + return PTR_ERR(rt); + ++ if (skb_dst(skb)) { ++ int mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr) - ++ GENEVE_BASE_HLEN - info->options_len - 14; ++ ++ skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); ++ } ++ + sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); + if (geneve->collect_md) { + tos = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb); +@@ -864,6 +871,13 @@ static int geneve6_xmit_skb(struct sk_bu + if (IS_ERR(dst)) + return PTR_ERR(dst); + ++ if (skb_dst(skb)) { ++ int mtu = dst_mtu(dst) - sizeof(struct ipv6hdr) - ++ GENEVE_BASE_HLEN - info->options_len - 14; ++ ++ skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); ++ } ++ + sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); + if (geneve->collect_md) { + prio = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb); diff --git a/queue-4.14/ib-hfi1-fix-handling-of-fecn-marked-multicast-packet.patch b/queue-4.14/ib-hfi1-fix-handling-of-fecn-marked-multicast-packet.patch new file mode 100644 index 00000000000..8a65860b343 --- /dev/null +++ b/queue-4.14/ib-hfi1-fix-handling-of-fecn-marked-multicast-packet.patch @@ -0,0 +1,151 @@ +From f59fb9e05109b836230813e45f71c9ecc2d5dbe6 Mon Sep 17 00:00:00 2001 +From: Mike Marciniszyn +Date: Tue, 1 May 2018 05:35:36 -0700 +Subject: IB/hfi1: Fix handling of FECN marked multicast packet + +From: Mike Marciniszyn + +commit f59fb9e05109b836230813e45f71c9ecc2d5dbe6 upstream. + +The code for handling a marked UD packet unconditionally returns the +dlid in the header of the FECN marked packet. This is not correct +for multicast packets where the DLID is in the multicast range. + +The subsequent attempt to send the CNP with the multicast lid will +cause the chip to halt the ack send context because the source +lid doesn't match the chip programming. The send context will +be halted and flush any other pending packets in the pio ring causing +the CNP to not be sent. + +A part of investigating the fix, it was determined that the 16B work +broke the FECN routine badly with inconsistent use of 16 bit and 32 bits +types for lids and pkeys. Since the port's source lid was correctly 32 +bits the type mixmatches need to be dealt with at the same time as +fixing the CNP header issue. + +Fix these issues by: +- Using the ports lid for as the SLID for responding to FECN marked UD + packets +- Insure pkey is always 16 bit in this and subordinate routines +- Insure lids are 32 bits in this and subordinate routines + +Cc: # 4.14.x +Fixes: 88733e3b8450 ("IB/hfi1: Add 16B UD support") +Reviewed-by: Don Hiatt +Reviewed-by: Michael J. Ruhl +Signed-off-by: Mike Marciniszyn +Signed-off-by: Dennis Dalessandro +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/hfi1/driver.c | 19 +++++++++++++++---- + drivers/infiniband/hw/hfi1/hfi.h | 8 ++++---- + drivers/infiniband/hw/hfi1/ud.c | 4 ++-- + 3 files changed, 21 insertions(+), 10 deletions(-) + +--- a/drivers/infiniband/hw/hfi1/driver.c ++++ b/drivers/infiniband/hw/hfi1/driver.c +@@ -437,31 +437,43 @@ void hfi1_process_ecn_slowpath(struct rv + bool do_cnp) + { + struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); ++ struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); + struct ib_other_headers *ohdr = pkt->ohdr; + struct ib_grh *grh = pkt->grh; + u32 rqpn = 0, bth1; +- u16 pkey, rlid, dlid = ib_get_dlid(pkt->hdr); ++ u16 pkey; ++ u32 rlid, slid, dlid = 0; + u8 hdr_type, sc, svc_type; + bool is_mcast = false; + ++ /* can be called from prescan */ + if (pkt->etype == RHF_RCV_TYPE_BYPASS) { + is_mcast = hfi1_is_16B_mcast(dlid); + pkey = hfi1_16B_get_pkey(pkt->hdr); + sc = hfi1_16B_get_sc(pkt->hdr); ++ dlid = hfi1_16B_get_dlid(pkt->hdr); ++ slid = hfi1_16B_get_slid(pkt->hdr); + hdr_type = HFI1_PKT_TYPE_16B; + } else { + is_mcast = (dlid > be16_to_cpu(IB_MULTICAST_LID_BASE)) && + (dlid != be16_to_cpu(IB_LID_PERMISSIVE)); + pkey = ib_bth_get_pkey(ohdr); + sc = hfi1_9B_get_sc5(pkt->hdr, pkt->rhf); ++ dlid = ib_get_dlid(pkt->hdr); ++ slid = ib_get_slid(pkt->hdr); + hdr_type = HFI1_PKT_TYPE_9B; + } + + switch (qp->ibqp.qp_type) { ++ case IB_QPT_UD: ++ dlid = ppd->lid; ++ rlid = slid; ++ rqpn = ib_get_sqpn(pkt->ohdr); ++ svc_type = IB_CC_SVCTYPE_UD; ++ break; + case IB_QPT_SMI: + case IB_QPT_GSI: +- case IB_QPT_UD: +- rlid = ib_get_slid(pkt->hdr); ++ rlid = slid; + rqpn = ib_get_sqpn(pkt->ohdr); + svc_type = IB_CC_SVCTYPE_UD; + break; +@@ -486,7 +498,6 @@ void hfi1_process_ecn_slowpath(struct rv + dlid, rlid, sc, grh); + + if (!is_mcast && (bth1 & IB_BECN_SMASK)) { +- struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); + u32 lqpn = bth1 & RVT_QPN_MASK; + u8 sl = ibp->sc_to_sl[sc]; + +--- a/drivers/infiniband/hw/hfi1/hfi.h ++++ b/drivers/infiniband/hw/hfi1/hfi.h +@@ -1523,13 +1523,13 @@ void set_link_ipg(struct hfi1_pportdata + void process_becn(struct hfi1_pportdata *ppd, u8 sl, u32 rlid, u32 lqpn, + u32 rqpn, u8 svc_type); + void return_cnp(struct hfi1_ibport *ibp, struct rvt_qp *qp, u32 remote_qpn, +- u32 pkey, u32 slid, u32 dlid, u8 sc5, ++ u16 pkey, u32 slid, u32 dlid, u8 sc5, + const struct ib_grh *old_grh); + void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp, +- u32 remote_qpn, u32 pkey, u32 slid, u32 dlid, ++ u32 remote_qpn, u16 pkey, u32 slid, u32 dlid, + u8 sc5, const struct ib_grh *old_grh); + typedef void (*hfi1_handle_cnp)(struct hfi1_ibport *ibp, struct rvt_qp *qp, +- u32 remote_qpn, u32 pkey, u32 slid, u32 dlid, ++ u32 remote_qpn, u16 pkey, u32 slid, u32 dlid, + u8 sc5, const struct ib_grh *old_grh); + + /* We support only two types - 9B and 16B for now */ +@@ -2431,7 +2431,7 @@ static inline void hfi1_make_16b_hdr(str + ((slid >> OPA_16B_SLID_SHIFT) << OPA_16B_SLID_HIGH_SHIFT); + lrh2 = (lrh2 & ~OPA_16B_DLID_MASK) | + ((dlid >> OPA_16B_DLID_SHIFT) << OPA_16B_DLID_HIGH_SHIFT); +- lrh2 = (lrh2 & ~OPA_16B_PKEY_MASK) | (pkey << OPA_16B_PKEY_SHIFT); ++ lrh2 = (lrh2 & ~OPA_16B_PKEY_MASK) | ((u32)pkey << OPA_16B_PKEY_SHIFT); + lrh2 = (lrh2 & ~OPA_16B_L4_MASK) | l4; + + hdr->lrh[0] = lrh0; +--- a/drivers/infiniband/hw/hfi1/ud.c ++++ b/drivers/infiniband/hw/hfi1/ud.c +@@ -630,7 +630,7 @@ int hfi1_lookup_pkey_idx(struct hfi1_ibp + } + + void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp, +- u32 remote_qpn, u32 pkey, u32 slid, u32 dlid, ++ u32 remote_qpn, u16 pkey, u32 slid, u32 dlid, + u8 sc5, const struct ib_grh *old_grh) + { + u64 pbc, pbc_flags = 0; +@@ -688,7 +688,7 @@ void return_cnp_16B(struct hfi1_ibport * + } + + void return_cnp(struct hfi1_ibport *ibp, struct rvt_qp *qp, u32 remote_qpn, +- u32 pkey, u32 slid, u32 dlid, u8 sc5, ++ u16 pkey, u32 slid, u32 dlid, u8 sc5, + const struct ib_grh *old_grh) + { + u64 pbc, pbc_flags = 0; diff --git a/queue-4.14/ib-hfi1-fix-loss-of-becn-with-ahg.patch b/queue-4.14/ib-hfi1-fix-loss-of-becn-with-ahg.patch new file mode 100644 index 00000000000..22ec979338c --- /dev/null +++ b/queue-4.14/ib-hfi1-fix-loss-of-becn-with-ahg.patch @@ -0,0 +1,125 @@ +From 0a0bcb046b2f0c15b89f8c1b08ad3de601a83c66 Mon Sep 17 00:00:00 2001 +From: Mike Marciniszyn +Date: Tue, 1 May 2018 05:35:51 -0700 +Subject: IB/hfi1: Fix loss of BECN with AHG + +From: Mike Marciniszyn + +commit 0a0bcb046b2f0c15b89f8c1b08ad3de601a83c66 upstream. + +AHG may be armed to use the stored header, which by design is limited +to edits in the PSN/A 32 bit word (bth2). + +When the code is trying to send a BECN, the use of the stored header +will lose the BECN bit. + +Fix by avoiding AHG when getting ready to send a BECN. This is +accomplished by always claiming the packet is not a middle packet which +is an AHG precursor. BECNs are not a normal case and this should not +hurt AHG optimizations. + +Cc: # 4.14.x +Reviewed-by: Michael J. Ruhl +Signed-off-by: Mike Marciniszyn +Signed-off-by: Dennis Dalessandro +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/hfi1/ruc.c | 50 +++++++++++++++++++++++++++++++-------- + 1 file changed, 40 insertions(+), 10 deletions(-) + +--- a/drivers/infiniband/hw/hfi1/ruc.c ++++ b/drivers/infiniband/hw/hfi1/ruc.c +@@ -745,6 +745,20 @@ static inline void hfi1_make_ruc_bth(str + ohdr->bth[2] = cpu_to_be32(bth2); + } + ++/** ++ * hfi1_make_ruc_header_16B - build a 16B header ++ * @qp: the queue pair ++ * @ohdr: a pointer to the destination header memory ++ * @bth0: bth0 passed in from the RC/UC builder ++ * @bth2: bth2 passed in from the RC/UC builder ++ * @middle: non zero implies indicates ahg "could" be used ++ * @ps: the current packet state ++ * ++ * This routine may disarm ahg under these situations: ++ * - packet needs a GRH ++ * - BECN needed ++ * - migration state not IB_MIG_MIGRATED ++ */ + static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, + struct ib_other_headers *ohdr, + u32 bth0, u32 bth2, int middle, +@@ -789,6 +803,12 @@ static inline void hfi1_make_ruc_header_ + else + middle = 0; + ++ if (qp->s_flags & RVT_S_ECN) { ++ qp->s_flags &= ~RVT_S_ECN; ++ /* we recently received a FECN, so return a BECN */ ++ becn = true; ++ middle = 0; ++ } + if (middle) + build_ahg(qp, bth2); + else +@@ -796,11 +816,6 @@ static inline void hfi1_make_ruc_header_ + + bth0 |= pkey; + bth0 |= extra_bytes << 20; +- if (qp->s_flags & RVT_S_ECN) { +- qp->s_flags &= ~RVT_S_ECN; +- /* we recently received a FECN, so return a BECN */ +- becn = 1; +- } + hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2); + + if (!ppd->lid) +@@ -818,6 +833,20 @@ static inline void hfi1_make_ruc_header_ + pkey, becn, 0, l4, priv->s_sc); + } + ++/** ++ * hfi1_make_ruc_header_9B - build a 9B header ++ * @qp: the queue pair ++ * @ohdr: a pointer to the destination header memory ++ * @bth0: bth0 passed in from the RC/UC builder ++ * @bth2: bth2 passed in from the RC/UC builder ++ * @middle: non zero implies indicates ahg "could" be used ++ * @ps: the current packet state ++ * ++ * This routine may disarm ahg under these situations: ++ * - packet needs a GRH ++ * - BECN needed ++ * - migration state not IB_MIG_MIGRATED ++ */ + static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp, + struct ib_other_headers *ohdr, + u32 bth0, u32 bth2, int middle, +@@ -853,6 +882,12 @@ static inline void hfi1_make_ruc_header_ + else + middle = 0; + ++ if (qp->s_flags & RVT_S_ECN) { ++ qp->s_flags &= ~RVT_S_ECN; ++ /* we recently received a FECN, so return a BECN */ ++ bth1 |= (IB_BECN_MASK << IB_BECN_SHIFT); ++ middle = 0; ++ } + if (middle) + build_ahg(qp, bth2); + else +@@ -860,11 +895,6 @@ static inline void hfi1_make_ruc_header_ + + bth0 |= pkey; + bth0 |= extra_bytes << 20; +- if (qp->s_flags & RVT_S_ECN) { +- qp->s_flags &= ~RVT_S_ECN; +- /* we recently received a FECN, so return a BECN */ +- bth1 |= (IB_BECN_MASK << IB_BECN_SHIFT); +- } + hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2); + + if (!ppd->lid) diff --git a/queue-4.14/ib-hfi1-fix-null-pointer-dereference-when-invalid-num_vls-is-used.patch b/queue-4.14/ib-hfi1-fix-null-pointer-dereference-when-invalid-num_vls-is-used.patch new file mode 100644 index 00000000000..20491a44c6f --- /dev/null +++ b/queue-4.14/ib-hfi1-fix-null-pointer-dereference-when-invalid-num_vls-is-used.patch @@ -0,0 +1,79 @@ +From 45d924571a5e1329580811f2419da61b07ac3613 Mon Sep 17 00:00:00 2001 +From: Sebastian Sanchez +Date: Tue, 1 May 2018 05:35:58 -0700 +Subject: IB/hfi1: Fix NULL pointer dereference when invalid num_vls is used + +From: Sebastian Sanchez + +commit 45d924571a5e1329580811f2419da61b07ac3613 upstream. + +When an invalid num_vls is used as a module parameter, the code +execution follows an exception path where the macro dd_dev_err() +expects dd->pcidev->dev not to be NULL in hfi1_init_dd(). This +causes a NULL pointer dereference. + +Fix hfi1_init_dd() by initializing dd->pcidev and dd->pcidev->dev +earlier in the code. If a dd exists, then dd->pcidev and +dd->pcidev->dev always exists. + +BUG: unable to handle kernel NULL pointer dereference +at 00000000000000f0 +IP: __dev_printk+0x15/0x90 +Workqueue: events work_for_cpu_fn +RIP: 0010:__dev_printk+0x15/0x90 +Call Trace: + dev_err+0x6c/0x90 + ? hfi1_init_pportdata+0x38d/0x3f0 [hfi1] + hfi1_init_dd+0xdd/0x2530 [hfi1] + ? pci_conf1_read+0xb2/0xf0 + ? pci_read_config_word.part.9+0x64/0x80 + ? pci_conf1_write+0xb0/0xf0 + ? pcie_capability_clear_and_set_word+0x57/0x80 + init_one+0x141/0x490 [hfi1] + local_pci_probe+0x3f/0xa0 + work_for_cpu_fn+0x10/0x20 + process_one_work+0x152/0x350 + worker_thread+0x1cf/0x3e0 + kthread+0xf5/0x130 + ? max_active_store+0x80/0x80 + ? kthread_bind+0x10/0x10 + ? do_syscall_64+0x6e/0x1a0 + ? SyS_exit_group+0x10/0x10 + ret_from_fork+0x35/0x40 + +Cc: # 4.9.x +Reviewed-by: Mike Marciniszyn +Reviewed-by: Michael J. Ruhl +Signed-off-by: Sebastian Sanchez +Signed-off-by: Dennis Dalessandro +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/hfi1/init.c | 2 ++ + drivers/infiniband/hw/hfi1/pcie.c | 3 --- + 2 files changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/infiniband/hw/hfi1/init.c ++++ b/drivers/infiniband/hw/hfi1/init.c +@@ -1234,6 +1234,8 @@ struct hfi1_devdata *hfi1_alloc_devdata( + return ERR_PTR(-ENOMEM); + dd->num_pports = nports; + dd->pport = (struct hfi1_pportdata *)(dd + 1); ++ dd->pcidev = pdev; ++ pci_set_drvdata(pdev, dd); + + INIT_LIST_HEAD(&dd->list); + idr_preload(GFP_KERNEL); +--- a/drivers/infiniband/hw/hfi1/pcie.c ++++ b/drivers/infiniband/hw/hfi1/pcie.c +@@ -163,9 +163,6 @@ int hfi1_pcie_ddinit(struct hfi1_devdata + resource_size_t addr; + int ret = 0; + +- dd->pcidev = pdev; +- pci_set_drvdata(pdev, dd); +- + addr = pci_resource_start(pdev, 0); + len = pci_resource_len(pdev, 0); + diff --git a/queue-4.14/iw_cxgb4-atomically-flush-per-qp-hw-cqes.patch b/queue-4.14/iw_cxgb4-atomically-flush-per-qp-hw-cqes.patch new file mode 100644 index 00000000000..19dbbd7ca22 --- /dev/null +++ b/queue-4.14/iw_cxgb4-atomically-flush-per-qp-hw-cqes.patch @@ -0,0 +1,88 @@ +From 2df19e19ae90d94fd8724083f161f368a2797537 Mon Sep 17 00:00:00 2001 +From: Bharat Potnuri +Date: Fri, 27 Apr 2018 16:41:16 +0530 +Subject: iw_cxgb4: Atomically flush per QP HW CQEs + +From: Bharat Potnuri + +commit 2df19e19ae90d94fd8724083f161f368a2797537 upstream. + +When a CQ is shared by multiple QPs, c4iw_flush_hw_cq() needs to acquire +corresponding QP lock before moving the CQEs into its corresponding SW +queue and accessing the SQ contents for completing a WR. +Ignore CQEs if corresponding QP is already flushed. + +Cc: stable@vger.kernel.org +Signed-off-by: Potnuri Bharat Teja +Reviewed-by: Steve Wise +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/cxgb4/cq.c | 11 ++++++++++- + drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 2 +- + drivers/infiniband/hw/cxgb4/qp.c | 4 ++-- + 3 files changed, 13 insertions(+), 4 deletions(-) + +--- a/drivers/infiniband/hw/cxgb4/cq.c ++++ b/drivers/infiniband/hw/cxgb4/cq.c +@@ -330,7 +330,7 @@ static void advance_oldest_read(struct t + * Deal with out-of-order and/or completions that complete + * prior unsignalled WRs. + */ +-void c4iw_flush_hw_cq(struct c4iw_cq *chp) ++void c4iw_flush_hw_cq(struct c4iw_cq *chp, struct c4iw_qp *flush_qhp) + { + struct t4_cqe *hw_cqe, *swcqe, read_cqe; + struct c4iw_qp *qhp; +@@ -354,6 +354,13 @@ void c4iw_flush_hw_cq(struct c4iw_cq *ch + if (qhp == NULL) + goto next_cqe; + ++ if (flush_qhp != qhp) { ++ spin_lock(&qhp->lock); ++ ++ if (qhp->wq.flushed == 1) ++ goto next_cqe; ++ } ++ + if (CQE_OPCODE(hw_cqe) == FW_RI_TERMINATE) + goto next_cqe; + +@@ -405,6 +412,8 @@ void c4iw_flush_hw_cq(struct c4iw_cq *ch + next_cqe: + t4_hwcq_consume(&chp->cq); + ret = t4_next_hw_cqe(&chp->cq, &hw_cqe); ++ if (qhp && flush_qhp != qhp) ++ spin_unlock(&qhp->lock); + } + } + +--- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h ++++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +@@ -993,7 +993,7 @@ void c4iw_pblpool_free(struct c4iw_rdev + u32 c4iw_ocqp_pool_alloc(struct c4iw_rdev *rdev, int size); + void c4iw_ocqp_pool_free(struct c4iw_rdev *rdev, u32 addr, int size); + int c4iw_ofld_send(struct c4iw_rdev *rdev, struct sk_buff *skb); +-void c4iw_flush_hw_cq(struct c4iw_cq *chp); ++void c4iw_flush_hw_cq(struct c4iw_cq *chp, struct c4iw_qp *flush_qhp); + void c4iw_count_rcqes(struct t4_cq *cq, struct t4_wq *wq, int *count); + int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp); + int c4iw_flush_rq(struct t4_wq *wq, struct t4_cq *cq, int count); +--- a/drivers/infiniband/hw/cxgb4/qp.c ++++ b/drivers/infiniband/hw/cxgb4/qp.c +@@ -1349,12 +1349,12 @@ static void __flush_qp(struct c4iw_qp *q + qhp->wq.flushed = 1; + t4_set_wq_in_error(&qhp->wq); + +- c4iw_flush_hw_cq(rchp); ++ c4iw_flush_hw_cq(rchp, qhp); + c4iw_count_rcqes(&rchp->cq, &qhp->wq, &count); + rq_flushed = c4iw_flush_rq(&qhp->wq, &rchp->cq, count); + + if (schp != rchp) +- c4iw_flush_hw_cq(schp); ++ c4iw_flush_hw_cq(schp, qhp); + sq_flushed = c4iw_flush_sq(qhp); + + spin_unlock(&qhp->lock); diff --git a/queue-4.14/net-don-t-call-update_pmtu-unconditionally.patch b/queue-4.14/net-don-t-call-update_pmtu-unconditionally.patch new file mode 100644 index 00000000000..2f0db9c953c --- /dev/null +++ b/queue-4.14/net-don-t-call-update_pmtu-unconditionally.patch @@ -0,0 +1,173 @@ +From f15ca723c1ebe6c1a06bc95fda6b62cd87b44559 Mon Sep 17 00:00:00 2001 +From: Nicolas Dichtel +Date: Thu, 25 Jan 2018 19:03:03 +0100 +Subject: net: don't call update_pmtu unconditionally + +From: Nicolas Dichtel + +commit f15ca723c1ebe6c1a06bc95fda6b62cd87b44559 upstream. + +Some dst_ops (e.g. md_dst_ops)) doesn't set this handler. It may result to: +"BUG: unable to handle kernel NULL pointer dereference at (null)" + +Let's add a helper to check if update_pmtu is available before calling it. + +Fixes: 52a589d51f10 ("geneve: update skb dst pmtu on tx path") +Fixes: a93bf0ff4490 ("vxlan: update skb dst pmtu on tx path") +CC: Roman Kapl +CC: Xin Long +Signed-off-by: Nicolas Dichtel +Signed-off-by: David S. Miller +Cc: Thomas Deutschmann +Cc: Eddie Chapman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/ipoib/ipoib_cm.c | 3 +-- + drivers/net/geneve.c | 4 ++-- + drivers/net/vxlan.c | 6 ++---- + include/net/dst.h | 8 ++++++++ + net/ipv4/ip_tunnel.c | 3 +-- + net/ipv4/ip_vti.c | 2 +- + net/ipv6/ip6_tunnel.c | 5 ++--- + net/ipv6/ip6_vti.c | 2 +- + net/ipv6/sit.c | 4 ++-- + 9 files changed, 20 insertions(+), 17 deletions(-) + +--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c ++++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c +@@ -1447,8 +1447,7 @@ void ipoib_cm_skb_too_long(struct net_de + struct ipoib_dev_priv *priv = ipoib_priv(dev); + int e = skb_queue_empty(&priv->cm.skb_queue); + +- if (skb_dst(skb)) +- skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); ++ skb_dst_update_pmtu(skb, mtu); + + skb_queue_tail(&priv->cm.skb_queue, skb); + if (e) +--- a/drivers/net/geneve.c ++++ b/drivers/net/geneve.c +@@ -829,7 +829,7 @@ static int geneve_xmit_skb(struct sk_buf + int mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr) - + GENEVE_BASE_HLEN - info->options_len - 14; + +- skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); ++ skb_dst_update_pmtu(skb, mtu); + } + + sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); +@@ -875,7 +875,7 @@ static int geneve6_xmit_skb(struct sk_bu + int mtu = dst_mtu(dst) - sizeof(struct ipv6hdr) - + GENEVE_BASE_HLEN - info->options_len - 14; + +- skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); ++ skb_dst_update_pmtu(skb, mtu); + } + + sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -2158,8 +2158,7 @@ static void vxlan_xmit_one(struct sk_buf + if (skb_dst(skb)) { + int mtu = dst_mtu(ndst) - VXLAN_HEADROOM; + +- skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, +- skb, mtu); ++ skb_dst_update_pmtu(skb, mtu); + } + + tos = ip_tunnel_ecn_encap(tos, old_iph, skb); +@@ -2200,8 +2199,7 @@ static void vxlan_xmit_one(struct sk_buf + if (skb_dst(skb)) { + int mtu = dst_mtu(ndst) - VXLAN6_HEADROOM; + +- skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, +- skb, mtu); ++ skb_dst_update_pmtu(skb, mtu); + } + + tos = ip_tunnel_ecn_encap(tos, old_iph, skb); +--- a/include/net/dst.h ++++ b/include/net/dst.h +@@ -520,4 +520,12 @@ static inline struct xfrm_state *dst_xfr + } + #endif + ++static inline void skb_dst_update_pmtu(struct sk_buff *skb, u32 mtu) ++{ ++ struct dst_entry *dst = skb_dst(skb); ++ ++ if (dst && dst->ops->update_pmtu) ++ dst->ops->update_pmtu(dst, NULL, skb, mtu); ++} ++ + #endif /* _NET_DST_H */ +--- a/net/ipv4/ip_tunnel.c ++++ b/net/ipv4/ip_tunnel.c +@@ -521,8 +521,7 @@ static int tnl_update_pmtu(struct net_de + else + mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; + +- if (skb_dst(skb)) +- skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); ++ skb_dst_update_pmtu(skb, mtu); + + if (skb->protocol == htons(ETH_P_IP)) { + if (!skb_is_gso(skb) && +--- a/net/ipv4/ip_vti.c ++++ b/net/ipv4/ip_vti.c +@@ -209,7 +209,7 @@ static netdev_tx_t vti_xmit(struct sk_bu + + mtu = dst_mtu(dst); + if (skb->len > mtu) { +- skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); ++ skb_dst_update_pmtu(skb, mtu); + if (skb->protocol == htons(ETH_P_IP)) { + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, + htonl(mtu)); +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -652,7 +652,7 @@ ip4ip6_err(struct sk_buff *skb, struct i + if (rel_info > dst_mtu(skb_dst(skb2))) + goto out; + +- skb_dst(skb2)->ops->update_pmtu(skb_dst(skb2), NULL, skb2, rel_info); ++ skb_dst_update_pmtu(skb2, rel_info); + } + if (rel_type == ICMP_REDIRECT) + skb_dst(skb2)->ops->redirect(skb_dst(skb2), NULL, skb2); +@@ -1141,8 +1141,7 @@ route_lookup: + mtu = 576; + } + +- if (skb_dst(skb) && !t->parms.collect_md) +- skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); ++ skb_dst_update_pmtu(skb, mtu); + if (skb->len - t->tun_hlen - eth_hlen > mtu && !skb_is_gso(skb)) { + *pmtu = mtu; + err = -EMSGSIZE; +--- a/net/ipv6/ip6_vti.c ++++ b/net/ipv6/ip6_vti.c +@@ -486,7 +486,7 @@ vti6_xmit(struct sk_buff *skb, struct ne + + mtu = dst_mtu(dst); + if (!skb->ignore_df && skb->len > mtu) { +- skb_dst(skb)->ops->update_pmtu(dst, NULL, skb, mtu); ++ skb_dst_update_pmtu(skb, mtu); + + if (skb->protocol == htons(ETH_P_IPV6)) { + if (mtu < IPV6_MIN_MTU) +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -925,8 +925,8 @@ static netdev_tx_t ipip6_tunnel_xmit(str + df = 0; + } + +- if (tunnel->parms.iph.daddr && skb_dst(skb)) +- skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); ++ if (tunnel->parms.iph.daddr) ++ skb_dst_update_pmtu(skb, mtu); + + if (skb->len > mtu && !skb_is_gso(skb)) { + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); diff --git a/queue-4.14/series b/queue-4.14/series index 1acd1edeff7..246616a76c2 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -21,3 +21,13 @@ rdma-mlx5-fix-multiple-null-ptr-deref-errors-in-rereg_mr-flow.patch rdma-mlx5-protect-from-shift-operand-overflow.patch net-usb-qmi_wwan-add-support-for-ublox-r410m-pid-0x90b2.patch ib-mlx5-use-unlimited-rate-when-static-rate-is-not-supported.patch +ib-hfi1-fix-handling-of-fecn-marked-multicast-packet.patch +ib-hfi1-fix-loss-of-becn-with-ahg.patch +ib-hfi1-fix-null-pointer-dereference-when-invalid-num_vls-is-used.patch +iw_cxgb4-atomically-flush-per-qp-hw-cqes.patch +drm-vc4-make-sure-vc4_bo_-inc-dec-_usecnt-calls-are-balanced.patch +drm-vmwgfx-fix-a-buffer-object-leak.patch +drm-bridge-vga-dac-fix-edid-memory-leak.patch +test_firmware-fix-setting-old-custom-fw-path-back-on-exit-second-try.patch +geneve-update-skb-dst-pmtu-on-tx-path.patch +net-don-t-call-update_pmtu-unconditionally.patch diff --git a/queue-4.14/test_firmware-fix-setting-old-custom-fw-path-back-on-exit-second-try.patch b/queue-4.14/test_firmware-fix-setting-old-custom-fw-path-back-on-exit-second-try.patch new file mode 100644 index 00000000000..9837b77ee54 --- /dev/null +++ b/queue-4.14/test_firmware-fix-setting-old-custom-fw-path-back-on-exit-second-try.patch @@ -0,0 +1,44 @@ +From e538409257d0217a9bc715686100a5328db75a15 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Wed, 4 Apr 2018 22:38:49 +0200 +Subject: test_firmware: fix setting old custom fw path back on exit, second try + +From: Ben Hutchings + +commit e538409257d0217a9bc715686100a5328db75a15 upstream. + +Commit 65c79230576 tried to clear the custom firmware path on exit by +writing a single space to the firmware_class.path parameter. This +doesn't work because nothing strips this space from the value stored +and fw_get_filesystem_firmware() only ignores zero-length paths. + +Instead, write a null byte. + +Fixes: 0a8adf58475 ("test: add firmware_class loader test") +Fixes: 65c79230576 ("test_firmware: fix setting old custom fw path back on exit") +Signed-off-by: Ben Hutchings +Acked-by: Luis R. Rodriguez +Cc: stable +Signed-off-by: Greg Kroah-Hartman + + +--- + tools/testing/selftests/firmware/fw_filesystem.sh | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/tools/testing/selftests/firmware/fw_filesystem.sh ++++ b/tools/testing/selftests/firmware/fw_filesystem.sh +@@ -46,9 +46,11 @@ test_finish() + echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout + fi + if [ "$OLD_FWPATH" = "" ]; then +- OLD_FWPATH=" " ++ # A zero-length write won't work; write a null byte ++ printf '\000' >/sys/module/firmware_class/parameters/path ++ else ++ echo -n "$OLD_FWPATH" >/sys/module/firmware_class/parameters/path + fi +- echo -n "$OLD_FWPATH" >/sys/module/firmware_class/parameters/path + rm -f "$FW" + rmdir "$FWPATH" + }