Linux virtualization list
 help / color / mirror / Atom feed
* [PATCH 0/4] virtio: fix four bugs across mmio, pci, and vring
@ 2026-04-07 12:39 Andrew Stellman
  2026-04-07 12:39 ` [PATCH 1/4] virtio-mmio: wait for status readback after reset Andrew Stellman
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Andrew Stellman @ 2026-04-07 12:39 UTC (permalink / raw)
  To: Michael S . Tsirkin, Jason Wang
  Cc: Xuan Zhuo, Eugenio Pérez, virtualization, Andrew Stellman

Four independent fixes across the virtio subsystem:

1. virtio-mmio: vm_reset() returns without polling for the status
   register to read back as 0, violating the spec. Add a poll loop
   matching the existing pattern in virtio-pci's vp_reset().

2. virtio-pci: vp_find_vqs_intx() uses a sequential counter instead
   of avq->vq_index for the admin VQ, unlike the MSI-X path.

3. virtio-pci: vp_interrupt() returns IRQ_NONE for config-change-only
   interrupts because it unconditionally returns vp_vring_interrupt()'s
   result. Track the config-change handling and return IRQ_HANDLED.

4. virtio_ring: vring_transport_features() clears VIRTIO_F_RING_RESET
   during feature negotiation because it is missing from the whitelist.

Andrew Stellman (4):
  virtio-mmio: wait for status readback after reset
  virtio-pci: use avq->vq_index for admin VQ in INTx path
  virtio-pci: return IRQ_HANDLED for config-change interrupts
  virtio_ring: preserve VIRTIO_F_RING_RESET in transport features

 drivers/virtio/virtio_mmio.c       |  3 +++
 drivers/virtio/virtio_pci_common.c | 12 +++++++++---
 drivers/virtio/virtio_ring.c       |  2 ++
 3 files changed, 14 insertions(+), 3 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/4] virtio-mmio: wait for status readback after reset
  2026-04-07 12:39 [PATCH 0/4] virtio: fix four bugs across mmio, pci, and vring Andrew Stellman
@ 2026-04-07 12:39 ` Andrew Stellman
  2026-04-07 16:24   ` Michael S. Tsirkin
  2026-04-07 12:39 ` [PATCH 2/4] virtio-pci: use avq->vq_index for admin VQ in INTx path Andrew Stellman
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 14+ messages in thread
From: Andrew Stellman @ 2026-04-07 12:39 UTC (permalink / raw)
  To: Michael S . Tsirkin, Jason Wang
  Cc: Xuan Zhuo, Eugenio Pérez, virtualization, Andrew Stellman

The virtio specification requires that after writing 0 to the status
register, the driver must wait until the device has actually completed
the reset (status reads back as 0) before proceeding. vm_reset() writes
0 but returns immediately without confirming the device has reset.

Add a poll loop matching the pattern already used in virtio-pci's
vp_reset(), which calls msleep(1) in a loop until the status register
reads 0.

Signed-off-by: Andrew Stellman <astellman@stellman-greene.com>
---
 drivers/virtio/virtio_mmio.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 595c227..a477977 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -56,6 +56,7 @@
 
 #include <linux/acpi.h>
 #include <linux/dma-mapping.h>
+#include <linux/delay.h>
 #include <linux/highmem.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -254,6 +255,8 @@ static void vm_reset(struct virtio_device *vdev)
 
 	/* 0 status means a reset. */
 	writel(0, vm_dev->base + VIRTIO_MMIO_STATUS);
+	while (readl(vm_dev->base + VIRTIO_MMIO_STATUS))
+		msleep(1);
 }
 
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/4] virtio-pci: use avq->vq_index for admin VQ in INTx path
  2026-04-07 12:39 [PATCH 0/4] virtio: fix four bugs across mmio, pci, and vring Andrew Stellman
  2026-04-07 12:39 ` [PATCH 1/4] virtio-mmio: wait for status readback after reset Andrew Stellman
@ 2026-04-07 12:39 ` Andrew Stellman
  2026-04-07 16:26   ` Michael S. Tsirkin
  2026-04-07 12:39 ` [PATCH 3/4] virtio-pci: return IRQ_HANDLED for config-change interrupts Andrew Stellman
  2026-04-07 12:39 ` [PATCH 4/4] virtio_ring: preserve VIRTIO_F_RING_RESET in transport features Andrew Stellman
  3 siblings, 1 reply; 14+ messages in thread
From: Andrew Stellman @ 2026-04-07 12:39 UTC (permalink / raw)
  To: Michael S . Tsirkin, Jason Wang
  Cc: Xuan Zhuo, Eugenio Pérez, virtualization, Andrew Stellman

vp_find_vqs_intx() sets up the admin virtqueue using queue_idx++
(a sequential counter) instead of avq->vq_index (the actual transport
queue index). The MSI-X path in vp_find_vqs_msix() correctly uses
avq->vq_index. When the admin VQ index does not equal the next
sequential queue_idx value, the INTx path binds the admin VQ to the
wrong transport queue.

Use avq->vq_index to match the MSI-X path.

Signed-off-by: Andrew Stellman <astellman@stellman-greene.com>
---
 drivers/virtio/virtio_pci_common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
index da97b6a..0b9d66b 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -497,7 +497,7 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned int nvqs,
 	if (!avq_num)
 		return 0;
 	sprintf(avq->name, "avq.%u", avq->vq_index);
-	vq = vp_setup_vq(vdev, queue_idx++, vp_modern_avq_done, avq->name,
+	vq = vp_setup_vq(vdev, avq->vq_index, vp_modern_avq_done, avq->name,
 			 false, VIRTIO_MSI_NO_VECTOR,
 			 &vp_dev->admin_vq.info);
 	if (IS_ERR(vq)) {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/4] virtio-pci: return IRQ_HANDLED for config-change interrupts
  2026-04-07 12:39 [PATCH 0/4] virtio: fix four bugs across mmio, pci, and vring Andrew Stellman
  2026-04-07 12:39 ` [PATCH 1/4] virtio-mmio: wait for status readback after reset Andrew Stellman
  2026-04-07 12:39 ` [PATCH 2/4] virtio-pci: use avq->vq_index for admin VQ in INTx path Andrew Stellman
@ 2026-04-07 12:39 ` Andrew Stellman
  2026-04-07 16:20   ` Michael S. Tsirkin
  2026-04-07 12:39 ` [PATCH 4/4] virtio_ring: preserve VIRTIO_F_RING_RESET in transport features Andrew Stellman
  3 siblings, 1 reply; 14+ messages in thread
