diff options
author | Gurchetan Singh <gurchetansingh@chromium.org> | 2019-04-23 10:27:49 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-10-01 07:53:33 +0000 |
commit | 5b636babc1e83b7187ef72bd85b3a3bdc2e5d03f (patch) | |
tree | 1c856e04303e3c2882a140d2be45015bdb621b2e | |
parent | 144c279d281cb2e69caeb8504ff7267d268c4561 (diff) | |
download | crosvm-5b636babc1e83b7187ef72bd85b3a3bdc2e5d03f.tar crosvm-5b636babc1e83b7187ef72bd85b3a3bdc2e5d03f.tar.gz crosvm-5b636babc1e83b7187ef72bd85b3a3bdc2e5d03f.tar.bz2 crosvm-5b636babc1e83b7187ef72bd85b3a3bdc2e5d03f.tar.lz crosvm-5b636babc1e83b7187ef72bd85b3a3bdc2e5d03f.tar.xz crosvm-5b636babc1e83b7187ef72bd85b3a3bdc2e5d03f.tar.zst crosvm-5b636babc1e83b7187ef72bd85b3a3bdc2e5d03f.zip |
virtio-gpu: handle VIRTIO_GPU_CMD_ALLOCATION_METADATA
Designed to return metadata to the guest. BUG=chromium:924405 TEST=compile Change-Id: Ic04a0bbb6b0a5bb6d08314371181f256eb7230df Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1591464 Reviewed-by: Zach Reizner <zachr@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Tested-by: Gurchetan Singh <gurchetansingh@chromium.org> Commit-Queue: Gurchetan Singh <gurchetansingh@chromium.org>
-rw-r--r-- | devices/src/virtio/gpu/backend.rs | 28 | ||||
-rw-r--r-- | devices/src/virtio/gpu/mod.rs | 23 | ||||
-rw-r--r-- | devices/src/virtio/gpu/protocol.rs | 52 | ||||
-rw-r--r-- | gpu_renderer/src/lib.rs | 18 |
4 files changed, 119 insertions, 2 deletions
diff --git a/devices/src/virtio/gpu/backend.rs b/devices/src/virtio/gpu/backend.rs index 9415226..4cfac7a 100644 --- a/devices/src/virtio/gpu/backend.rs +++ b/devices/src/virtio/gpu/backend.rs @@ -23,8 +23,8 @@ use gpu_renderer::{ }; use super::protocol::{ - GpuResponse, GpuResponsePlaneInfo, VIRTIO_GPU_CAPSET3, VIRTIO_GPU_CAPSET_VIRGL, - VIRTIO_GPU_CAPSET_VIRGL2, + AllocationMetadataResponse, GpuResponse, GpuResponsePlaneInfo, VIRTIO_GPU_CAPSET3, + VIRTIO_GPU_CAPSET_VIRGL, VIRTIO_GPU_CAPSET_VIRGL2, }; use crate::virtio::resource_bridge::*; use vm_control::VmMemoryControlRequestSocket; @@ -778,4 +778,28 @@ impl Backend { pub fn force_ctx_0(&mut self) { self.renderer.force_ctx_0(); } + + pub fn allocation_metadata( + &mut self, + request_id: u32, + request: Vec<u8>, + mut response: Vec<u8>, + ) -> GpuResponse { + let res = self.renderer.allocation_metadata(&request, &mut response); + + match res { + Ok(_) => { + let res_info = AllocationMetadataResponse { + request_id, + response, + }; + + GpuResponse::OkAllocationMetadata { res_info } + } + Err(_) => { + error!("failed to get metadata"); + GpuResponse::ErrUnspec + } + } + } } diff --git a/devices/src/virtio/gpu/mod.rs b/devices/src/virtio/gpu/mod.rs index b229cb5..2ad1f2e 100644 --- a/devices/src/virtio/gpu/mod.rs +++ b/devices/src/virtio/gpu/mod.rs @@ -262,6 +262,29 @@ impl Frontend { GpuResponse::OkNoData } } + GpuCommand::AllocationMetadata(info) => { + if reader.available_bytes() != 0 { + let id = info.request_id.to_native(); + let request_size = info.request_size.to_native(); + let response_size = info.response_size.to_native(); + if request_size > VIRTIO_GPU_MAX_BLOB_ARGUMENT_SIZE + || response_size > VIRTIO_GPU_MAX_BLOB_ARGUMENT_SIZE + { + return GpuResponse::ErrUnspec; + } + + let mut request_buf = vec![0; request_size as usize]; + let response_buf = vec![0; response_size as usize]; + if reader.read(&mut request_buf[..]).is_ok() { + self.backend + .allocation_metadata(id, request_buf, response_buf) + } else { + GpuResponse::ErrInvalidParameter + } + } else { + GpuResponse::ErrUnspec + } + } } } diff --git a/devices/src/virtio/gpu/protocol.rs b/devices/src/virtio/gpu/protocol.rs index 26d7168..9c3b112 100644 --- a/devices/src/virtio/gpu/protocol.rs +++ b/devices/src/virtio/gpu/protocol.rs @@ -84,6 +84,9 @@ pub const VIRTIO_GPU_CACHED: u32 = 1; pub const VIRTIO_GPU_WRITE_COMBINE: u32 = 2; pub const VIRTIO_GPU_UNCACHED: u32 = 3; +/* Limits on virtio-gpu stream (not upstreamed) */ +pub const VIRTIO_GPU_MAX_BLOB_ARGUMENT_SIZE: u32 = 4096; + pub fn virtio_gpu_cmd_str(cmd: u32) -> &'static str { match cmd { VIRTIO_GPU_CMD_GET_DISPLAY_INFO => "VIRTIO_GPU_CMD_GET_DISPLAY_INFO", @@ -489,6 +492,29 @@ pub struct virtio_gpu_config { unsafe impl DataInit for virtio_gpu_config {} +#[derive(Copy, Clone, Debug, Default)] +#[repr(C)] +pub struct virtio_gpu_allocation_metadata { + pub hdr: virtio_gpu_ctrl_hdr, + pub request_id: Le32, + pub padding: Le32, + pub request_size: Le32, + pub response_size: Le32, +} + +unsafe impl DataInit for virtio_gpu_allocation_metadata {} + +/* VIRTIO_GPU_RESP_OK_ALLOCATION_METADATA */ +#[derive(Copy, Clone, Debug, Default)] +#[repr(C)] +pub struct virtio_gpu_resp_allocation_metadata { + pub hdr: virtio_gpu_ctrl_hdr, + pub request_id: Le32, + pub response_size: Le32, +} + +unsafe impl DataInit for virtio_gpu_resp_allocation_metadata {} + /* simple formats for fbcon/X use */ pub const VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM: u32 = 1; pub const VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM: u32 = 2; @@ -520,6 +546,7 @@ pub enum GpuCommand { TransferToHost3d(virtio_gpu_transfer_host_3d), TransferFromHost3d(virtio_gpu_transfer_host_3d), CmdSubmit3d(virtio_gpu_cmd_submit), + AllocationMetadata(virtio_gpu_allocation_metadata), UpdateCursor(virtio_gpu_update_cursor), MoveCursor(virtio_gpu_update_cursor), } @@ -577,6 +604,7 @@ impl fmt::Debug for GpuCommand { TransferToHost3d(_info) => f.debug_struct("TransferToHost3d").finish(), TransferFromHost3d(_info) => f.debug_struct("TransferFromHost3d").finish(), CmdSubmit3d(_info) => f.debug_struct("CmdSubmit3d").finish(), + AllocationMetadata(_info) => f.debug_struct("AllocationMetadata").finish(), UpdateCursor(_info) => f.debug_struct("UpdateCursor").finish(), MoveCursor(_info) => f.debug_struct("MoveCursor").finish(), } @@ -607,6 +635,7 @@ impl GpuCommand { VIRTIO_GPU_CMD_TRANSFER_TO_HOST_3D => TransferToHost3d(cmd.read_obj()?), VIRTIO_GPU_CMD_TRANSFER_FROM_HOST_3D => TransferFromHost3d(cmd.read_obj()?), VIRTIO_GPU_CMD_SUBMIT_3D => CmdSubmit3d(cmd.read_obj()?), + VIRTIO_GPU_CMD_ALLOCATION_METADATA => AllocationMetadata(cmd.read_obj()?), VIRTIO_GPU_CMD_UPDATE_CURSOR => UpdateCursor(cmd.read_obj()?), VIRTIO_GPU_CMD_MOVE_CURSOR => MoveCursor(cmd.read_obj()?), _ => return Err(GpuCommandDecodeError::InvalidType(hdr.type_.into())), @@ -635,6 +664,7 @@ impl GpuCommand { TransferToHost3d(info) => &info.hdr, TransferFromHost3d(info) => &info.hdr, CmdSubmit3d(info) => &info.hdr, + AllocationMetadata(info) => &info.hdr, UpdateCursor(info) => &info.hdr, MoveCursor(info) => &info.hdr, } @@ -647,6 +677,12 @@ pub struct GpuResponsePlaneInfo { pub offset: u32, } +#[derive(Default, Debug, PartialEq)] +pub struct AllocationMetadataResponse { + pub request_id: u32, + pub response: Vec<u8>, +} + /// A response to a `GpuCommand`. These correspond to `VIRTIO_GPU_RESP_*`. #[derive(Debug, PartialEq)] pub enum GpuResponse { @@ -662,6 +698,9 @@ pub enum GpuResponse { format_modifier: u64, plane_info: Vec<GpuResponsePlaneInfo>, }, + OkAllocationMetadata { + res_info: AllocationMetadataResponse, + }, ErrUnspec, ErrOutOfMemory, ErrInvalidScanoutId, @@ -786,6 +825,17 @@ impl GpuResponse { size_of_val(&hdr) } } + GpuResponse::OkAllocationMetadata { ref res_info } => { + let resp_info = virtio_gpu_resp_allocation_metadata { + hdr, + request_id: Le32::from(res_info.request_id), + response_size: Le32::from(res_info.response.len() as u32), + }; + + resp.write_obj(resp_info)?; + resp.write(&res_info.response)?; + size_of_val(&resp_info) + res_info.response.len() + } _ => { resp.write_obj(hdr)?; size_of_val(&hdr) @@ -802,6 +852,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::OkAllocationMetadata { .. } => VIRTIO_GPU_RESP_OK_ALLOCATION_METADATA, 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, @@ -819,6 +870,7 @@ impl GpuResponse { GpuResponse::OkCapsetInfo { .. } => true, GpuResponse::OkCapset(_) => true, GpuResponse::OkResourcePlaneInfo { .. } => true, + GpuResponse::OkAllocationMetadata { .. } => true, _ => false, } } diff --git a/gpu_renderer/src/lib.rs b/gpu_renderer/src/lib.rs index c8f6f84..42df26a 100644 --- a/gpu_renderer/src/lib.rs +++ b/gpu_renderer/src/lib.rs @@ -392,6 +392,24 @@ impl Renderer { pub fn force_ctx_0(&self) { unsafe { virgl_renderer_force_ctx_0() }; } + + #[allow(unused_variables)] + pub fn allocation_metadata(&self, request: &[u8], response: &mut Vec<u8>) -> Result<()> { + #[cfg(feature = "virtio-gpu-next")] + { + let ret = unsafe { + virgl_renderer_allocation_metadata( + request.as_ptr() as *const c_void, + response.as_mut_ptr() as *mut c_void, + request.len() as u32, + response.len() as u32, + ) + }; + ret_to_res(ret) + } + #[cfg(not(feature = "virtio-gpu-next"))] + Err(Error::Unsupported) + } } /// A context in which resources can be attached/detached and commands can be submitted. |