summary refs log tree commit diff
diff options
context:
space:
mode:
authorZach Reizner <zachr@google.com>2019-06-19 17:46:03 -0700
committerCommit Bot <commit-bot@chromium.org>2019-08-08 03:19:58 +0000
commit0f2cfb095dc2d49bfe22cb2d560b7777a19901e8 (patch)
tree366bf094ea0194b21f5d7415259281717cb32d3d
parent7f855be1f96905c44599b944a0d8449ae528ac39 (diff)
downloadcrosvm-0f2cfb095dc2d49bfe22cb2d560b7777a19901e8.tar
crosvm-0f2cfb095dc2d49bfe22cb2d560b7777a19901e8.tar.gz
crosvm-0f2cfb095dc2d49bfe22cb2d560b7777a19901e8.tar.bz2
crosvm-0f2cfb095dc2d49bfe22cb2d560b7777a19901e8.tar.lz
crosvm-0f2cfb095dc2d49bfe22cb2d560b7777a19901e8.tar.xz
crosvm-0f2cfb095dc2d49bfe22cb2d560b7777a19901e8.tar.zst
crosvm-0f2cfb095dc2d49bfe22cb2d560b7777a19901e8.zip
crosvm: add x-display argument for choosing the X11 gpu display
TEST=cargo run -- run --gpu --x-display :0
BUG=None

Change-Id: I76b4b33a6b14cb6fad322ffa95f00cce976f81a3
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1670550
Reviewed-by: Zach Reizner <zachr@chromium.org>
Commit-Queue: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
-rw-r--r--devices/src/virtio/gpu/mod.rs12
-rw-r--r--src/crosvm.rs2
-rw-r--r--src/linux.rs48
-rw-r--r--src/main.rs9
4 files changed, 48 insertions, 23 deletions
diff --git a/devices/src/virtio/gpu/mod.rs b/devices/src/virtio/gpu/mod.rs
index c81afa5..2c09761 100644
--- a/devices/src/virtio/gpu/mod.rs
+++ b/devices/src/virtio/gpu/mod.rs
@@ -11,7 +11,7 @@ use std::i64;
 use std::mem::{self, size_of};
 use std::num::NonZeroU8;
 use std::os::unix::io::{AsRawFd, RawFd};
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
 use std::rc::Rc;
 use std::sync::atomic::{AtomicUsize, Ordering};
 use std::sync::Arc;
