diff options
author | Ram Vepa <ram.vepa@qlogic.com> | 2011-12-23 08:01:43 -0500 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2012-01-03 23:53:02 -0500 |
commit | eddfb675256f49d14e8c5763098afe3eb2c93701 (patch) | |
tree | fefe361432c162a48f98076f7156920e083c42fb /drivers/infiniband/hw | |
parent | 8482d5d1bc18c17429a89ad37f8b74d5a16de239 (diff) |
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: Ramkrishna Vepa <ram.vepa@qlogic.com>
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@qlogic.com>
Cc: <stable@kernel.org>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r-- | drivers/infiniband/hw/qib/qib_iba6120.c | 4 | ||||
-rw-r--r-- | drivers/infiniband/hw/qib/qib_iba7220.c | 4 | ||||
-rw-r--r-- | drivers/infiniband/hw/qib/qib_iba7322.c | 6 |
3 files changed, 10 insertions, 4 deletions
diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c index 781a802a321f..4f18e2d332df 100644 --- a/drivers/infiniband/hw/qib/qib_iba6120.c +++ b/drivers/infiniband/hw/qib/qib_iba6120.c | |||
@@ -2076,9 +2076,11 @@ static void qib_6120_config_ctxts(struct qib_devdata *dd) | |||
2076 | static void qib_update_6120_usrhead(struct qib_ctxtdata *rcd, u64 hd, | 2076 | static void qib_update_6120_usrhead(struct qib_ctxtdata *rcd, u64 hd, |
2077 | u32 updegr, u32 egrhd, u32 npkts) | 2077 | u32 updegr, u32 egrhd, u32 npkts) |
2078 | { | 2078 | { |
2079 | qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); | ||
2080 | if (updegr) | 2079 | if (updegr) |
2081 | qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); | 2080 | qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); |
2081 | mmiowb(); | ||
2082 | qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); | ||
2083 | mmiowb(); | ||
2082 | } | 2084 | } |
2083 | 2085 | ||
2084 | static u32 qib_6120_hdrqempty(struct qib_ctxtdata *rcd) | 2086 | static u32 qib_6120_hdrqempty(struct qib_ctxtdata *rcd) |
diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c index 9dd886cc633a..3c722f79d6f6 100644 --- a/drivers/infiniband/hw/qib/qib_iba7220.c +++ b/drivers/infiniband/hw/qib/qib_iba7220.c | |||
@@ -2725,9 +2725,11 @@ static int qib_7220_set_loopback(struct qib_pportdata *ppd, const char *what) | |||
2725 | static void qib_update_7220_usrhead(struct qib_ctxtdata *rcd, u64 hd, | 2725 | static void qib_update_7220_usrhead(struct qib_ctxtdata *rcd, u64 hd, |
2726 | u32 updegr, u32 egrhd, u32 npkts) | 2726 | u32 updegr, u32 egrhd, u32 npkts) |
2727 | { | 2727 | { |
2728 | qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); | ||
2729 | if (updegr) | 2728 | if (updegr) |
2730 | qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); | 2729 | qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); |
2730 | mmiowb(); | ||
2731 | qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); | ||
2732 | mmiowb(); | ||
2731 | } | 2733 | } |
2732 | 2734 | ||
2733 | static u32 qib_7220_hdrqempty(struct qib_ctxtdata *rcd) | 2735 | static u32 qib_7220_hdrqempty(struct qib_ctxtdata *rcd) |
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index abd218d429fe..e22735402649 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c | |||
@@ -4083,10 +4083,12 @@ static void qib_update_7322_usrhead(struct qib_ctxtdata *rcd, u64 hd, | |||
4083 | */ | 4083 | */ |
4084 | if (hd >> IBA7322_HDRHEAD_PKTINT_SHIFT) | 4084 | if (hd >> IBA7322_HDRHEAD_PKTINT_SHIFT) |
4085 | adjust_rcv_timeout(rcd, npkts); | 4085 | adjust_rcv_timeout(rcd, npkts); |
4086 | qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); | ||
4087 | qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); | ||
4088 | if (updegr) | 4086 | if (updegr) |
4089 | qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); | 4087 | qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); |
4088 | mmiowb(); | ||
4089 | qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); | ||
4090 | qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); | ||
4091 | mmiowb(); | ||
4090 | } | 4092 | } |
4091 | 4093 | ||
4092 | static u32 qib_7322_hdrqempty(struct qib_ctxtdata *rcd) | 4094 | static u32 qib_7322_hdrqempty(struct qib_ctxtdata *rcd) |