summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorKeiichi Watanabe <keiichiw@chromium.org>2019-12-06 22:24:40 +0900
committerCommit Bot <commit-bot@chromium.org>2020-05-23 09:54:13 +0000
commit57df6a0ab23c3b2ba233b9aa5886ecf47ba3f91f (patch)
tree11bc695e179762b6eac26302e6b89db55b251dba /src
parentb2ca24c97b0084b805f7da28804b4c430c151ccb (diff)
downloadcrosvm-57df6a0ab23c3b2ba233b9aa5886ecf47ba3f91f.tar
crosvm-57df6a0ab23c3b2ba233b9aa5886ecf47ba3f91f.tar.gz
crosvm-57df6a0ab23c3b2ba233b9aa5886ecf47ba3f91f.tar.bz2
crosvm-57df6a0ab23c3b2ba233b9aa5886ecf47ba3f91f.tar.lz
crosvm-57df6a0ab23c3b2ba233b9aa5886ecf47ba3f91f.tar.xz
crosvm-57df6a0ab23c3b2ba233b9aa5886ecf47ba3f91f.tar.zst
crosvm-57df6a0ab23c3b2ba233b9aa5886ecf47ba3f91f.zip
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 <keiichiw@chromium.org>
Tested-by: Keiichi Watanabe <keiichiw@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Keiichi Watanabe <keiichiw@chromium.org>
Diffstat (limited to 'src')
-rw-r--r--src/crosvm.rs4
-rw-r--r--src/linux.rs88
-rw-r--r--src/main.rs10
3 files changed, 102 insertions, 0 deletions
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<PathBuf>,
     pub split_irqchip: bool,
     pub vfio: Vec<PathBuf>,
+    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<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 +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();