From 16affa21f48797ba971641b9be8f6636fc528a39 Mon Sep 17 00:00:00 2001 From: Yixi Shen Date: Mon, 22 Dec 2025 13:43:27 +0800 Subject: [PATCH 1/2] ub: ubase: Resolve mailbox timeout issue. drivers inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ID7LHB CVE: NA ----------------------------------------------------------- In the current mailbox processing, after the task is processed, the hardware reports an EQ event and the driver program schedules a delayed tasks for processing. However, when the CPU load is high, scheduling delays may occur, resulting in timeouts Modify the handling of EQ events and handle hardware EQ events in the top half of interrupts. Fixes: 8d68017f37fa ("ub: ubase: support for command process") Signed-off-by: Yixi Shen --- drivers/ub/ubase/ubase_cmd.c | 25 ------------------------- drivers/ub/ubase/ubase_cmd.h | 5 +---- drivers/ub/ubase/ubase_eq.c | 28 +++++++++++++++++----------- drivers/ub/ubase/ubase_eq.h | 2 +- 4 files changed, 19 insertions(+), 41 deletions(-) diff --git a/drivers/ub/ubase/ubase_cmd.c b/drivers/ub/ubase/ubase_cmd.c index ab554343136f..47695e5c7ef7 100644 --- a/drivers/ub/ubase/ubase_cmd.c +++ b/drivers/ub/ubase/ubase_cmd.c @@ -666,31 +666,6 @@ static bool ubase_cmd_is_mbx_avail(struct ubase_dev *udev) return true; } -int ubase_cmd_mbx_event_cb(struct notifier_block *nb, - unsigned long action, void *data) -{ - struct ubase_event_nb *ev_nb = container_of(nb, struct ubase_event_nb, nb); - struct ubase_aeq_notify_info *info = data; - struct ubase_aeqe *aeqe = info->aeqe; - struct ubase_dev *udev = ev_nb->back; - struct ubase_mbx_event_context *ctx; - - ctx = &udev->mb_cmd.ctx; - if (aeqe->event.cmd.seq_num != ctx->seq_num) { - ubase_err(udev, - "mbx seq num is different, cmd seq_num = %u, ctx seq_num = %u.\n", - aeqe->event.cmd.seq_num, ctx->seq_num); - return NOTIFY_DONE; - } - - ctx->result = aeqe->event.cmd.status == 0 ? 0 : -EIO; - ctx->out_param = aeqe->event.cmd.out_param; - - complete(&ctx->done); - - return NOTIFY_OK; -} - static int ubase_cmd_wait_mbx_completed(struct ubase_dev *udev, union ubase_mbox *mbx) { diff --git a/drivers/ub/ubase/ubase_cmd.h b/drivers/ub/ubase/ubase_cmd.h index d6f2def22117..c31c334d0a3f 100644 --- a/drivers/ub/ubase/ubase_cmd.h +++ b/drivers/ub/ubase/ubase_cmd.h @@ -14,7 +14,7 @@ #define UBASE_CMDQ_DESC_NUM_S 3 #define UBASE_CMDQ_DESC_NUM 1024 #define UBASE_CMDQ_TX_TIMEOUT 300000 -#define UBASE_CMDQ_MBX_TX_TIMEOUT 500 +#define UBASE_CMDQ_MBX_TX_TIMEOUT 50 #define UBASE_CMDQ_CLEAR_WAIT_TIME 200 #define UBASE_CMDQ_WAIT_TIME 10 @@ -311,9 +311,6 @@ int __ubase_cmd_send_in(struct ubase_dev *udev, struct ubase_cmd_buf *in); int __ubase_cmd_send_inout(struct ubase_dev *udev, struct ubase_cmd_buf *in, struct ubase_cmd_buf *out); -int ubase_cmd_mbx_event_cb(struct notifier_block *nb, unsigned long action, - void *data); - int __ubase_register_crq_event(struct ubase_dev *udev, struct ubase_crq_event_nb *nb); void __ubase_unregister_crq_event(struct ubase_dev *udev, u16 opcode); diff --git a/drivers/ub/ubase/ubase_eq.c b/drivers/ub/ubase/ubase_eq.c index 2afe9c3bf7fc..ff2a2e3ea721 100644 --- a/drivers/ub/ubase/ubase_eq.c +++ b/drivers/ub/ubase/ubase_eq.c @@ -402,6 +402,19 @@ static void ubase_init_aeq_work(struct ubase_dev *udev, struct ubase_aeqe *aeqe) queue_work(udev->ubase_async_wq, &aeq_work->work); } +static void ubase_mbx_complete(struct ubase_dev *udev, struct ubase_aeqe *aeqe) +{ + struct ubase_mbx_event_context *ctx = &udev->mb_cmd.ctx; + + if (aeqe->event.cmd.seq_num != ctx->seq_num) + return; + + ctx->result = aeqe->event.cmd.status == 0 ? 0 : -EIO; + ctx->out_param = aeqe->event.cmd.out_param; + + complete(&ctx->done); +} + static int ubase_async_event_handler(struct ubase_dev *udev) { struct ubase_aeq *aeq = &udev->irq_table.aeq; @@ -415,14 +428,12 @@ static int ubase_async_event_handler(struct ubase_dev *udev) trace_ubase_aeqe(udev->dev, aeqe, eq); - ubase_dbg(udev, - "event_type = 0x%x, sub_type = 0x%x, owner = %u, seq_num = %u, cons_index = %u.\n", - aeqe->event_type, aeqe->sub_type, aeqe->owner, - aeqe->event.cmd.seq_num, eq->cons_index); - ret = IRQ_HANDLED; - ubase_init_aeq_work(udev, aeqe); + if (aeqe->event_type == UBASE_EVENT_TYPE_MB) + ubase_mbx_complete(udev, aeqe); + else + ubase_init_aeq_work(udev, aeqe); ++aeq->eq.cons_index; aeqe = ubase_next_aeqe(udev, aeq); @@ -1170,11 +1181,6 @@ int ubase_register_ae_event(struct ubase_dev *udev) { struct ubase_event_nb ubase_ae_nbs[UBASE_AE_LEVEL_NUM] = { { - UBASE_DRV_UNIC, - UBASE_EVENT_TYPE_MB, - { ubase_cmd_mbx_event_cb }, - udev - }, { UBASE_DRV_UNIC, UBASE_EVENT_TYPE_TP_FLUSH_DONE, { ubase_ae_tp_flush_done }, diff --git a/drivers/ub/ubase/ubase_eq.h b/drivers/ub/ubase/ubase_eq.h index 59fa2c620720..18d18f026f0c 100644 --- a/drivers/ub/ubase/ubase_eq.h +++ b/drivers/ub/ubase/ubase_eq.h @@ -34,7 +34,7 @@ #define UBASE_INT_NAME_LEN 32 -#define UBASE_AE_LEVEL_NUM 4 +#define UBASE_AE_LEVEL_NUM 3 /* Vector0 interrupt CMDQ event source register(RW) */ #define UBASE_VECTOR0_CMDQ_SRC_REG 0x18004 -- Gitee From 951ede65b3eb5d79da7753db915002a625c06543 Mon Sep 17 00:00:00 2001 From: Yixi Shen Date: Mon, 22 Dec 2025 14:06:41 +0800 Subject: [PATCH 2/2] net: unic: Fix ethtool configuration error issue. drivers inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ID7LHB CVE: NA ------------------------------------------------------------ Due to the fact that the double pointer is a random value when passed in, using this pointer during assignment will access the exception address. Change the application method to apply for memory using local variables, and return it to the double pointer after the assignment is completed. Fixes: e0ccc63cc72e ("net: unic: support querying and configuring coalesce parameters.") Signed-off-by: Yixi Shen --- drivers/net/ub/unic/unic_ethtool.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/net/ub/unic/unic_ethtool.c b/drivers/net/ub/unic/unic_ethtool.c index 337d77b16ff4..c027989ac8e8 100644 --- a/drivers/net/ub/unic/unic_ethtool.c +++ b/drivers/net/ub/unic/unic_ethtool.c @@ -430,28 +430,32 @@ static int unic_backup_stats(struct unic_dev *unic_dev, struct unic_sq_stats **sq_stats, struct unic_rq_stats **rq_stats) { + struct unic_sq_stats *tx_stats; + struct unic_rq_stats *rx_stats; u32 i; - *sq_stats = kcalloc(unic_dev->channels.num, sizeof(**sq_stats), - GFP_KERNEL); - if (ZERO_OR_NULL_PTR(*sq_stats)) + tx_stats = kcalloc(unic_dev->channels.num, sizeof(*tx_stats), + GFP_KERNEL); + if (!tx_stats) return -ENOMEM; - *rq_stats = kcalloc(unic_dev->channels.num, sizeof(**rq_stats), - GFP_KERNEL); - if (ZERO_OR_NULL_PTR(*rq_stats)) { - if (unic_tx_changed(unic_dev)) - kfree(*sq_stats); + rx_stats = kcalloc(unic_dev->channels.num, sizeof(*rx_stats), + GFP_KERNEL); + if (!rx_stats) { + kfree(tx_stats); return -ENOMEM; } for (i = 0; i < unic_dev->channels.num; i++) { - memcpy(sq_stats[i], &unic_dev->channels.c[i].sq->stats, + memcpy(&tx_stats[i], &unic_dev->channels.c[i].sq->stats, sizeof(struct unic_sq_stats)); - memcpy(rq_stats[i], &unic_dev->channels.c[i].rq->stats, + memcpy(&rx_stats[i], &unic_dev->channels.c[i].rq->stats, sizeof(struct unic_rq_stats)); } + *sq_stats = tx_stats; + *rq_stats = rx_stats; + return 0; } -- Gitee