From d809f2fe0909f88b3264607ddc96b472698c1a76 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Thu, 7 May 2020 14:52:41 +0200 Subject: [PATCH] vm-virtio: Add virtio reset() support to MmioDevice All our virtio devices support to be reset, but the virtio-mmio transport layer was not implemented for it. This patch fixes this lack of support. Signed-off-by: Sebastien Boeuf --- vm-virtio/src/transport/mmio.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/vm-virtio/src/transport/mmio.rs b/vm-virtio/src/transport/mmio.rs index 2d52bc07f..d663baeed 100644 --- a/vm-virtio/src/transport/mmio.rs +++ b/vm-virtio/src/transport/mmio.rs @@ -206,6 +206,11 @@ impl MmioDevice { self.driver_status == ready_bits && self.driver_status & DEVICE_FAILED == 0 } + /// Determines if the driver has requested the device (re)init / reset itself + fn is_driver_init(&self) -> bool { + self.driver_status == DEVICE_INIT + } + fn are_queues_valid(&self) -> bool { if let Some(mem) = self.mem.as_ref() { self.queues.iter().all(|q| q.is_valid(&mem.memory())) @@ -412,6 +417,26 @@ impl BusDevice for MmioDevice { } } } + + // Device has been reset by the driver + if self.device_activated && self.is_driver_init() { + let mut device = self.device.lock().unwrap(); + if let Some((interrupt_cb, mut queue_evts)) = device.reset() { + // Upon reset the device returns its interrupt EventFD and it's queue EventFDs + self.interrupt_cb = Some(interrupt_cb); + self.queue_evts.append(&mut queue_evts); + + self.device_activated = false; + + // Reset queue readiness (changes queue_enable), queue sizes + // and selected_queue as per spec for reset + self.queues.iter_mut().for_each(Queue::reset); + self.queue_select = 0; + } else { + error!("Attempt to reset device when not implemented in underlying device"); + self.driver_status = DEVICE_FAILED; + } + } } }