summary refs log tree commit diff
diff options
context:
space:
mode:
authorGurchetan Singh <gurchetansingh@chromium.org>2020-01-21 20:04:32 -0800
committerCommit Bot <commit-bot@chromium.org>2020-03-23 20:37:11 +0000
commit151af70ac9778f5247f6fd58fe8b20c089604429 (patch)
tree6005dd8571b877189b154ff203a3f1f063d5f66a
parent911e21e3925634833cf91ca1dd688c6047dc4b47 (diff)
downloadcrosvm-151af70ac9778f5247f6fd58fe8b20c089604429.tar
crosvm-151af70ac9778f5247f6fd58fe8b20c089604429.tar.gz
crosvm-151af70ac9778f5247f6fd58fe8b20c089604429.tar.bz2
crosvm-151af70ac9778f5247f6fd58fe8b20c089604429.tar.lz
crosvm-151af70ac9778f5247f6fd58fe8b20c089604429.tar.xz
crosvm-151af70ac9778f5247f6fd58fe8b20c089604429.tar.zst
crosvm-151af70ac9778f5247f6fd58fe8b20c089604429.zip
devices: gpu: modify resource v2
Rebase of zero-copy virtio-gpu flow:

    * Removes guest_memory_type/guest_caching_type in favor of a bitmask
    * Removes ALLOCATION_METADATA, since ideally we'd just read from
      guest memory to get guest responses
    * Renames HOST_COHERENT to HOST_VISIBLE
    * Adds a few more feature flags

BUG=chromium:924405
TEST=compile

Change-Id: I0d5a84b66cfa6d09f7e2d07ed8e761e7ba850284
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2013767
Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
Commit-Queue: Gurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: Lingfeng Yang <lfy@google.com>
Reviewed-by: Zach Reizner <zachr@chromium.org>
-rw-r--r--devices/src/virtio/gpu/mod.rs117
-rw-r--r--devices/src/virtio/gpu/protocol.rs92
-rw-r--r--devices/src/virtio/gpu/virtio_3d_backend.rs59
-rw-r--r--gpu_renderer/src/generated/virglrenderer.rs27
-rw-r--r--gpu_renderer/src/lib.rs59
5 files changed, 110 insertions, 244 deletions
diff --git a/devices/src/virtio/gpu/mod.rs b/devices/src/virtio/gpu/mod.rs
index 8cc211f..d211768 100644
--- a/devices/src/virtio/gpu/mod.rs
+++ b/devices/src/virtio/gpu/mod.rs
@@ -277,25 +277,16 @@ trait Backend {
         GpuResponse::ErrUnspec
     }
 
-    fn allocation_metadata(
-        &mut self,
-        _request_id: u32,
-        _request: Vec<u8>,
-        mut _response: Vec<u8>,
-    ) -> GpuResponse {
-        GpuResponse::ErrUnspec
-    }
-
     fn resource_create_v2(
         &mut self,
         _resource_id: u32,
-        _guest_memory_type: u32,
-        _guest_caching_type: u32,
+        _ctx_id: u32,
+        _flags: u32,
         _size: u64,
+        _memory_id: u64,
         _pci_addr: u64,
-        _mem: &GuestMemory,
         _vecs: Vec<(GuestAddress, usize)>,
-        _args: Vec<u8>,
+        _mem: &GuestMemory,
     ) -> GpuResponse {
         GpuResponse::ErrUnspec
     }
