summary refs log tree commit diff
diff options
context:
space:
mode:
authorGurchetan Singh <gurchetansingh@chromium.org>2019-05-15 15:30:38 -0700
committerchrome-bot <chrome-bot@chromium.org>2019-05-28 21:11:21 -0700
commit7ec58fafbace41df54b439f9239edc9e9e12d3b7 (patch)
treefd6937cbe9294a5c864f14d8d8d7119218d7617d
parent6c1e23eee3065b3f3d6fc4fb992ac9884dbabf68 (diff)
downloadcrosvm-7ec58fafbace41df54b439f9239edc9e9e12d3b7.tar
crosvm-7ec58fafbace41df54b439f9239edc9e9e12d3b7.tar.gz
crosvm-7ec58fafbace41df54b439f9239edc9e9e12d3b7.tar.bz2
crosvm-7ec58fafbace41df54b439f9239edc9e9e12d3b7.tar.lz
crosvm-7ec58fafbace41df54b439f9239edc9e9e12d3b7.tar.xz
crosvm-7ec58fafbace41df54b439f9239edc9e9e12d3b7.tar.zst
crosvm-7ec58fafbace41df54b439f9239edc9e9e12d3b7.zip
virtio-gpu: add gpu control socket
The GPU process will need access to KVM.

BUG=chromium:924405
TEST=compile

Change-Id: I9e454d79a36a40a20c6c4b3a62ea367f339e526b
Reviewed-on: https://chromium-review.googlesource.com/1626793
Commit-Ready: Gurchetan Singh <gurchetansingh@chromium.org>
Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: David Riley <davidriley@chromium.org>
-rw-r--r--devices/src/virtio/gpu/backend.rs11
-rw-r--r--devices/src/virtio/gpu/mod.rs132
-rw-r--r--src/linux.rs3
3 files changed, 87 insertions, 59 deletions
diff --git a/devices/src/virtio/gpu/backend.rs b/devices/src/virtio/gpu/backend.rs
index cda00ce..e53adb3 100644
--- a/devices/src/virtio/gpu/backend.rs
+++ b/devices/src/virtio/gpu/backend.rs
@@ -27,6 +27,7 @@ use super::protocol::{
     GpuResponse, GpuResponsePlaneInfo, VIRTIO_GPU_CAPSET_VIRGL, VIRTIO_GPU_CAPSET_VIRGL2,
 };
 use crate::virtio::resource_bridge::*;
+use vm_control::VmMemoryControlRequestSocket;
 
 const DEFAULT_WIDTH: u32 = 1280;
 const DEFAULT_HEIGHT: u32 = 1024;