From: Andrew Stellman @ 2026-04-07 12:39 UTC (permalink / raw)
  To: Michael S . Tsirkin, Jason Wang
  Cc: Xuan Zhuo, Eugenio Pérez, virtualization, Andrew Stellman

vp_interrupt() unconditionally returns the result of
vp_vring_interrupt(). When a config-change interrupt fires but no vring
activity is pending, vp_vring_interrupt() returns IRQ_NONE — even
though the interrupt was legitimately handled by vp_config_changed().
Over time this causes the IRQ subsystem to flag the line as spurious.

Track the return value explicitly: set ret to IRQ_HANDLED when the
config-change bit is set, OR it with the vring result, and return the
combined value.

Signed-off-by: Andrew Stellman <astellman@stellman-greene.com>
---
 drivers/virtio/virtio_pci_common.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
index 0b9d66b..1d1ab02 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -106,6 +106,7 @@ static irqreturn_t vp_vring_interrupt(int irq, void *opaque)
 static irqreturn_t vp_interrupt(int irq, void *opaque)
 {
 	struct virtio_pci_device *vp_dev = opaque;
+	irqreturn_t ret = IRQ_NONE;
 	u8 isr;
 
 	/* reading the ISR has the effect of also clearing it so it's very
@@ -117,10 +118,15 @@ static irqreturn_t vp_interrupt(int irq, void *opaque)
 		return IRQ_NONE;
 
 	/* Configuration change?  Tell driver if it wants to know. */
-	if (isr & VIRTIO_PCI_ISR_CONFIG)
+	if (isr & VIRTIO_PCI_ISR_CONFIG) {
 		vp_config_changed(irq, opaque);
+		ret = IRQ_HANDLED;
+	}
 
-	return vp_vring_interrupt(irq, opaque);
+	if (vp_vring_interrupt(irq, opaque) == IRQ_HANDLED)
+		ret = IRQ_HANDLED;
+
+	return ret;
 }
 
 static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/4] virtio_ring: preserve VIRTIO_F_RING_RESET in transport features
  2026-04-07 12:39 [PATCH 0/4] virtio: fix four bugs across mmio, pci, and vring Andrew Stellman
                   ` (2 preceding siblings ...)
  2026-04-07 12:39 ` [PATCH 3/4] virtio-pci: return IRQ_HANDLED for config-change interrupts Andrew Stellman
@ 2026-04-07 12:39 ` Andrew Stellman
  2026-04-07 16:21   ` Michael S. Tsirkin
  3 siblings, 1 reply; 14+ messages in thread
From: Andrew Stellman @ 2026-04-07 12:39 UTC (permalink / raw)
  To: Michael S . Tsirkin, Jason Wang
  Cc: Xuan Zhuo, Eugenio Pérez, virtualization, Andrew Stellman

vring_transport_features() whitelists known transport feature bits and
clears the rest via __virtio_clear_bit(). VIRTIO_F_RING_RESET is
missing from the whitelist, so it is unconditionally cleared during
feature negotiation. Drivers that depend on ring reset capability
silently lose the feature.

Add VIRTIO_F_RING_RESET to the switch statement, matching the other
transport-level features.

Signed-off-by: Andrew Stellman <astellman@stellman-greene.com>
---
 drivers/virtio/virtio_ring.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index fbca7ce..2cb643f 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -3524,6 +3524,8 @@ void vring_transport_features(struct virtio_device *vdev)
 			break;
 		case VIRTIO_F_IN_ORDER:
 			break;