@@ -474,19 +465,19 @@ impl Frontend {
                 let available_bytes = reader.available_bytes();
                 if available_bytes != 0 {
                     let entry_count = info.nr_entries.to_native() as usize;
-                    let mut iovecs = Vec::with_capacity(entry_count);
+                    let mut vecs = Vec::with_capacity(entry_count);
                     for _ in 0..entry_count {
                         match reader.read_obj::<virtio_gpu_mem_entry>() {
                             Ok(entry) => {
                                 let addr = GuestAddress(entry.addr.to_native());
                                 let len = entry.length.to_native() as usize;
-                                iovecs.push((addr, len))
+                                vecs.push((addr, len))
                             }
                             Err(_) => return GpuResponse::ErrUnspec,
                         }
                     }
                     self.backend
-                        .attach_backing(info.resource_id.to_native(), mem, iovecs)
+                        .attach_backing(info.resource_id.to_native(), mem, vecs)
                 } else {
                     error!("missing data for command {:?}", cmd);
                     GpuResponse::ErrUnspec
@@ -610,74 +601,42 @@ 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_exact(&mut request_buf[..]).is_ok() {
-                        self.backend
-                            .allocation_metadata(id, request_buf, response_buf)
-                    } else {
-                        GpuResponse::ErrInvalidParameter
-                    }
-                } else {
-                    GpuResponse::ErrUnspec
-                }
-            }
             GpuCommand::ResourceCreateV2(info) => {
-                if reader.available_bytes() != 0 {
-                    let resource_id = info.resource_id.to_native();
-                    let guest_memory_type = info.guest_memory_type.to_native();
-                    let size = info.size.to_native();
-                    let guest_caching_type = info.guest_caching_type.to_native();
-                    let pci_addr = info.pci_addr.to_native();
-                    let entry_count = info.nr_entries.to_native();
-                    let args_size = info.args_size.to_native();
-                    if args_size > VIRTIO_GPU_MAX_BLOB_ARGUMENT_SIZE
-                        || entry_count > VIRTIO_GPU_MAX_IOVEC_ENTRIES
-                    {
-                        return GpuResponse::ErrUnspec;
-                    }
-
-                    let mut iovecs = Vec::with_capacity(entry_count as usize);
-                    let mut args = vec![0; args_size as usize];
+                let resource_id = info.resource_id.to_native();
+                let ctx_id = info.hdr.ctx_id.to_native();
+                let flags = info.flags.to_native();
+                let size = info.size.to_native();
+                let pci_addr = info.pci_addr.to_native();
+                let memory_id = info.memory_id.to_native();
+                let entry_count = info.nr_entries.to_native();
+                if entry_count > VIRTIO_GPU_MAX_IOVEC_ENTRIES
+                    || (reader.available_bytes() == 0 && entry_count > 0)
+                {
+                    return GpuResponse::ErrUnspec;
+                }
 
-                    for _ in 0..entry_count {
-                        match reader.read_obj::<virtio_gpu_mem_entry>() {
-                            Ok(entry) => {
-                                let addr = GuestAddress(entry.addr.to_native());
-                                let len = entry.length.to_native() as usize;
-                                iovecs.push((addr, len))
-                            }
-                            Err(_) => return GpuResponse::ErrUnspec,
+                let mut vecs = Vec::with_capacity(entry_count as usize);
+                for _ in 0..entry_count {
+                    match reader.read_obj::<virtio_gpu_mem_entry>() {
+                        Ok(entry) => {
+                            let addr = GuestAddress(entry.addr.to_native());
+                            let len = entry.length.to_native() as usize;
+                            vecs.push((addr, len))
                         }
+                        Err(_) => return GpuResponse::ErrUnspec,
                     }
-
-                    match reader.read_exact(&mut args[..]) {
-                        Ok(_) => self.backend.resource_create_v2(
-                            resource_id,
-                            guest_memory_type,
-                            guest_caching_type,
-                            size,
-                            pci_addr,
-                            mem,
-                            iovecs,
-                            args,
-                        ),
-                        Err(_) => GpuResponse::ErrUnspec,
-                    }
-                } else {
-                    GpuResponse::ErrUnspec
                 }
+
+                self.backend.resource_create_v2(
+                    resource_id,
+                    ctx_id,
+                    flags,
+                    size,
+                    pci_addr,
+                    memory_id,
+                    vecs,
+                    mem,
+                )
             }
             GpuCommand::ResourceV2Unref(info) => {
                 let resource_id = info.resource_id.to_native();
diff --git a/devices/src/virtio/gpu/protocol.rs b/devices/src/virtio/gpu/protocol.rs
index b4610b2..0563c1b 100644
--- a/devices/src/virtio/gpu/protocol.rs
+++ b/devices/src/virtio/gpu/protocol.rs
@@ -19,9 +19,10 @@ use data_model::{DataInit, Le32, Le64};
 pub const VIRTIO_GPU_F_VIRGL: u32 = 0;
 pub const VIRTIO_GPU_F_EDID: u32 = 1;
 /* The following capabilities are not upstreamed. */
-pub const VIRTIO_GPU_F_MEMORY: u32 = 2;
-pub const VIRTIO_GPU_F_SHARED_GUEST: u32 = 3;
-pub const VIRTIO_GPU_F_HOST_COHERENT: u32 = 4;
+pub const VIRTIO_GPU_F_RESOURCE_UUID: u32 = 2;
+pub const VIRTIO_GPU_F_RESOURCE_V2: u32 = 3;
+pub const VIRTIO_GPU_F_HOST_VISIBLE: u32 = 4;
+pub const VIRTIO_GPU_F_VULKAN: u32 = 5;
 
 pub const VIRTIO_GPU_UNDEFINED: u32 = 0x0;
 
@@ -50,7 +51,6 @@ pub const VIRTIO_GPU_CMD_SUBMIT_3D: u32 = 0x207;
 /* The following hypercalls are not upstreamed. */
 pub const VIRTIO_GPU_CMD_RESOURCE_CREATE_V2: u32 = 0x208;
 pub const VIRTIO_GPU_CMD_RESOURCE_CREATE_V2_UNREF: u32 = 0x209;
-pub const VIRTIO_GPU_CMD_ALLOCATION_METADATA: u32 = 0x20a;
 
 /* cursor commands */
 pub const VIRTIO_GPU_CMD_UPDATE_CURSOR: u32 = 0x300;
@@ -63,7 +63,6 @@ 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_ALLOCATION_METADATA: u32 = 0x1106;
 
 /* error responses */
 pub const VIRTIO_GPU_RESP_ERR_UNSPEC: u32 = 0x1200;
@@ -73,20 +72,22 @@ pub const VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID: u32 = 0x1203;
 pub const VIRTIO_GPU_RESP_ERR_INVALID_CONTEXT_ID: u32 = 0x1204;
 pub const VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER: u32 = 0x1205;
 
-/* guest memory types (not upstreamed) */
-pub const VIRTIO_GPU_MEMORY_UNDEFINED: u32 = 0;
-pub const VIRTIO_GPU_MEMORY_TRANSFER: u32 = 1;
-pub const VIRTIO_GPU_MEMORY_SHARED_GUEST: u32 = 2;
-pub const VIRTIO_GPU_MEMORY_HOST_COHERENT: u32 = 3;
+/* Resource flags (not upstreamed) */
+pub const VIRTIO_GPU_RESOURCE_GUEST_NONE: u32 = 0x0000;
+pub const VIRTIO_GPU_RESOURCE_GUEST_MASK: u32 = 0x000f;
+pub const VIRTIO_GPU_RESOURCE_GUEST_SYSTEM: u32 = 0x0001;
 
-/* guest caching types (not upstreamed) */
-pub const VIRTIO_GPU_UNDEFINED_CACHING: u32 = 0;
-pub const VIRTIO_GPU_CACHED: u32 = 1;
-pub const VIRTIO_GPU_WRITE_COMBINE: u32 = 2;
-pub const VIRTIO_GPU_UNCACHED: u32 = 3;
+pub const VIRTIO_GPU_RESOURCE_HOST_NONE: u32 = 0x0000;
+pub const VIRTIO_GPU_RESOURCE_HOST_MASK: u32 = 0x00f0;
+pub const VIRTIO_GPU_RESOURCE_HOST: u32 = 0x0010;
+pub const VIRTIO_GPU_RESOURCE_HOST_FROM_GUEST: u32 = 0x0020;
+
+pub const VIRTIO_GPU_RESOURCE_USE_NONE: u32 = 0x0000;
+pub const VIRTIO_GPU_RESOURCE_USE_MASK: u32 = 0x0f00;
+pub const VIRTIO_GPU_RESOURCE_USE_MAPPABLE: u32 = 0x0100;
+pub const VIRTIO_GPU_RESOURCE_USE_SHAREABLE: u32 = 0x0200;
+pub const VIRTIO_GPU_RESOURCE_USE_CROSS_DEVICE: u32 = 0x0400;
 
-/* Limits on virtio-gpu stream (not upstreamed) */
-pub const VIRTIO_GPU_MAX_BLOB_ARGUMENT_SIZE: u32 = 4096;
 /* This matches the limit in udmabuf.c */
 pub const VIRTIO_GPU_MAX_IOVEC_ENTRIES: u32 = 1024;
 
@@ -113,7 +114,6 @@ pub fn virtio_gpu_cmd_str(cmd: u32) -> &'static str {
         VIRTIO_GPU_CMD_SUBMIT_3D => "VIRTIO_GPU_CMD_SUBMIT_3D",
         VIRTIO_GPU_CMD_RESOURCE_CREATE_V2 => "VIRTIO_GPU_CMD_RESOURCE_CREATE_V2",
         VIRTIO_GPU_CMD_RESOURCE_CREATE_V2_UNREF => "VIRTIO_GPU_CMD_RESOURCE_CREATE_V2_UNREF",
-        VIRTIO_GPU_CMD_ALLOCATION_METADATA => "VIRTIO_GPU_CMD_ALLOCATION_METADATA",
         VIRTIO_GPU_CMD_UPDATE_CURSOR => "VIRTIO_GPU_CMD_UPDATE_CURSOR",
         VIRTIO_GPU_CMD_MOVE_CURSOR => "VIRTIO_GPU_CMD_MOVE_CURSOR",
         VIRTIO_GPU_RESP_OK_NODATA => "VIRTIO_GPU_RESP_OK_NODATA",
@@ -497,39 +497,15 @@ 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 {}
-
-#[derive(Copy, Clone, Debug, Default)]
-#[repr(C)]
 pub struct virtio_gpu_resource_create_v2 {
     pub hdr: virtio_gpu_ctrl_hdr,
     pub resource_id: Le32,
-    pub guest_memory_type: Le32,
-    pub guest_caching_type: Le32,
-    pub padding: Le32,
+    pub flags: Le32,
     pub size: Le64,
     pub pci_addr: Le64,
-    pub args_size: Le32,
+    pub memory_id: Le64,
     pub nr_entries: Le32,
+    pub padding: Le32,
 }
 
 unsafe impl DataInit for virtio_gpu_resource_create_v2 {}
@@ -577,7 +553,6 @@ pub enum GpuCommand {
     CmdSubmit3d(virtio_gpu_cmd_submit),
     ResourceCreateV2(virtio_gpu_resource_create_v2),
     ResourceV2Unref(virtio_gpu_resource_v2_unref),
-    AllocationMetadata(virtio_gpu_allocation_metadata),
     UpdateCursor(virtio_gpu_update_cursor),
     MoveCursor(virtio_gpu_update_cursor),
 }
@@ -646,7 +621,6 @@ impl fmt::Debug for GpuCommand {
             CmdSubmit3d(_info) => f.debug_struct("CmdSubmit3d").finish(),
             ResourceCreateV2(_info) => f.debug_struct("ResourceCreateV2").finish(),
             ResourceV2Unref(_info) => f.debug_struct("ResourceV2Unref").finish(),
-            AllocationMetadata(_info) => f.debug_struct("AllocationMetadata").finish(),
             UpdateCursor(_info) => f.debug_struct("UpdateCursor").finish(),
             MoveCursor(_info) => f.debug_struct("MoveCursor").finish(),
         }
@@ -679,7 +653,6 @@ impl GpuCommand {
             VIRTIO_GPU_CMD_SUBMIT_3D => CmdSubmit3d(cmd.read_obj()?),
             VIRTIO_GPU_CMD_RESOURCE_CREATE_V2 => ResourceCreateV2(cmd.read_obj()?),
             VIRTIO_GPU_CMD_RESOURCE_CREATE_V2_UNREF => ResourceV2Unref(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())),
@@ -710,7 +683,6 @@ impl GpuCommand {
             CmdSubmit3d(info) => &info.hdr,
             ResourceCreateV2(info) => &info.hdr,
             ResourceV2Unref(info) => &info.hdr,
-            AllocationMetadata(info) => &info.hdr,
             UpdateCursor(info) => &info.hdr,
             MoveCursor(info) => &info.hdr,
         }
@@ -723,12 +695,6 @@ 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 {
@@ -744,9 +710,6 @@ pub enum GpuResponse {
         format_modifier: u64,
         plane_info: Vec<GpuResponsePlaneInfo>,
     },
-    OkAllocationMetadata {
-        res_info: AllocationMetadataResponse,
-    },
     ErrUnspec,
     ErrOutOfMemory,
     ErrInvalidScanoutId,
@@ -880,17 +843,6 @@ 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_all(&res_info.response)?;
-                size_of_val(&resp_info) + res_info.response.len()
-            }
             _ => {
                 resp.write_obj(hdr)?;
                 size_of_val(&hdr)
@@ -907,7 +859,6 @@ 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,
@@ -925,7 +876,6 @@ impl GpuResponse {
             GpuResponse::OkCapsetInfo { .. } => true,
             GpuResponse::OkCapset(_) => true,
             GpuResponse::OkResourcePlaneInfo { .. } => true,
-            GpuResponse::OkAllocationMetadata { .. } => true,
             _ => false,
         }
     }
diff --git a/devices/src/virtio/gpu/virtio_3d_backend.rs b/devices/src/virtio/gpu/virtio_3d_backend.rs
index 7ae044c..21b5bf4 100644
--- a/devices/src/virtio/gpu/virtio_3d_backend.rs
+++ b/devices/src/virtio/gpu/virtio_3d_backend.rs
@@ -26,13 +26,13 @@ use gpu_renderer::{
 };
 
 use super::protocol::{
-    AllocationMetadataResponse, GpuResponse, GpuResponsePlaneInfo, VIRTIO_GPU_CAPSET3,
-    VIRTIO_GPU_CAPSET_VIRGL, VIRTIO_GPU_CAPSET_VIRGL2, VIRTIO_GPU_MEMORY_HOST_COHERENT,
+    GpuResponse, GpuResponsePlaneInfo, VIRTIO_GPU_CAPSET3, VIRTIO_GPU_CAPSET_VIRGL,
+    VIRTIO_GPU_CAPSET_VIRGL2, VIRTIO_GPU_RESOURCE_USE_MAPPABLE, VIRTIO_GPU_RESOURCE_USE_MASK,
 };
 pub use crate::virtio::gpu::virtio_backend::{VirtioBackend, VirtioResource};
 use crate::virtio::gpu::{
-    Backend, DisplayBackend, VIRTIO_F_VERSION_1, VIRTIO_GPU_F_HOST_COHERENT, VIRTIO_GPU_F_MEMORY,
-    VIRTIO_GPU_F_VIRGL,
+    Backend, DisplayBackend, VIRTIO_F_VERSION_1, VIRTIO_GPU_F_HOST_VISIBLE,
+    VIRTIO_GPU_F_RESOURCE_UUID, VIRTIO_GPU_F_RESOURCE_V2, VIRTIO_GPU_F_VIRGL, VIRTIO_GPU_F_VULKAN,
 };
 use crate::virtio::resource_bridge::{PlaneInfo, ResourceInfo, ResourceResponse};
 
@@ -225,8 +225,10 @@ impl Backend for Virtio3DBackend {
     fn features() -> u64 {
         1 << VIRTIO_GPU_F_VIRGL
             | 1 << VIRTIO_F_VERSION_1
-            | 1 << VIRTIO_GPU_F_MEMORY
-            | 1 << VIRTIO_GPU_F_HOST_COHERENT
+            | 1 << VIRTIO_GPU_F_RESOURCE_UUID
+            | 1 << VIRTIO_GPU_F_RESOURCE_V2
+            | 1 << VIRTIO_GPU_F_HOST_VISIBLE
+            | 1 << VIRTIO_GPU_F_VULKAN
     }
 
     /// Returns the underlying Backend.
@@ -757,51 +759,27 @@ impl Backend for Virtio3DBackend {
         }
     }
 
-    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
-            }
-        }
-    }
-
     fn resource_create_v2(
         &mut self,
         resource_id: u32,
-        guest_memory_type: u32,
-        guest_caching_type: u32,
+        ctx_id: u32,
+        flags: u32,
         size: u64,
         pci_addr: u64,
-        mem: &GuestMemory,
+        memory_id: u64,
         vecs: Vec<(GuestAddress, usize)>,
-        args: Vec<u8>,
+        mem: &GuestMemory,
     ) -> GpuResponse {
         match self.resources.entry(resource_id) {
             Entry::Vacant(entry) => {
                 let resource = match self.renderer.resource_create_v2(
                     resource_id,
-                    guest_memory_type,
-                    guest_caching_type,
+                    ctx_id,
+                    flags,
                     size,
-                    mem,
+                    memory_id,
                     &vecs,
-                    &args,
+                    mem,
                 ) {
                     Ok(resource) => resource,
                     Err(e) => {
@@ -810,8 +788,9 @@ impl Backend for Virtio3DBackend {
                     }
                 };
 
-                match guest_memory_type {
-                    VIRTIO_GPU_MEMORY_HOST_COHERENT => {
+                let use_flags = VIRTIO_GPU_RESOURCE_USE_MASK & flags;
+                match use_flags {
+                    VIRTIO_GPU_RESOURCE_USE_MAPPABLE => {
                         let dma_buf_fd = match resource.export() {
                             Ok(export) => export.1,
                             Err(e) => {
diff --git a/gpu_renderer/src/generated/virglrenderer.rs b/gpu_renderer/src/generated/virglrenderer.rs
index 01bf219..020d69f 100644
--- a/gpu_renderer/src/generated/virglrenderer.rs
+++ b/gpu_renderer/src/generated/virglrenderer.rs
@@ -307,24 +307,21 @@ extern "C" {
         execute_size: u32,
     ) -> ::std::os::raw::c_int;
 }
-extern "C" {
-    pub fn virgl_renderer_allocation_metadata(
-        request: *const ::std::os::raw::c_void,
-        response: *mut ::std::os::raw::c_void,
-        request_size: u32,
-        response_size: u32,
-    ) -> ::std::os::raw::c_int;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct virgl_renderer_resource_create_v2_args {
+    pub version: u32,
+    pub res_handle: u32,
+    pub ctx_id: u32,
+    pub flags: u32,
+    pub size: u64,
+    pub memory_id: u64,
+    pub iovecs: *mut iovec,
+    pub num_iovs: u32,
 }
 extern "C" {
     pub fn virgl_renderer_resource_create_v2(
-        resource_id: u32,
-        guest_memory_type: u32,
-        guest_caching_type: u32,
-        size: u64,
-        iovec: *const iovec,
-        num_iovs: u32,
-        args: *const ::std::os::raw::c_void,
-        args_size: u32,
+        args: *mut virgl_renderer_resource_create_v2_args,
     ) -> ::std::os::raw::c_int;
 }
 pub type __builtin_va_list = [__va_list_tag; 1usize];
diff --git a/gpu_renderer/src/lib.rs b/gpu_renderer/src/lib.rs
index d75add1..5e5ab95 100644
--- a/gpu_renderer/src/lib.rs
+++ b/gpu_renderer/src/lib.rs
@@ -37,7 +37,7 @@ pub use crate::command_buffer::CommandBufferBuilder;
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub use crate::vsnprintf::vsnprintf;
 
-/// Arguments used in `Renderer::create_resource`..
+/// Arguments used in `Renderer::create_resource`.
 pub type ResourceCreateArgs = virgl_renderer_resource_create_args;
 /// Some of the information returned from `Resource::export_query`.
 pub type Query = virgl_renderer_export_query;
@@ -406,71 +406,52 @@ impl Renderer {
     }
 
     #[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)
-    }
-
-    #[allow(unused_variables)]
     pub fn resource_create_v2(
         &self,
         resource_id: u32,
-        guest_memory_type: u32,
-        guest_caching_type: u32,
+        ctx_id: u32,
+        flags: u32,
         size: u64,
+        memory_id: u64,
+        vecs: &[(GuestAddress, usize)],
         mem: &GuestMemory,
-        iovecs: &[(GuestAddress, usize)],
-        args: &[u8],
     ) -> Result<Resource> {
         #[cfg(feature = "virtio-gpu-next")]
         {
-            if iovecs
+            if vecs
                 .iter()
                 .any(|&(addr, len)| mem.get_slice(addr.offset(), len as u64).is_err())
             {
                 return Err(Error::InvalidIovec);
             }
 
-            let mut vecs = Vec::new();
-            for &(addr, len) in iovecs {
+            let mut iovecs = Vec::new();
+            for &(addr, len) in vecs {
                 // Unwrap will not panic because we already checked the slices.
                 let slice = mem.get_slice(addr.offset(), len as u64).unwrap();
-                vecs.push(VirglVec {
+                iovecs.push(VirglVec {
                     base: slice.as_ptr() as *mut c_void,
                     len,
                 });
             }
 
-            let ret = unsafe {
-                virgl_renderer_resource_create_v2(
-                    resource_id,
-                    guest_memory_type,
-                    guest_caching_type,
-                    size,
-                    vecs.as_ptr() as *const iovec,
-                    vecs.len() as u32,
-                    args.as_ptr() as *const c_void,
-                    args.len() as u32,
-                )
+            let mut resource_create_args = virgl_renderer_resource_create_v2_args {
+                version: 1,
+                res_handle: resource_id,
+                ctx_id,
+                flags,
+                size,
+                memory_id,
+                iovecs: iovecs.as_mut_ptr() as *mut iovec,
+                num_iovs: iovecs.len() as u32,
             };
 
+            let ret = unsafe { virgl_renderer_resource_create_v2(&mut resource_create_args) };
             ret_to_res(ret)?;
 
             Ok(Resource {
                 id: resource_id,
-                backing_iovecs: vecs,
+                backing_iovecs: iovecs,
                 backing_mem: None,
                 no_sync_send: PhantomData,
             })