From 57e766bdbbfcdf1f36f696fc735fbebbea97f5ca Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Thu, 26 Mar 2026 06:44:23 -0700 Subject: [PATCH] virtio-devices: Only try and activate if the device became ready Previously this code could lead to the device being trying to be activated multiple times as the code to trigger the activation was based on the state of the device (not yet activated and device being ready). This could occur if anothe vCPU wrote to a PCI BAR on this device before the device activation was completed by the VMM thread. Now we only trigger the activation if the device readiness has changed as a result of this BAR write (by checking that the readiness was originally unready.) Signed-off-by: Rob Bradford --- virtio-devices/src/transport/pci_device.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/virtio-devices/src/transport/pci_device.rs b/virtio-devices/src/transport/pci_device.rs index 3e2a96ccd..1eb1cc03f 100644 --- a/virtio-devices/src/transport/pci_device.rs +++ b/virtio-devices/src/transport/pci_device.rs @@ -1179,6 +1179,7 @@ impl PciDevice for VirtioPciDevice { } fn write_bar(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option> { + let initial_ready = self.is_driver_ready(); match offset { o if o < COMMON_CONFIG_BAR_OFFSET + COMMON_CONFIG_SIZE => self.common_config.write( o - COMMON_CONFIG_BAR_OFFSET, @@ -1230,8 +1231,8 @@ impl PciDevice for VirtioPciDevice { _ => (), } - // Try and activate the device if the driver status has changed - if self.needs_activation() { + // Try and activate the device if the driver status has changed (from unready to ready) + if !initial_ready && self.needs_activation() { let barrier = Arc::new(Barrier::new(2)); let activator = self.prepare_activator(Some(barrier.clone())); self.pending_activations.lock().unwrap().push(activator);