Kernel KVM virtualization development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Josh Hilke" <jrhilke@google.com>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH v3 1/9] vfio: selftests: igb: Add driver for IGB QEMU device
Date: Wed, 08 Jul 2026 23:31:51 +0000	[thread overview]
Message-ID: <20260708233151.6EACE1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260708-igb_v3_b4-v3-1-1272650ca614@google.com>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] Advanced Receive Descriptor Misconfiguration (SRRCTL)
- [High] Unsupported MAC Loopback and Link State Deadlock
- [High] Interrupt Delivery Failure due to Incomplete MSI-X Configuration
- [High] Fault Recovery Failure due to PCIe Completion Timeout Resend
- [High] Inadequate Wait Timeout for Large Memcpy Batches
--

--- Patch [1]: [PATCH v3 1/9] vfio: selftests: igb: Add driver for IGB QEMU device ---
commit a7e0dd62086e602fc2886d15801884902daf6cba
Author: Josh Hilke <jrhilke@google.com>

vfio: selftests: igb: Add driver for IGB QEMU device

This patch adds a VFIO selftest driver for the Intel Gigabit Ethernet
controller (IGB) to allow running VFIO selftests in QEMU without requiring
specific hardware. It utilizes the IGB loopback mode to implement the
required memcpy operations.

> diff --git a/tools/testing/selftests/vfio/lib/drivers/igb/igb.c b/tools/testing/selftests/vfio/lib/drivers/igb/igb.c
> new file mode 100644
> index 0000000000000..339ca88b9c555
> --- /dev/null
> +++ b/tools/testing/selftests/vfio/lib/drivers/igb/igb.c

[ ... ]

