diff options
author | Michael S. Tsirkin <mst@dev.mellanox.co.il> | 2007-05-14 10:14:50 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-05-14 17:10:34 -0400 |
commit | bd18c112774db5bb887adb981ffbe9bfe00b2f3a (patch) | |
tree | b879940658532e3962e98ce5624f7d86661e122a /drivers/infiniband/hw/mthca/mthca_cq.c | |
parent | 3e28c56b9b67347b42ba06f9a9373b408902beee (diff) |
IB/mthca: Set cleaned CQEs back to HW ownership when cleaning CQ
mthca_cq_clean() updates the CQ consumer index without moving CQEs
back to HW ownership. As a result, the same WRID might get reported
twice, resulting in a use-after-free. This was observed in IPoIB CM.
Fix by moving all freed CQEs to HW ownership.
This fixes <https://bugs.openfabrics.org/show_bug.cgi?id=617>
Signed-off-by: Michael S. Tsirkin <mst@dev.mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/mthca/mthca_cq.c')
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_cq.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c index cf0868f6e965..ca224d018af2 100644 --- a/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/drivers/infiniband/hw/mthca/mthca_cq.c | |||
@@ -284,7 +284,7 @@ void mthca_cq_clean(struct mthca_dev *dev, struct mthca_cq *cq, u32 qpn, | |||
284 | { | 284 | { |
285 | struct mthca_cqe *cqe; | 285 | struct mthca_cqe *cqe; |
286 | u32 prod_index; | 286 | u32 prod_index; |
287 | int nfreed = 0; | 287 | int i, nfreed = 0; |
288 | 288 | ||
289 | spin_lock_irq(&cq->lock); | 289 | spin_lock_irq(&cq->lock); |
290 | 290 | ||
@@ -321,6 +321,8 @@ void mthca_cq_clean(struct mthca_dev *dev, struct mthca_cq *cq, u32 qpn, | |||
321 | } | 321 | } |
322 | 322 | ||
323 | if (nfreed) { | 323 | if (nfreed) { |
324 | for (i = 0; i < nfreed; ++i) | ||
325 | set_cqe_hw(get_cqe(cq, (cq->cons_index + i) & cq->ibcq.cqe)); | ||
324 | wmb(); | 326 | wmb(); |
325 | cq->cons_index += nfreed; | 327 | cq->cons_index += nfreed; |
326 | update_cons_index(dev, cq, nfreed); | 328 | update_cons_index(dev, cq, nfreed); |