瀏覽代碼

Wait for device to finish resetting before returning from drop.

This appears only to be required for the PCI transport, there is no
mention of it for the MMIO transport.
Andrew Walbran 2 年之前
父節點
當前提交
c3d6edf6d7
共有 4 個文件被更改,包括 21 次插入1 次删除
  1. 4 0
      src/transport/fake.rs
  2. 5 0
      src/transport/mmio.rs
  3. 3 0
      src/transport/mod.rs
  4. 9 1
      src/transport/pci.rs

+ 4 - 0
src/transport/fake.rs

@@ -38,6 +38,10 @@ impl<C> Transport for FakeTransport<C> {
         self.state.lock().unwrap().queues[queue as usize].notified = true;
     }
 
+    fn get_status(&self) -> DeviceStatus {
+        self.state.lock().unwrap().status
+    }
+
     fn set_status(&mut self, status: DeviceStatus) {
         self.state.lock().unwrap().status = status;
     }

+ 5 - 0
src/transport/mmio.rs

@@ -350,6 +350,11 @@ impl Transport for MmioTransport {
         }
     }
 
+    fn get_status(&self) -> DeviceStatus {
+        // Safe because self.header points to a valid VirtIO MMIO region.
+        unsafe { volread!(self.header, status) }
+    }
+
     fn set_status(&mut self, status: DeviceStatus) {
         // Safe because self.header points to a valid VirtIO MMIO region.
         unsafe {

+ 3 - 0
src/transport/mod.rs

@@ -26,6 +26,9 @@ pub trait Transport {
     /// Notifies the given queue on the device.
     fn notify(&mut self, queue: u16);
 
+    /// Gets the device status.
+    fn get_status(&self) -> DeviceStatus;
+
     /// Sets the device status.
     fn set_status(&mut self, status: DeviceStatus);
 

+ 9 - 1
src/transport/pci.rs

@@ -251,6 +251,13 @@ impl Transport for PciTransport {
         }
     }
 
+    fn get_status(&self) -> DeviceStatus {
+        // Safe because the common config pointer is valid and we checked in get_bar_region that it
+        // was aligned.
+        let status = unsafe { volread!(self.common_cfg, device_status) };
+        DeviceStatus::from_bits_truncate(status.into())
+    }
+
     fn set_status(&mut self, status: DeviceStatus) {
         // Safe because the common config pointer is valid and we checked in get_bar_region that it
         // was aligned.
@@ -341,7 +348,8 @@ impl Transport for PciTransport {
 impl Drop for PciTransport {
     fn drop(&mut self) {
         // Reset the device when the transport is dropped.
-        self.set_status(DeviceStatus::empty())
+        self.set_status(DeviceStatus::empty());
+        while self.get_status() != DeviceStatus::empty() {}
     }
 }