Commit eddfb675 authored by Ram Vepa's avatar Ram Vepa Committed by Roland Dreier

IB/qib: Fix a possible data corruption when receiving packets

Prevent a receive data corruption by ensuring that the write to update
the rcvhdrheadn register to generate an interrupt is at the very end
of the receive processing.
Signed-off-by: default avatarRamkrishna Vepa <ram.vepa@qlogic.com>
Signed-off-by: default avatarMike Marciniszyn <mike.marciniszyn@qlogic.com>
Cc: <stable@kernel.org>
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent 8482d5d1
...@@ -2076,9 +2076,11 @@ static void qib_6120_config_ctxts(struct qib_devdata *dd) ...@@ -2076,9 +2076,11 @@ static void qib_6120_config_ctxts(struct qib_devdata *dd)
static void qib_update_6120_usrhead(struct qib_ctxtdata *rcd, u64 hd, static void qib_update_6120_usrhead(struct qib_ctxtdata *rcd, u64 hd,
u32 updegr, u32 egrhd, u32 npkts) u32 updegr, u32 egrhd, u32 npkts)
{ {
qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
if (updegr) if (updegr)
qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt);
mmiowb();
qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
mmiowb();
} }
static u32 qib_6120_hdrqempty(struct qib_ctxtdata *rcd) static u32 qib_6120_hdrqempty(struct qib_ctxtdata *rcd)
......
...@@ -2725,9 +2725,11 @@ static int qib_7220_set_loopback(struct qib_pportdata *ppd, const char *what) ...@@ -2725,9 +2725,11 @@ static int qib_7220_set_loopback(struct qib_pportdata *ppd, const char *what)
static void qib_update_7220_usrhead(struct qib_ctxtdata *rcd, u64 hd, static void qib_update_7220_usrhead(struct qib_ctxtdata *rcd, u64 hd,
u32 updegr, u32 egrhd, u32 npkts) u32 updegr, u32 egrhd, u32 npkts)
{ {
qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
if (updegr) if (updegr)
qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt);
mmiowb();
qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
mmiowb();
} }
static u32 qib_7220_hdrqempty(struct qib_ctxtdata *rcd) static u32 qib_7220_hdrqempty(struct qib_ctxtdata *rcd)
......
...@@ -4083,10 +4083,12 @@ static void qib_update_7322_usrhead(struct qib_ctxtdata *rcd, u64 hd, ...@@ -4083,10 +4083,12 @@ static void qib_update_7322_usrhead(struct qib_ctxtdata *rcd, u64 hd,
*/ */
if (hd >> IBA7322_HDRHEAD_PKTINT_SHIFT) if (hd >> IBA7322_HDRHEAD_PKTINT_SHIFT)
adjust_rcv_timeout(rcd, npkts); adjust_rcv_timeout(rcd, npkts);
qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
if (updegr) if (updegr)
qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt);
mmiowb();
qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
mmiowb();
} }
static u32 qib_7322_hdrqempty(struct qib_ctxtdata *rcd) static u32 qib_7322_hdrqempty(struct qib_ctxtdata *rcd)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment