Commit 7ca6a3a7 authored by Junxian Huang's avatar Junxian Huang
Browse files

RDMA/hns: Fix unmatched condition in error path of alloc_user_qp_db()

maillist inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBV0G0
CVE: NA

Reference: https://web.git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?h=wip/leon-for-rc&id=b9f59a24ba35a7d955a9f8e148dd9f85b7b40a01



----------------------------------------------------------------------

Currently the condition of unmapping sdb in error path is not exactly
the same as the condition of mapping in alloc_user_qp_db(). This may
cause a problem of unmapping an unmapped db in some case, such as
when the QP is XRC TGT. Unified the two conditions.

Fixes: 90ae0b57 ("RDMA/hns: Combine enable flags of qp")
Signed-off-by: default avatarJunxian Huang <huangjunxian6@hisilicon.com>
Link: https://patch.msgid.link/20250311084857.3803665-4-huangjunxian6@hisilicon.com


Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
Signed-off-by: default avatarXinghai Cen <cenxinghai@h-partners.com>
parent 1607e88b
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -1017,12 +1017,14 @@ static int alloc_user_qp_db(struct hns_roce_dev *hr_dev,
			    struct hns_roce_ib_create_qp *ucmd,
			    struct hns_roce_ib_create_qp_resp *resp)
{
	bool has_sdb = user_qp_has_sdb(hr_dev, init_attr, udata, resp, ucmd);
	struct hns_roce_ucontext *uctx = rdma_udata_to_drv_context(udata,
		struct hns_roce_ucontext, ibucontext);
	bool has_rdb = user_qp_has_rdb(hr_dev, init_attr, udata, resp);
	struct ib_device *ibdev = &hr_dev->ib_dev;
	int ret;

	if (user_qp_has_sdb(hr_dev, init_attr, udata, resp, ucmd)) {
	if (has_sdb) {
		ret = hns_roce_db_map_user(uctx, ucmd->sdb_addr, &hr_qp->sdb);
		if (ret) {
			ibdev_err(ibdev,
@@ -1033,7 +1035,7 @@ static int alloc_user_qp_db(struct hns_roce_dev *hr_dev,
		hr_qp->en_flags |= HNS_ROCE_QP_CAP_SQ_RECORD_DB;
	}

	if (user_qp_has_rdb(hr_dev, init_attr, udata, resp)) {
	if (has_rdb) {
		ret = hns_roce_db_map_user(uctx, ucmd->db_addr, &hr_qp->rdb);
		if (ret) {
			ibdev_err(ibdev,
@@ -1047,7 +1049,7 @@ static int alloc_user_qp_db(struct hns_roce_dev *hr_dev,
	return 0;

err_sdb:
	if (hr_qp->en_flags & HNS_ROCE_QP_CAP_SQ_RECORD_DB)
	if (has_sdb)
		hns_roce_db_unmap_user(uctx, &hr_qp->sdb, false);
err_out:
	return ret;