> +static void igb_phy_setup_autoneg(struct igb *igb)
> +{
> +	int timeout_ms = 1000;
> +	bool success = false;
> +	u16 phy_status;
> +	int ret;
> +	int i;
> +
> +	/* Trigger auto-negotiation */
> +	ret = igb_write_phy(igb, MII_BMCR,
> +			    BMCR_ANENABLE | BMCR_ANRESTART);

[Severity: High]
Does this configuration work on unplugged physical hardware? 

Writing to the PHY without enabling BMCR_LOOPBACK and relying on
autonegotiation will block indefinitely and time out after 1 second if no
network cable is connected.

> +	VFIO_ASSERT_EQ(ret, 0, "Failed to write PHY control register");
> +
> +	for (i = 0; i < timeout_ms; i++) {
> +		if (igb_read_phy(igb, MII_BMSR, &phy_status) == 0) {
> +			success = !!(phy_status & BMSR_ANEGCOMPLETE);

[ ... ]

> +static void igb_init(struct vfio_pci_device *device)
> +{
> +	struct igb *igb = to_igb_state(device);
> +	u64 iova_tx, iova_rx;
> +	u32 ctrl, rctl;
> +	u16 cmd_reg;
> +	int retries;
> +
> +	VFIO_ASSERT_GE(device->driver.region.size, sizeof(struct igb));
> +
> +	/* Set up rings and calculate IOVAs */
> +	igb->bar0 = device->bars[0].vaddr;
> +
> +	iova_tx = to_iova(device, igb->tx_ring);
> +	iova_rx = to_iova(device, igb->rx_ring);

[Severity: High]
Could an unmapped IOVA access permanently lock up the physical device here?

VFIO selftests intentionally submit descriptors targeting unmapped IOVAs to
test IOMMU fault handling. By default, 82576 hardware sets the
E1000_GCR_CMPL_TMOUT_RESEND bit, which instructs the DMA engine to
indefinitely retry upon PCIe Completion Timeout or Unsupported Request from
the IOMMU, flooding the system with PCIe AER errors.

Should the initialization sequence clear this bit in the E1000_GCR register
before starting DMA operations so the device can gracefully recover?

> +	igb_write32(igb, E1000_CTRL, igb_read32(igb, E1000_CTRL) | E1000_CTRL_RST);
> +	/*
> +	 * Must wait at least 1 millisecond after setting the reset bit before
> +	 * checking if this device is ready to be used (82576 datasheet section
> +	 * 4.2.1.6.1).
> +	 */

[ ... ]

> +	/* Configure TX and RX descriptor rings */
> +	igb_write32(igb, E1000_TDBAL(0), (u32)iova_tx);
> +	igb_write32(igb, E1000_TDBAH(0), (u32)(iova_tx >> 32));
> +	igb_write32(igb, E1000_TDLEN(0), RING_SIZE * sizeof(struct igb_tx_desc));
> +	igb_write32(igb, E1000_TDH(0), 0);
> +	igb_write32(igb, E1000_TDT(0), 0);
> +	igb_write32(igb, E1000_TXDCTL(0), E1000_TXDCTL_QUEUE_ENABLE);
> +
> +	igb_write32(igb, E1000_RDBAL(0), (u32)iova_rx);

[Severity: High]
Will the hardware use the correct descriptor format without configuring
E1000_SRRCTL?

The driver's struct igb_rx_desc expects the Advanced One-Buffer format, but
without writing E1000_SRRCTL_DESCTYPE_ADV_ONEBUF to E1000_SRRCTL during
igb_init(), the 82576 hardware defaults to the legacy format.

This causes the hardware to write the status byte to offset 4 instead of
offset 8, making igb_memcpy_wait() poll an unpopulated offset and causing
the test to fail with an indefinite timeout on physical hardware.

> +	igb_write32(igb, E1000_RDBAH(0), (u32)(iova_rx >> 32));
> +	igb_write32(igb, E1000_RDLEN(0), RING_SIZE * sizeof(struct igb_rx_desc));
> +	igb_write32(igb, E1000_RDH(0), 0);
> +	igb_write32(igb, E1000_RDT(0), 0);
> +	igb_write32(igb, E1000_RXDCTL(0), E1000_RXDCTL_QUEUE_ENABLE);
> +
> +	/* Wait for TX and RX queues to be enabled */
> +	retries = 2000;
> +	while (retries-- > 0) {
> +		if ((igb_read32(igb, E1000_TXDCTL(0)) & E1000_TXDCTL_QUEUE_ENABLE) &&
> +		    (igb_read32(igb, E1000_RXDCTL(0)) & E1000_RXDCTL_QUEUE_ENABLE))
> +			break;
> +		usleep(10);
> +	}
> +
> +	/* Enable Receiver and Transmitter */
> +	rctl = E1000_RCTL_EN |       /* Receiver Enable */
> +	       E1000_RCTL_UPE |      /* Unicast Promiscuous (for dummy MAC) */
> +	       E1000_RCTL_LBM_MAC |  /* MAC Loopback Mode */
> +	       E1000_RCTL_SECRC;     /* Strip CRC (needed for memcmp) */
> +	igb_write32(igb, E1000_RCTL, rctl);

[Severity: High]
Is it expected that internal MAC loopback is not actually implemented on
real 82576 hardware?

The datasheet (Section 3.5.6.2) indicates E1000_RCTL_LBM_MAC has no physical
effect on the 82576. Additionally, the MAC link is never forced up via
E1000_CTRL_SLU here. This will stall the descriptor engine when running on
real hardware without a live network connection.

> +	igb_write32(igb, E1000_TCTL, E1000_TCTL_EN);
> +
> +	/* Enable MSI-X with 1 vector for the test */
> +	vfio_pci_msix_enable(device, MSIX_VECTOR, 1);
> +
> +	/* Enable auto-masking of interrupts to avoid storms without a real ISR */
> +	igb_write32(igb, E1000_GPIE, E1000_GPIE_EIAME);
> +
> +	/* Enable interrupts on vector 0 */
> +	igb_write32(igb, E1000_EIMS, 1);
> +
> +	/* Map vector 0 to interrupt cause 0 and mark it valid */
> +	igb_write32(igb, E1000_IVAR0, E1000_IVAR_VALID);

[Severity: High]
Will the hardware successfully deliver MSI-X interrupts with this configuration?

The RX queue is mapped to MSI-X vector 0 using E1000_IVAR0, but the
E1000_GPIE_MSIX_MODE bit isn't set in E1000_GPIE. This leaves the 82576
operating in legacy interrupt mode, causing it to ignore IVAR routing.

Also, while E1000_GPIE_EIAME (Auto-Mask Enable) is set, the E1000_EIAM
and E1000_EIAC registers appear to be left unprogrammed.

> +
> +	/* Initialize driver state and capability limits */
> +	igb->tx_tail = 0;

[ ... ]

> +static int igb_memcpy_wait(struct vfio_pci_device *device)
> +{
> +	struct igb *igb = to_igb_state(device);
> +	struct igb_rx_desc *rx;
> +	u32 status = 0;
> +	u32 prev_tail;
> +	int retries;
> +
> +	prev_tail = (igb->rx_tail + RING_SIZE - 1) % RING_SIZE;
> +	rx = &igb->rx_ring[prev_tail];
> +
> +	retries = 100;
> +	while (retries-- > 0) {
> +		status = le32_to_cpu(READ_ONCE(rx->wb.status_error));
> +		if (status & 1)
> +			break;
> +		usleep(10);
> +	}

[Severity: High]
Is a 1 millisecond total wait timeout sufficient for full-size batch copies?

This lockless polling loop executes 100 iterations of 10 microseconds each,
yielding a strict 1ms timeout limit. However, the driver initializes
max_memcpy_count to 4095 and max_memcpy_size to 1024 bytes. Transmitting
~4 MB of data across a 1 Gbps loopback interface physically requires at least
~33.5 milliseconds, which will cause large memcpy batches to consistently
time out before completion.

> +
> +	igb_irq_clear(igb);
> +
> +	igb_irq_enable(igb);
> +
> +	return (status & 1) ? 0 : -ETIMEDOUT;
> +}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260708-igb_v3_b4-v3-0-1272650ca614@google.com?part=1

  reply	other threads:[~2026-07-08 23:31 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-08 23:18 [PATCH v3 0/9] vfio: selftests: Add driver for Intel Ethernet Gigabit Controller (IGB) Josh Hilke
2026-07-08 23:18 ` [PATCH v3 1/9] vfio: selftests: igb: Add driver for IGB QEMU device Josh Hilke
2026-07-08 23:31   ` sashiko-bot [this message]
2026-07-09 19:23     ` Josh Hilke
2026-07-08 23:18 ` [PATCH v3 2/9] vfio: selftests: igb: Use PHY internal loopback on 82576 Josh Hilke
2026-07-08 23:28   ` sashiko-bot
2026-07-09 19:27     ` Josh Hilke
2026-07-08 23:18 ` [PATCH v3 3/9] vfio: selftests: igb: Use advanced TX and RX descriptors Josh Hilke
2026-07-08 23:29   ` sashiko-bot
2026-07-09 20:43     ` Josh Hilke
2026-07-09 21:33     ` Alex Williamson
2026-07-08 23:18 ` [PATCH v3 4/9] vfio: selftests: igb: Program MSI-X interrupt routing Josh Hilke
2026-07-08 23:33   ` sashiko-bot
2026-07-09 20:44     ` Josh Hilke
2026-07-09 22:59     ` Alex Williamson
2026-07-08 23:18 ` [PATCH v3 5/9] vfio: selftests: igb: Extend memcpy completion timeout for line-rate hardware Josh Hilke
2026-07-08 23:18 ` [PATCH v3 6/9] vfio: selftests: igb: Disable PCIe completion timeout retries Josh Hilke
2026-07-08 23:31   ` sashiko-bot
2026-07-09 22:48     ` Josh Hilke
2026-07-09 22:59     ` Alex Williamson
2026-07-08 23:18 ` [PATCH v3 7/9] vfio: selftests: Add helpers to re-enable interrupts Josh Hilke
2026-07-08 23:18 ` [PATCH v3 8/9] vfio: selftests: igb: Factor hardware programming into igb_hw_init() Josh Hilke
2026-07-08 23:18 ` [PATCH v3 9/9] vfio: selftests: igb: Recover after DMA-read faults Josh Hilke

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=20260708233151.6EACE1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=jrhilke@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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