+		case VIRTIO_F_RING_RESET:
+			break;
 		default:
 			/* We don't understand this bit. */
 			__virtio_clear_bit(vdev, i);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/4] virtio-pci: return IRQ_HANDLED for config-change interrupts
  2026-04-07 12:39 ` [PATCH 3/4] virtio-pci: return IRQ_HANDLED for config-change interrupts Andrew Stellman
@ 2026-04-07 16:20   ` Michael S. Tsirkin
       [not found]     ` <CAChPuV9iGu6o5yJz87DEo6=gfr2P7m_jM=-auFuZevrr-HoYNw@mail.gmail.com>
  0 siblings, 1 reply; 14+ messages in thread
From: Michael S. Tsirkin @ 2026-04-07 16:20 UTC (permalink / raw)
  To: Andrew Stellman; +Cc: Jason Wang, Xuan Zhuo, Eugenio Pérez, virtualization

On Tue, Apr 07, 2026 at 08:39:03AM -0400, Andrew Stellman wrote:
> vp_interrupt() unconditionally returns the result of
> vp_vring_interrupt(). When a config-change interrupt fires but no vring
> activity is pending, vp_vring_interrupt() returns IRQ_NONE — even
> though the interrupt was legitimately handled by vp_config_changed().
> Over time this causes the IRQ subsystem to flag the line as spurious.
> 
> Track the return value explicitly: set ret to IRQ_HANDLED when the
> config-change bit is set, OR it with the vring result, and return the
> combined value.
> 
> Signed-off-by: Andrew Stellman <astellman@stellman-greene.com>

Fixes tag?

> ---
>  drivers/virtio/virtio_pci_common.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
> index 0b9d66b..1d1ab02 100644
> --- a/drivers/virtio/virtio_pci_common.c
> +++ b/drivers/virtio/virtio_pci_common.c
> @@ -106,6 +106,7 @@ static irqreturn_t vp_vring_interrupt(int irq, void *opaque)
>  static irqreturn_t vp_interrupt(int irq, void *opaque)
>  {
>  	struct virtio_pci_device *vp_dev = opaque;
> +	irqreturn_t ret = IRQ_NONE;
>  	u8 isr;
>  
>  	/* reading the ISR has the effect of also clearing it so it's very
> @@ -117,10 +118,15 @@ static irqreturn_t vp_interrupt(int irq, void *opaque)
>  		return IRQ_NONE;
>  
>  	/* Configuration change?  Tell driver if it wants to know. */
> -	if (isr & VIRTIO_PCI_ISR_CONFIG)
> +	if (isr & VIRTIO_PCI_ISR_CONFIG) {
>  		vp_config_changed(irq, opaque);
> +		ret = IRQ_HANDLED;
> +	}
>  
> -	return vp_vring_interrupt(irq, opaque);
> +	if (vp_vring_interrupt(irq, opaque) == IRQ_HANDLED)
> +		ret = IRQ_HANDLED;
> +
> +	return ret;
>  }
>  
>  static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors,
> -- 
> 2.34.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/4] virtio_ring: preserve VIRTIO_F_RING_RESET in transport features
  2026-04-07 12:39 ` [PATCH 4/4] virtio_ring: preserve VIRTIO_F_RING_RESET in transport features Andrew Stellman
@ 2026-04-07 16:21   ` Michael S. Tsirkin
       [not found]     ` <CAChPuV92aD4BibJiGfMASQVQBHAoz+3OgzQS6Hb2Dw7JDcRJTQ@mail.gmail.com>
  0 siblings, 1 reply; 14+ messages in thread
From: Michael S. Tsirkin @ 2026-04-07 16:21 UTC (permalink / raw)
  To: Andrew Stellman; +Cc: Jason Wang, Xuan Zhuo, Eugenio Pérez, virtualization

On Tue, Apr 07, 2026 at 08:39:04AM -0400, Andrew Stellman wrote:
> vring_transport_features() whitelists known transport feature bits and
> clears the rest via __virtio_clear_bit(). VIRTIO_F_RING_RESET is
> missing from the whitelist, so it is unconditionally cleared during
> feature negotiation. Drivers that depend on ring reset capability
> silently lose the feature.

Hmm was this observed in practice or just from code analysis?
And on which transport?
Because


static void vp_transport_features(struct virtio_device *vdev, u64 features)
{               
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        struct pci_dev *pci_dev = vp_dev->pci_dev;
                        
        if ((features & BIT_ULL(VIRTIO_F_SR_IOV)) &&
                        pci_find_ext_capability(pci_dev, PCI_EXT_CAP_ID_SRIOV))
                __virtio_set_bit(vdev, VIRTIO_F_SR_IOV);
        
        if (features & BIT_ULL(VIRTIO_F_RING_RESET))
                __virtio_set_bit(vdev, VIRTIO_F_RING_RESET);
        

...



}




> Add VIRTIO_F_RING_RESET to the switch statement, matching the other
> transport-level features.
> 
> Signed-off-by: Andrew Stellman <astellman@stellman-greene.com>
> ---
>  drivers/virtio/virtio_ring.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
> index fbca7ce..2cb643f 100644
> --- a/drivers/virtio/virtio_ring.c
> +++ b/drivers/virtio/virtio_ring.c
> @@ -3524,6 +3524,8 @@ void vring_transport_features(struct virtio_device *vdev)
>  			break;
>  		case VIRTIO_F_IN_ORDER:
>  			break;
> +		case VIRTIO_F_RING_RESET:
> +			break;
>  		default:
>  			/* We don't understand this bit. */
>  			__virtio_clear_bit(vdev, i);
> -- 
> 2.34.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/4] virtio-mmio: wait for status readback after reset
  2026-04-07 12:39 ` [PATCH 1/4] virtio-mmio: wait for status readback after reset Andrew Stellman
@ 2026-04-07 16:24   ` Michael S. Tsirkin
  0 siblings, 0 replies; 14+ messages in thread
From: Michael S. Tsirkin @ 2026-04-07 16:24 UTC (permalink / raw)
  To: Andrew Stellman; +Cc: Jason Wang, Xuan Zhuo, Eugenio Pérez, virtualization

On Tue, Apr 07, 2026 at 08:39:01AM -0400, Andrew Stellman wrote:
> The virtio specification requires that after writing 0 to the status
> register, the driver must wait until the device has actually completed
> the reset (status reads back as 0) before proceeding.

It does? But where?
I see:
    Reading from this register returns the current device status
    flags.
    Writing non-zero values to this register sets the status flags,
    indicating the OS/driver progress. Writing zero (0x0) to this
    register triggers a device reset. The device
    sets \field{QueuePFN} to zero (0x0) for all queues in the device.



