diff --git a/src/vmm/src/devices/virtio/transport/mmio.rs b/src/vmm/src/devices/virtio/transport/mmio.rs index 42cfe2b3ed7..4964f837aca 100644 --- a/src/vmm/src/devices/virtio/transport/mmio.rs +++ b/src/vmm/src/devices/virtio/transport/mmio.rs @@ -179,21 +179,18 @@ impl MmioTransport { } DRIVER_OK if self.device_status == (ACKNOWLEDGE | DRIVER | FEATURES_OK) => { self.device_status = status; - let device_activated = self.locked_device().is_activated(); + let mut locked_device = self.device.lock().expect("Poisoned lock"); + let device_activated = locked_device.is_activated(); if !device_activated { // temporary variable needed for borrow checker - let activate_result = self - .locked_device() - .activate(self.mem.clone(), self.interrupt.clone()); + let activate_result = + locked_device.activate(self.mem.clone(), self.interrupt.clone()); if let Err(err) = activate_result { self.device_status |= DEVICE_NEEDS_RESET; // Section 2.1.2 of the specification states that we need to send a device // configuration change interrupt - let _ = self - .locked_device() - .interrupt_trigger() - .trigger(VirtioInterruptType::Config); + let _ = self.interrupt.trigger(VirtioInterruptType::Config); error!("Failed to activate virtio device: {}", err) } @@ -204,16 +201,19 @@ impl MmioTransport { self.device_status |= FAILED; } _ if status == 0 => { - if self.locked_device().is_activated() { - let mut device_status = self.device_status; - let reset_result = self.locked_device().reset(); - match reset_result { - Some((_interrupt_evt, mut _queue_evts)) => {} - None => { - device_status |= FAILED; + { + let mut locked_device = self.device.lock().expect("Poisoned lock"); + if locked_device.is_activated() { + let mut device_status = self.device_status; + let reset_result = locked_device.reset(); + match reset_result { + Some((_interrupt_evt, mut _queue_evts)) => {} + None => { + device_status |= FAILED; + } } + self.device_status = device_status; } - self.device_status = device_status; } // If the backend device driver doesn't support reset, diff --git a/src/vmm/src/devices/virtio/transport/pci/device.rs b/src/vmm/src/devices/virtio/transport/pci/device.rs index 0c4b275bb96..ba91163fe49 100644 --- a/src/vmm/src/devices/virtio/transport/pci/device.rs +++ b/src/vmm/src/devices/virtio/transport/pci/device.rs @@ -1029,15 +1029,22 @@ impl PciDevice for VirtioPciDevice { // Try and activate the device if the driver status has changed if self.needs_activation() { debug!("Activating device"); - self.virtio_device() + let interrupt = Arc::clone(self.virtio_interrupt.as_ref().unwrap()); + match self + .virtio_device() .lock() .unwrap() - .activate( - self.memory.clone(), - Arc::clone(self.virtio_interrupt.as_ref().unwrap()), - ) - .unwrap_or_else(|err| error!("Error activating device: {err:?}")); - self.device_activated.store(true, Ordering::SeqCst); + .activate(self.memory.clone(), interrupt.clone()) + { + Ok(()) => self.device_activated.store(true, Ordering::SeqCst), + Err(err) => { + error!("Error activating device: {err:?}"); + + // Section 2.1.2 of the specification states that we need to send a device + // configuration change interrupt + let _ = interrupt.trigger(VirtioInterruptType::Config); + } + } } else { debug!("Device doesn't need activation"); }