summary refs log tree commit diff
path: root/vhost
diff options
context:
space:
mode:
authorChirantan Ekbote <chirantan@chromium.org>2017-08-28 09:51:18 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-09-18 16:48:43 -0700
commit88f9cba448ff7f1cd61c8bf66e34772132a8663f (patch)
treebe3a916b0991914a841ef51cbc487e07dacacf89 /vhost
parent270f7b6a16a1c0475da061d5ecb344db10306a64 (diff)
downloadcrosvm-88f9cba448ff7f1cd61c8bf66e34772132a8663f.tar
crosvm-88f9cba448ff7f1cd61c8bf66e34772132a8663f.tar.gz
crosvm-88f9cba448ff7f1cd61c8bf66e34772132a8663f.tar.bz2
crosvm-88f9cba448ff7f1cd61c8bf66e34772132a8663f.tar.lz
crosvm-88f9cba448ff7f1cd61c8bf66e34772132a8663f.tar.xz
crosvm-88f9cba448ff7f1cd61c8bf66e34772132a8663f.tar.zst
crosvm-88f9cba448ff7f1cd61c8bf66e34772132a8663f.zip
Implement virtio-vsock
Implement the virtual sockets device using vhost subsystem of the host
kernel to handle data transfer.

BUG=chromium:708267
TEST=build and run maitred in guest VM without issue

Change-Id: I35b542c0fc7e0fd9296f7ba3e1dfce60bf524d15
Signed-off-by: Chirantan Ekbote <chirantan@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/638838
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Diffstat (limited to 'vhost')
-rw-r--r--vhost/src/lib.rs3
-rw-r--r--vhost/src/net.rs25
-rw-r--r--vhost/src/vsock.rs82
3 files changed, 94 insertions, 16 deletions
diff --git a/vhost/src/lib.rs b/vhost/src/lib.rs
index b4282d2..4a103a2 100644
--- a/vhost/src/lib.rs
+++ b/vhost/src/lib.rs
@@ -8,7 +8,10 @@ extern crate sys_util;
 extern crate virtio_sys;
 
 pub mod net;
+mod vsock;
+
 pub use net::Net;
+pub use vsock::Vsock;
 
 use std::io::Error as IoError;
 use std::mem;
diff --git a/vhost/src/net.rs b/vhost/src/net.rs
index f7c5dfd..0c6eaad 100644
--- a/vhost/src/net.rs
+++ b/vhost/src/net.rs
@@ -4,10 +4,9 @@
 
 use libc;
 use net_util;
-use std::ffi::CString;
-use std::fs::File;
-use std::io::Error as IoError;
-use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
+use std::fs::{File, OpenOptions};
+use std::os::unix::fs::OpenOptionsExt;
+use std::os::unix::io::{AsRawFd, RawFd};
 use virtio_sys;
 
 use sys_util::{ioctl_with_ref, GuestMemory};
@@ -43,19 +42,13 @@ impl Net {
     /// # Arguments
     /// * `mem` - Guest memory mapping.
     pub fn new(mem: &GuestMemory) -> Result<Net> {
-        // Open calls are safe because we give a constant nul-terminated
-        // string and verify the result.  The CString unwrap is safe because
-        // DEVICE does not have any embedded '\0' characters.
-        let fd = unsafe {
-            libc::open(CString::new(DEVICE).unwrap().as_ptr(),
-                       libc::O_RDWR | libc::O_NONBLOCK | libc::O_CLOEXEC)
-        };
-        if fd < 0 {
-            return Err(Error::VhostOpen(IoError::last_os_error()));
-        }
         Ok(Net {
-            // There are no other users of this fd, so this is safe.
-            fd: unsafe { File::from_raw_fd(fd) },
+            fd: OpenOptions::new()
+                .read(true)
+                .write(true)
+                .custom_flags(libc::O_CLOEXEC | libc::O_NONBLOCK)
+                .open(DEVICE)
+                .map_err(Error::VhostOpen)?,
             mem: mem.clone(),
         })
     }
diff --git a/vhost/src/vsock.rs b/vhost/src/vsock.rs
new file mode 100644
index 0000000..8c96b9f
--- /dev/null
+++ b/vhost/src/vsock.rs
@@ -0,0 +1,82 @@
+// 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 libc;
+use std::fs::{File, OpenOptions};
+use std::os::unix::fs::OpenOptionsExt;
+use std::os::unix::io::{AsRawFd, RawFd};
+
+use sys_util::{ioctl_with_ref, GuestMemory};
+use virtio_sys::{VHOST_VSOCK_SET_GUEST_CID, VHOST_VSOCK_SET_RUNNING};
+
+use super::{ioctl_result, Error, Result, Vhost};
+
+static DEVICE: &'static str = "/dev/vhost-vsock";
+
+/// Handle for running VHOST_VSOCK ioctls.
+pub struct Vsock {
+    fd: File,
+    mem: GuestMemory,
+}
+
+impl Vsock {
+    /// Open a handle to a new VHOST_VSOCK instance.
+    pub fn new(mem: &GuestMemory) -> Result<Vsock> {
+        Ok(Vsock {
+            fd: OpenOptions::new()
+                .read(true)
+                .write(true)
+                .custom_flags(libc::O_CLOEXEC | libc::O_NONBLOCK)
+                .open(DEVICE)
+                .map_err(Error::VhostOpen)?,
+            mem: mem.clone(),
+        })
+    }
+
+    /// Set the CID for the guest.  This number is used for routing all data destined for
+    /// programs
+    /// running in the guest.
+    ///
+    /// # Arguments
+    /// * `cid` - CID to assign to the guest
+    pub fn set_cid(&self, cid: u64) -> Result<()> {
+        let ret = unsafe { ioctl_with_ref(&self.fd, VHOST_VSOCK_SET_GUEST_CID(), &cid) };
+        if ret < 0 {
+            return ioctl_result();
+        }
+        Ok(())
+    }
+
+    /// Tell the VHOST driver to start performing data transfer.
+    pub fn start(&self) -> Result<()> {
+        self.set_running(true)
+    }
+
+    /// Tell the VHOST driver to stop performing data transfer.
+    pub fn stop(&self) -> Result<()> {
+        self.set_running(false)
+    }
+
+    fn set_running(&self, running: bool) -> Result<()> {
+        let on: ::std::os::raw::c_int = if running { 1 } else { 0 };
+        let ret = unsafe { ioctl_with_ref(&self.fd, VHOST_VSOCK_SET_RUNNING(), &on) };
+
+        if ret < 0 {
+            return ioctl_result();
+        }
+        Ok(())
+    }
+}
+
+impl Vhost for Vsock {
+    fn mem(&self) -> &GuestMemory {
+        &self.mem
+    }
+}
+
+impl AsRawFd for Vsock {
+    fn as_raw_fd(&self) -> RawFd {
+        self.fd.as_raw_fd()
+    }
+}