summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2020-05-22 00:34:09 +0000
committerAlyssa Ross <hi@alyssa.is>2020-06-15 09:37:34 +0000
commit54ab55f99cd593f71a9b572d23199101a48206ec (patch)
tree633e6f29a69e27db3947fa2b8a857a9ccc2ae638 /src
parente0e035c065fdfbbea1e734d137d87a2635dbd0fa (diff)
downloadcrosvm-54ab55f99cd593f71a9b572d23199101a48206ec.tar
crosvm-54ab55f99cd593f71a9b572d23199101a48206ec.tar.gz
crosvm-54ab55f99cd593f71a9b572d23199101a48206ec.tar.bz2
crosvm-54ab55f99cd593f71a9b572d23199101a48206ec.tar.lz
crosvm-54ab55f99cd593f71a9b572d23199101a48206ec.tar.xz
crosvm-54ab55f99cd593f71a9b572d23199101a48206ec.tar.zst
crosvm-54ab55f99cd593f71a9b572d23199101a48206ec.zip
crosvm: add memfd server
Diffstat (limited to 'src')
-rw-r--r--src/crosvm.rs2
-rw-r--r--src/linux.rs67
-rw-r--r--src/main.rs6
3 files changed, 66 insertions, 9 deletions
diff --git a/src/crosvm.rs b/src/crosvm.rs
index e6e7268..ab4429a 100644
--- a/src/crosvm.rs
+++ b/src/crosvm.rs
@@ -180,6 +180,7 @@ pub struct Config {
     pub vhost_net: bool,
     pub tap_fd: Vec<RawFd>,
     pub cid: Option<u64>,
+    pub wl_memfd: bool,
     pub wayland_socket_paths: BTreeMap<String, PathBuf>,
     pub remote_wayland_device_socket_path: Option<PathBuf>,
     pub wayland_dmabuf: bool,
@@ -235,6 +236,7 @@ impl Default for Config {
             #[cfg(feature = "gpu")]
             gpu_parameters: None,
             software_tpm: false,
+            wl_memfd: false,
             wayland_socket_paths: BTreeMap::new(),
             remote_wayland_device_socket_path: None,
             wayland_dmabuf: false,
diff --git a/src/linux.rs b/src/linux.rs
index ee248a4..d5e12cd 100644
--- a/src/linux.rs
+++ b/src/linux.rs
@@ -5,8 +5,9 @@
 use std::cmp::max;
 use std::collections::{BTreeMap, VecDeque};
 use std::convert::TryFrom;
+use std::env;
 use std::error::Error as StdError;
-use std::ffi::CStr;
+use std::ffi::{CStr, OsString};
 use std::fmt::{self, Display};
 use std::fs::{File, OpenOptions};
 use std::io::{self, stdin, Read};
@@ -16,8 +17,9 @@ use std::net::Ipv4Addr;
 use std::num::NonZeroU8;
 use std::num::ParseIntError;
 use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
-use std::os::unix::net::UnixStream;
+use std::os::unix::net::{UnixListener, UnixStream};
 use std::path::{Path, PathBuf};
+use std::process;
 use std::ptr;
 use std::str;
 use std::sync::{Arc, Barrier};
@@ -42,6 +44,7 @@ use msg_socket::{MsgError, MsgReceiver, MsgResult, MsgSender, MsgSocket};
 use net_util::{Error as NetError, MacAddress, Tap};
 use remain::sorted;
 use resources::{Alloc, MmioType, SystemAllocator};
+use servers::MemfdServer;
 use sync::{Condvar, Mutex};
 use sys_util::net::{UnixSeqpacket, UnixSeqpacketListener, UnlinkUnixSeqpacketListener};
 
@@ -63,8 +66,8 @@ use vm_control::{
 
 use crate::{Config, DiskOption, Executable, SharedDir, SharedDirKind, TouchDeviceOption};
 use arch::{
-    self, LinuxArch, RunnableLinuxVm, SerialHardware, SerialParameters, VirtioDeviceStub,
-    VmComponents, VmImage,
+    self, LinuxArch, RunnableLinuxVm, SerialHardware, SerialParameters, ServerStub,
+    VirtioDeviceStub, VmComponents, VmImage,
 };
 
 #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
@@ -407,6 +410,16 @@ fn simple_jail(cfg: &Config, policy: &str) -> Result<Option<Minijail>> {
 }
 
 type DeviceResult<T = VirtioDeviceStub> = std::result::Result<T, Error>;
+type ServerResult<T = ServerStub> = std::result::Result<T, Error>;
+
+fn create_memfd_server(cfg: &Config, memfd_socket_path: &Path) -> ServerResult {
+    let sock = UnixListener::bind(&memfd_socket_path).map_err(Error::CreateSocket)?;
+    let server = MemfdServer::new(sock);
+    Ok(ServerStub {
+        server: Box::new(server),
+        jail: simple_jail(&cfg, "memfd_server")?,
+    })
+}
 
 fn create_block_device(
     cfg: &Config,
@@ -461,7 +474,6 @@ fn create_rng_device(cfg: &Config) -> DeviceResult {
 fn create_tpm_device(cfg: &Config) -> DeviceResult {
     use std::ffi::CString;
     use std::fs;
-    use std::process;
     use sys_util::chown;
 
     let tpm_storage: PathBuf;
@@ -756,12 +768,18 @@ fn create_gpu_device(
 
 fn create_wayland_device(
     cfg: &Config,
+    memfd_socket_path: Option<&Path>,
     vm_socket: VmMemoryControlRequestSocket,
     resource_bridge: Option<virtio::resource_bridge::ResourceRequestSocket>,
     memory_params: MemoryParams,
 ) -> DeviceResult {
-    let wayland_socket_dirs = cfg
-        .wayland_socket_paths
+    let mut wayland_socket_paths = cfg.wayland_socket_paths.clone();
+
+    if let Some(memfd_socket_path) = memfd_socket_path {
+        wayland_socket_paths.insert("__crosvm_memfd".to_string(), memfd_socket_path.into());
+    }
+
+    let wayland_socket_dirs = wayland_socket_paths
         .iter()
         .map(|(_name, path)| path.parent())
         .collect::<Option<Vec<_>>>()
@@ -778,7 +796,7 @@ fn create_wayland_device(
 
         None => Box::new(
             virtio::Wl::new(Params {
-                wayland_paths: cfg.wayland_socket_paths.clone(),
+                wayland_paths: wayland_socket_paths.clone(),
                 vm_socket,
                 resource_bridge,
             })
@@ -1076,6 +1094,7 @@ fn create_virtio_devices(
     vm: &mut Vm,
     resources: &mut SystemAllocator,
     _exit_evt: &EventFd,
+    memfd_socket_path: Option<&Path>,
     wayland_device_control_socket: VmMemoryControlRequestSocket,
     gpu_device_control_socket: VmMemoryControlRequestSocket,
     balloon_device_control_socket: BalloonControlResponseSocket,
@@ -1171,6 +1190,7 @@ fn create_virtio_devices(
 
         devs.push(create_wayland_device(
             cfg,
+            memfd_socket_path,
             wayland_device_control_socket,
             wl_resource_bridge,
             mem_params,
@@ -1279,6 +1299,7 @@ fn create_devices(
     vm: &mut Vm,
     resources: &mut SystemAllocator,
     exit_evt: &EventFd,
+    memfd_socket_path: Option<&Path>,
     control_sockets: &mut Vec<TaggedControlSocket>,
     wayland_device_control_socket: VmMemoryControlRequestSocket,
     gpu_device_control_socket: VmMemoryControlRequestSocket,
@@ -1294,6 +1315,7 @@ fn create_devices(
         vm,
         resources,
         exit_evt,
+        memfd_socket_path,
         wayland_device_control_socket,
         gpu_device_control_socket,
         balloon_device_control_socket,
@@ -1830,6 +1852,29 @@ pub fn run_config(cfg: Config) -> Result<()> {
         msg_socket::pair::<VmIrqResponse, VmIrqRequest>().map_err(Error::CreateSocket)?;
     control_sockets.push(TaggedControlSocket::VmIrq(ioapic_host_socket));
 
+    let mut servers = vec![];
+    let mut memfd_socket_path = None;
+
+    if cfg.wl_memfd {
+        let mut sock_name = OsString::from("crosvm-");
+        sock_name.push(process::id().to_string());
+        sock_name.push("-memfd.sock");
+
+        memfd_socket_path = Some(
+            [
+                env::var_os("XDG_RUNTIME_DIR").expect("XDG_RUNTIME_DIR not set"),
+                sock_name,
+            ]
+            .iter()
+            .collect::<PathBuf>(),
+        );
+
+        servers.push(create_memfd_server(
+            &cfg,
+            memfd_socket_path.as_ref().unwrap(),
+        )?);
+    }
+
     let sandbox = cfg.sandbox;
     let linux = Arch::build_vm(
         components,
@@ -1837,6 +1882,7 @@ pub fn run_config(cfg: Config) -> Result<()> {
         ioapic_device_control_socket,
         &cfg.serial_parameters,
         simple_jail(&cfg, "serial")?,
+        servers,
         |mem, mem_params, vm, sys_allocator, exit_evt| {
             create_devices(
                 &cfg,
@@ -1845,6 +1891,7 @@ pub fn run_config(cfg: Config) -> Result<()> {
                 vm,
                 sys_allocator,
                 exit_evt,
+                memfd_socket_path.as_ref().map(Path::new),
                 &mut control_sockets,
                 wayland_device_control_socket,
                 gpu_device_control_socket,
@@ -1952,6 +1999,10 @@ fn run_control(
         drop_capabilities().map_err(Error::DropCapabilities)?;
     }
 
+    for server in &mut linux.servers {
+        server.activate();
+    }
+
     let mut vcpu_handles = Vec::with_capacity(linux.vcpus.len());
     let vcpu_thread_barrier = Arc::new(Barrier::new(linux.vcpus.len() + 1));
     let run_mode_arc = Arc::new(VcpuRunMode::default());
diff --git a/src/main.rs b/src/main.rs
index 7ea2e01..87ecdb6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -829,7 +829,7 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument::
                         })?,
                 )
         }
-
+        "wl-memfd" => cfg.wl_memfd = true,
         "wayland-sock" => {
             let mut components = value.unwrap().split(',');
             let path =
@@ -1469,6 +1469,10 @@ Number of virtio-net virtual queue pairs.
 (default: 1)
 ",
         ),
+        Argument::flag(
+            "wl-memfd",
+            "Enable support for requesting memfds over virtio_wl.",
+        ),
         Argument::value(
             "wayland-sock",
             "PATH[,name=NAME]",