> vm_reset() writes
> 0 but returns immediately without confirming the device has reset.
> 
> Add a poll loop matching the pattern already used in virtio-pci's
> vp_reset(), which calls msleep(1) in a loop until the status register
> reads 0.
> 
> Signed-off-by: Andrew Stellman <astellman@stellman-greene.com>
> ---
>  drivers/virtio/virtio_mmio.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
> index 595c227..a477977 100644
> --- a/drivers/virtio/virtio_mmio.c
> +++ b/drivers/virtio/virtio_mmio.c
> @@ -56,6 +56,7 @@
>  
>  #include <linux/acpi.h>
>  #include <linux/dma-mapping.h>
> +#include <linux/delay.h>
>  #include <linux/highmem.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
> @@ -254,6 +255,8 @@ static void vm_reset(struct virtio_device *vdev)
>  
>  	/* 0 status means a reset. */
>  	writel(0, vm_dev->base + VIRTIO_MMIO_STATUS);
> +	while (readl(vm_dev->base + VIRTIO_MMIO_STATUS))
> +		msleep(1);
>  }
>  
>  
> -- 
> 2.34.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/4] virtio-pci: use avq->vq_index for admin VQ in INTx path
  2026-04-07 12:39 ` [PATCH 2/4] virtio-pci: use avq->vq_index for admin VQ in INTx path Andrew Stellman
@ 2026-04-07 16:26   ` Michael S. Tsirkin
       [not found]     ` <CAChPuV9OuQw_F5dsna4meVxV6Hicxe4+674xoSx+KEev6JEEQw@mail.gmail.com>
  0 siblings, 1 reply; 14+ messages in thread
From: Michael S. Tsirkin @ 2026-04-07 16:26 UTC (permalink / raw)
  To: Andrew Stellman
  Cc: Jason Wang, Xuan Zhuo, Eugenio Pérez, virtualization,
	Jiri Pirko

On Tue, Apr 07, 2026 at 08:39:02AM -0400, Andrew Stellman wrote:
> vp_find_vqs_intx() sets up the admin virtqueue using queue_idx++
> (a sequential counter) instead of avq->vq_index (the actual transport
> queue index). The MSI-X path in vp_find_vqs_msix() correctly uses
> avq->vq_index. When the admin VQ index does not equal the next
> sequential queue_idx value, the INTx path binds the admin VQ to the
> wrong transport queue.
> 
> Use avq->vq_index to match the MSI-X path.
> 
> Signed-off-by: Andrew Stellman <astellman@stellman-greene.com>


Cc Jiri. fixes tag?

> ---
>  drivers/virtio/virtio_pci_common.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
> index da97b6a..0b9d66b 100644
> --- a/drivers/virtio/virtio_pci_common.c
> +++ b/drivers/virtio/virtio_pci_common.c
> @@ -497,7 +497,7 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned int nvqs,
>  	if (!avq_num)
>  		return 0;
>  	sprintf(avq->name, "avq.%u", avq->vq_index);
> -	vq = vp_setup_vq(vdev, queue_idx++, vp_modern_avq_done, avq->name,
> +	vq = vp_setup_vq(vdev, avq->vq_index, vp_modern_avq_done, avq->name,
>  			 false, VIRTIO_MSI_NO_VECTOR,
>  			 &vp_dev->admin_vq.info);
>  	if (IS_ERR(vq)) {
> -- 
> 2.34.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/4] virtio_ring: preserve VIRTIO_F_RING_RESET in transport features
       [not found]     ` <CAChPuV92aD4BibJiGfMASQVQBHAoz+3OgzQS6Hb2Dw7JDcRJTQ@mail.gmail.com>
@ 2026-04-07 18:08       ` Michael S. Tsirkin
  2026-04-07 20:00         ` Andrew Stellman
  0 siblings, 1 reply; 14+ messages in thread
From: Michael S. Tsirkin @ 2026-04-07 18:08 UTC (permalink / raw)
  To: Andrew Stellman; +Cc: Jason Wang, Xuan Zhuo, Eugenio Pérez, virtualization

On Tue, Apr 07, 2026 at 01:33:39PM -0400, Andrew Stellman wrote:
> Code analysis only — not observed in practice. And you're right that on PCI it
> doesn't matter: vp_transport_features() re-sets the bit after
> vring_transport_features() clears it, so PCI never actually loses the feature.

Oh. please do test patches, or note they were not tested.
how were rest of patches here tested?

> 
> The gap is for transports that call vring_transport_features() without
> independently re-setting VIRTIO_F_RING_RESET afterward. Whether any current
> transport hits this in practice I'm not sure — it may just be a whitelist
> consistency fix at this point.
> 
> Happy to add a Fixes tag and resend, or drop it if you think the PCI-level
> re-set makes it unnecessary.
> 
> Fixes: 04ca0b0b16f1 ("virtio_pci: support VIRTIO_F_RING_RESET")


surely not this because pci is fine.

