summary refs log tree commit diff
path: root/src/guest
diff options
context:
space:
mode:
Diffstat (limited to 'src/guest')
-rw-r--r--src/guest/wl.rs183
1 files changed, 183 insertions, 0 deletions
diff --git a/src/guest/wl.rs b/src/guest/wl.rs
new file mode 100644
index 0000000..e273246
--- /dev/null
+++ b/src/guest/wl.rs
@@ -0,0 +1,183 @@
+// Copyright 2017 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+use devices::virtio::remote::RemotePciCapability;
+use devices::virtio::virtualized::{Request, Response};
+use devices::virtio::{
+    InterruptProxy, InterruptProxyEvent, Params, VirtioDevice, VirtioDeviceNew, Wl,
+};
+use msg_socket::MsgSocket;
+use std::collections::BTreeMap;
+use std::fs::remove_file;
+use std::io::prelude::*;
+use std::io::stdout;
+use std::os::unix::prelude::*;
+use std::process;
+use sys_util::{error, net::UnixSeqpacketListener, GuestMemory};
+use vm_control::MaybeOwnedFd;
+
+#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
+pub use aarch64::arch_memory_regions;
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+pub use x86_64::arch_memory_regions;
+
+type Socket = msg_socket2::Socket<Response, Request>;
+
+fn main() {
+    eprintln!("hello world");
+
+    // Create and display the socket.
+    let mut path = std::env::var_os("XDG_RUNTIME_DIR").expect("XDG_RUNTIME_DIR missing");
+    path.push("/crosvm_wl-");
+    path.push(process::id().to_string());
+    path.push(".sock");
+    let _ = remove_file(&path);
+    let server = UnixSeqpacketListener::bind(&path).expect("failed to create control socket");
+    match stdout().write_all(path.as_bytes()) {
+        Ok(()) => println!(),
+        Err(e) => eprintln!("{}", e),
+    }
+
+    // Receive connection from crosvm.
+    let conn = server.accept().expect("accept failed");
+    let msg_socket: Socket = msg_socket2::Socket::new(conn);
+
+    let (memory_params, ext_socket) = match msg_socket.recv() {
+        Ok(Request::Create {
+            memory_params,
+            ext_socket,
+        }) => (memory_params, ext_socket),
+
+        Ok(msg) => {
+            panic!("received unexpected message: {:?}", msg);
+        }
+
+        Err(e) => {
+            panic!("recv error: {}", e);
+        }
+    };
+
+    let mut wayland_paths = BTreeMap::new();
+    wayland_paths.insert("".into(), "/run/user/1000/wayland-0".into());
+
+    let mut wl = Wl::new(Params {
+        wayland_paths,
+        vm_socket: MsgSocket::new(ext_socket),
+        resource_bridge: None,
+    })
+    .unwrap();
+
+    loop {
+        match dbg!(msg_socket.recv()) {
+            Ok(Request::DebugLabel) => {
+                let result = wl.debug_label();
+                if let Err(e) = msg_socket.send(Response::DebugLabel(result)) {
+                    panic!("responding to DebugLabel failed: {}", e);
+                }
+            }
+
+            Ok(Request::DeviceType) => {
+                let result = wl.device_type();
+                if let Err(e) = msg_socket.send(Response::DeviceType(result)) {
+                    panic!("responding to DeviceType failed: {}", e);
+                }
+            }
+
+            Ok(Request::QueueMaxSizes) => {
+                let result = wl.queue_max_sizes();
+                if let Err(e) = msg_socket.send(dbg!(Response::QueueMaxSizes(result))) {
+                    panic!("responding to QueueMaxSizes failed: {}", e);
+                }
+            }
+
+            Ok(Request::Features) => {
+                let result = wl.features();
+                if let Err(e) = msg_socket.send(Response::Features(result)) {
+                    panic!("responding to Features failed: {}", e);
+                }
+            }
+
+            Ok(Request::AckFeatures(value)) => wl.ack_features(value),
+
+            Ok(Request::ReadConfig { offset, len }) => {
+                let mut data = vec![0; len];
+                wl.read_config(offset, &mut data);
+                if let Err(e) = msg_socket.send(Response::ReadConfig(data)) {
+                    panic!("responding to ReadConfig failed: {}", e);
+                }
+            }
+
+            Ok(Request::WriteConfig { offset, ref data }) => wl.write_config(offset, data),
+
+            Ok(Request::Activate {
+                shm,
+                interrupt,
+                interrupt_resample_evt,
+                queues,
+                queue_evts,
+            }) => {
+                let shm = shm.owned();
+
+                let regions = arch_memory_regions(memory_params);
+                let mem =
+                    GuestMemory::with_memfd(&regions, shm).expect("GuestMemory::with_memfd failed");
+
+                let interrupt: MsgSocket<InterruptProxyEvent, ()> =
+                    MsgSocket::new(interrupt.owned());
+
+                wl.activate(
+                    mem,
+                    Box::new(InterruptProxy::new(
+                        interrupt,
+                        interrupt_resample_evt.owned(),
+                    )),
+                    queues,
+                    queue_evts.into_iter().map(MaybeOwnedFd::owned).collect(),
+                );
+
+                println!("activated Wl");
+            }
+
+            Ok(Request::Reset) => {
+                let result = wl.reset();
+                if let Err(e) = msg_socket.send(dbg!(Response::Reset(result))) {
+                    panic!("responding to Reset failed: {}", e);
+                }
+            }
+
+            Ok(Request::GetDeviceBars(address)) => {
+                let result = wl.get_device_bars(address);
+                if let Err(e) = msg_socket.send(Response::GetDeviceBars(result)) {
+                    panic!("responding to GetDeviceBars failed: {}", e);
+                }
+            }
+
+            Ok(Request::GetDeviceCaps) => {
+                let result = wl
+                    .get_device_caps()
+                    .into_iter()
+                    .map(|c| RemotePciCapability::from(&*c))
+                    .collect();
+                if let Err(e) = msg_socket.send(Response::GetDeviceCaps(result)) {
+                    panic!("responding to GetDeviceCaps failed: {}", e);
+                }
+            }
+
+            Ok(Request::Kill) => {
+                // Will block until worker shuts down.
+                drop(wl);
+
+                if let Err(e) = msg_socket.send(Response::Kill) {
+                    error!("responding to Kill failed: {}", e);
+                }
+
+                break;
+            }
+
+            Ok(msg @ Request::Create { .. }) => panic!("unexpected message {:?}", msg),
+
+            Err(e) => panic!("recv failed: {}", e),
+        }
+    }
+}