@@ -314,6 +315,8 @@ pub struct Backend {
     renderer: Renderer,
     resources: Map<u32, Box<dyn VirglResource>>,
     contexts: Map<u32, RendererContext>,
+    #[allow(dead_code)]
+    gpu_device_socket: VmMemoryControlRequestSocket,
     scanout_surface: Option<u32>,
     cursor_surface: Option<u32>,
     scanout_resource: u32,
@@ -324,11 +327,17 @@ impl Backend {
     /// Creates a new backend for virtio-gpu that realizes all commands using the given `device` for
     /// allocating buffers, `display` for showing the results, and `renderer` for submitting
     /// rendering commands.
-    pub fn new(device: Device, display: GpuDisplay, renderer: Renderer) -> Backend {
+    pub fn new(
+        device: Device,
+        display: GpuDisplay,
+        renderer: Renderer,
+        gpu_device_socket: VmMemoryControlRequestSocket,
+    ) -> Backend {
         Backend {
             display: Rc::new(RefCell::new(display)),
             device,
             renderer,
+            gpu_device_socket,
             resources: Default::default(),
             contexts: Default::default(),
             scanout_surface: None,
diff --git a/devices/src/virtio/gpu/mod.rs b/devices/src/virtio/gpu/mod.rs
index e8fb49f..cc42ace 100644
--- a/devices/src/virtio/gpu/mod.rs
+++ b/devices/src/virtio/gpu/mod.rs
@@ -36,6 +36,8 @@ use self::backend::Backend;
 use self::protocol::*;
 use crate::pci::{PciBarConfiguration, PciBarPrefetchable, PciBarRegionType};
 
+use vm_control::VmMemoryControlRequestSocket;
+
 // First queue is for virtio gpu commands. Second queue is for cursor commands, which we expect
 // there to be fewer of.
 const QUEUE_SIZES: &[u16] = &[256, 16];
@@ -601,6 +603,7 @@ impl Worker {
 pub struct Gpu {
     config_event: bool,
     exit_evt: EventFd,
+    gpu_device_socket: Option<VmMemoryControlRequestSocket>,
     resource_bridge: Option<ResourceResponseSocket>,
     kill_evt: Option<EventFd>,
     wayland_socket_path: PathBuf,
@@ -609,12 +612,14 @@ pub struct Gpu {
 impl Gpu {
     pub fn new<P: AsRef<Path>>(
         exit_evt: EventFd,
+        gpu_device_socket: Option<VmMemoryControlRequestSocket>,
         resource_bridge: Option<ResourceResponseSocket>,
         wayland_socket_path: P,
     ) -> Gpu {
         Gpu {
             config_event: false,
             exit_evt,
+            gpu_device_socket,
             resource_bridge,
             kill_evt: None,
             wayland_socket_path: wayland_socket_path.as_ref().to_path_buf(),
@@ -653,6 +658,11 @@ impl VirtioDevice for Gpu {
             keep_fds.push(libc::STDOUT_FILENO);
             keep_fds.push(libc::STDERR_FILENO);
         }
+
+        if let Some(ref gpu_device_socket) = self.gpu_device_socket {
+            keep_fds.push(gpu_device_socket.as_raw_fd());
+        }
+
         keep_fds.push(self.exit_evt.as_raw_fd());
         if let Some(resource_bridge) = &self.resource_bridge {
             keep_fds.push(resource_bridge.as_raw_fd());
@@ -736,70 +746,78 @@ impl VirtioDevice for Gpu {
         let cursor_queue = queues.remove(0);
         let cursor_evt = queue_evts.remove(0);
         let socket_path = self.wayland_socket_path.clone();
-        let worker_result =
-            thread::Builder::new()
-                .name("virtio_gpu".to_string())
-                .spawn(move || {
-                    const UNDESIRED_CARDS: &[&str] = &["vgem", "pvr"];
-                    let drm_card = match gpu_buffer::rendernode::open_device(UNDESIRED_CARDS) {
-                        Ok(f) => f,
-                        Err(()) => {
-                            error!("failed to open card");
-                            return;
-                        }
-                    };
+        if let Some(gpu_device_socket) = self.gpu_device_socket.take() {
+            let worker_result =
+                thread::Builder::new()
+                    .name("virtio_gpu".to_string())
+                    .spawn(move || {
+                        const UNDESIRED_CARDS: &[&str] = &["vgem", "pvr"];
+                        let drm_card = match gpu_buffer::rendernode::open_device(UNDESIRED_CARDS) {
+                            Ok(f) => f,
+                            Err(()) => {
+                                error!("failed to open card");
+                                return;
+                            }
+                        };
 
-                    let device = match Device::new(drm_card) {
-                        Ok(d) => d,
-                        Err(()) => {
-                            error!("failed to open device");
-                            return;
-                        }
-                    };
+                        let device = match Device::new(drm_card) {
+                            Ok(d) => d,
+                            Err(()) => {
+                                error!("failed to open device");
+                                return;
+                            }
+                        };
 
-                    let display = match GpuDisplay::new(socket_path) {
-                        Ok(c) => c,
-                        Err(e) => {
-                            error!("failed to open display: {}", e);
-                            return;
-                        }
-                    };
+                        let display = match GpuDisplay::new(socket_path) {
+                            Ok(c) => c,
+                            Err(e) => {
+                                error!("failed to open display: {}", e);
+                                return;
+                            }
+                        };
 
-                    if cfg!(debug_assertions) {
-                        let ret = unsafe { libc::dup2(libc::STDOUT_FILENO, libc::STDERR_FILENO) };
-                        if ret == -1 {
-                            warn!("unable to dup2 stdout to stderr: {}", Error::last());
+                        if cfg!(debug_assertions) {
+                            let ret =
+                                unsafe { libc::dup2(libc::STDOUT_FILENO, libc::STDERR_FILENO) };
+                            if ret == -1 {
+                                warn!("unable to dup2 stdout to stderr: {}", Error::last());
+                            }
                         }
-                    }
 
-                    let renderer = match Renderer::init() {
-                        Ok(r) => r,
-                        Err(e) => {
-                            error!("failed to initialize gpu renderer: {}", e);
-                            return;
+                        let renderer = match Renderer::init() {
+                            Ok(r) => r,
+                            Err(e) => {
+                                error!("failed to initialize gpu renderer: {}", e);
+                                return;
+                            }
+                        };
+
+                        Worker {
+                            exit_evt,
+                            mem,
+                            interrupt_evt,
+                            interrupt_resample_evt,
+                            interrupt_status,
+                            ctrl_queue,
+                            ctrl_evt,
+                            cursor_queue,
+                            cursor_evt,
+                            resource_bridge,
+                            kill_evt,
+                            state: Frontend::new(Backend::new(
+                                device,
+                                display,
+                                renderer,
+                                gpu_device_socket,
+                            )),
                         }
-                    };
-
-                    Worker {
-                        exit_evt,
-                        mem,
-                        interrupt_evt,
-                        interrupt_resample_evt,
-                        interrupt_status,
-                        ctrl_queue,
-                        ctrl_evt,
-                        cursor_queue,
-                        cursor_evt,
-                        resource_bridge,
-                        kill_evt,
-                        state: Frontend::new(Backend::new(device, display, renderer)),
-                    }
-                    .run()
-                });
+                        .run()
+                    });
 
-        if let Err(e) = worker_result {
-            error!("failed to spawn virtio_gpu worker: {}", e);
-            return;
+            if let Err(e) = worker_result {
+                error!("failed to spawn virtio_gpu worker: {}", e);
+                return;
+            }
         }
     }
 
diff --git a/src/linux.rs b/src/linux.rs
index b5235d1..78942ea 100644
--- a/src/linux.rs
+++ b/src/linux.rs
@@ -535,7 +535,7 @@ fn create_net_device(
 fn create_gpu_device(
     cfg: &Config,
     exit_evt: &EventFd,
-    _gpu_device_socket: VmMemoryControlRequestSocket,
+    gpu_device_socket: VmMemoryControlRequestSocket,
     gpu_socket: virtio::resource_bridge::ResourceResponseSocket,
     wayland_socket_path: &Path,
 ) -> DeviceResult {
@@ -543,6 +543,7 @@ fn create_gpu_device(
 
     let dev = virtio::Gpu::new(
         exit_evt.try_clone().map_err(Error::CloneEventFd)?,
+        Some(gpu_device_socket),
         Some(gpu_socket),
         if cfg.sandbox {
             &jailed_wayland_path