From 57df6a0ab23c3b2ba233b9aa5886ecf47ba3f91f Mon Sep 17 00:00:00 2001 From: Keiichi Watanabe Date: Fri, 6 Dec 2019 22:24:40 +0900 Subject: devices: virtio: Initial implementation of virtio-video device This CL adds a fundamental part of the virtio video device, which will be shared between the encoder and the decoder. Both devices uses the virtio-video protocol proposed as RFC v3 [1,2]. The corresponding driver code is at CL:2060327 and its children CLs. The actual decoding and encoding logic will be implemented in different CLs. [1]: mail: https://markmail.org/thread/wxdne5re7aaugbjg [2]: PDF: https://drive.google.com/file/d/1jOsS2WdVhL4PpcWLO8Zukq5J0fXDiWn-/view BUG=b:147465619, b:140082257 TEST=cargo check --features=video-decoder,video-encoder TEST=ARCVM started with --video-decoder --video-encoder Cq-Depend: chromium:2203997 Change-Id: I01999eea218ba0f3aaed1558ca2311a57d0c6819 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1973973 Reviewed-by: Keiichi Watanabe Tested-by: Keiichi Watanabe Tested-by: kokoro Commit-Queue: Keiichi Watanabe --- src/crosvm.rs | 4 +++ src/linux.rs | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 10 +++++++ 3 files changed, 102 insertions(+) (limited to 'src') diff --git a/src/crosvm.rs b/src/crosvm.rs index 49a08c0..33ed236 100644 --- a/src/crosvm.rs +++ b/src/crosvm.rs @@ -202,6 +202,8 @@ pub struct Config { pub virtio_input_evdevs: Vec, pub split_irqchip: bool, pub vfio: Vec, + pub video_dec: bool, + pub video_enc: bool, } impl Default for Config { @@ -250,6 +252,8 @@ impl Default for Config { virtio_input_evdevs: Vec::new(), split_irqchip: false, vfio: Vec::new(), + video_dec: false, + video_enc: false, } } } diff --git a/src/linux.rs b/src/linux.rs index e480a4c..e95f372 100644 --- a/src/linux.rs +++ b/src/linux.rs @@ -792,6 +792,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, + resource_bridges: &mut Vec, + 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 +1152,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 { diff --git a/src/main.rs b/src/main.rs index 557c630..61fcd48 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1226,6 +1226,12 @@ 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; + } "help" => return Err(argument::Error::PrintHelp), _ => unreachable!(), @@ -1396,6 +1402,10 @@ writeback=BOOL - Indicates whether the VM can use writeback caching (default: fa Argument::flag("split-irqchip", "(EXPERIMENTAL) enable split-irqchip support"), Argument::value("bios", "PATH", "Path to BIOS/firmware ROM"), Argument::value("vfio", "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::short_flag('h', "help", "Print help message.")]; let mut cfg = Config::default(); -- cgit 1.4.1