summaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorLang Cheng <chenglang@huawei.com>2020-08-25 19:07:54 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-10-29 10:11:38 +0100
commit3321bce35115a7a19a366b20351f3b0ad6591c52 (patch)
treed0d9e5fac0e1a0417a742bf9a8c040b7680fc1a9 /drivers/infiniband
parent2772ec907249ac6f23e6e75b36117ae0edf0bf2f (diff)
downloadlinux-stable-3321bce35115a7a19a366b20351f3b0ad6591c52.tar.gz
linux-stable-3321bce35115a7a19a366b20351f3b0ad6591c52.tar.bz2
linux-stable-3321bce35115a7a19a366b20351f3b0ad6591c52.zip
RDMA/hns: Add a check for current state before modifying QP
[ Upstream commit e0ef0f68c4c0d85b1eb63f38d5d10324361280e8 ] It should be considered an illegal operation if the ULP attempts to modify a QP from another state to the current hardware state. Otherwise, the ULP can modify some fields of QPC at any time. For example, for a QP in state of RTS, modify it from RTR to RTS can change the PSN, which is always not as expected. Fixes: 9a4435375cd1 ("IB/hns: Add driver files for hns RoCE driver") Link: https://lore.kernel.org/r/1598353674-24270-1-git-send-email-liweihang@huawei.com Signed-off-by: Lang Cheng <chenglang@huawei.com> Signed-off-by: Weihang Li <liweihang@huawei.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_qp.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c
index c063c450c715..975281f03468 100644
--- a/drivers/infiniband/hw/hns/hns_roce_qp.c
+++ b/drivers/infiniband/hw/hns/hns_roce_qp.c
@@ -1161,8 +1161,10 @@ int hns_roce_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
mutex_lock(&hr_qp->mutex);
- cur_state = attr_mask & IB_QP_CUR_STATE ?
- attr->cur_qp_state : (enum ib_qp_state)hr_qp->state;
+ if (attr_mask & IB_QP_CUR_STATE && attr->cur_qp_state != hr_qp->state)
+ goto out;
+
+ cur_state = hr_qp->state;
new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;
if (ibqp->uobject &&