From 3b23268ccdde90b8d3a10b706fc1a022d3fbcdc5 Mon Sep 17 00:00:00 2001 From: Yonglong Liu Date: Mon, 14 Apr 2025 22:18:21 +0800 Subject: [PATCH 1/2] ptp: hisi: fix list not delete problem driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IC84TA ---------------------------------------------------------------------- If hisi_ptp_create_clock() return failed, need to delete it from the list, and reduce the count, or we can not reprobe the device anymore and may cause a use-after-free problem. Fixes: e6aa0ecf50a8 ("net: hns3: add support for Hisilicon ptp sync device") Signed-off-by: Yonglong Liu Signed-off-by: Hao Chen Signed-off-by: hbmm --- drivers/ptp/ptp_hisi.c | 43 ++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/drivers/ptp/ptp_hisi.c b/drivers/ptp/ptp_hisi.c index c53bcdd08747..421ffd947f79 100644 --- a/drivers/ptp/ptp_hisi.c +++ b/drivers/ptp/ptp_hisi.c @@ -331,12 +331,13 @@ static int hisi_ptp_get_rx_resource(struct platform_device *pdev, ptp->rx_total = rx_total; if (ptp->rx_total != rx_total || ptp->rx_cnt > ptp->rx_total) { + ptp->rx_cnt--; write_unlock_irqrestore(&ptp->rw_lock, flags); dev_err(&pdev->dev, "failed to probe rx device, please check the asl file!\n"); dev_err(&pdev->dev, "rx_total:%u, current rx_total:%u, rx_cnt:%u\n", - ptp->rx_total, rx_total, ptp->rx_cnt); + ptp->rx_total, rx_total, ptp->rx_cnt + 1); return -EINVAL; } @@ -618,6 +619,28 @@ static void hisi_ptp_timer(struct timer_list *t) write_unlock_irqrestore(&ptp->rw_lock, flags); } +static void hisi_ptp_remove_resource(struct platform_device *pdev) +{ + struct hisi_ptp_pdev *ptp = &g_ptpdev; + + if (ptp->ptp_tx && ptp->ptp_tx->dev == &pdev->dev) { + ptp->tx_cnt--; + ptp->ptp_tx = NULL; + dev_info(&pdev->dev, "remove tx ptp device\n"); + } else { + struct hisi_ptp_rx *rx; + + list_for_each_entry(rx, &ptp->ptp_rx_list, node) { + if (rx->dev == &pdev->dev) { + ptp->rx_cnt--; + list_del(&rx->node); + dev_info(&pdev->dev, "remove rx ptp device\n"); + break; + } + } + } +} + static int hisi_ptp_probe(struct platform_device *pdev) { struct hisi_ptp_pdev *ptp = &g_ptpdev; @@ -659,6 +682,7 @@ static int hisi_ptp_probe(struct platform_device *pdev) } if (!ptp->rx_base) { + hisi_ptp_remove_resource(pdev); write_unlock_irqrestore(&ptp->rw_lock, flags); dev_err(&pdev->dev, "failed to probe, no base rx device, please check the asl file!\n"); @@ -677,6 +701,7 @@ static int hisi_ptp_probe(struct platform_device *pdev) if (ret) { write_lock_irqsave(&ptp->rw_lock, flags); hisi_ptp_disable(ptp); + hisi_ptp_remove_resource(pdev); write_unlock_irqrestore(&ptp->rw_lock, flags); return ret; } @@ -690,7 +715,6 @@ static int hisi_ptp_probe(struct platform_device *pdev) static int hisi_ptp_remove(struct platform_device *pdev) { struct hisi_ptp_pdev *ptp = &g_ptpdev; - struct hisi_ptp_rx *rx; unsigned long flags; if (test_and_clear_bit(HISI_PTP_INIT_DONE, &ptp->flag)) { @@ -705,20 +729,7 @@ static int hisi_ptp_remove(struct platform_device *pdev) } write_lock_irqsave(&ptp->rw_lock, flags); - if (ptp->ptp_tx && ptp->ptp_tx->dev == &pdev->dev) { - ptp->tx_cnt--; - ptp->ptp_tx = NULL; - dev_info(&pdev->dev, "remove tx ptp device\n"); - } else { - list_for_each_entry(rx, &ptp->ptp_rx_list, node) { - if (rx->dev == &pdev->dev) { - ptp->rx_cnt--; - list_del(&rx->node); - dev_info(&pdev->dev, "remove rx ptp device\n"); - break; - } - } - } + hisi_ptp_remove_resource(pdev); write_unlock_irqrestore(&ptp->rw_lock, flags); return 0; -- Gitee From c5132648c9f9191d04af821b54a3435c862aa41b Mon Sep 17 00:00:00 2001 From: Yonglong Liu Date: Tue, 15 Apr 2025 17:34:15 +0800 Subject: [PATCH 2/2] ptp: hisi: the print of element in ptp need protected by lock driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IC84TA ---------------------------------------------------------------------- Make the access of ptp->rx_total, ptp->rx_cnt and ptp->tx_cnt under the lock. Fixes: e6aa0ecf50a8 ("net: hns3: add support for Hisilicon ptp sync device") Signed-off-by: Yonglong Liu Signed-off-by: Hao Chen Signed-off-by: hbmm --- drivers/ptp/ptp_hisi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ptp/ptp_hisi.c b/drivers/ptp/ptp_hisi.c index 421ffd947f79..a64255147640 100644 --- a/drivers/ptp/ptp_hisi.c +++ b/drivers/ptp/ptp_hisi.c @@ -332,12 +332,12 @@ static int hisi_ptp_get_rx_resource(struct platform_device *pdev, if (ptp->rx_total != rx_total || ptp->rx_cnt > ptp->rx_total) { ptp->rx_cnt--; - write_unlock_irqrestore(&ptp->rw_lock, flags); dev_err(&pdev->dev, "failed to probe rx device, please check the asl file!\n"); dev_err(&pdev->dev, "rx_total:%u, current rx_total:%u, rx_cnt:%u\n", ptp->rx_total, rx_total, ptp->rx_cnt + 1); + write_unlock_irqrestore(&ptp->rw_lock, flags); return -EINVAL; } @@ -674,10 +674,10 @@ static int hisi_ptp_probe(struct platform_device *pdev) if (ptp->rx_total == 0 || ptp->rx_total != ptp->rx_cnt || ptp->tx_cnt != 1) { - write_unlock_irqrestore(&ptp->rw_lock, flags); dev_info(&pdev->dev, "waiting for devices...rx total:%u, now:%u. tx total:1, now:%u\n", ptp->rx_total, ptp->rx_cnt, ptp->tx_cnt); + write_unlock_irqrestore(&ptp->rw_lock, flags); return 0; } -- Gitee