diff options
Diffstat (limited to 'src/linux.rs')
-rw-r--r-- | src/linux.rs | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/linux.rs b/src/linux.rs index ee659cb..e7583a4 100644 --- a/src/linux.rs +++ b/src/linux.rs @@ -41,6 +41,8 @@ use sys_util::{ FlockOperation, GuestMemory, Killable, PollContext, PollToken, SignalFd, Terminal, TimerFd, SIGRTMIN, }; +#[cfg(feature = "gpu-forward")] +use sys_util::{GuestAddress, MemoryMapping, Protection}; use vhost; use vm_control::{VmRequest, VmResponse, VmRunMode}; @@ -53,8 +55,17 @@ use aarch64::AArch64 as Arch; #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] use x86_64::X8664arch as Arch; +#[cfg(feature = "gpu-forward")] +extern crate render_node_forward; +#[cfg(feature = "gpu-forward")] +use self::render_node_forward::*; +#[cfg(not(feature = "gpu-forward"))] +type RenderNodeHost = (); + #[derive(Debug)] pub enum Error { + AddGpuDeviceMemory(sys_util::Error), + AllocateGpuDeviceAddress, BalloonDeviceNew(virtio::BalloonError), BlockDeviceNew(sys_util::Error), BlockSignal(sys_util::signal::Error), @@ -101,6 +112,8 @@ pub enum Error { RegisterRng(arch::DeviceRegistrationError), RegisterSignalHandler(sys_util::Error), RegisterWayland(arch::DeviceRegistrationError), + ReserveGpuMemory(sys_util::MmapError), + ReserveMemory(sys_util::Error), ResetTimerFd(sys_util::Error), RngDeviceNew(virtio::RngError), SettingGidMap(io_jail::Error), @@ -120,6 +133,8 @@ impl Display for Error { use self::Error::*; match self { + AddGpuDeviceMemory(e) => write!(f, "failed to add gpu device memory: {}", e), + AllocateGpuDeviceAddress => write!(f, "failed to allocate gpu device guest address"), BalloonDeviceNew(e) => write!(f, "failed to create balloon: {}", e), BlockDeviceNew(e) => write!(f, "failed to create block device: {}", e), BlockSignal(e) => write!(f, "failed to block signal: {}", e), @@ -181,6 +196,8 @@ impl Display for Error { RegisterRng(e) => write!(f, "error registering rng device: {}", e), RegisterSignalHandler(e) => write!(f, "error registering signal handler: {}", e), RegisterWayland(e) => write!(f, "error registering wayland device: {}", e), + ReserveGpuMemory(e) => write!(f, "failed to reserve gpu memory: {}", e), + ReserveMemory(e) => write!(f, "failed to reserve memory: {}", e), ResetTimerFd(e) => write!(f, "failed to reset timerfd: {}", e), RngDeviceNew(e) => write!(f, "failed to set up rng: {}", e), SettingGidMap(e) => write!(f, "error setting GID map: {}", e), @@ -1115,6 +1132,41 @@ pub fn run_config(cfg: Config) -> Result<()> { ) }) .map_err(Error::BuildVm)?; + + let _render_node_host = (); + #[cfg(feature = "gpu-forward")] + let (_render_node_host, linux) = { + // Rebinds linux as mutable. + let mut linux = linux; + + // Reserve memory range for GPU buffer allocation in advance to bypass region count + // limitation. We use mremap/MAP_FIXED later to make sure GPU buffers fall into this range. + let gpu_mmap = + MemoryMapping::new_protection(RENDER_NODE_HOST_SIZE as usize, Protection::none()) + .map_err(Error::ReserveGpuMemory)?; + + // Put the non-accessible memory map into device memory so that no other devices use that + // guest address space. + let gpu_addr = linux + .resources + .allocate_device_addresses(RENDER_NODE_HOST_SIZE) + .ok_or(Error::AllocateGpuDeviceAddress)?; + + let host = RenderNodeHost::start(&gpu_mmap, gpu_addr, linux.vm.get_memory().clone()); + + // Makes the gpu memory accessible at allocated address. + linux + .vm + .add_device_memory( + GuestAddress(gpu_addr), + gpu_mmap, + /* read_only = */ false, + /* log_dirty_pages = */ false, + ) + .map_err(Error::AddGpuDeviceMemory)?; + (host, linux) + }; + run_control( linux, control_server_socket, @@ -1122,6 +1174,7 @@ pub fn run_config(cfg: Config) -> Result<()> { balloon_host_socket, &disk_host_sockets, sigchld_fd, + _render_node_host, ) } @@ -1132,6 +1185,7 @@ fn run_control( balloon_host_socket: UnixSeqpacket, disk_host_sockets: &[MsgSocket<VmRequest, VmResponse>], sigchld_fd: SignalFd, + _render_node_host: RenderNodeHost, ) -> Result<()> { // Paths to get the currently available memory and the low memory threshold. const LOWMEM_MARGIN: &str = "/sys/kernel/mm/chromeos-low_mem/margin"; |