> On Tue, Apr 7, 2026 at 12:22 PM Michael S. Tsirkin <mst@redhat.com> wrote:
> 
>     On Tue, Apr 07, 2026 at 08:39:04AM -0400, Andrew Stellman wrote:
>     > vring_transport_features() whitelists known transport feature bits and
>     > clears the rest via __virtio_clear_bit(). VIRTIO_F_RING_RESET is
>     > missing from the whitelist, so it is unconditionally cleared during
>     > feature negotiation. Drivers that depend on ring reset capability
>     > silently lose the feature.
> 
>     Hmm was this observed in practice or just from code analysis?
>     And on which transport?
>     Because
> 
> 
>     static void vp_transport_features(struct virtio_device *vdev, u64 features)
>     {               
>             struct virtio_pci_device *vp_dev = to_vp_device(vdev);
>             struct pci_dev *pci_dev = vp_dev->pci_dev;
> 
>             if ((features & BIT_ULL(VIRTIO_F_SR_IOV)) &&
>                             pci_find_ext_capability(pci_dev,
>     PCI_EXT_CAP_ID_SRIOV))
>                     __virtio_set_bit(vdev, VIRTIO_F_SR_IOV);
> 
>             if (features & BIT_ULL(VIRTIO_F_RING_RESET))
>                     __virtio_set_bit(vdev, VIRTIO_F_RING_RESET);
> 
> 
>     ...
> 
> 
> 
>     }
> 
> 
> 
> 
>     > Add VIRTIO_F_RING_RESET to the switch statement, matching the other
>     > transport-level features.
>     >
>     > Signed-off-by: Andrew Stellman <astellman@stellman-greene.com>
>     > ---
>     >  drivers/virtio/virtio_ring.c | 2 ++
>     >  1 file changed, 2 insertions(+)
>     >
>     > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
>     > index fbca7ce..2cb643f 100644
>     > --- a/drivers/virtio/virtio_ring.c
>     > +++ b/drivers/virtio/virtio_ring.c
>     > @@ -3524,6 +3524,8 @@ void vring_transport_features(struct virtio_device
>     *vdev)
>     >                       break;
>     >               case VIRTIO_F_IN_ORDER:
>     >                       break;
>     > +             case VIRTIO_F_RING_RESET:
>     > +                     break;
>     >               default:
>     >                       /* We don't understand this bit. */
>     >                       __virtio_clear_bit(vdev, i);
>     > --
>     > 2.34.1
> 
> 


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/4] virtio-pci: use avq->vq_index for admin VQ in INTx path
       [not found]     ` <CAChPuV9OuQw_F5dsna4meVxV6Hicxe4+674xoSx+KEev6JEEQw@mail.gmail.com>
@ 2026-04-07 18:08       ` Michael S. Tsirkin
  0 siblings, 0 replies; 14+ messages in thread
From: Michael S. Tsirkin @ 2026-04-07 18:08 UTC (permalink / raw)
  To: Andrew Stellman
  Cc: Jason Wang, Xuan Zhuo, Eugenio Pérez, virtualization,
	Jiri Pirko

On Tue, Apr 07, 2026 at 01:34:23PM -0400, Andrew Stellman wrote:
> Fixes: af22bbe1f4a5 ("virtio: create admin queues alongside other virtqueues")


and how was this tested?

