summary refs log tree commit diff
path: root/devices/src
diff options
context:
space:
mode:
authorDavid Stevens <stevensd@chromium.org>2020-01-22 21:17:28 +0900
committerCommit Bot <commit-bot@chromium.org>2020-04-04 13:49:16 +0000
commit11e71a1838b8417c605894ec3397f99a2ab9dd66 (patch)
treefed7f3b9365ec4a00df4fb1ac3acd572fe156f33 /devices/src
parent4cbcc26f5c34d8254a9f98e065a923abb194ba8b (diff)
downloadcrosvm-11e71a1838b8417c605894ec3397f99a2ab9dd66.tar
crosvm-11e71a1838b8417c605894ec3397f99a2ab9dd66.tar.gz
crosvm-11e71a1838b8417c605894ec3397f99a2ab9dd66.tar.bz2
crosvm-11e71a1838b8417c605894ec3397f99a2ab9dd66.tar.lz
crosvm-11e71a1838b8417c605894ec3397f99a2ab9dd66.tar.xz
crosvm-11e71a1838b8417c605894ec3397f99a2ab9dd66.tar.zst
crosvm-11e71a1838b8417c605894ec3397f99a2ab9dd66.zip
virtio-gpu: add support for exporting virtgpu resources
BUG=b:136269340
TEST=boot ARCVM and launch play store

