Skip to content

Commit a7b2b74

Browse files
wenglianfaopsiff
authored andcommitted
RDMA/hns: Fix double destruction of rsv_qp
[ Upstream commit c6957b95ecc5b63c5a4bb4ecc28af326cf8f6dc8 ] rsv_qp may be double destroyed in error flow, first in free_mr_init(), and then in hns_roce_exit(). Fix it by moving the free_mr_init() call into hns_roce_v2_init(). list_del corruption, ffff589732eb9b50->next is LIST_POISON1 (dead000000000100) WARNING: CPU: 8 PID: 1047115 at lib/list_debug.c:53 __list_del_entry_valid+0x148/0x240 ... Call trace: __list_del_entry_valid+0x148/0x240 hns_roce_qp_remove+0x4c/0x3f0 [hns_roce_hw_v2] hns_roce_v2_destroy_qp_common+0x1dc/0x5f4 [hns_roce_hw_v2] hns_roce_v2_destroy_qp+0x22c/0x46c [hns_roce_hw_v2] free_mr_exit+0x6c/0x120 [hns_roce_hw_v2] hns_roce_v2_exit+0x170/0x200 [hns_roce_hw_v2] hns_roce_exit+0x118/0x350 [hns_roce_hw_v2] __hns_roce_hw_v2_init_instance+0x1c8/0x304 [hns_roce_hw_v2] hns_roce_hw_v2_reset_notify_init+0x170/0x21c [hns_roce_hw_v2] hns_roce_hw_v2_reset_notify+0x6c/0x190 [hns_roce_hw_v2] hclge_notify_roce_client+0x6c/0x160 [hclge] hclge_reset_rebuild+0x150/0x5c0 [hclge] hclge_reset+0x10c/0x140 [hclge] hclge_reset_subtask+0x80/0x104 [hclge] hclge_reset_service_task+0x168/0x3ac [hclge] hclge_service_task+0x50/0x100 [hclge] process_one_work+0x250/0x9a0 worker_thread+0x324/0x990 kthread+0x190/0x210 ret_from_fork+0x10/0x18 Fixes: fd84892 ("RDMA/hns: Fix Use-After-Free of rsv_qp on HIP08") Signed-off-by: wenglianfa <[email protected]> Signed-off-by: Junxian Huang <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Sasha Levin <[email protected]> (cherry picked from commit dab173bae3303f074f063750a8dead2550d8c782)
1 parent b849156 commit a7b2b74

File tree

2 files changed

+16
-15
lines changed

2 files changed

+16
-15
lines changed

drivers/infiniband/hw/hns/hns_roce_hw_v2.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2971,14 +2971,22 @@ static int hns_roce_v2_init(struct hns_roce_dev *hr_dev)
29712971
{
29722972
int ret;
29732973

2974+
if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) {
2975+
ret = free_mr_init(hr_dev);
2976+
if (ret) {
2977+
dev_err(hr_dev->dev, "failed to init free mr!\n");
2978+
return ret;
2979+
}
2980+
}
2981+
29742982
/* The hns ROCEE requires the extdb info to be cleared before using */
29752983
ret = hns_roce_clear_extdb_list_info(hr_dev);
29762984
if (ret)
2977-
return ret;
2985+
goto err_clear_extdb_failed;
29782986

29792987
ret = get_hem_table(hr_dev);
29802988
if (ret)
2981-
return ret;
2989+
goto err_clear_extdb_failed;
29822990

29832991
if (hr_dev->is_vf)
29842992
return 0;
@@ -2993,6 +3001,9 @@ static int hns_roce_v2_init(struct hns_roce_dev *hr_dev)
29933001

29943002
err_llm_init_failed:
29953003
put_hem_table(hr_dev);
3004+
err_clear_extdb_failed:
3005+
if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08)
3006+
free_mr_exit(hr_dev);
29963007

29973008
return ret;
29983009
}
@@ -7027,21 +7038,11 @@ static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle)
70277038
goto error_failed_roce_init;
70287039
}
70297040

7030-
if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) {
7031-
ret = free_mr_init(hr_dev);
7032-
if (ret) {
7033-
dev_err(hr_dev->dev, "failed to init free mr!\n");
7034-
goto error_failed_free_mr_init;
7035-
}
7036-
}
70377041

70387042
handle->priv = hr_dev;
70397043

70407044
return 0;
70417045

7042-
error_failed_free_mr_init:
7043-
hns_roce_exit(hr_dev);
7044-
70457046
error_failed_roce_init:
70467047
kfree(hr_dev->priv);
70477048

drivers/infiniband/hw/hns/hns_roce_main.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,9 @@ static int hns_roce_setup_hca(struct hns_roce_dev *hr_dev)
965965

966966
spin_lock_init(&hr_dev->sm_lock);
967967

968+
INIT_LIST_HEAD(&hr_dev->qp_list);
969+
spin_lock_init(&hr_dev->qp_list_lock);
970+
968971
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_CQ_RECORD_DB ||
969972
hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_QP_RECORD_DB) {
970973
INIT_LIST_HEAD(&hr_dev->pgdir_list);
@@ -1132,9 +1135,6 @@ int hns_roce_init(struct hns_roce_dev *hr_dev)
11321135
}
11331136
}
11341137

1135-
INIT_LIST_HEAD(&hr_dev->qp_list);
1136-
spin_lock_init(&hr_dev->qp_list_lock);
1137-
11381138
ret = hns_roce_register_device(hr_dev);
11391139
if (ret)
11401140
goto error_failed_register_device;

0 commit comments

Comments
 (0)