mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-24 20:48:55 +00:00
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>
This commit is contained in:
parent
1bc4a06801
commit
608938818b
5 changed files with 136 additions and 0 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -104,6 +104,7 @@ dependencies = [
|
|||
"protobuf 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"qcow 0.1.0",
|
||||
"rand_ish 0.1.0",
|
||||
"render_node_forward 0.1.0",
|
||||
"resources 0.1.0",
|
||||
"sync 0.1.0",
|
||||
"sys_util 0.1.0",
|
||||
|
@ -405,6 +406,13 @@ dependencies = [
|
|||
name = "rand_ish"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "render_node_forward"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"sys_util 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "resources"
|
||||
version = "0.1.0"
|
||||
|
|
|
@ -27,6 +27,7 @@ gpu = ["devices/gpu"]
|
|||
usb-emulation = ["usb_util"]
|
||||
sandboxed-libusb = ["usb_util/sandboxed-libusb"]
|
||||
tpm = ["devices/tpm"]
|
||||
gpu-forward = ["render_node_forward"]
|
||||
|
||||
[dependencies]
|
||||
arch = { path = "arch" }
|
||||
|
@ -58,6 +59,7 @@ resources = { path = "resources" }
|
|||
p9 = { path = "p9" }
|
||||
sync = { path = "sync" }
|
||||
rand_ish = { path = "rand_ish" }
|
||||
render_node_forward = { path = "render_node_forward", optional = true }
|
||||
|
||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||
x86_64 = { path = "x86_64" }
|
||||
|
|
10
render_node_forward/Cargo.toml
Normal file
10
render_node_forward/Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "render_node_forward"
|
||||
version = "0.1.0"
|
||||
authors = ["The Chromium OS Authors"]
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
sys_util = { path = "../sys_util" }
|
62
render_node_forward/lib.rs
Normal file
62
render_node_forward/lib.rs
Normal file
|
@ -0,0 +1,62 @@
|
|||
// Copyright 2019 The Chromium OS Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
extern crate sys_util;
|
||||
|
||||
use sys_util::{GuestAddress, GuestMemory, MemoryMapping};
|
||||
|
||||
#[link(name = "rendernodehost")]
|
||||
extern "C" {
|
||||
fn start_render_node_host(
|
||||
gpu_host_mem: *mut u8,
|
||||
gpu_guest_mem_start: u64,
|
||||
gpu_guest_mem_size: u64,
|
||||
host_start: *const u8,
|
||||
host_4g_start: *const u8,
|
||||
);
|
||||
}
|
||||
|
||||
/// The number of bytes in 4 GiB.
|
||||
pub const FOUR_GB: u64 = (1 << 32);
|
||||
/// The size required for the render node host in host and guest address space.
|
||||
pub const RENDER_NODE_HOST_SIZE: u64 = FOUR_GB;
|
||||
|
||||
/// A render node host device that interfaces with the guest render node forwarder.
|
||||
pub struct RenderNodeHost {
|
||||
#[allow(dead_code)]
|
||||
guest_mem: GuestMemory,
|
||||
}
|
||||
|
||||
impl RenderNodeHost {
|
||||
/// Starts the render node host forwarding service over the given guest and host address ranges.
|
||||
pub fn start(
|
||||
mmap: &MemoryMapping,
|
||||
gpu_guest_address: u64,
|
||||
guest_mem: GuestMemory,
|
||||
) -> RenderNodeHost {
|
||||
// Render node forward library need to do address translation between host user space
|
||||
// address and guest physical address. We could call Rust function from C library. But
|
||||
// since it's actually a linear mapping now, we just pass the host start address to
|
||||
// render node forward library. We need two start address here since there would be a
|
||||
// hole below 4G if guest memory size is bigger than 4G.
|
||||
|
||||
let host_start_addr = guest_mem.get_host_address(GuestAddress(0)).unwrap();
|
||||
let host_4g_addr = if guest_mem.memory_size() > FOUR_GB {
|
||||
guest_mem.get_host_address(GuestAddress(FOUR_GB)).unwrap()
|
||||
} else {
|
||||
host_start_addr
|
||||
};
|
||||
// Safe because only valid addresses are given.
|
||||
unsafe {
|
||||
start_render_node_host(
|
||||
mmap.as_ptr(),
|
||||
gpu_guest_address,
|
||||
mmap.size() as u64,
|
||||
host_start_addr,
|
||||
host_4g_addr,
|
||||
)
|
||||
}
|
||||
RenderNodeHost { guest_mem }
|
||||
}
|
||||
}
|
54
src/linux.rs
54
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";
|
||||
|
|
Loading…
Reference in a new issue