Change-Id: I2d78ffb15dcf2dc0f245916485f5ebb636ef6e78
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2014680
Reviewed-by: David Stevens <stevensd@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Tested-by: David Stevens <stevensd@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Keiichi Watanabe <keiichiw@chromium.org>
Diffstat (limited to 'devices/src')
-rw-r--r--devices/src/virtio/gpu/mod.rs8
-rw-r--r--devices/src/virtio/gpu/protocol.rs38
-rw-r--r--devices/src/virtio/gpu/virtio_3d_backend.rs17
3 files changed, 63 insertions, 0 deletions
diff --git a/devices/src/virtio/gpu/mod.rs b/devices/src/virtio/gpu/mod.rs
index 93d004f..e8e7f4a 100644
--- a/devices/src/virtio/gpu/mod.rs
+++ b/devices/src/virtio/gpu/mod.rs
@@ -182,6 +182,10 @@ trait Backend {
     /// Detaches any backing memory from the given resource, if there is any.
     fn detach_backing(&mut self, id: u32) -> GpuResponse;
 
+    fn resource_assign_uuid(&mut self, _id: u32) -> GpuResponse {
+        GpuResponse::ErrUnspec
+    }
+
     /// Updates the cursor's memory to the given id, and sets its position to the given coordinates.
     fn update_cursor(&mut self, id: u32, x: u32, y: u32) -> GpuResponse;
 
@@ -497,6 +501,10 @@ impl Frontend {
             GpuCommand::MoveCursor(info) => self
                 .backend
                 .move_cursor(info.pos.x.into(), info.pos.y.into()),
+            GpuCommand::ResourceAssignUuid(info) => {
+                let resource_id = info.resource_id.to_native();
+                self.backend.resource_assign_uuid(resource_id)
+            }
             GpuCommand::GetCapsetInfo(info) => {
                 self.backend.get_capset_info(info.capset_index.to_native())
             }
diff --git a/devices/src/virtio/gpu/protocol.rs b/devices/src/virtio/gpu/protocol.rs
index c98e289..3df6975 100644
--- a/devices/src/virtio/gpu/protocol.rs
+++ b/devices/src/virtio/gpu/protocol.rs
@@ -38,6 +38,7 @@ pub const VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING: u32 = 0x107;
 pub const VIRTIO_GPU_CMD_GET_CAPSET_INFO: u32 = 0x108;
 pub const VIRTIO_GPU_CMD_GET_CAPSET: u32 = 0x109;
 pub const VIRTIO_GPU_CMD_GET_EDID: u32 = 0x10a;
+pub const VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID: u32 = 0x10b;
 
 /* 3d commands */
 pub const VIRTIO_GPU_CMD_CTX_CREATE: u32 = 0x200;
@@ -64,6 +65,7 @@ pub const VIRTIO_GPU_RESP_OK_CAPSET_INFO: u32 = 0x1102;
 pub const VIRTIO_GPU_RESP_OK_CAPSET: u32 = 0x1103;
 pub const VIRTIO_GPU_RESP_OK_RESOURCE_PLANE_INFO: u32 = 0x1104;
 pub const VIRTIO_GPU_RESP_OK_EDID: u32 = 0x1105;
+pub const VIRTIO_GPU_RESP_OK_RESOURCE_UUID: u32 = 0x1105;
 
 /* error responses */
 pub const VIRTIO_GPU_RESP_ERR_UNSPEC: u32 = 0x1200;
@@ -109,6 +111,7 @@ pub fn virtio_gpu_cmd_str(cmd: u32) -> &'static str {
         VIRTIO_GPU_CMD_CTX_DESTROY => "VIRTIO_GPU_CMD_CTX_DESTROY",
         VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE => "VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE",
         VIRTIO_GPU_CMD_CTX_DETACH_RESOURCE => "VIRTIO_GPU_CMD_CTX_DETACH_RESOURCE",
+        VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID => "VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID",
         VIRTIO_GPU_CMD_RESOURCE_CREATE_3D => "VIRTIO_GPU_CMD_RESOURCE_CREATE_3D",
         VIRTIO_GPU_CMD_TRANSFER_TO_HOST_3D => "VIRTIO_GPU_CMD_TRANSFER_TO_HOST_3D",
         VIRTIO_GPU_CMD_TRANSFER_FROM_HOST_3D => "VIRTIO_GPU_CMD_TRANSFER_FROM_HOST_3D",
@@ -123,6 +126,7 @@ pub fn virtio_gpu_cmd_str(cmd: u32) -> &'static str {
         VIRTIO_GPU_RESP_OK_CAPSET_INFO => "VIRTIO_GPU_RESP_OK_CAPSET_INFO",
         VIRTIO_GPU_RESP_OK_CAPSET => "VIRTIO_GPU_RESP_OK_CAPSET",
         VIRTIO_GPU_RESP_OK_RESOURCE_PLANE_INFO => "VIRTIO_GPU_RESP_OK_RESOURCE_PLANE_INFO",
+        VIRTIO_GPU_RESP_OK_RESOURCE_UUID => "VIRTIO_GPU_RESP_OK_RESOURCE_UUID",
         VIRTIO_GPU_RESP_ERR_UNSPEC => "VIRTIO_GPU_RESP_ERR_UNSPEC",
         VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY => "VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY",
         VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID => "VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID",
@@ -532,6 +536,25 @@ pub struct virtio_gpu_resource_unmap {
 
 unsafe impl DataInit for virtio_gpu_resource_unmap {}
 
+#[derive(Copy, Clone, Debug, Default)]
+#[repr(C)]
+pub struct virtio_gpu_resource_assign_uuid {
+    pub hdr: virtio_gpu_ctrl_hdr,
+    pub resource_id: Le32,
+    pub padding: Le32,
+}
+
+unsafe impl DataInit for virtio_gpu_resource_assign_uuid {}
+
+#[derive(Copy, Clone, Debug, Default)]
+#[repr(C)]
+pub struct virtio_gpu_resp_resource_uuid {
+    pub hdr: virtio_gpu_ctrl_hdr,
+    pub uuid: [u8; 16],
+}
+
+unsafe impl DataInit for virtio_gpu_resp_resource_uuid {}
+
 /* simple formats for fbcon/X use */
 pub const VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM: u32 = 1;
 pub const VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM: u32 = 2;
@@ -568,6 +591,7 @@ pub enum GpuCommand {
     ResourceUnmap(virtio_gpu_resource_unmap),
     UpdateCursor(virtio_gpu_update_cursor),
     MoveCursor(virtio_gpu_update_cursor),
+    ResourceAssignUuid(virtio_gpu_resource_assign_uuid),
 }
 
 /// An error indicating something went wrong decoding a `GpuCommand`. These correspond to
@@ -637,6 +661,7 @@ impl fmt::Debug for GpuCommand {
             ResourceUnmap(_info) => f.debug_struct("ResourceUnmap").finish(),
             UpdateCursor(_info) => f.debug_struct("UpdateCursor").finish(),
             MoveCursor(_info) => f.debug_struct("MoveCursor").finish(),
+            ResourceAssignUuid(_info) => f.debug_struct("ResourceAssignUuid").finish(),
         }
     }
 }
@@ -670,6 +695,7 @@ impl GpuCommand {
             VIRTIO_GPU_CMD_RESOURCE_UNMAP => ResourceUnmap(cmd.read_obj()?),
             VIRTIO_GPU_CMD_UPDATE_CURSOR => UpdateCursor(cmd.read_obj()?),
             VIRTIO_GPU_CMD_MOVE_CURSOR => MoveCursor(cmd.read_obj()?),
+            VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID => ResourceAssignUuid(cmd.read_obj()?),
             _ => return Err(GpuCommandDecodeError::InvalidType(hdr.type_.into())),
         })
     }
