summary refs log tree commit diff
path: root/kvm
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor@chromium.org>2018-03-26 17:14:19 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-03-29 22:00:14 -0700
commit4757cf164b4a9b00e686326fbddaafa598686d6c (patch)
tree8bc803b21fd57924caeb17203c5fc181208df0dc /kvm
parentb2e528b5758bf852c2092dd5da9e680e66c8c1dd (diff)
downloadcrosvm-4757cf164b4a9b00e686326fbddaafa598686d6c.tar
crosvm-4757cf164b4a9b00e686326fbddaafa598686d6c.tar.gz
crosvm-4757cf164b4a9b00e686326fbddaafa598686d6c.tar.bz2
crosvm-4757cf164b4a9b00e686326fbddaafa598686d6c.tar.lz
crosvm-4757cf164b4a9b00e686326fbddaafa598686d6c.tar.xz
crosvm-4757cf164b4a9b00e686326fbddaafa598686d6c.tar.zst
crosvm-4757cf164b4a9b00e686326fbddaafa598686d6c.zip
kvm: plumb accessors for VCPU MP state
Plumb in KVM_GET_MP_STATE and KVM_SET_MP_STATE to allow saving and
restoring "multiprocessing state" of VCPUs.

BUG=b:76083711
TEST=cargo test -p kvm

Change-Id: Ia6e98a09c12dcc859196908f865fac57d48b2ddd
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/982372
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'kvm')
-rw-r--r--kvm/src/lib.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/kvm/src/lib.rs b/kvm/src/lib.rs
index 539a4a4..a585fff 100644
--- a/kvm/src/lib.rs
+++ b/kvm/src/lib.rs
@@ -1023,6 +1023,44 @@ impl Vcpu {
         Ok(())
     }
 
+    /// Gets the vcpu's current "multiprocessing state".
+    ///
+    /// See the documentation for KVM_GET_MP_STATE. This call can only succeed after
+    /// a call to `Vm::create_irq_chip`.
+    ///
+    /// Note that KVM defines the call for both x86 and s390 but we do not expect anyone
+    /// to run crosvm on s390.
+    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+    pub fn get_mp_state(&self) -> Result<kvm_mp_state> {
+        // Safe because we know that our file is a VCPU fd, we know the kernel will only
+        // write correct amount of memory to our pointer, and we verify the return result.
+        let mut state: kvm_mp_state = unsafe { std::mem::zeroed() };
+        let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_MP_STATE(), &mut state) };
+        if ret < 0 {
+            return errno_result();
+        }
+        Ok(state)
+    }
+
+    /// Sets the vcpu's current "multiprocessing state".
+    ///
+    /// See the documentation for KVM_SET_MP_STATE. This call can only succeed after
+    /// a call to `Vm::create_irq_chip`.
+    ///
+    /// Note that KVM defines the call for both x86 and s390 but we do not expect anyone
+    /// to run crosvm on s390.
+    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+    pub fn set_mp_state(&self, state: &kvm_mp_state) -> Result<()> {
+        let ret = unsafe {
+            // The ioctl is safe because the kernel will only read from the kvm_mp_state struct.
+            ioctl_with_ref(self, KVM_SET_MP_STATE(), state)
+        };
+        if ret < 0 {
+            return errno_result();
+        }
+        Ok(())
+    }
+
     /// Specifies set of signals that are blocked during execution of KVM_RUN.
     /// Signals that are not blocked will will cause KVM_RUN to return
     /// with -EINTR.
@@ -1417,6 +1455,17 @@ mod tests {
     }
 
     #[test]
+    fn mp_state() {
+        let kvm = Kvm::new().unwrap();
+        let gm = GuestMemory::new(&vec![(GuestAddress(0), 0x10000)]).unwrap();
+        let vm = Vm::new(&kvm, gm).unwrap();
+        vm.create_irq_chip().unwrap();
+        let vcpu = Vcpu::new(0, &kvm, &vm).unwrap();
+        let state = vcpu.get_mp_state().unwrap();
+        vcpu.set_mp_state(&state).unwrap();
+    }
+
+    #[test]
     fn set_signal_mask() {
         let kvm = Kvm::new().unwrap();
         let gm = GuestMemory::new(&vec![(GuestAddress(0), 0x10000)]).unwrap();