Explorar o código

Merge branch 'master' into x86_64

Yuekai Jia %!s(int64=2) %!d(string=hai) anos
pai
achega
8180f86361
Modificáronse 5 ficheiros con 16 adicións e 9 borrados
  1. 1 1
      src/queue.rs
  2. 1 1
      src/transport/fake.rs
  3. 5 2
      src/transport/mmio.rs
  4. 4 3
      src/transport/mod.rs
  5. 5 2
      src/transport/pci.rs

+ 1 - 1
src/queue.rs

@@ -60,7 +60,7 @@ impl<H: Hal, const SIZE: usize> VirtQueue<H, SIZE> {
         }
         if !SIZE.is_power_of_two()
             || SIZE > u16::MAX.into()
-            || transport.max_queue_size() < SIZE as u32
+            || transport.max_queue_size(idx) < SIZE as u32
         {
             return Err(Error::InvalidParam);
         }

+ 1 - 1
src/transport/fake.rs

@@ -30,7 +30,7 @@ impl<C> Transport for FakeTransport<C> {
         self.state.lock().unwrap().driver_features = driver_features;
     }
 
-    fn max_queue_size(&self) -> u32 {
+    fn max_queue_size(&mut self, _queue: u16) -> u32 {
         self.max_queue_size
     }
 

+ 5 - 2
src/transport/mmio.rs

@@ -338,9 +338,12 @@ impl Transport for MmioTransport {
         }
     }
 
-    fn max_queue_size(&self) -> u32 {
+    fn max_queue_size(&mut self, queue: u16) -> u32 {
         // Safe because self.header points to a valid VirtIO MMIO region.
-        unsafe { volread!(self.header, queue_num_max) }
+        unsafe {
+            volwrite!(self.header, queue_sel, queue.into());
+            volread!(self.header, queue_num_max)
+        }
     }
 
     fn notify(&mut self, queue: u16) {

+ 4 - 3
src/transport/mod.rs

@@ -20,8 +20,8 @@ pub trait Transport {
     /// Writes device features.
     fn write_driver_features(&mut self, driver_features: u64);
 
-    /// Gets the max size of queue.
-    fn max_queue_size(&self) -> u32;
+    /// Gets the max size of the given queue.
+    fn max_queue_size(&mut self, queue: u16) -> u32;
 
     /// Notifies the given queue on the device.
     fn notify(&mut self, queue: u16);
@@ -65,6 +65,7 @@ pub trait Transport {
     ///
     /// Ref: virtio 3.1.1 Device Initialization
     fn begin_init(&mut self, negotiate_features: impl FnOnce(u64) -> u64) {
+        self.set_status(DeviceStatus::empty());
         self.set_status(DeviceStatus::ACKNOWLEDGE | DeviceStatus::DRIVER);
 
         let features = self.read_device_features();
@@ -91,7 +92,7 @@ pub trait Transport {
 }
 
 bitflags! {
-    /// The device status field.
+    /// The device status field. Writing 0 into this field resets the device.
     #[derive(Default)]
     pub struct DeviceStatus: u32 {
         /// Indicates that the guest OS has found the device and recognized it

+ 5 - 2
src/transport/pci.rs

@@ -231,10 +231,13 @@ impl Transport for PciTransport {
         }
     }
 
-    fn max_queue_size(&self) -> u32 {
+    fn max_queue_size(&mut self, queue: u16) -> u32 {
         // Safe because the common config pointer is valid and we checked in get_bar_region that it
         // was aligned.
-        unsafe { volread!(self.common_cfg, queue_size) }.into()
+        unsafe {
+            volwrite!(self.common_cfg, queue_select, queue);
+            volread!(self.common_cfg, queue_size).into()
+        }
     }
 
     fn notify(&mut self, queue: u16) {