
From: Tao Jihua <taojihua4@huawei.com> driver inclusion category: Bugfix bugzilla: NA CVE: NA This modification is mainly to prevent the hem pointer from being emptied during reset when reset and QP coupling are created, but the QP creation process is not aware, and access to the null pointer occurs. Signed-off-by: Tao Jihua <taojihua4@huawei.com> Reviewed-by: Hu Chunzhi <huchunzhi@huawei.com> Reviewed-by: Wang Lin <wanglin137@huawei.com> Reviewed-by: Zhao Weibo <zhaoweibo3@huawei.com> Signed-off-by: Yang Yingliang <yangyingliang@huawei.com> --- drivers/infiniband/hw/hns/hns_roce_hem.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c index b7a0856..510c008 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hem.c +++ b/drivers/infiniband/hw/hns/hns_roce_hem.c @@ -509,6 +509,11 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev, mutex_lock(&table->mutex); + if (!table->hem) { + ret = -ENODEV; + goto out; + } + if (table->hem[hem_idx]) { ++table->hem[hem_idx]->refcount; goto out; @@ -646,6 +651,11 @@ int hns_roce_table_get(struct hns_roce_dev *hr_dev, mutex_lock(&table->mutex); + if (!table->hem) { + ret = -ENODEV; + goto out; + } + if (table->hem[i]) { ++table->hem[i]->refcount; goto out; @@ -723,6 +733,11 @@ static void hns_roce_table_mhop_put(struct hns_roce_dev *hr_dev, mutex_lock(&table->mutex); + if (!table->hem) { + mutex_unlock(&table->mutex); + return; + } + if (check_refcount && (--table->hem[hem_idx]->refcount > 0)) { mutex_unlock(&table->mutex); return; @@ -797,6 +812,11 @@ void hns_roce_table_put(struct hns_roce_dev *hr_dev, mutex_lock(&table->mutex); + if (!table->hem) { + mutex_unlock(&table->mutex); + return; + } + if (--table->hem[i]->refcount == 0) { /* Clear HEM base address */ hr_dev->hw->clear_hem(hr_dev, table, obj, 0); @@ -830,6 +850,11 @@ void *hns_roce_table_find(struct hns_roce_dev *hr_dev, mutex_lock(&table->mutex); + if (!table->hem) { + mutex_unlock(&table->mutex); + return NULL; + } + if (!hns_roce_check_whether_mhop(hr_dev, table->type)) { obj_per_chunk = table->table_chunk_size / table->obj_size; hem = table->hem[(obj & (table->num_obj - 1)) / obj_per_chunk]; @@ -837,9 +862,9 @@ void *hns_roce_table_find(struct hns_roce_dev *hr_dev, dma_offset = offset = idx_offset * table->obj_size; } else { u32 seg_size; + if (hns_roce_calc_hem_mhop(hr_dev, table, &mhop_obj, &mhop)) goto out; - /* mtt mhop */ i = mhop.l0_idx; j = mhop.l1_idx; @@ -1062,6 +1087,7 @@ static void hns_roce_cleanup_mhop_hem_table(struct hns_roce_dev *hr_dev, } } + mutex_lock(&table->mutex); kfree(table->hem); table->hem = NULL; kfree(table->bt_l1); @@ -1072,6 +1098,7 @@ static void hns_roce_cleanup_mhop_hem_table(struct hns_roce_dev *hr_dev, table->bt_l0 = NULL; kfree(table->bt_l0_dma_addr); table->bt_l0_dma_addr = NULL; + mutex_unlock(&table->mutex); } void hns_roce_cleanup_hem_table(struct hns_roce_dev *hr_dev, -- 1.8.3