Skip to content

Commit

Permalink
gpu: use resource_map() for mapping BOs
Browse files Browse the repository at this point in the history
Use rutabaga's resource_map() to delegate mappings to virglrenderer.
This allows libkrun + virglrenderer to map BOs without relying on PRIME
fds, simplifying the ability to honor BO sharing semantics

The feature is gated behind "virgl_resource_map2" until
https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests/1374
gets merged.

Signed-off-by: Sergio Lopez <slp@redhat.com>
  • Loading branch information
slp committed Jun 5, 2024
1 parent 8ff6263 commit 3e8e143
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/devices/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ blk = []
efi = ["blk", "net"]
gpu = ["rutabaga_gfx", "thiserror", "zerocopy", "zerocopy-derive"]
snd = ["pw", "thiserror"]
virgl_resource_map2 = []

[dependencies]
bitflags = "1.2.0"
Expand Down
68 changes: 66 additions & 2 deletions src/devices/src/virtio/gpu/virtio_gpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ use hvf::MemoryMapping;
use libc::c_void;
#[cfg(target_os = "macos")]
use rutabaga_gfx::RUTABAGA_MEM_HANDLE_TYPE_APPLE;
#[cfg(all(not(feature = "virgl_resource_map2"), target_os = "linux"))]
use rutabaga_gfx::RUTABAGA_MEM_HANDLE_TYPE_OPAQUE_FD;
#[cfg(all(feature = "virgl_resource_map2", target_os = "linux"))]
use rutabaga_gfx::RUTABAGA_MEM_HANDLE_TYPE_SHM;
use rutabaga_gfx::{
ResourceCreate3D, ResourceCreateBlob, Rutabaga, RutabagaBuilder, RutabagaChannel,
RutabagaFence, RutabagaFenceHandler, RutabagaIovec, Transfer3D, RUTABAGA_CHANNEL_TYPE_WAYLAND,
Expand All @@ -21,7 +25,7 @@ use rutabaga_gfx::{
#[cfg(target_os = "linux")]
use rutabaga_gfx::{
RUTABAGA_MAP_ACCESS_MASK, RUTABAGA_MAP_ACCESS_READ, RUTABAGA_MAP_ACCESS_RW,
RUTABAGA_MAP_ACCESS_WRITE, RUTABAGA_MEM_HANDLE_TYPE_OPAQUE_FD,
RUTABAGA_MAP_ACCESS_WRITE,
};
use utils::eventfd::EventFd;
use vm_memory::{GuestAddress, GuestMemory, GuestMemoryMmap, VolatileSlice};
Expand Down Expand Up @@ -491,7 +495,7 @@ impl VirtioGpu {
/// rutabaga as ExternalMapping.
/// When sandboxing is enabled, external_blob is set and opaque fds must be mapped in the
/// hypervisor process by Vulkano using metadata provided by Rutabaga::vulkan_info().
#[cfg(target_os = "linux")]
#[cfg(all(not(feature = "virgl_resource_map2"), target_os = "linux"))]
pub fn resource_map_blob(
&mut self,
resource_id: u32,
Expand Down Expand Up @@ -548,6 +552,66 @@ impl VirtioGpu {
map_info: map_info & RUTABAGA_MAP_CACHE_MASK,
})
}
#[cfg(all(feature = "virgl_resource_map2", target_os = "linux"))]
pub fn resource_map_blob(
&mut self,
resource_id: u32,
shm_region: &VirtioShmRegion,
offset: u64,
) -> VirtioGpuResult {
let resource = self
.resources
.get_mut(&resource_id)
.ok_or(ErrInvalidResourceId)?;

let map_info = self.rutabaga.map_info(resource_id).map_err(|_| ErrUnspec)?;

let prot = match map_info & RUTABAGA_MAP_ACCESS_MASK {
RUTABAGA_MAP_ACCESS_READ => libc::PROT_READ,
RUTABAGA_MAP_ACCESS_WRITE => libc::PROT_WRITE,
RUTABAGA_MAP_ACCESS_RW => libc::PROT_READ | libc::PROT_WRITE,
_ => panic!("unexpected prot mode for mapping"),
};

if offset + resource.size > shm_region.size as u64 {
error!("resource map doesn't fit in shm region");
return Err(ErrUnspec);
}
let addr = shm_region.host_addr + offset;

if let Ok(export) = self.rutabaga.export_blob(resource_id) {
if export.handle_type == RUTABAGA_MEM_HANDLE_TYPE_SHM {
let ret = unsafe {
libc::mmap(
addr as *mut libc::c_void,
resource.size as usize,
prot,
libc::MAP_SHARED | libc::MAP_FIXED,
export.os_handle.as_raw_fd(),
0 as libc::off_t,
)
};
if ret == libc::MAP_FAILED {
error!("failed to mmap resource in shm region");
return Err(ErrUnspec);
}
} else {
self.rutabaga.resource_map(
resource_id,
addr,
resource.size,
prot,
libc::MAP_SHARED | libc::MAP_FIXED,
)?;
}
}

resource.shmem_offset = Some(offset);
// Access flags not a part of the virtio-gpu spec.
Ok(OkMapInfo {
map_info: map_info & RUTABAGA_MAP_CACHE_MASK,
})
}
#[cfg(target_os = "macos")]
pub fn resource_map_blob(
&mut self,
Expand Down

0 comments on commit 3e8e143

Please sign in to comment.