diff options
author | Chuanxiao Dong <chuanxiao.dong@intel.corp-partner.google.com> | 2019-12-03 09:34:39 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-01-03 11:12:01 +0000 |
commit | 572ca0cca2b53157ce857676b1f054464d4522bd (patch) | |
tree | a62c3822353642d8246d3215d99c6de69eff6a64 | |
parent | 3dc90d0124ca4d797ff9119daf16016b225c1d96 (diff) | |
download | crosvm-572ca0cca2b53157ce857676b1f054464d4522bd.tar crosvm-572ca0cca2b53157ce857676b1f054464d4522bd.tar.gz crosvm-572ca0cca2b53157ce857676b1f054464d4522bd.tar.bz2 crosvm-572ca0cca2b53157ce857676b1f054464d4522bd.tar.lz crosvm-572ca0cca2b53157ce857676b1f054464d4522bd.tar.xz crosvm-572ca0cca2b53157ce857676b1f054464d4522bd.tar.zst crosvm-572ca0cca2b53157ce857676b1f054464d4522bd.zip |
virtio: call virtio device reset method for reset
It refers to the implementation of the Cloud-hypervisor commit: - vm-virtio: Reset underlying device on driver request If the driver triggers a reset by writing zero into the status register then reset the underlying device if supported. A device reset also requires resetting various aspects of the queue. The reset method of a virtio device might return false if it is failed to reset the device or it is not implemented. In this case, we don't reset the queues. Otherwise the queues will also be reset together with a successful device reset. BUG=chromium:1030609 TEST=cargo test -p devices Change-Id: Iad2be38149e423a79d8366dc72e570a1d6eb297c Signed-off-by: Chuanxiao Dong <chuanxiao.dong@intel.corp-partner.google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1971096 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com>
-rw-r--r-- | devices/src/virtio/mod.rs | 1 | ||||
-rw-r--r-- | devices/src/virtio/queue.rs | 12 | ||||
-rw-r--r-- | devices/src/virtio/virtio_pci_device.rs | 16 |
3 files changed, 29 insertions, 0 deletions
diff --git a/devices/src/virtio/mod.rs b/devices/src/virtio/mod.rs index c0b84fe..a1701f5 100644 --- a/devices/src/virtio/mod.rs +++ b/devices/src/virtio/mod.rs @@ -49,6 +49,7 @@ pub use self::wl::*; use std::cmp; use std::convert::TryFrom; +const DEVICE_RESET: u32 = 0x0; const DEVICE_ACKNOWLEDGE: u32 = 0x01; const DEVICE_DRIVER: u32 = 0x02; const DEVICE_DRIVER_OK: u32 = 0x04; diff --git a/devices/src/virtio/queue.rs b/devices/src/virtio/queue.rs index 78a9cc3..153449a 100644 --- a/devices/src/virtio/queue.rs +++ b/devices/src/virtio/queue.rs @@ -245,6 +245,18 @@ impl Queue { min(self.size, self.max_size) } + /// Reset queue to a clean state + pub fn reset(&mut self) { + self.ready = false; + self.size = self.max_size; + self.vector = VIRTIO_MSI_NO_VECTOR; + self.desc_table = GuestAddress(0); + self.avail_ring = GuestAddress(0); + self.used_ring = GuestAddress(0); + self.next_avail = Wrapping(0); + self.next_used = Wrapping(0); + } + pub fn is_valid(&self, mem: &GuestMemory) -> bool { let queue_size = self.actual_size() as usize; let desc_table = self.desc_table; diff --git a/devices/src/virtio/virtio_pci_device.rs b/devices/src/virtio/virtio_pci_device.rs index dbfaa69..2be272c 100644 --- a/devices/src/virtio/virtio_pci_device.rs +++ b/devices/src/virtio/virtio_pci_device.rs @@ -297,6 +297,11 @@ impl VirtioPciDevice { && self.common_config.driver_status & DEVICE_FAILED as u8 == 0 } + /// Determines if the driver has requested the device reset itself + fn is_reset_requested(&self) -> bool { + self.common_config.driver_status == DEVICE_RESET as u8 + } + fn are_queues_valid(&self) -> bool { if let Some(mem) = self.mem.as_ref() { self.queues.iter().all(|q| q.is_valid(mem)) @@ -688,5 +693,16 @@ impl PciDevice for VirtioPciDevice { } } } + + // Device has been reset by the driver + if self.device_activated && self.is_reset_requested() { + if self.device.reset() { + self.device_activated = false; + // reset queues + self.queues.iter_mut().for_each(Queue::reset); + // select queue 0 by default + self.common_config.queue_select = 0; + } + } } } |