summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2020-03-14 00:53:34 +0000
committerAlyssa Ross <hi@alyssa.is>2020-06-15 09:36:53 +0000
commit15cbc91653fb35f1145b47dd2c808df2daa1633a (patch)
tree4ecbc228beec6d81a23962e80fabc48b22078098
parentc895e48de84f2a6b6f5b21e8037abef50e365a51 (diff)
downloadcrosvm-15cbc91653fb35f1145b47dd2c808df2daa1633a.tar
crosvm-15cbc91653fb35f1145b47dd2c808df2daa1633a.tar.gz
crosvm-15cbc91653fb35f1145b47dd2c808df2daa1633a.tar.bz2
crosvm-15cbc91653fb35f1145b47dd2c808df2daa1633a.tar.lz
crosvm-15cbc91653fb35f1145b47dd2c808df2daa1633a.tar.xz
crosvm-15cbc91653fb35f1145b47dd2c808df2daa1633a.tar.zst
crosvm-15cbc91653fb35f1145b47dd2c808df2daa1633a.zip
get_device_caps
-rw-r--r--devices/src/pci/pci_configuration.rs2
-rw-r--r--devices/src/virtio/controller.rs47
-rw-r--r--src/wl.rs13
3 files changed, 59 insertions, 3 deletions
diff --git a/devices/src/pci/pci_configuration.rs b/devices/src/pci/pci_configuration.rs
index a0c92bd..22345fa 100644
--- a/devices/src/pci/pci_configuration.rs
+++ b/devices/src/pci/pci_configuration.rs
@@ -136,7 +136,7 @@ pub trait PciProgrammingInterface {
 }
 
 /// Types of PCI capabilities.
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
 pub enum PciCapabilityID {
     ListID = 0,
     PowerManagement = 0x01,
diff --git a/devices/src/virtio/controller.rs b/devices/src/virtio/controller.rs
index 33dbdd4..c5d2ef4 100644
--- a/devices/src/virtio/controller.rs
+++ b/devices/src/virtio/controller.rs
@@ -37,7 +37,7 @@ use std::thread;
 use super::resource_bridge::*;
 use super::{Interrupt, InterruptProxyEvent, Queue, VirtioDevice, TYPE_WL, VIRTIO_F_VERSION_1};
 use crate::{
-    pci::{PciAddress, PciBarConfiguration},
+    pci::{PciAddress, PciBarConfiguration, PciCapability, PciCapabilityID},
     MemoryParams,
 };
 use vm_control::{MaybeOwnedFd, VmMemoryControlRequestSocket};
@@ -47,6 +47,33 @@ use serde::{Deserialize, Serialize};
 use sys_util::net::UnixSeqpacket;
 use sys_util::{error, EventFd, GuestMemory, PollContext, PollToken, SharedMemory};
 
+// As far as I can tell, these never change on the other side, so it's
+// fine to just copy them over.
+#[derive(Clone, Debug, Deserialize, Serialize)]
+pub struct RemotePciCapability {
+    bytes: Vec<u8>,
+    id: PciCapabilityID,
+}
+
+impl RemotePciCapability {
+    pub fn from(capability: &dyn PciCapability) -> Self {
+        Self {
+            bytes: capability.bytes().to_vec(),
+            id: capability.id(),
+        }
+    }
+}
+
+impl PciCapability for RemotePciCapability {
+    fn bytes(&self) -> &[u8] {
+        &self.bytes
+    }
+
+    fn id(&self) -> PciCapabilityID {
+        self.id
+    }
+}
+
 #[derive(Debug, MsgOnSocket)]
 pub enum MsgOnSocketRequest {
     Create {
@@ -79,6 +106,7 @@ pub enum BincodeRequest {
     WriteConfig { offset: u64, data: Vec<u8> },
 
     GetDeviceBars(PciAddress),
+    GetDeviceCaps,
 }
 
 pub type Request = poly_msg_socket::Value<MsgOnSocketRequest, BincodeRequest>;
@@ -106,6 +134,7 @@ pub enum BincodeResponse {
     ReadConfig(Vec<u8>),
 
     GetDeviceBars(Vec<PciBarConfiguration>),
+    GetDeviceCaps(Vec<RemotePciCapability>),
 }
 
 pub type Response = poly_msg_socket::Value<MsgOnSocketResponse, BincodeResponse>;
@@ -406,4 +435,20 @@ impl VirtioDevice for Controller {
             }
         }
     }
+
+    fn get_device_caps(&self) -> Vec<Box<dyn PciCapability>> {
+        if let Err(e) = self.socket.send(BincodeRequest::GetDeviceCaps) {
+            panic!("failed to send GetDeviceCaps: {}", e);
+        }
+
+        match self.socket.recv_bincode() {
+            Ok(BincodeResponse::GetDeviceCaps(caps)) => caps
+                .into_iter()
+                .map(|cap| Box::new(cap) as Box<dyn PciCapability>)
+                .collect(),
+            response => {
+                panic!("bad response to GetDeviceCaps: {:?}", response);
+            }
+        }
+    }
 }
diff --git a/src/wl.rs b/src/wl.rs
index 5576acb..7177f74 100644
--- a/src/wl.rs
+++ b/src/wl.rs
@@ -2,7 +2,7 @@
 
 use devices::virtio::{
     BincodeRequest, BincodeResponse, InterruptProxy, InterruptProxyEvent, MsgOnSocketRequest,
-    MsgOnSocketResponse, VirtioDevice, Wl,
+    MsgOnSocketResponse, RemotePciCapability, VirtioDevice, Wl,
 };
 use msg_socket::MsgSocket;
 use poly_msg_socket::PolyMsgSocket;
@@ -125,6 +125,17 @@ fn main() {
                 }
             }
 
+            Ok(Bincode(BincodeRequest::GetDeviceCaps)) => {
+                let result = wl
+                    .get_device_caps()
+                    .into_iter()
+                    .map(|c| RemotePciCapability::from(&*c))
+                    .collect();
+                if let Err(e) = msg_socket.send(BincodeResponse::GetDeviceCaps(result)) {
+                    panic!("responding to GetDeviceCaps failed: {}", e);
+                }
+            }
+
             Ok(MsgOnSocket(msg @ MsgOnSocketRequest::Create { .. })) => {
                 panic!("unexpected message {:?}", msg)
             }