summary refs log tree commit diff
path: root/hypervisor
diff options
context:
space:
mode:
authorUdam Saini <udam@google.com>2020-04-30 13:46:40 -0700
committerCommit Bot <commit-bot@chromium.org>2020-05-03 22:01:30 +0000
commit6fe08fa36338ee6339dd4748173865763bfc7b31 (patch)
tree0e5290eefc71e7129db56bf8369b72f54275a0f3 /hypervisor
parentf990be36d06bd2826482184f6b2b8c9b3fc4c49b (diff)
downloadcrosvm-6fe08fa36338ee6339dd4748173865763bfc7b31.tar
crosvm-6fe08fa36338ee6339dd4748173865763bfc7b31.tar.gz
crosvm-6fe08fa36338ee6339dd4748173865763bfc7b31.tar.bz2
crosvm-6fe08fa36338ee6339dd4748173865763bfc7b31.tar.lz
crosvm-6fe08fa36338ee6339dd4748173865763bfc7b31.tar.xz
crosvm-6fe08fa36338ee6339dd4748173865763bfc7b31.tar.zst
crosvm-6fe08fa36338ee6339dd4748173865763bfc7b31.zip
Adding hypervisor crate to abstract out Kvm implementation
This is a separate hypervisor crate for interacting with Kvm in an
abstract manner. The intention is to not leak the internals of kvm
with its specific calls in various places in the codebase. Currently,
this just creates an initial structure for adding various
implementations over time.

In addition, a SafeDescriptor class is added, that wraps a raw file
descriptor safely, without needing to wrap it in the rust file class.
The intention is to use this for non file raw descriptors.

BUG=chromium:1077058
TEST=added a basic kvm test that creates a Kvm struct

Change-Id: I4229203902e480b52435cde12bf0d25a322c71be
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2174756
Commit-Queue: Udam Saini <udam@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'hypervisor')
-rw-r--r--hypervisor/Cargo.toml10
-rw-r--r--hypervisor/src/caps.rs6
-rw-r--r--hypervisor/src/kvm/mod.rs62
-rw-r--r--hypervisor/src/lib.rs25
-rw-r--r--hypervisor/src/types/mod.rs9
-rw-r--r--hypervisor/src/types/x86.rs10
6 files changed, 122 insertions, 0 deletions
diff --git a/hypervisor/Cargo.toml b/hypervisor/Cargo.toml
new file mode 100644
index 0000000..de82105
--- /dev/null
+++ b/hypervisor/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "hypervisor"
+version = "0.1.0"
+authors = ["The Chromium OS Authors"]
+edition = "2018"
+
+[dependencies]
+libc = "*"
+kvm_sys = { path = "../kvm_sys" }
+sys_util = { path = "../sys_util" }
\ No newline at end of file
diff --git a/hypervisor/src/caps.rs b/hypervisor/src/caps.rs
new file mode 100644
index 0000000..d088ca7
--- /dev/null
+++ b/hypervisor/src/caps.rs
@@ -0,0 +1,6 @@
+// Copyright 2020 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.
+
+/// An enumeration of different hypervisor capabilities.
+pub enum HypervisorCap {}
diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs
new file mode 100644
index 0000000..7058921
--- /dev/null
+++ b/hypervisor/src/kvm/mod.rs
@@ -0,0 +1,62 @@
+// Copyright 2020 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 super::{CpuId, Hypervisor, HypervisorCap};
+use libc::{open, O_CLOEXEC, O_RDWR};
+use std::os::raw::c_char;
+use sys_util::{
+    errno_result, AsRawDescriptor, FromRawDescriptor, RawDescriptor, Result, SafeDescriptor,
+};
+
+pub struct Kvm {
+    kvm: SafeDescriptor,
+}
+
+impl Kvm {
+    /// Opens `/dev/kvm/` and returns a Kvm object on success.
+    pub fn new() -> Result<Kvm> {
+        // Open calls are safe because we give a constant nul-terminated string and verify the
+        // result.
+        let ret = unsafe { open("/dev/kvm\0".as_ptr() as *const c_char, O_RDWR | O_CLOEXEC) };
+        if ret < 0 {
+            return errno_result();
+        }
+        // Safe because we verify that ret is valid and we own the fd.
+        Ok(Kvm {
+            kvm: unsafe { SafeDescriptor::from_raw_descriptor(ret) },
+        })
+    }
+}
+
+impl AsRawDescriptor for Kvm {
+    fn as_raw_descriptor(&self) -> RawDescriptor {
+        self.kvm.as_raw_descriptor()
+    }
+}
+
+impl Hypervisor for Kvm {
+    fn check_capability(&self, _cap: &HypervisorCap) -> bool {
+        unimplemented!("check_capability for Kvm is not yet implemented");
+    }
+
+    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+    fn get_supported_cpuid(&self) -> Result<CpuId> {
+        unimplemented!("get_supported_cpuid for Kvm is not yet implemented");
+    }
+
+    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+    fn get_emulated_cpuid(&self) -> Result<CpuId> {
+        unimplemented!("get_emulated_cpuid for Kvm is not yet implemented");
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::Kvm;
+
+    #[test]
+    fn new() {
+        Kvm::new().unwrap();
+    }
+}
diff --git a/hypervisor/src/lib.rs b/hypervisor/src/lib.rs
new file mode 100644
index 0000000..056070b
--- /dev/null
+++ b/hypervisor/src/lib.rs
@@ -0,0 +1,25 @@
+// Copyright 2020 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.
+
+//! A crate for abstracting the underlying kernel hypervisor used in crosvm.
+pub mod caps;
+pub mod kvm;
+pub mod types;
+
+use sys_util::Result;
+
+pub use crate::caps::*;
+pub use crate::types::*;
+
+/// A trait for managing the underlying cpu information for the hypervisor and to check its capabilities.
+trait Hypervisor {
+    // Checks if a particular `HypervisorCap` is available.
+    fn check_capability(&self, cap: &HypervisorCap) -> bool;
+    // Get the system supported CPUID values.
+    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+    fn get_supported_cpuid(&self) -> Result<CpuId>;
+    // Get the system emulated CPUID values.
+    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+    fn get_emulated_cpuid(&self) -> Result<CpuId>;
+}
diff --git a/hypervisor/src/types/mod.rs b/hypervisor/src/types/mod.rs
new file mode 100644
index 0000000..69fa9e4
--- /dev/null
+++ b/hypervisor/src/types/mod.rs
@@ -0,0 +1,9 @@
+// Copyright 2020 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.
+
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+pub mod x86;
+
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+pub use self::x86::*;
diff --git a/hypervisor/src/types/x86.rs b/hypervisor/src/types/x86.rs
new file mode 100644
index 0000000..cd5236a
--- /dev/null
+++ b/hypervisor/src/types/x86.rs
@@ -0,0 +1,10 @@
+// Copyright 2020 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 kvm_sys::kvm_cpuid_entry2;
+
+pub type CpuIdEntry = kvm_cpuid_entry2;
+pub struct CpuId {
+    _cpu_id_entries: Vec<CpuIdEntry>,
+}