From: Alex Williamson <alex.williamson@nvidia.com>
To: jrhilke@google.com
Cc: Alex Williamson <alex.williamson@nvidia.com>,
Alex Williamson <alex@shazbot.org>, kvm <kvm@vger.kernel.org>,
David Matlack <dmatlack@google.com>,
linux-kernel <linux-kernel@vger.kernel.org>,
Jason Gunthorpe <jgg@nvidia.com>
Subject: [PATCH 3/8] selftests/vfio: igb: Program MSI-X interrupt routing
Date: Fri, 15 May 2026 16:03:10 -0600 [thread overview]
Message-ID: <20260515220330.565792-4-alex.williamson@nvidia.com> (raw)
In-Reply-To: <20260515220330.565792-1-alex.williamson@nvidia.com>
The submitted driver writes only GPIE.EIAME (with a register value of
0x10, which is actually GPIE.Multiple_MSIX, bit 4) and clears EICR by
reading it. On QEMU this works because the emulated loopback path is
synchronous and EICR is implemented as read-to-clear unconditionally.
Real 82576 hardware needs the full MSI-X programming sequence.
Per 82576 datasheet section 7.3.2.11 Table 7-47, MSI-X mode requires:
GPIE.Multiple_MSIX (bit 4): route causes through IVAR.
GPIE.EIAME (bit 30): apply EIAM on MSI-X assertion. Without EIAME,
section 7.3.2.11 specifies EIAM only takes effect on EICR
read/write, which is not the path used here.
Configure auto-clear and auto-mask for vector 0:
EIAC (section 8.8.5): auto-clear of EICR cause bit on MSI-X assertion.
EIAM (section 8.8.6): with EIAME set, auto-mask of EIMS on MSI-X
assertion. This guarantees one interrupt per memcpy batch and
prevents repeat delivery if the cause re-asserts before EIMS is
restored.
Replace the read-to-clear of EICR with write-to-clear. Section 8.8.5
states "If any bits are set in EIAC, the EICR register should not be
read", and section 7.3.4.3 cautions against read-to-clear in MSI-X
mode in general. Write-to-clear (section 7.3.4.2) is unconditional.
Replace the magic '1' values written to EIMS/EIMC with IGB_EICR_VEC0,
add the GPIE/EIAC/EIAM macros, and drop the wrong-valued IGB_GPIE_EIAME
macro (the new definition lives next to IGB_GPIE_MULTIPLE_MSIX).
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Alex Williamson <alex.williamson@nvidia.com>
---
.../selftests/vfio/lib/drivers/igb/igb.c | 40 ++++++++++++++++---
.../vfio/lib/drivers/igb/registers.h | 9 ++++-
2 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/vfio/lib/drivers/igb/igb.c b/tools/testing/selftests/vfio/lib/drivers/igb/igb.c
index 594e51ba29f5..d44a08a36171 100644
--- a/tools/testing/selftests/vfio/lib/drivers/igb/igb.c
+++ b/tools/testing/selftests/vfio/lib/drivers/igb/igb.c
@@ -275,11 +275,32 @@ static void igb_init(struct vfio_pci_device *device)
/* 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, IGB_GPIE, IGB_GPIE_EIAME);
+ /*
+ * Program MSI-X interrupt routing per 82576 datasheet:
+ *
+ * GPIE (section 7.3.2.11, Table 7-47): set Multiple_MSIX (bit 4) to
+ * route interrupt causes through IVAR mapping, and EIAME (bit 30)
+ * to apply EIAM on MSI-X assertion (without EIAME, EIAM only
+ * applies on EICR read/write).
+ *
+ * EIAC (section 8.8.5): enable auto-clear of EICR for vector 0.
+ * Without auto-clear the cause stays set after delivery and the
+ * test can see spurious interrupts on the next memcpy batch.
+ *
+ * EIAM (section 8.8.6): enable auto-mask of EIMS for vector 0 on
+ * MSI-X assertion (effective because EIAME is set), so a single
+ * interrupt is delivered per memcpy batch even if the cause
+ * re-asserts before software re-enables the mask.
+ *
+ * IVAR (section 7.3.1.2, register definition in 8.8.13): map RX
+ * cause 0 to MSI-X vector 0 and mark the entry valid.
+ */
+ igb_write32(igb, IGB_GPIE, IGB_GPIE_MULTIPLE_MSIX | IGB_GPIE_EIAME);
+ igb_write32(igb, IGB_EIAC, IGB_EICR_VEC0);
+ igb_write32(igb, IGB_EIAM, IGB_EICR_VEC0);
/* Enable interrupts on vector 0 */
- igb_write32(igb, IGB_EIMS, 1);
+ igb_write32(igb, IGB_EIMS, IGB_EICR_VEC0);
/* Map vector 0 to interrupt cause 0 and mark it valid */
igb_write32(igb, IGB_IVAR0, IGB_IVAR_VALID);
@@ -305,17 +326,24 @@ static void igb_remove(struct vfio_pci_device *device)
static void igb_irq_disable(struct igb *igb)
{
- igb_write32(igb, IGB_EIMC, 1);
+ igb_write32(igb, IGB_EIMC, IGB_EICR_VEC0);
}
static void igb_irq_enable(struct igb *igb)
{
- igb_write32(igb, IGB_EIMS, 1);
+ igb_write32(igb, IGB_EIMS, IGB_EICR_VEC0);
}
static void igb_irq_clear(struct igb *igb)
{
- igb_read32(igb, IGB_EICR);
+ /*
+ * Use write-to-clear (datasheet 7.3.4.2). In MSI-X mode with EIAC
+ * programmed, section 8.8.5 explicitly states "If any bits are set
+ * in EIAC, the EICR register should not be read", which rules out
+ * the read-to-clear path in 7.3.4.3. Bits not in EIAC are still
+ * cleared by writing 1.
+ */
+ igb_write32(igb, IGB_EICR, 0xFFFFFFFF);
}
static void igb_memcpy_start(struct vfio_pci_device *device, iova_t src,
diff --git a/tools/testing/selftests/vfio/lib/drivers/igb/registers.h b/tools/testing/selftests/vfio/lib/drivers/igb/registers.h
index c44788642522..139f1c2e6fdd 100644
--- a/tools/testing/selftests/vfio/lib/drivers/igb/registers.h
+++ b/tools/testing/selftests/vfio/lib/drivers/igb/registers.h
@@ -78,12 +78,18 @@
#define IGB_VMOLR_BAM 0x08000000 /* Broadcast Accept Mode */
#define IGB_RAH_POOL_1 0x00040000 /* Pool 1 assignment */
-#define IGB_EIMS 0x01524 /* Extended Interrupt Mask Set */
#define IGB_EICS 0x01520 /* Extended Interrupt Cause Set */
+#define IGB_EIMS 0x01524 /* Extended Interrupt Mask Set */
#define IGB_EIMC 0x01528 /* Extended Interrupt Mask Clear */
+#define IGB_EIAC 0x0152C /* Extended Interrupt Auto Clear */
+#define IGB_EIAM 0x01530 /* Extended Interrupt Auto Mask Enable */
+#define IGB_EICR_VEC0 BIT(0) /* MSI-X cause/vector 0 */
#define IGB_CTRL_GIO_MASTER_DISABLE BIT(2) /* GIO Master Disable */
#define IGB_STATUS_GIO_MASTER_ENABLE BIT(19) /* GIO Master Enable */
#define IGB_GPIE 0x01514 /* General Purpose Interrupt Enable */
+/* GPIE fields per 82576 datasheet section 7.3.2.11, Table 7-47 */
+#define IGB_GPIE_MULTIPLE_MSIX BIT(4) /* Multi-vector MSI-X mode */
+#define IGB_GPIE_EIAME BIT(30) /* Apply EIAM on MSI-X assertion */
#define IGB_TXDCTL0_Q_EN BIT(25) /* Transmit Queue Enable */
#define IGB_RXDCTL0_Q_EN BIT(25) /* Receive Queue Enable */
#define IGB_MRQC 0x05818 /* Multiple Receive Queues Command */
@@ -101,7 +107,6 @@
#define IGB_PHY_CTRL_FULL_DUPLEX 0x0100 /* bit 8 */
#define IGB_PHY_CTRL_LOOPBACK 0x4000 /* bit 14 */
-#define IGB_GPIE_EIAME 0x10 /* Extended Interrupt Auto Mask Enable */
#define IGB_IVAR_VALID 0x80 /* Valid bit for IVAR register */
/*
--
2.51.0
next prev parent reply other threads:[~2026-05-15 22:04 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-15 22:03 [PATCH 0/8] selftests/vfio: igb: 82576 hardware compatibility Alex Williamson
2026-05-15 22:03 ` [PATCH 1/8] selftests/vfio: igb: Use PHY internal loopback on 82576 Alex Williamson
2026-05-15 22:03 ` [PATCH 2/8] selftests/vfio: igb: Use advanced TX and RX descriptors Alex Williamson
2026-05-15 22:03 ` Alex Williamson [this message]
2026-05-15 22:03 ` [PATCH 4/8] selftests/vfio: igb: Extend memcpy completion timeout for line-rate hardware Alex Williamson
2026-05-15 22:03 ` [PATCH 5/8] selftests/vfio: igb: Disable PCIe completion timeout retries Alex Williamson
2026-05-15 22:03 ` [PATCH 6/8] selftests/vfio: Add vfio_pci_irq_reenable() helper Alex Williamson
2026-05-15 22:03 ` [PATCH 7/8] selftests/vfio: igb: Factor hardware programming into igb_hw_init() Alex Williamson
2026-05-15 22:03 ` [PATCH 8/8] selftests/vfio: igb: Recover after DMA-read faults Alex Williamson
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=20260515220330.565792-4-alex.williamson@nvidia.com \
--to=alex.williamson@nvidia.com \
--cc=alex@shazbot.org \
--cc=dmatlack@google.com \
--cc=jgg@nvidia.com \
--cc=jrhilke@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/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