mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-05 18:20:34 +00:00
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>
This commit is contained in:
parent
b6d842fa56
commit
5d471b454a
1 changed files with 42 additions and 0 deletions
|
@ -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.
|
||||
|
@ -1674,6 +1705,17 @@ mod tests {
|
|||
assert_eq!(read_val, 67u8);
|
||||
}
|
||||
|
||||
#[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();
|
||||
|
|
Loading…
Reference in a new issue