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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.