summary refs log tree commit diff
path: root/kvm/src/lib.rs
diff options
context:
space:
mode:
authorZach Reizner <zachr@google.com>2018-01-31 12:54:51 -0800
committerchrome-bot <chrome-bot@chromium.org>2018-02-12 22:42:35 -0800
commit53528e33eda615ef309915447b227d2dcacb2090 (patch)
tree3a6e80a92de761df09a96ad0596b7982d8f463aa /kvm/src/lib.rs
parentbb678718926888701eb17f1ba1c5721592d7f881 (diff)
downloadcrosvm-53528e33eda615ef309915447b227d2dcacb2090.tar
crosvm-53528e33eda615ef309915447b227d2dcacb2090.tar.gz
crosvm-53528e33eda615ef309915447b227d2dcacb2090.tar.bz2
crosvm-53528e33eda615ef309915447b227d2dcacb2090.tar.lz
crosvm-53528e33eda615ef309915447b227d2dcacb2090.tar.xz
crosvm-53528e33eda615ef309915447b227d2dcacb2090.tar.zst
crosvm-53528e33eda615ef309915447b227d2dcacb2090.zip
add support for accessing debug registers in the plugin process
The debug registers are useful to access for the plugin process in some
cases.

TEST=cargo test --features plugin; cargo test -p kvm; ./build_test
BUG=chromium:800626

Change-Id: I8f3f6c31c6989061a43cef948cf5b4e64bd52d30
Reviewed-on: https://chromium-review.googlesource.com/896945
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'kvm/src/lib.rs')
-rw-r--r--kvm/src/lib.rs40
1 files changed, 40 insertions, 0 deletions
diff --git a/kvm/src/lib.rs b/kvm/src/lib.rs
index 8f977af..82e8939 100644
--- a/kvm/src/lib.rs
+++ b/kvm/src/lib.rs
@@ -804,6 +804,32 @@ impl Vcpu {
         Ok(())
     }
 
+    /// Gets the VCPU debug registers.
+    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+    pub fn get_debugregs(&self) -> Result<kvm_debugregs> {
+        // Safe because we know that our file is a VCPU fd, we know the kernel will only write the
+        // correct amount of memory to our pointer, and we verify the return result.
+        let mut regs = unsafe { std::mem::zeroed() };
+        let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_DEBUGREGS(), &mut regs) };
+        if ret != 0 {
+            return errno_result();
+        }
+        Ok(regs)
+    }
+
+    /// Sets the VCPU debug registers
+    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+    pub fn set_debugregs(&self, dregs: &kvm_debugregs) -> Result<()> {
+        let ret = unsafe {
+            // Here we trust the kernel not to read past the end of the kvm_fpu struct.
+            ioctl_with_ref(self, KVM_SET_DEBUGREGS(), dregs)
+        };
+        if ret < 0 {
+            return errno_result();
+        }
+        Ok(())
+    }
+
     /// X86 specific call to setup the MSRS
     ///
     /// See the documentation for KVM_SET_MSRS.
@@ -1144,6 +1170,20 @@ mod tests {
     }
 
     #[test]
+    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+    fn debugregs() {
+        let kvm = Kvm::new().unwrap();
+        let gm = GuestMemory::new(&vec![(GuestAddress(0), 0x10000)]).unwrap();
+        let vm = Vm::new(&kvm, gm).unwrap();
+        let vcpu = Vcpu::new(0, &kvm, &vm).unwrap();
+        let mut dregs = vcpu.get_debugregs().unwrap();
+        dregs.dr7 = 13;
+        vcpu.set_debugregs(&dregs).unwrap();
+        let dregs2 = vcpu.get_debugregs().unwrap();
+        assert_eq!(dregs.dr7, dregs2.dr7);
+    }
+
+    #[test]
     fn vcpu_mmap_size() {
         let kvm = Kvm::new().unwrap();
         let mmap_size = kvm.get_vcpu_mmap_size().unwrap();