@@ -711,22 +711,20 @@ pub struct Gpu {
 }
 
 impl Gpu {
-    pub fn new<P: AsRef<Path>>(
+    pub fn new(
         exit_evt: EventFd,
         gpu_device_socket: Option<VmMemoryControlRequestSocket>,
+        num_scanouts: NonZeroU8,
         resource_bridges: Vec<ResourceResponseSocket>,
-        wayland_socket_path: P,
+        display_backends: Vec<DisplayBackend>,
     ) -> Gpu {
-        let display_backends = vec![DisplayBackend::Wayland(Some(
-            wayland_socket_path.as_ref().to_owned(),
-        ))];
         Gpu {
             config_event: false,
             exit_evt,
             gpu_device_socket,
             resource_bridges,
             kill_evt: None,
-            num_scanouts: NonZeroU8::new(1).unwrap(),
+            num_scanouts,
             display_backends,
         }
     }
diff --git a/src/crosvm.rs b/src/crosvm.rs
index 4e820c9..bc39e7f 100644
--- a/src/crosvm.rs
+++ b/src/crosvm.rs
@@ -91,6 +91,7 @@ pub struct Config {
     pub cid: Option<u64>,
     pub wayland_socket_path: Option<PathBuf>,
     pub wayland_dmabuf: bool,
+    pub x_display: Option<String>,
     pub shared_dirs: Vec<(PathBuf, String)>,
     pub sandbox: bool,
     pub seccomp_policy_dir: PathBuf,
@@ -136,6 +137,7 @@ impl Default for Config {
             software_tpm: false,
             wayland_socket_path: None,
             wayland_dmabuf: false,
+            x_display: None,
             shared_dirs: Vec::new(),
             sandbox: !cfg!(feature = "default-no-sandbox"),
             seccomp_policy_dir: PathBuf::from(SECCOMP_POLICY_DIR),
diff --git a/src/linux.rs b/src/linux.rs
index 56750ae..b579e8a 100644
--- a/src/linux.rs
+++ b/src/linux.rs
@@ -11,6 +11,7 @@ use std::fmt::{self, Display};
 use std::fs::{File, OpenOptions};
 use std::io::{self, stdin, Read};
 use std::net::Ipv4Addr;
+use std::num::NonZeroU8;
 use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
 use std::os::unix::net::UnixStream;
 use std::path::{Path, PathBuf};
@@ -562,19 +563,33 @@ fn create_gpu_device(
     exit_evt: &EventFd,
     gpu_device_socket: VmMemoryControlRequestSocket,
     gpu_sockets: Vec<virtio::resource_bridge::ResourceResponseSocket>,
-    wayland_socket_path: &Path,
+    wayland_socket_path: Option<PathBuf>,
+    x_display: Option<String>,
 ) -> DeviceResult {
     let jailed_wayland_path = Path::new("/wayland-0");
 
+    let mut display_backends = vec![
+        virtio::DisplayBackend::X(x_display),
+        virtio::DisplayBackend::Null,
+    ];
+
+    if let Some(socket_path) = wayland_socket_path.as_ref() {
+        display_backends.insert(
+            0,
+            virtio::DisplayBackend::Wayland(if cfg.sandbox {
+                Some(jailed_wayland_path.to_owned())
+            } else {
+                Some(socket_path.to_owned())
+            }),
+        );
+    }
+
     let dev = virtio::Gpu::new(
         exit_evt.try_clone().map_err(Error::CloneEventFd)?,
         Some(gpu_device_socket),
+        NonZeroU8::new(1).unwrap(), // number of scanouts
         gpu_sockets,
-        if cfg.sandbox {
-            &jailed_wayland_path
-        } else {
-            wayland_socket_path
-        },
+        display_backends,
     );
 
     let jail = match simple_jail(&cfg, "gpu_device.policy")? {
@@ -619,7 +634,9 @@ fn create_gpu_device(
 
             // Bind mount the wayland socket into jail's root. This is necessary since each
             // new wayland context must open() the socket.
-            jail.mount_bind(wayland_socket_path, jailed_wayland_path, true)?;
+            if let Some(path) = wayland_socket_path {
+                jail.mount_bind(path.as_ref(), jailed_wayland_path, true)?;
+            }
 
             add_crosvm_user_to_jail(&mut jail, "gpu")?;
 
@@ -894,15 +911,14 @@ fn create_virtio_devices(
     #[cfg(feature = "gpu")]
     {
         if cfg.gpu {
-            if let Some(wayland_socket_path) = &cfg.wayland_socket_path {
-                devs.push(create_gpu_device(
-                    cfg,
-                    _exit_evt,
-                    gpu_device_socket,
-                    resource_bridges,
-                    wayland_socket_path,
-                )?);
-            }
+            devs.push(create_gpu_device(
+                cfg,
+                _exit_evt,
+                gpu_device_socket,
+                resource_bridges,
+                cfg.wayland_socket_path.clone(),
+                cfg.x_display.clone(),
+            )?);
         }
     }
 
diff --git a/src/main.rs b/src/main.rs
index 1d18c3b..75d08ae 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -406,6 +406,14 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument::
         }
         #[cfg(feature = "wl-dmabuf")]
         "wayland-dmabuf" => cfg.wayland_dmabuf = true,
+        "x-display" => {
+            if cfg.x_display.is_some() {
+                return Err(argument::Error::TooManyArguments(
+                    "`x-display` already given".to_owned(),
+                ));
+            }
+            cfg.x_display = Some(value.unwrap().to_owned());
+        }
         "socket" => {
             if cfg.socket_path.is_some() {
                 return Err(argument::Error::TooManyArguments(
@@ -728,6 +736,7 @@ fn run_vm(args: std::env::Args) -> std::result::Result<(), ()> {
                           stdin - Direct standard input to this serial device. Can only be given once. Will default to first serial port if not provided.
                           "),
           Argument::value("syslog-tag", "TAG", "When logging to syslog, use the provided tag."),
+          Argument::value("x-display", "DISPLAY", "X11 display name to use."),
           Argument::value("wayland-sock", "PATH", "Path to the Wayland socket to use."),
           #[cfg(feature = "wl-dmabuf")]
           Argument::flag("wayland-dmabuf", "Enable support for DMABufs in Wayland device."),