From: Jakub Kicinski <kuba@kernel.org>
To: satishkh@cisco.com
Cc: Jakub Kicinski <kuba@kernel.org>,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
pabeni@redhat.com, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, leitao@debian.org,
sebaddel@cisco.com
Subject: Re: [PATCH net-next v12 05/12] enic: add admin CQ service with MSI-X interrupt and workqueue polling
Date: Mon, 27 Jul 2026 17:41:22 -0700 [thread overview]
Message-ID: <20260728004122.2979545-1-kuba@kernel.org> (raw)
In-Reply-To: <20260719-enic-sriov-v2-admin-channel-v2-v12-5-6ff2c617001d@cisco.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
Now I have the confirmation. Let me generate the report.
commit 91d5187517ef604e2669cd4fde3a2c606489afe1
Author: Satish Kharat <satishkh@cisco.com>
enic: add admin CQ service with MSI-X interrupt and workqueue polling
This adds an MSI-X driven CQ service for the admin channel with a
workqueue-based poller, a bounded admin_msg backlog, and a deferred
dispatch work_struct for received admin messages.
> diff --git a/drivers/net/ethernet/cisco/enic/enic_admin.c b/drivers/net/ethernet/cisco/enic/enic_admin.c
> index b2be42092106..9358165263d9 100644
> --- a/drivers/net/ethernet/cisco/enic/enic_admin.c
> +++ b/drivers/net/ethernet/cisco/enic/enic_admin.c
[ ... ]
> @@ -94,6 +96,266 @@ static void enic_admin_rq_drain(struct enic *enic)
> vnic_rq_clean(&enic->admin_rq, enic_admin_rq_buf_clean);
> }
>
> +static unsigned int enic_admin_cq_color(void *cq_desc, unsigned int desc_size)
> +{
[ ... ]
> +unsigned int enic_admin_rq_cq_service(struct enic *enic)
> +{
> + struct vnic_cq *cq = &enic->admin_cq[1];
> + struct vnic_rq *rq = &enic->admin_rq;
> + struct cq_enet_rq_desc *rq_desc;
> + struct vnic_rq_buf *buf;
> + u16 bwf, bytes_written;
> + unsigned int work = 0;
> + void *desc;
> +
[ ... ]
> + rq_desc = desc;
> + bwf = le16_to_cpu(rq_desc->bytes_written_flags);
> + bytes_written = bwf & CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK;
> + if (bytes_written > buf->len)
> + goto next_desc;
> +
> + dma_sync_single_for_cpu(&enic->pdev->dev,
> + buf->dma_addr, buf->len,
> + DMA_FROM_DEVICE);
[ ... ]
> + enic_admin_msg_enqueue(enic, buf->os_buf, bytes_written);
[Medium]
Can this path leak uninitialised heap contents to downstream admin
message consumers?
The admin RQ buffers are allocated with plain kmalloc() in
enic_admin_rq_post_one():
buf = kmalloc(ENIC_ADMIN_BUF_SIZE, gfp);
so the buffer contents are uninitialised heap. The only bound applied
here is bytes_written > buf->len, but there is no check that hardware
actually DMA'd bytes_written bytes. enic_admin_msg_enqueue() then does:
memcpy(msg->data, buf, len);
A firmware or peer that DMAs a short payload but reports a larger
bytes_written value would cause the tail region to be copied verbatim
from stale heap into the queued admin_msg.
The commit comment above this block already flags a "buggy or hostile
VF" as part of the threat model. Would switching enic_admin_rq_post_one()
to kzalloc(), or zeroing [bytes_written, buf->len) after
dma_sync_single_for_cpu() and before enqueue, be preferable?
The admin_rq_handler is NULL at this point in the series, but later
patches ("enic: add MBOX PF handlers for VF register and capability"
and "enic: add MBOX VF handlers for capability, register and link
state") process payload bytes, so any stale content would then reach
handler logic.
[ ... ]
> +static void enic_admin_poll_work_handler(struct work_struct *work)
> +{
> + struct enic *enic = container_of(work, struct enic, admin_poll_work);
> + unsigned int credits;
> + unsigned int rq_work;
> +
> + /* Snapshot the pending credit count before draining so we acknowledge
> + * exactly what the hardware reported for this interrupt. Credits that
> + * accrue while enic_admin_rq_cq_service() runs are left for the next
> + * interrupt, which is harmless on this low-rate control path.
> + */
> + credits = vnic_intr_credits(&enic->admin_intr);
> +
> + rq_work = enic_admin_rq_cq_service(enic);
> +
> + if (rq_work > 0)
> + schedule_work(&enic->admin_msg_work);
> +
> + /* Acknowledge the snapshotted credits and unmask the vector. Unlike
> + * the NAPI data path, the admin channel is not re-polled, so the vector
> + * must be re-armed here to receive the next completion. The unmask is
> + * applied through the interrupt mask register independently of the
> + * credit count, so returning zero credits on a spurious wakeup still
> + * re-arms the vector.
> + */
> + vnic_intr_return_credits(&enic->admin_intr,
> + credits,
> + 1 /* unmask */, 0);
> +}
[Low]
The commit message states:
At least one credit is returned so the write always
carries a non-zero acknowledgment and re-arms the vector, since the
admin channel is not re-polled like the NAPI data path.
Does the code actually enforce a floor of one credit?
credits comes directly from vnic_intr_credits() and is passed verbatim
to vnic_intr_return_credits() with no max(credits, 1U) clamp. On a
spurious wakeup credits can be zero. The in-function comment right
below correctly notes:
returning zero credits on a spurious wakeup still
re-arms the vector.
Should the commit message be reworded to match the actual behaviour
(the UNMASK bit re-arms the vector independently of the credit count),
or should a max(credits, 1U) be added to match the message?
[ ... ]
--
pw-bot: cr
next prev parent reply other threads:[~2026-07-28 0:41 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-19 8:41 [PATCH net-next v12 00/12] enic: SR-IOV V2 admin channel and MBOX protocol Satish Kharat
2026-07-19 8:41 ` [PATCH net-next v12 01/12] enic: cancel tx_hang_reset work on device removal Satish Kharat
2026-07-28 0:37 ` Jakub Kicinski
2026-07-19 8:41 ` [PATCH net-next v12 02/12] enic: verify firmware supports V2 SR-IOV at probe time Satish Kharat
2026-07-19 8:41 ` [PATCH net-next v12 03/12] enic: add admin channel open and close for SR-IOV Satish Kharat
2026-07-19 8:41 ` [PATCH net-next v12 04/12] enic: add admin RQ buffer management Satish Kharat
2026-07-19 8:41 ` [PATCH net-next v12 05/12] enic: add admin CQ service with MSI-X interrupt and workqueue polling Satish Kharat
2026-07-28 0:41 ` Jakub Kicinski [this message]
2026-07-28 0:41 ` Jakub Kicinski
2026-07-19 8:41 ` [PATCH net-next v12 06/12] enic: define MBOX message types and header structures Satish Kharat
2026-07-19 8:41 ` [PATCH net-next v12 07/12] enic: add MBOX core send and receive for admin channel Satish Kharat
2026-07-19 8:41 ` [PATCH net-next v12 08/12] enic: add MBOX PF handlers for VF register and capability Satish Kharat
2026-07-19 8:41 ` [PATCH net-next v12 09/12] enic: add MBOX VF handlers for capability, register and link state Satish Kharat
2026-07-19 8:41 ` [PATCH net-next v12 10/12] enic: wire V2 SR-IOV enable with admin channel and MBOX Satish Kharat
2026-07-19 8:41 ` [PATCH net-next v12 11/12] enic: add V2 VF probe with admin channel and PF registration Satish Kharat
2026-07-19 8:41 ` [PATCH net-next v12 12/12] enic: re-establish V2 VF admin channel and PF registration after reset Satish Kharat
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260728004122.2979545-1-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=leitao@debian.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=satishkh@cisco.com \
--cc=sebaddel@cisco.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox