summary refs log tree commit diff
path: root/src/linux.rs
diff options
context:
space:
mode:
authorLepton Wu <lepton@chromium.org>2018-11-21 11:06:18 -0800
committerchrome-bot <chrome-bot@chromium.org>2019-03-14 20:53:53 -0700
commit608938818be555b51695972a78fc3bbe9c64c850 (patch)
tree557a028cc1fa98052b516a41751e6ca4f223bb0a /src/linux.rs
parent1bc4a06801a312e4fb770d323c35d34065a4d618 (diff)
downloadcrosvm-608938818be555b51695972a78fc3bbe9c64c850.tar
crosvm-608938818be555b51695972a78fc3bbe9c64c850.tar.gz
crosvm-608938818be555b51695972a78fc3bbe9c64c850.tar.bz2
crosvm-608938818be555b51695972a78fc3bbe9c64c850.tar.lz
crosvm-608938818be555b51695972a78fc3bbe9c64c850.tar.xz
crosvm-608938818be555b51695972a78fc3bbe9c64c850.tar.zst
crosvm-608938818be555b51695972a78fc3bbe9c64c850.zip
Start render node host service in crosvm
BUG=b:118408510
TEST=manual - build crosvm with/without crosvm-gpu-forward USE flag and run arcvm.

Change-Id: Ibb85d52dc679aa8524b29d86148ca28d82d8fe98
Reviewed-on: https://chromium-review.googlesource.com/1347330
Commit-Ready: Lepton Wu <lepton@chromium.org>
Tested-by: Lepton Wu <lepton@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Lepton Wu <lepton@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'src/linux.rs')
-rw-r--r--src/linux.rs54
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";