* [PATCH] vfio/pci: sanitize bogus INTx interrupt pin values
@ 2026-03-28 21:58 Christos Longros
2026-03-28 23:01 ` [PATCH v2] " Christos Longros
0 siblings, 1 reply; 5+ messages in thread
From: Christos Longros @ 2026-03-28 21:58 UTC (permalink / raw)
To: Alex Williamson; +Cc: kvm, linux-kernel, Christos Longros
Some PCI devices report invalid interrupt pin values in config space
(e.g., 0xFF instead of the valid range 0-4). The VFIO PCI config
virtualization layer passes these values through to userspace, causing
QEMU to crash with an assertion failure in pci_irq_handler() when it
computes irq_num = pin - 1, which exceeds PCI_NUM_PINS (4).
The existing code already handles bogus VF interrupt pins (set to 0
per SR-IOV spec §3.4.1.18), but physical functions with out-of-range
pin values are not caught. Extend the condition that clears the
virtualized interrupt pin to also cover values outside 1-4.
Observed on Realtek RTL8852CE (10ec:c852) which reports interrupt pin
0xFF in hardware config space.
Signed-off-by: Christos Longros <chris.longros@gmail.com>
---
drivers/vfio/pci/vfio_pci_config.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c
index b4e39253f..ed75c1cc3 100644
--- a/drivers/vfio/pci/vfio_pci_config.c
+++ b/drivers/vfio/pci/vfio_pci_config.c
@@ -1829,8 +1829,17 @@ int vfio_config_init(struct vfio_pci_core_device *vdev)
cpu_to_le16(PCI_COMMAND_MEMORY);
}
+ /*
+ * Sanitize bogus interrupt pin values. Valid pins are 1 (INTA)
+ * through 4 (INTD); anything else disables legacy interrupts.
+ */
+ if (vconfig[PCI_INTERRUPT_PIN] > 4)
+ pci_info(pdev, "Bogus INTx pin %d, disabling INTx virtualization\n",
+ vconfig[PCI_INTERRUPT_PIN]);
+
if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx ||
- !vdev->pdev->irq || vdev->pdev->irq == IRQ_NOTCONNECTED)
+ !vdev->pdev->irq || vdev->pdev->irq == IRQ_NOTCONNECTED ||
+ vconfig[PCI_INTERRUPT_PIN] > 4)
vconfig[PCI_INTERRUPT_PIN] = 0;
ret = vfio_cap_init(vdev);
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2] vfio/pci: sanitize bogus INTx interrupt pin values
2026-03-28 21:58 [PATCH] vfio/pci: sanitize bogus INTx interrupt pin values Christos Longros
@ 2026-03-28 23:01 ` Christos Longros
2026-04-01 22:59 ` Alex Williamson
0 siblings, 1 reply; 5+ messages in thread
From: Christos Longros @ 2026-03-28 23:01 UTC (permalink / raw)
To: Alex Williamson
Cc: Cédric Le Goater, kvm, linux-kernel, Christos Longros
Some PCI devices may report out-of-range interrupt pin values in
config space (e.g., 0xFF when the device is in an error state).
The VFIO PCI config virtualization layer passes these values through
to userspace, causing QEMU to crash with an assertion failure in
pci_irq_handler() when it computes irq_num = pin - 1, which exceeds
PCI_NUM_PINS (4).
The existing code already handles bogus VF interrupt pins (set to 0
per SR-IOV spec 3.4.1.18), but physical functions with out-of-range
pin values are not caught. Extend the condition that clears the
virtualized interrupt pin to also cover values outside 1-4.
Signed-off-by: Christos Longros <chris.longros@gmail.com>
---
drivers/vfio/pci/vfio_pci_config.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c
index b4e39253f..ed75c1cc3 100644
--- a/drivers/vfio/pci/vfio_pci_config.c
+++ b/drivers/vfio/pci/vfio_pci_config.c
@@ -1829,8 +1829,17 @@ int vfio_config_init(struct vfio_pci_core_device *vdev)
cpu_to_le16(PCI_COMMAND_MEMORY);
}
+ /*
+ * Sanitize bogus interrupt pin values. Valid pins are 1 (INTA)
+ * through 4 (INTD); anything else disables legacy interrupts.
+ */
+ if (vconfig[PCI_INTERRUPT_PIN] > 4)
+ pci_info(pdev, "Bogus INTx pin %d, disabling INTx virtualization\n",
+ vconfig[PCI_INTERRUPT_PIN]);
+
if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx ||
- !vdev->pdev->irq || vdev->pdev->irq == IRQ_NOTCONNECTED)
+ !vdev->pdev->irq || vdev->pdev->irq == IRQ_NOTCONNECTED ||
+ vconfig[PCI_INTERRUPT_PIN] > 4)
vconfig[PCI_INTERRUPT_PIN] = 0;
ret = vfio_cap_init(vdev);
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2] vfio/pci: sanitize bogus INTx interrupt pin values
2026-03-28 23:01 ` [PATCH v2] " Christos Longros
@ 2026-04-01 22:59 ` Alex Williamson
2026-04-04 18:14 ` Christos Longros
0 siblings, 1 reply; 5+ messages in thread
From: Alex Williamson @ 2026-04-01 22:59 UTC (permalink / raw)
To: Christos Longros; +Cc: Cédric Le Goater, kvm, linux-kernel, alex
On Sun, 29 Mar 2026 00:01:26 +0100
Christos Longros <chris.longros@gmail.com> wrote:
> Some PCI devices may report out-of-range interrupt pin values in
> config space (e.g., 0xFF when the device is in an error state).
> The VFIO PCI config virtualization layer passes these values through
> to userspace, causing QEMU to crash with an assertion failure in
> pci_irq_handler() when it computes irq_num = pin - 1, which exceeds
> PCI_NUM_PINS (4).
>
> The existing code already handles bogus VF interrupt pins (set to 0
> per SR-IOV spec 3.4.1.18), but physical functions with out-of-range
> pin values are not caught. Extend the condition that clears the
> virtualized interrupt pin to also cover values outside 1-4.
The description has taken quite a change in direction between v1 and
v2, which makes me wonder what's actually happening here. v1 suggested
this was an issue with a specific RTL NIC where the pin register reads
as 0xFF, but proposes a generic solution. v2 proposes the same
solution, but drops the reference to the RTL NIC, instead suggesting
that a device "in an error state" might have this trait.
If the device is in error state and the PIN register reads as 0xFF,
does all of config space read as 0xFF? Was the PIN register valid
before? How did it get into an "error state".
If this has only actually been observed with this RTL NIC, is it
really an error state or is the hardware non-spec compliant, trying to
indicate lack of INTx support with 0xFF rather than 0x0.
It would be surprising if a device in an error state was only broken
relative to the INTx PIN register, and exposing a broken device only
masking the INTx support seems incomplete. If we're dealing with a
specific broken device, maybe the right answer is a quirk to set
pdev->irq to zero.
Please elaborate on what's actually happening here. Thanks,
Alex
> Signed-off-by: Christos Longros <chris.longros@gmail.com>
> ---
> drivers/vfio/pci/vfio_pci_config.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c
> index b4e39253f..ed75c1cc3 100644
> --- a/drivers/vfio/pci/vfio_pci_config.c
> +++ b/drivers/vfio/pci/vfio_pci_config.c
> @@ -1829,8 +1829,17 @@ int vfio_config_init(struct vfio_pci_core_device *vdev)
> cpu_to_le16(PCI_COMMAND_MEMORY);
> }
>
> + /*
> + * Sanitize bogus interrupt pin values. Valid pins are 1 (INTA)
> + * through 4 (INTD); anything else disables legacy interrupts.
> + */
> + if (vconfig[PCI_INTERRUPT_PIN] > 4)
> + pci_info(pdev, "Bogus INTx pin %d, disabling INTx virtualization\n",
> + vconfig[PCI_INTERRUPT_PIN]);
> +
> if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx ||
> - !vdev->pdev->irq || vdev->pdev->irq == IRQ_NOTCONNECTED)
> + !vdev->pdev->irq || vdev->pdev->irq == IRQ_NOTCONNECTED ||
> + vconfig[PCI_INTERRUPT_PIN] > 4)
> vconfig[PCI_INTERRUPT_PIN] = 0;
>
> ret = vfio_cap_init(vdev);
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2] vfio/pci: sanitize bogus INTx interrupt pin values
2026-04-01 22:59 ` Alex Williamson
@ 2026-04-04 18:14 ` Christos Longros
2026-04-10 16:53 ` Alex Williamson
0 siblings, 1 reply; 5+ messages in thread
From: Christos Longros @ 2026-04-04 18:14 UTC (permalink / raw)
To: Alex Williamson; +Cc: Christos Longros, kvm, linux-kernel
Hi Alex,
The RTL8852CE reports a valid interrupt pin (INTA = 0x01) under
normal operation. The 0xFF only appears after a VFIO bus reset
bricks the device -- at that point the entire config space reads
0xFFFFFFFF, not just the pin register.
Since the root cause is the device bricking on bus reset, I think
the right fix is a PCI quirk rather than the generic bounds check
I proposed here. I have a quirk_no_bus_reset patch ready for
10ec:c852 (RTL8852CE) -- I'll send that as a v3 instead.
Should I drop this VFIO patch entirely, or is there value in
keeping a safety net for the pin register? The PCI spec limits it
to 0x00-0x04, so anything outside that range is invalid, but I
understand if you'd rather not add checks for scenarios that
shouldn't happen with functioning hardware.
Christos
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2] vfio/pci: sanitize bogus INTx interrupt pin values
2026-04-04 18:14 ` Christos Longros
@ 2026-04-10 16:53 ` Alex Williamson
0 siblings, 0 replies; 5+ messages in thread
From: Alex Williamson @ 2026-04-10 16:53 UTC (permalink / raw)
To: Christos Longros; +Cc: Alex Williamson, kvm, linux-kernel, alex
On Sat, 4 Apr 2026 20:14:36 +0200
Christos Longros <chris.longros@gmail.com> wrote:
> Hi Alex,
>
> The RTL8852CE reports a valid interrupt pin (INTA = 0x01) under
> normal operation. The 0xFF only appears after a VFIO bus reset
> bricks the device -- at that point the entire config space reads
> 0xFFFFFFFF, not just the pin register.
>
> Since the root cause is the device bricking on bus reset, I think
> the right fix is a PCI quirk rather than the generic bounds check
> I proposed here. I have a quirk_no_bus_reset patch ready for
> 10ec:c852 (RTL8852CE) -- I'll send that as a v3 instead.
Seems like the better solution.
> Should I drop this VFIO patch entirely, or is there value in
> keeping a safety net for the pin register? The PCI spec limits it
> to 0x00-0x04, so anything outside that range is invalid, but I
> understand if you'd rather not add checks for scenarios that
> shouldn't happen with functioning hardware.
The pin register is a bit arbitrary. We're talking about a scenario
where the device has gone fatal while it's in use. Is it vfio-pci's
job to sanitize every config space access to prevent userspace from
crashing in such a condition, or does QEMU need to apply a bit of
sanity itself? Maybe QEMU should detect the state of the device after
reset and perform a surprise removal if it's in a broken state. Thanks,
Alex
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-04-10 16:53 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-28 21:58 [PATCH] vfio/pci: sanitize bogus INTx interrupt pin values Christos Longros
2026-03-28 23:01 ` [PATCH v2] " Christos Longros
2026-04-01 22:59 ` Alex Williamson
2026-04-04 18:14 ` Christos Longros
2026-04-10 16:53 ` Alex Williamson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox