IB/hfi1: Fix ECN processing in prescan_rxq
authorDasaratharaman Chandramouli <dasaratharaman.chandramouli@intel.com>
Tue, 25 Oct 2016 20:12:23 +0000 (13:12 -0700)
committerDoug Ledford <dledford@redhat.com>
Tue, 15 Nov 2016 21:16:46 +0000 (16:16 -0500)
When processing ECN via the prescan_rxq path, some fields in the packet
structure are passed uninitialized. This can potentially
cause NULL pointer exceptions during ECN handling.

Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Dasaratharaman Chandramouli <dasaratharaman.chandramouli@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/hw/hfi1/driver.c

index dadd35eedc01aa9796c2beca8741eb29e39dc79d..c5efff29c1479138ea37e585395eccd17059640b 100644 (file)
@@ -599,7 +599,6 @@ static void __prescan_rxq(struct hfi1_packet *packet)
                                         dd->rhf_offset;
                struct rvt_qp *qp;
                struct ib_header *hdr;
-               struct ib_other_headers *ohdr;
                struct rvt_dev_info *rdi = &dd->verbs_dev.rdi;
                u64 rhf = rhf_to_cpu(rhf_addr);
                u32 etype = rhf_rcv_type(rhf), qpn, bth1;
@@ -615,18 +614,21 @@ static void __prescan_rxq(struct hfi1_packet *packet)
                if (etype != RHF_RCV_TYPE_IB)
                        goto next;
 
-               hdr = hfi1_get_msgheader(dd, rhf_addr);
+               packet->hdr = hfi1_get_msgheader(dd, rhf_addr);
+               hdr = packet->hdr;
 
                lnh = be16_to_cpu(hdr->lrh[0]) & 3;
 
-               if (lnh == HFI1_LRH_BTH)
-                       ohdr = &hdr->u.oth;
-               else if (lnh == HFI1_LRH_GRH)
-                       ohdr = &hdr->u.l.oth;
-               else
+               if (lnh == HFI1_LRH_BTH) {
+                       packet->ohdr = &hdr->u.oth;
+               } else if (lnh == HFI1_LRH_GRH) {
+                       packet->ohdr = &hdr->u.l.oth;
+                       packet->rcv_flags |= HFI1_HAS_GRH;
+               } else {
                        goto next; /* just in case */
+               }
 
-               bth1 = be32_to_cpu(ohdr->bth[1]);
+               bth1 = be32_to_cpu(packet->ohdr->bth[1]);
                is_ecn = !!(bth1 & (HFI1_FECN_SMASK | HFI1_BECN_SMASK));
 
                if (!is_ecn)
@@ -646,7 +648,7 @@ static void __prescan_rxq(struct hfi1_packet *packet)
 
                /* turn off BECN, FECN */
                bth1 &= ~(HFI1_FECN_SMASK | HFI1_BECN_SMASK);
-               ohdr->bth[1] = cpu_to_be32(bth1);
+               packet->ohdr->bth[1] = cpu_to_be32(bth1);
 next:
                update_ps_mdata(&mdata, rcd);
        }