diff options
author | Lang Cheng <chenglang@huawei.com> | 2020-08-25 19:07:54 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-10-29 10:11:38 +0100 |
commit | 3321bce35115a7a19a366b20351f3b0ad6591c52 (patch) | |
tree | d0d9e5fac0e1a0417a742bf9a8c040b7680fc1a9 /drivers/infiniband | |
parent | 2772ec907249ac6f23e6e75b36117ae0edf0bf2f (diff) | |
download | linux-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.c | 6 |
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 && |