diff options
author | Dmitry Torokhov <dtor@chromium.org> | 2019-01-17 12:04:18 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-01-22 21:05:18 -0800 |
commit | 5d471b454a04dbb38e8338017b204f1a403aadb9 (patch) | |
tree | 7e90183b312c620c3b620a3aeb4b8e2198728387 /kvm | |
parent | b6d842fa56f0ccb9e5084d0e06100c53170d46f7 (diff) | |
download | crosvm-5d471b454a04dbb38e8338017b204f1a403aadb9.tar crosvm-5d471b454a04dbb38e8338017b204f1a403aadb9.tar.gz crosvm-5d471b454a04dbb38e8338017b204f1a403aadb9.tar.bz2 crosvm-5d471b454a04dbb38e8338017b204f1a403aadb9.tar.lz crosvm-5d471b454a04dbb38e8338017b204f1a403aadb9.tar.xz crosvm-5d471b454a04dbb38e8338017b204f1a403aadb9.tar.zst crosvm-5d471b454a04dbb38e8338017b204f1a403aadb9.zip |
kvm: plumb accessors for KVM_GET_CLOCK/KVM_SET_CLOCK
Plumb in KVM_GET_CLOCK and KVM_SET_CLOCK to allow clients synchronize timers handled by KVM (LAPIC, PIT) with timers handled by the virtual device layer. BUG=b:122878975 TEST=cargo test -p kvm Change-Id: I2f8867918b82f8ac303e6b60fce2736e38ce2883 Signed-off-by: Dmitry Torokhov <dtor@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1419372 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'kvm')
-rw-r--r-- | kvm/src/lib.rs | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/kvm/src/lib.rs b/kvm/src/lib.rs index beaad55..65c4ee5 100644 --- a/kvm/src/lib.rs +++ b/kvm/src/lib.rs @@ -486,6 +486,37 @@ impl Vm { } } + /// Retrieves the current timestamp of kvmclock as seen by the current guest. + /// + /// See the documentation on the KVM_GET_CLOCK ioctl. + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + pub fn get_clock(&self) -> Result<kvm_clock_data> { + // Safe because we know that our file is a VM fd, we know the kernel will only write + // correct amount of memory to our pointer, and we verify the return result. + let mut clock_data = unsafe { std::mem::zeroed() }; + let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_CLOCK(), &mut clock_data) }; + if ret == 0 { + Ok(clock_data) + } else { + errno_result() + } + } + + /// Sets the current timestamp of kvmclock to the specified value. + /// + /// See the documentation on the KVM_SET_CLOCK ioctl. + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + pub fn set_clock(&self, clock_data: &kvm_clock_data) -> Result<()> { + // Safe because we know that our file is a VM fd, we know the kernel will only read + // correct amount of memory from our pointer, and we verify the return result. + let ret = unsafe { ioctl_with_ref(self, KVM_SET_CLOCK(), clock_data) }; + if ret == 0 { + Ok(()) + } else { + errno_result() + } + } + /// Crates an in kernel interrupt controller. /// /// See the documentation on the KVM_CREATE_IRQCHIP ioctl. @@ -1675,6 +1706,17 @@ mod tests { } #[test] + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + fn clock_handling() { + let kvm = Kvm::new().unwrap(); + let gm = GuestMemory::new(&vec![(GuestAddress(0), 0x10000)]).unwrap(); + let vm = Vm::new(&kvm, gm).unwrap(); + let mut clock_data = vm.get_clock().unwrap(); + clock_data.clock += 1000; + vm.set_clock(&clock_data).unwrap(); + } + + #[test] fn pic_handling() { let kvm = Kvm::new().unwrap(); let gm = GuestMemory::new(&vec![(GuestAddress(0), 0x10000)]).unwrap(); |