From: wenglianfa wenglianfa@huawei.com
driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8N7BG
----------------------------------------------------------------------
For the HIP08, the reserved loopback QP is used to release MRs before the MPT is destroyed. After free_mr_exit() and before hns_roce_unregister_device(), rsv_qp is released and set to NULL, and ib_device is not unregister. During this period, the user mode can use ib_device to execute dereg_mr(). As a result, rsv_qp is accessed again and a NULL pointer is reported.
To fix Use-After-Free of rsv_qp, execute free_mr_exit() after hns_roce_unregister_device().
Fixes: 6f5f556d3795 ("RDMA/hns: Use the reserved loopback QPs to free MR before destroying MPT") Signed-off-by: wenglianfa wenglianfa@huawei.com Signed-off-by: Juan Zhou zhoujuan51@h-partners.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 2b474c22cafa..34d5d1476db2 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -3339,6 +3339,9 @@ static int hns_roce_v2_init(struct hns_roce_dev *hr_dev)
static void hns_roce_v2_exit(struct hns_roce_dev *hr_dev) { + if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) + free_mr_exit(hr_dev); + hns_roce_function_clear(hr_dev);
if (!hr_dev->is_vf) @@ -7699,9 +7702,6 @@ static void __hns_roce_hw_v2_uninit_instance(struct hnae3_handle *handle, hr_dev->state = HNS_ROCE_DEVICE_STATE_UNINIT; hns_roce_handle_device_err(hr_dev);
- if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) - free_mr_exit(hr_dev); - hns_roce_exit(hr_dev, bond_cleanup); kfree(hr_dev->priv); ib_dealloc_device(&hr_dev->ib_dev);
From: Junxian Huang huangjunxian6@hisilicon.com
driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8QLD3
----------------------------------------------------------------------
This reverts commit 2185e6513c793a4a2c5c3fc1ac6b57c5df2b8d9b.
Signed-off-by: Junxian Huang huangjunxian6@hisilicon.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 34d5d1476db2..4909c9c186cc 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -7653,8 +7653,7 @@ static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle)
hns_roce_hw_v2_get_cfg(hr_dev, handle);
- if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_BOND && - hr_dev->is_vf && !check_vf_support(hr_dev->pci_dev)) { + if (hr_dev->is_vf && !check_vf_support(hr_dev->pci_dev)) { ret = -EOPNOTSUPP; goto error_failed_roce_init; }
From: Junxian Huang huangjunxian6@hisilicon.com
driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8QLD3
----------------------------------------------------------------------
This patch makes 2 changes for check_vf_support():
1. add check of RDMA over UBLink VFs before check_vf_support(), since VFs in this case will never be of RoCE bonding slaves.
2. since RDMA over UBLink VFs won't enter check_vf_support() anymore, the return value is changed to false when the PF doesn't have a corresponding hr_dev so that VFs init can be correctly blocked on those non-main_hr_dev slaves.
Fixes: 67fc10550307 ("RDMA/hns: Add support for RDMA VF over UBL") Signed-off-by: Junxian Huang huangjunxian6@hisilicon.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 4909c9c186cc..2c03f556f8e0 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -7624,9 +7624,8 @@ static bool check_vf_support(struct pci_dev *vf) handle = &hdev->vport[0].roce; hr_dev = handle->priv;
- /* In UB link vf can not find the pf device */ if (!hr_dev) - return true; + return false;
bond_grp = hns_roce_get_bond_grp(get_hr_netdev(hr_dev, 0), pf->bus->number); @@ -7639,6 +7638,7 @@ static bool check_vf_support(struct pci_dev *vf) static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle) { struct hns_roce_dev *hr_dev; + struct pci_dev *pdev; int ret;
hr_dev = ib_alloc_device(hns_roce_dev, ib_dev); @@ -7653,7 +7653,9 @@ static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle)
hns_roce_hw_v2_get_cfg(hr_dev, handle);
- if (hr_dev->is_vf && !check_vf_support(hr_dev->pci_dev)) { + pdev = hr_dev->pci_dev; + if (pdev->device != HNAE3_DEV_ID_RDMA_OVER_UBL_VF && + hr_dev->is_vf && !check_vf_support(pdev)) { ret = -EOPNOTSUPP; goto error_failed_roce_init; } @@ -7664,7 +7666,7 @@ static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle) goto error_failed_roce_init; }
- if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) { + if (pdev->revision == PCI_REVISION_ID_HIP08) { ret = free_mr_init(hr_dev); if (ret) { dev_err(hr_dev->dev, "failed to init free mr!\n");