diff options
author | Alyssa Ross <hi@alyssa.is> | 2020-06-02 03:03:26 +0000 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2020-06-14 11:23:24 +0000 |
commit | 28d9682698d287d14cbe67a0ed7acc1427add320 (patch) | |
tree | 669ed98d9b1388b553c8e0f0189678cc68dd4162 /src | |
parent | 460406d10bbfaa890d56d616b4610813da63a312 (diff) | |
parent | 4264464153a7a788ef73c5015ac8bbde5f8ebe1c (diff) | |
download | crosvm-28d9682698d287d14cbe67a0ed7acc1427add320.tar crosvm-28d9682698d287d14cbe67a0ed7acc1427add320.tar.gz crosvm-28d9682698d287d14cbe67a0ed7acc1427add320.tar.bz2 crosvm-28d9682698d287d14cbe67a0ed7acc1427add320.tar.lz crosvm-28d9682698d287d14cbe67a0ed7acc1427add320.tar.xz crosvm-28d9682698d287d14cbe67a0ed7acc1427add320.tar.zst crosvm-28d9682698d287d14cbe67a0ed7acc1427add320.zip |
Merge remote-tracking branch 'origin/master'
Diffstat (limited to 'src')
-rw-r--r-- | src/crosvm.rs | 6 | ||||
-rw-r--r-- | src/linux.rs | 97 | ||||
-rw-r--r-- | src/main.rs | 35 | ||||
-rw-r--r-- | src/plugin/process.rs | 4 |
4 files changed, 140 insertions, 2 deletions
diff --git a/src/crosvm.rs b/src/crosvm.rs index 49a08c0..1ea7e0d 100644 --- a/src/crosvm.rs +++ b/src/crosvm.rs @@ -202,6 +202,9 @@ pub struct Config { pub virtio_input_evdevs: Vec<PathBuf>, pub split_irqchip: bool, pub vfio: Vec<PathBuf>, + pub video_dec: bool, + pub video_enc: bool, + pub acpi_tables: Vec<PathBuf>, } impl Default for Config { @@ -250,6 +253,9 @@ impl Default for Config { virtio_input_evdevs: Vec::new(), split_irqchip: false, vfio: Vec::new(), + video_dec: false, + video_enc: false, + acpi_tables: Vec::new(), } } } diff --git a/src/linux.rs b/src/linux.rs index 574493d..3e2045f 100644 --- a/src/linux.rs +++ b/src/linux.rs @@ -26,6 +26,8 @@ use std::time::Duration; use libc::{self, c_int, gid_t, uid_t}; +use acpi_tables::sdt::SDT; + #[cfg(feature = "gpu")] use devices::virtio::EventDevice; use devices::virtio::{self, Console, VirtioDevice}; @@ -109,6 +111,7 @@ pub enum Error { LoadKernel(Box<dyn StdError>), MemoryTooLarge, NetDeviceNew(virtio::NetError), + OpenAcpiTable(PathBuf, io::Error), OpenAndroidFstab(PathBuf, io::Error), OpenBios(PathBuf, io::Error), OpenInitrd(PathBuf, io::Error), @@ -196,6 +199,7 @@ impl Display for Error { LoadKernel(e) => write!(f, "failed to load kernel: {}", e), MemoryTooLarge => write!(f, "requested memory size too large"), NetDeviceNew(e) => write!(f, "failed to set up virtio networking: {}", e), + OpenAcpiTable(p, e) => write!(f, "failed to open ACPI file {}: {}", p.display(), e), OpenAndroidFstab(p, e) => write!( f, "failed to open android fstab file {}: {}", @@ -792,6 +796,70 @@ fn create_wayland_device( }) } +#[cfg(any(feature = "video-decoder", feature = "video-encoder"))] +fn create_video_device( + cfg: &Config, + typ: devices::virtio::VideoDeviceType, + resource_bridge: virtio::resource_bridge::ResourceRequestSocket, +) -> DeviceResult { + let jail = match simple_jail(&cfg, "video_device")? { + Some(mut jail) => { + match typ { + devices::virtio::VideoDeviceType::Decoder => { + add_crosvm_user_to_jail(&mut jail, "video-decoder")? + } + devices::virtio::VideoDeviceType::Encoder => { + add_crosvm_user_to_jail(&mut jail, "video-encoder")? + } + }; + + // Create a tmpfs in the device's root directory so that we can bind mount files. + jail.mount_with_data( + Path::new("none"), + Path::new("/"), + "tmpfs", + (libc::MS_NOSUID | libc::MS_NODEV | libc::MS_NOEXEC) as usize, + "size=67108864", + )?; + + // Render node for libvda. + let dev_dri_path = Path::new("/dev/dri/renderD128"); + jail.mount_bind(dev_dri_path, dev_dri_path, false)?; + + // Device nodes required by libchrome which establishes Mojo connection in libvda. + let dev_urandom_path = Path::new("/dev/urandom"); + jail.mount_bind(dev_urandom_path, dev_urandom_path, false)?; + let system_bus_socket_path = Path::new("/run/dbus/system_bus_socket"); + jail.mount_bind(system_bus_socket_path, system_bus_socket_path, true)?; + + Some(jail) + } + None => None, + }; + + Ok(VirtioDeviceStub { + dev: Box::new(devices::virtio::VideoDevice::new( + typ, + Some(resource_bridge), + )), + jail, + }) +} + +#[cfg(any(feature = "video-decoder", feature = "video-encoder"))] +fn register_video_device( + devs: &mut Vec<VirtioDeviceStub>, + resource_bridges: &mut Vec<virtio::resource_bridge::ResourceResponseSocket>, + cfg: &Config, + typ: devices::virtio::VideoDeviceType, +) -> std::result::Result<(), Error> { + let (video_socket, gpu_socket) = + virtio::resource_bridge::pair().map_err(Error::CreateSocket)?; + resource_bridges.push(gpu_socket); + devs.push(create_video_device(cfg, typ, video_socket)?); + Ok(()) +} + fn create_vhost_vsock_device(cfg: &Config, cid: u64, mem: &GuestMemory) -> DeviceResult { let dev = virtio::vhost::Vsock::new(cid, mem).map_err(Error::VhostVsockDeviceNew)?; @@ -1088,6 +1156,30 @@ fn create_virtio_devices( )?); } + #[cfg(feature = "video-decoder")] + { + if cfg.video_dec { + register_video_device( + &mut devs, + &mut resource_bridges, + cfg, + devices::virtio::VideoDeviceType::Decoder, + )?; + } + } + + #[cfg(feature = "video-encoder")] + { + if cfg.video_enc { + register_video_device( + &mut devs, + &mut resource_bridges, + cfg, + devices::virtio::VideoDeviceType::Encoder, + )?; + } + } + #[cfg(feature = "gpu")] { if let Some(gpu_parameters) = &cfg.gpu_parameters { @@ -1624,6 +1716,11 @@ pub fn run_config(cfg: Config) -> Result<()> { initrd_image, extra_kernel_params: cfg.params.clone(), wayland_dmabuf: cfg.wayland_dmabuf, + acpi_sdts: cfg + .acpi_tables + .iter() + .map(|path| SDT::from_file(path).map_err(|e| Error::OpenAcpiTable(path.clone(), e))) + .collect::<Result<Vec<SDT>>>()?, }; let control_server_socket = match &cfg.socket_path { diff --git a/src/main.rs b/src/main.rs index 7fd3eca..ed7bb30 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1223,6 +1223,29 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument:: cfg.vfio.push(vfio_path); } + "video-decoder" => { + cfg.video_dec = true; + } + "video-encoder" => { + cfg.video_enc = true; + } + "acpi-table" => { + let acpi_table = PathBuf::from(value.unwrap()); + if !acpi_table.exists() { + return Err(argument::Error::InvalidValue { + value: value.unwrap().to_owned(), + expected: String::from("the acpi-table path does not exist"), + }); + } + if !acpi_table.is_file() { + return Err(argument::Error::InvalidValue { + value: value.unwrap().to_owned(), + expected: String::from("the acpi-table path should be a file"), + }); + } + + cfg.acpi_tables.push(acpi_table); + } "help" => return Err(argument::Error::PrintHelp), _ => unreachable!(), @@ -1677,6 +1700,18 @@ Enable split-irqchip support. "PATH", "Path to sysfs of pass through or mdev device", ), + #[cfg(feature = "video-decoder")] + Argument::flag("video-decoder", "\ +(EXPERIMENTAL) +Enable virtio-video decoder device. +", + ), + #[cfg(feature = "video-encoder")] + Argument::flag("video-encoder", "\ +(EXPERIMENTAL) +Enable virtio-video encoder device. +"), + Argument::value("acpi-table", "PATH", "Path to user provided ACPI table."), Argument::short_flag('h', "help", "Print help message."), ]; diff --git a/src/plugin/process.rs b/src/plugin/process.rs index 783239a..688aa85 100644 --- a/src/plugin/process.rs +++ b/src/plugin/process.rs @@ -5,7 +5,7 @@ use std::collections::hash_map::{Entry, HashMap, VacantEntry}; use std::env::set_var; use std::fs::File; -use std::io::Write; +use std::io::{IoSlice, Write}; use std::mem::transmute; use std::os::unix::io::{IntoRawFd, RawFd}; use std::os::unix::net::UnixDatagram; @@ -730,7 +730,7 @@ impl Process { .map_err(Error::EncodeResponse)?; assert_ne!(self.response_buffer.len(), 0); self.request_sockets[index] - .send_with_fds(&self.response_buffer[..], &response_fds) + .send_with_fds(&[IoSlice::new(&self.response_buffer[..])], &response_fds) .map_err(Error::PluginSocketSend)?; Ok(()) |