summary refs log tree commit diff
diff options
context:
space:
mode:
authorKeiichi Watanabe <keiichiw@chromium.org>2020-01-22 19:35:02 +0900
committerCommit Bot <commit-bot@chromium.org>2020-02-03 12:33:52 +0000
commit392b73cdbc3c862cf4ffaa0cace19d22077c5648 (patch)
treedb73f0df31ee95e241a3fecbaaf48680d30f16d8
parent327fc2454cdfe36fb612c73c9994435b8602c81a (diff)
downloadcrosvm-392b73cdbc3c862cf4ffaa0cace19d22077c5648.tar
crosvm-392b73cdbc3c862cf4ffaa0cace19d22077c5648.tar.gz
crosvm-392b73cdbc3c862cf4ffaa0cace19d22077c5648.tar.bz2
crosvm-392b73cdbc3c862cf4ffaa0cace19d22077c5648.tar.lz
crosvm-392b73cdbc3c862cf4ffaa0cace19d22077c5648.tar.xz
crosvm-392b73cdbc3c862cf4ffaa0cace19d22077c5648.tar.zst
crosvm-392b73cdbc3c862cf4ffaa0cace19d22077c5648.zip
devices: virtio: Add a function to get a FD via resource_bridge
Add a function to get a resource FD via resource_bridge by extracting code from
the wayland device implementation.
This function will be used by virtio-video devices.

BUG=b:147465619
TEST=Run ARCVM and check that a window is displayed

Change-Id: I7b064c9a04bd082e30dd488d0b14731228e6047d
Signed-off-by: Keiichi Watanabe <keiichiw@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2014520
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Chirantan Ekbote <chirantan@chromium.org>
-rw-r--r--devices/src/virtio/resource_bridge.rs50
-rw-r--r--devices/src/virtio/wl.rs20
2 files changed, 53 insertions, 17 deletions
diff --git a/devices/src/virtio/resource_bridge.rs b/devices/src/virtio/resource_bridge.rs
index d3a3375..aaf776c 100644
--- a/devices/src/virtio/resource_bridge.rs
+++ b/devices/src/virtio/resource_bridge.rs
@@ -5,11 +5,11 @@
 //! This module defines the protocol between `virtio-wayland` and `virtio-gpu` for sharing resources
 //! that are backed by file descriptors.
 
+use std::fmt;
 use std::fs::File;
-use std::io::Result;
 
 use msg_on_socket_derive::MsgOnSocket;
-use msg_socket::MsgSocket;
+use msg_socket::{MsgError, MsgReceiver, MsgSender, MsgSocket};
 
 #[derive(MsgOnSocket)]
 pub enum ResourceRequest {
@@ -25,6 +25,50 @@ pub enum ResourceResponse {
 pub type ResourceRequestSocket = MsgSocket<ResourceRequest, ResourceResponse>;
 pub type ResourceResponseSocket = MsgSocket<ResourceResponse, ResourceRequest>;
 
-pub fn pair() -> Result<(ResourceRequestSocket, ResourceResponseSocket)> {
+pub fn pair() -> std::io::Result<(ResourceRequestSocket, ResourceResponseSocket)> {
     msg_socket::pair()
 }
+
+#[derive(Debug)]
+pub enum ResourceBridgeError {
+    InvalidResource(u32),
+    SendFailure(u32, MsgError),
+    RecieveFailure(u32, MsgError),
+}
+
+impl fmt::Display for ResourceBridgeError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            ResourceBridgeError::InvalidResource(id) => {
+                write!(f, "attempt to send non-existent gpu resource for id {}", id)
+            }
+            ResourceBridgeError::SendFailure(id, e) => write!(
+                f,
+                "failed to send a resource bridge request for id {}: {}",
+                id, e
+            ),
+            ResourceBridgeError::RecieveFailure(id, e) => write!(
+                f,
+                "error receiving resource bridge response for id {}: {}",
+                id, e
+            ),
+        }
+    }
+}
+
+impl std::error::Error for ResourceBridgeError {}
+
+pub fn get_resource_fd(
+    sock: &ResourceRequestSocket,
+    id: u32,
+) -> std::result::Result<File, ResourceBridgeError> {
+    if let Err(e) = sock.send(&ResourceRequest::GetResource { id }) {
+        return Err(ResourceBridgeError::SendFailure(id, e));
+    }
+
+    match sock.recv() {
+        Ok(ResourceResponse::Resource(bridged_file)) => Ok(bridged_file),
+        Ok(ResourceResponse::Invalid) => Err(ResourceBridgeError::InvalidResource(id)),
+        Err(e) => Err(ResourceBridgeError::RecieveFailure(id, e)),
+    }
+}
diff --git a/devices/src/virtio/wl.rs b/devices/src/virtio/wl.rs
index 5bbd914..5ace29c 100644
--- a/devices/src/virtio/wl.rs
+++ b/devices/src/virtio/wl.rs
@@ -1092,26 +1092,18 @@ impl WlState {
                 },
                 #[cfg(feature = "gpu")]
                 VIRTIO_WL_CTRL_VFD_SEND_KIND_VIRTGPU if self.resource_bridge.is_some() => {
-                    if let Err(e) = self
-                        .resource_bridge
-                        .as_ref()
-                        .unwrap()
-                        .send(&ResourceRequest::GetResource { id })
-                    {
-                        error!("error sending resource bridge request: {}", e);
-                        return Ok(WlResp::InvalidId);
-                    }
-                    match self.resource_bridge.as_ref().unwrap().recv() {
-                        Ok(ResourceResponse::Resource(bridged_file)) => {
+                    let sock = self.resource_bridge.as_ref().unwrap();
+                    match get_resource_fd(sock, id) {
+                        Ok(bridged_file) => {
                             *fd = bridged_file.as_raw_fd();
                             bridged_files.push(bridged_file);
                         }
-                        Ok(ResourceResponse::Invalid) => {
-                            warn!("attempt to send non-existant gpu resource {}", id);
+                        Err(ResourceBridgeError::InvalidResource(id)) => {
+                            warn!("attempt to send non-existent gpu resource {}", id);
                             return Ok(WlResp::InvalidId);
                         }
                         Err(e) => {
-                            error!("error receiving resource bridge response: {}", e);
+                            error!("{}", e);
                             // If there was an error with the resource bridge, it can no longer be
                             // trusted to continue to function.
                             self.resource_bridge = None;