> 
> On Tue, Apr 7, 2026 at 12:26 PM Michael S. Tsirkin <mst@redhat.com> wrote:
> 
>     On Tue, Apr 07, 2026 at 08:39:02AM -0400, Andrew Stellman wrote:
>     > vp_find_vqs_intx() sets up the admin virtqueue using queue_idx++
>     > (a sequential counter) instead of avq->vq_index (the actual transport
>     > queue index). The MSI-X path in vp_find_vqs_msix() correctly uses
>     > avq->vq_index. When the admin VQ index does not equal the next
>     > sequential queue_idx value, the INTx path binds the admin VQ to the
>     > wrong transport queue.
>     >
>     > Use avq->vq_index to match the MSI-X path.
>     >
>     > Signed-off-by: Andrew Stellman <astellman@stellman-greene.com>
> 
> 
>     Cc Jiri. fixes tag?
> 
>     > ---
>     >  drivers/virtio/virtio_pci_common.c | 2 +-
>     >  1 file changed, 1 insertion(+), 1 deletion(-)
>     >
>     > diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/
>     virtio_pci_common.c
>     > index da97b6a..0b9d66b 100644
>     > --- a/drivers/virtio/virtio_pci_common.c
>     > +++ b/drivers/virtio/virtio_pci_common.c
>     > @@ -497,7 +497,7 @@ static int vp_find_vqs_intx(struct virtio_device
>     *vdev, unsigned int nvqs,
>     >       if (!avq_num)
>     >               return 0;
>     >       sprintf(avq->name, "avq.%u", avq->vq_index);
>     > -     vq = vp_setup_vq(vdev, queue_idx++, vp_modern_avq_done, avq->name,
>     > +     vq = vp_setup_vq(vdev, avq->vq_index, vp_modern_avq_done, avq->
>     name,
>     >                        false, VIRTIO_MSI_NO_VECTOR,
>     >                        &vp_dev->admin_vq.info);
>     >       if (IS_ERR(vq)) {
>     > --
>     > 2.34.1
> 
> 


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/4] virtio_ring: preserve VIRTIO_F_RING_RESET in transport features
  2026-04-07 18:08       ` Michael S. Tsirkin
@ 2026-04-07 20:00         ` Andrew Stellman
  2026-04-07 20:53           ` Michael S. Tsirkin
  0 siblings, 1 reply; 14+ messages in thread
From: Andrew Stellman @ 2026-04-07 20:00 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Jason Wang, Xuan Zhuo, Eugenio Pérez, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 4285 bytes --]

No, sorry, I tested it, only with a unit test after finding it via static
analysis, not the "real" way using the whole kernel build. (Also replied
with the test for 0002.)

Found with static analysis, reproduced with a unit test (save attached file
to drivers/virtio/test0004.c):

% cd drivers/virtio
% git checkout virtio_ring.c
Updated 0 paths from the index
% sed -n '/^void vring_transport_features/,/^}/p' virtio_ring.c >
extracted.c && gcc -Wall -Werror -o test0004 test0004.c && ./test0004
FAIL: VIRTIO_F_RING_RESET cleared during negotiation
% git apply 0004-virtio_ring-preserve-VIRTIO_F_RING_RESET-in-transpor.patch
% sed -n '/^void vring_transport_features/,/^}/p' virtio_ring.c >
extracted.c && gcc -Wall -Werror -o test0004 test0004.c && ./test0004
PASS: VIRTIO_F_RING_RESET preserved

If this doesn't work, feel free to ditch.

On Tue, Apr 7, 2026 at 2:08 PM Michael S. Tsirkin <mst@redhat.com> wrote:

> On Tue, Apr 07, 2026 at 01:33:39PM -0400, Andrew Stellman wrote:
> > Code analysis only — not observed in practice. And you're right that on
> PCI it
> > doesn't matter: vp_transport_features() re-sets the bit after
> > vring_transport_features() clears it, so PCI never actually loses the
> feature.
>
> Oh. please do test patches, or note they were not tested.
> how were rest of patches here tested?
>
> >
> > The gap is for transports that call vring_transport_features() without
> > independently re-setting VIRTIO_F_RING_RESET afterward. Whether any
> current
> > transport hits this in practice I'm not sure — it may just be a whitelist
> > consistency fix at this point.
> >
> > Happy to add a Fixes tag and resend, or drop it if you think the
> PCI-level
> > re-set makes it unnecessary.
> >
> > Fixes: 04ca0b0b16f1 ("virtio_pci: support VIRTIO_F_RING_RESET")
>
>
> surely not this because pci is fine.
>
> > On Tue, Apr 7, 2026 at 12:22 PM Michael S. Tsirkin <mst@redhat.com>
> wrote:
> >
> >     On Tue, Apr 07, 2026 at 08:39:04AM -0400, Andrew Stellman wrote:
> >     > vring_transport_features() whitelists known transport feature bits
> and
> >     > clears the rest via __virtio_clear_bit(). VIRTIO_F_RING_RESET is
> >     > missing from the whitelist, so it is unconditionally cleared during
> >     > feature negotiation. Drivers that depend on ring reset capability
> >     > silently lose the feature.
> >
> >     Hmm was this observed in practice or just from code analysis?
> >     And on which transport?
> >     Because
> >
> >
> >     static void vp_transport_features(struct virtio_device *vdev, u64
> features)
> >     {
> >             struct virtio_pci_device *vp_dev = to_vp_device(vdev);
> >             struct pci_dev *pci_dev = vp_dev->pci_dev;
> >
> >             if ((features & BIT_ULL(VIRTIO_F_SR_IOV)) &&
> >                             pci_find_ext_capability(pci_dev,
> >     PCI_EXT_CAP_ID_SRIOV))
> >                     __virtio_set_bit(vdev, VIRTIO_F_SR_IOV);
> >
> >             if (features & BIT_ULL(VIRTIO_F_RING_RESET))
> >                     __virtio_set_bit(vdev, VIRTIO_F_RING_RESET);
> >
> >
> >     ...
> >
> >
> >
> >     }
> >
> >
> >
> >
> >     > Add VIRTIO_F_RING_RESET to the switch statement, matching the other
> >     > transport-level features.
> >     >
> >     > Signed-off-by: Andrew Stellman <astellman@stellman-greene.com>
> >     > ---
> >     >  drivers/virtio/virtio_ring.c | 2 ++
> >     >  1 file changed, 2 insertions(+)
> >     >
> >     > diff --git a/drivers/virtio/virtio_ring.c
> b/drivers/virtio/virtio_ring.c
> >     > index fbca7ce..2cb643f 100644
> >     > --- a/drivers/virtio/virtio_ring.c
> >     > +++ b/drivers/virtio/virtio_ring.c
> >     > @@ -3524,6 +3524,8 @@ void vring_transport_features(struct
> virtio_device
> >     *vdev)
> >     >                       break;
> >     >               case VIRTIO_F_IN_ORDER:
> >     >                       break;
> >     > +             case VIRTIO_F_RING_RESET:
> >     > +                     break;
> >     >               default:
> >     >                       /* We don't understand this bit. */
> >     >                       __virtio_clear_bit(vdev, i);
> >     > --
> >     > 2.34.1
> >
> >
>
>

[-- Attachment #1.2: Type: text/html, Size: 5661 bytes --]

[-- Attachment #2: test0004.c --]
[-- Type: application/octet-stream, Size: 1406 bytes --]

// SPDX-License-Identifier: GPL-2.0-only
/* Test: virtio_ring: preserve VIRTIO_F_RING_RESET in transport features
 *
 * VIRTIO_F_RING_RESET is missing from the vring_transport_features()
 * whitelist, so it gets silently cleared during feature negotiation.
 *
 * sed -n '/^void vring_transport_features/,/^}/p' drivers/virtio/virtio_ring.c > extracted.c && gcc -Wall -Werror -o test0004 test0004.c && ./test0004
 */
#include <stdio.h>
#include <stdint.h>

typedef uint64_t u64;
struct virtio_device { u64 features; };

static void __virtio_clear_bit(struct virtio_device *vdev, unsigned int bit)
{
	vdev->features &= ~(1ULL << bit);
}

#define VIRTIO_TRANSPORT_F_START	28
#define VIRTIO_TRANSPORT_F_END		42
#define VIRTIO_RING_F_INDIRECT_DESC	28
#define VIRTIO_RING_F_EVENT_IDX		29
#define VIRTIO_F_VERSION_1		32
#define VIRTIO_F_ACCESS_PLATFORM	33
#define VIRTIO_F_RING_PACKED		34
#define VIRTIO_F_IN_ORDER		35
#define VIRTIO_F_ORDER_PLATFORM		36
#define VIRTIO_F_NOTIFICATION_DATA	38
#define VIRTIO_F_RING_RESET		40

#include "extracted.c"

int main(void)
{
	struct virtio_device vdev;

	vdev.features = (1ULL << VIRTIO_F_VERSION_1) | (1ULL << VIRTIO_F_RING_RESET);
	vring_transport_features(&vdev);

	if (!(vdev.features & (1ULL << VIRTIO_F_RING_RESET))) {
		printf("FAIL: VIRTIO_F_RING_RESET cleared during negotiation\n");
		return 1;
	}
	printf("PASS: VIRTIO_F_RING_RESET preserved\n");
	return 0;
}

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/4] virtio_ring: preserve VIRTIO_F_RING_RESET in transport features
  2026-04-07 20:00         ` Andrew Stellman
@ 2026-04-07 20:53           ` Michael S. Tsirkin
  0 siblings, 0 replies; 14+ messages in thread
From: Michael S. Tsirkin @ 2026-04-07 20:53 UTC (permalink / raw)
  To: Andrew Stellman; +Cc: Jason Wang, Xuan Zhuo, Eugenio Pérez, virtualization

On Tue, Apr 07, 2026 at 04:00:00PM -0400, Andrew Stellman wrote:
> No, sorry, I tested it, only with a unit test after finding it via static
> analysis, not the "real" way using the whole kernel build. (Also replied with
> the test for 0002.)
> 
> Found with static analysis, reproduced with a unit test (save attached file to
> drivers/virtio/test0004.c):
> 
> % cd drivers/virtio          
> % git checkout virtio_ring.c
> Updated 0 paths from the index
> % sed -n '/^void vring_transport_features/,/^}/p' virtio_ring.c > extracted.c &
> & gcc -Wall -Werror -o test0004 test0004.c && ./test0004
> FAIL: VIRTIO_F_RING_RESET cleared during negotiation
> % git apply 0004-virtio_ring-preserve-VIRTIO_F_RING_RESET-in-transpor.patch
> % sed -n '/^void vring_transport_features/,/^}/p' virtio_ring.c > extracted.c &
> & gcc -Wall -Werror -o test0004 test0004.c && ./test0004
> PASS: VIRTIO_F_RING_RESET preserved
> 
> If this doesn't work, feel free to ditch.

I want to know if there's a bug or not, and what does the patch achieve.
The current code does not make it clear at all.


> On Tue, Apr 7, 2026 at 2:08 PM Michael S. Tsirkin <mst@redhat.com> wrote:
> 
>     On Tue, Apr 07, 2026 at 01:33:39PM -0400, Andrew Stellman wrote:
>     > Code analysis only — not observed in practice. And you're right that on
>     PCI it
>     > doesn't matter: vp_transport_features() re-sets the bit after
>     > vring_transport_features() clears it, so PCI never actually loses the
>     feature.
> 
>     Oh. please do test patches, or note they were not tested.
>     how were rest of patches here tested?
> 
>     >
>     > The gap is for transports that call vring_transport_features() without
>     > independently re-setting VIRTIO_F_RING_RESET afterward. Whether any
>     current
>     > transport hits this in practice I'm not sure — it may just be a whitelist
>     > consistency fix at this point.
>     >
>     > Happy to add a Fixes tag and resend, or drop it if you think the
>     PCI-level
>     > re-set makes it unnecessary.
>     >
>     > Fixes: 04ca0b0b16f1 ("virtio_pci: support VIRTIO_F_RING_RESET")
> 
> 
>     surely not this because pci is fine.
> 
>     > On Tue, Apr 7, 2026 at 12:22 PM Michael S. Tsirkin <mst@redhat.com>
>     wrote:
>     >
>     >     On Tue, Apr 07, 2026 at 08:39:04AM -0400, Andrew Stellman wrote:
>     >     > vring_transport_features() whitelists known transport feature bits
>     and
>     >     > clears the rest via __virtio_clear_bit(). VIRTIO_F_RING_RESET is
>     >     > missing from the whitelist, so it is unconditionally cleared during
>     >     > feature negotiation. Drivers that depend on ring reset capability
>     >     > silently lose the feature.
>     >
>     >     Hmm was this observed in practice or just from code analysis?
>     >     And on which transport?
>     >     Because
>     >
>     >
>     >     static void vp_transport_features(struct virtio_device *vdev, u64
>     features)
>     >     {               
>     >             struct virtio_pci_device *vp_dev = to_vp_device(vdev);
>     >             struct pci_dev *pci_dev = vp_dev->pci_dev;
>     >
>     >             if ((features & BIT_ULL(VIRTIO_F_SR_IOV)) &&
>     >                             pci_find_ext_capability(pci_dev,
>     >     PCI_EXT_CAP_ID_SRIOV))
>     >                     __virtio_set_bit(vdev, VIRTIO_F_SR_IOV);
>     >
>     >             if (features & BIT_ULL(VIRTIO_F_RING_RESET))
>     >                     __virtio_set_bit(vdev, VIRTIO_F_RING_RESET);
>     >
>     >
>     >     ...
>     >
>     >
>     >
>     >     }
>     >
>     >
>     >
>     >
>     >     > Add VIRTIO_F_RING_RESET to the switch statement, matching the other
>     >     > transport-level features.
>     >     >
>     >     > Signed-off-by: Andrew Stellman <astellman@stellman-greene.com>
>     >     > ---
>     >     >  drivers/virtio/virtio_ring.c | 2 ++
>     >     >  1 file changed, 2 insertions(+)
>     >     >
>     >     > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/
>     virtio_ring.c
>     >     > index fbca7ce..2cb643f 100644
>     >     > --- a/drivers/virtio/virtio_ring.c
>     >     > +++ b/drivers/virtio/virtio_ring.c
>     >     > @@ -3524,6 +3524,8 @@ void vring_transport_features(struct
>     virtio_device
>     >     *vdev)
>     >     >                       break;
>     >     >               case VIRTIO_F_IN_ORDER:
>     >     >                       break;
>     >     > +             case VIRTIO_F_RING_RESET:
>     >     > +                     break;
>     >     >               default:
>     >     >                       /* We don't understand this bit. */
>     >     >                       __virtio_clear_bit(vdev, i);
>     >     > --
>     >     > 2.34.1
>     >
>     >
> 
> 



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/4] virtio-pci: return IRQ_HANDLED for config-change interrupts
       [not found]     ` <CAChPuV9iGu6o5yJz87DEo6=gfr2P7m_jM=-auFuZevrr-HoYNw@mail.gmail.com>
@ 2026-04-07 20:53       ` Michael S. Tsirkin
  0 siblings, 0 replies; 14+ messages in thread
From: Michael S. Tsirkin @ 2026-04-07 20:53 UTC (permalink / raw)
  To: Andrew Stellman; +Cc: Jason Wang, Xuan Zhuo, Eugenio Pérez, virtualization

On Tue, Apr 07, 2026 at 01:35:26PM -0400, Andrew Stellman wrote:
> Fixes: 77cf524654a8 ("virtio_pci: split up vp_interrupt")
> 
> Should I resend as v2 with the tag included, or is adding it on your end
> easier?


how was this tested? I don't think a unit test is sufficient here, FYI.


> On Tue, Apr 7, 2026 at 12:20 PM Michael S. Tsirkin <mst@redhat.com> wrote:
> 
>     On Tue, Apr 07, 2026 at 08:39:03AM -0400, Andrew Stellman wrote:
>     > vp_interrupt() unconditionally returns the result of
>     > vp_vring_interrupt(). When a config-change interrupt fires but no vring
>     > activity is pending, vp_vring_interrupt() returns IRQ_NONE — even
>     > though the interrupt was legitimately handled by vp_config_changed().
>     > Over time this causes the IRQ subsystem to flag the line as spurious.
>     >
>     > Track the return value explicitly: set ret to IRQ_HANDLED when the
>     > config-change bit is set, OR it with the vring result, and return the
>     > combined value.
>     >
>     > Signed-off-by: Andrew Stellman <astellman@stellman-greene.com>
> 
>     Fixes tag?
> 
>     > ---
>     >  drivers/virtio/virtio_pci_common.c | 10 ++++++++--
>     >  1 file changed, 8 insertions(+), 2 deletions(-)
>     >
>     > diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/
>     virtio_pci_common.c
>     > index 0b9d66b..1d1ab02 100644
>     > --- a/drivers/virtio/virtio_pci_common.c
>     > +++ b/drivers/virtio/virtio_pci_common.c
>     > @@ -106,6 +106,7 @@ static irqreturn_t vp_vring_interrupt(int irq, void
>     *opaque)
>     >  static irqreturn_t vp_interrupt(int irq, void *opaque)
>     >  {
>     >       struct virtio_pci_device *vp_dev = opaque;
>     > +     irqreturn_t ret = IRQ_NONE;
>     >       u8 isr;
>     > 
>     >       /* reading the ISR has the effect of also clearing it so it's very
>     > @@ -117,10 +118,15 @@ static irqreturn_t vp_interrupt(int irq, void
>     *opaque)
>     >               return IRQ_NONE;
>     > 
>     >       /* Configuration change?  Tell driver if it wants to know. */
>     > -     if (isr & VIRTIO_PCI_ISR_CONFIG)
>     > +     if (isr & VIRTIO_PCI_ISR_CONFIG) {
>     >               vp_config_changed(irq, opaque);
>     > +             ret = IRQ_HANDLED;
>     > +     }
>     > 
>     > -     return vp_vring_interrupt(irq, opaque);
>     > +     if (vp_vring_interrupt(irq, opaque) == IRQ_HANDLED)
>     > +             ret = IRQ_HANDLED;
>     > +
>     > +     return ret;
>     >  }
>     > 
>     >  static int vp_request_msix_vectors(struct virtio_device *vdev, int
>     nvectors,
>     > --
>     > 2.34.1
> 
> 


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-04-07 20:53 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-07 12:39 [PATCH 0/4] virtio: fix four bugs across mmio, pci, and vring Andrew Stellman
2026-04-07 12:39 ` [PATCH 1/4] virtio-mmio: wait for status readback after reset Andrew Stellman
2026-04-07 16:24   ` Michael S. Tsirkin
2026-04-07 12:39 ` [PATCH 2/4] virtio-pci: use avq->vq_index for admin VQ in INTx path Andrew Stellman
2026-04-07 16:26   ` Michael S. Tsirkin
     [not found]     ` <CAChPuV9OuQw_F5dsna4meVxV6Hicxe4+674xoSx+KEev6JEEQw@mail.gmail.com>
2026-04-07 18:08       ` Michael S. Tsirkin
2026-04-07 12:39 ` [PATCH 3/4] virtio-pci: return IRQ_HANDLED for config-change interrupts Andrew Stellman
2026-04-07 16:20   ` Michael S. Tsirkin
     [not found]     ` <CAChPuV9iGu6o5yJz87DEo6=gfr2P7m_jM=-auFuZevrr-HoYNw@mail.gmail.com>
2026-04-07 20:53       ` Michael S. Tsirkin
2026-04-07 12:39 ` [PATCH 4/4] virtio_ring: preserve VIRTIO_F_RING_RESET in transport features Andrew Stellman
2026-04-07 16:21   ` Michael S. Tsirkin
     [not found]     ` <CAChPuV92aD4BibJiGfMASQVQBHAoz+3OgzQS6Hb2Dw7JDcRJTQ@mail.gmail.com>
2026-04-07 18:08       ` Michael S. Tsirkin
2026-04-07 20:00         ` Andrew Stellman
2026-04-07 20:53           ` Michael S. Tsirkin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox