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 <rbradford@meta.com>
This commit is contained in:
Rob Bradford
2026-03-26 06:44:23 -07:00
parent 65073259c6
commit 57e766bdbb

View File

@@ -1179,6 +1179,7 @@ impl PciDevice for VirtioPciDevice {
}
fn write_bar(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
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);