@@ -701,6 +727,7 @@ impl GpuCommand {
             ResourceUnmap(info) => &info.hdr,
             UpdateCursor(info) => &info.hdr,
             MoveCursor(info) => &info.hdr,
+            ResourceAssignUuid(info) => &info.hdr,
         }
     }
 }
@@ -726,6 +753,9 @@ pub enum GpuResponse {
         format_modifier: u64,
         plane_info: Vec<GpuResponsePlaneInfo>,
     },
+    OkResourceUuid {
+        uuid: [u8; 16],
+    },
     ErrUnspec,
     ErrOutOfMemory,
     ErrInvalidScanoutId,
@@ -859,6 +889,12 @@ impl GpuResponse {
                     size_of_val(&hdr)
                 }
             }
+            GpuResponse::OkResourceUuid { uuid } => {
+                let resp_info = virtio_gpu_resp_resource_uuid { hdr, uuid };
+
+                resp.write_obj(resp_info)?;
+                size_of_val(&resp_info)
+            }
             _ => {
                 resp.write_obj(hdr)?;
                 size_of_val(&hdr)
@@ -875,6 +911,7 @@ impl GpuResponse {
             GpuResponse::OkCapsetInfo { .. } => VIRTIO_GPU_RESP_OK_CAPSET_INFO,
             GpuResponse::OkCapset(_) => VIRTIO_GPU_RESP_OK_CAPSET,
             GpuResponse::OkResourcePlaneInfo { .. } => VIRTIO_GPU_RESP_OK_RESOURCE_PLANE_INFO,
+            GpuResponse::OkResourceUuid { .. } => VIRTIO_GPU_RESP_OK_RESOURCE_UUID,
             GpuResponse::ErrUnspec => VIRTIO_GPU_RESP_ERR_UNSPEC,
             GpuResponse::ErrOutOfMemory => VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY,
             GpuResponse::ErrInvalidScanoutId => VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID,
@@ -892,6 +929,7 @@ impl GpuResponse {
             GpuResponse::OkCapsetInfo { .. } => true,
             GpuResponse::OkCapset(_) => true,
             GpuResponse::OkResourcePlaneInfo { .. } => true,
+            GpuResponse::OkResourceUuid { .. } => true,
             _ => false,
         }
     }
diff --git a/devices/src/virtio/gpu/virtio_3d_backend.rs b/devices/src/virtio/gpu/virtio_3d_backend.rs
index 3ede8a6..692bedc 100644
--- a/devices/src/virtio/gpu/virtio_3d_backend.rs
+++ b/devices/src/virtio/gpu/virtio_3d_backend.rs
@@ -497,6 +497,23 @@ impl Backend for Virtio3DBackend {
         self.base.move_cursor(x, y)
     }
 
+    /// Returns a uuid for the resource.
+    fn resource_assign_uuid(&mut self, id: u32) -> GpuResponse {
+        match self.resources.entry(id) {
+            Entry::Vacant(_) => GpuResponse::ErrInvalidResourceId,
+            Entry::Occupied(_) => {
+                // TODO(stevensd): use real uuids once the virtio wayland protocol is updated to
+                // handle more than 32 bits. For now, the virtwl driver knows that the uuid is
+                // actually just the resource id.
+                let mut uuid: [u8; 16] = [0; 16];
+                for (idx, byte) in id.to_be_bytes().iter().enumerate() {
+                    uuid[12 + idx] = *byte;
+                }
+                GpuResponse::OkResourceUuid { uuid }
+            }
+        }
+    }
+
     /// Gets the renderer's capset information associated with `index`.
     fn get_capset_info(&self, index: u32) -> GpuResponse {
         let id = match index {