diff options
author | Dmitry Torokhov <dtor@chromium.org> | 2019-01-17 16:20:33 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-01-22 21:05:18 -0800 |
commit | 2c7e88199ea4f7e8a9486c1c76ecaeababad4d49 (patch) | |
tree | 814f2b2a341f34917b5492a7832771fd883a2575 | |
parent | 5d471b454a04dbb38e8338017b204f1a403aadb9 (diff) | |
download | crosvm-2c7e88199ea4f7e8a9486c1c76ecaeababad4d49.tar crosvm-2c7e88199ea4f7e8a9486c1c76ecaeababad4d49.tar.gz crosvm-2c7e88199ea4f7e8a9486c1c76ecaeababad4d49.tar.bz2 crosvm-2c7e88199ea4f7e8a9486c1c76ecaeababad4d49.tar.lz crosvm-2c7e88199ea4f7e8a9486c1c76ecaeababad4d49.tar.xz crosvm-2c7e88199ea4f7e8a9486c1c76ecaeababad4d49.tar.zst crosvm-2c7e88199ea4f7e8a9486c1c76ecaeababad4d49.zip |
plugin: allow retrieving and setting VM clock
Add crossvm plugin API to allow reading and setting guest clock. BUG=b:122878975 TEST=cargo test -p kvm; cargo test --features=plugin Change-Id: I3fd656c06b0e7e43ac88a337ac5d0caec8c59dba Signed-off-by: Dmitry Torokhov <dtor@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1419373 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Zach Reizner <zachr@chromium.org>
-rw-r--r-- | Cargo.lock | 10 | ||||
-rw-r--r-- | crosvm_plugin/Cargo.toml | 2 | ||||
-rw-r--r-- | crosvm_plugin/crosvm.h | 9 | ||||
-rw-r--r-- | crosvm_plugin/src/lib.rs | 31 | ||||
-rw-r--r-- | plugin_proto/Cargo.toml | 2 | ||||
-rw-r--r-- | plugin_proto/protos/plugin.proto | 2 | ||||
-rw-r--r-- | src/plugin/process.rs | 11 | ||||
-rw-r--r-- | tests/plugin_vm_state.c | 28 |
8 files changed, 84 insertions, 11 deletions
diff --git a/Cargo.lock b/Cargo.lock index d43e449..86ba831 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,7 +73,7 @@ dependencies = [ "arch 0.1.0", "bit_field 0.1.0", "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crosvm_plugin 0.16.0", + "crosvm_plugin 0.17.0", "data_model 0.1.0", "devices 0.1.0", "gpu_buffer 0.1.0", @@ -86,7 +86,7 @@ dependencies = [ "msg_socket 0.1.0", "net_util 0.1.0", "p9 0.1.0", - "plugin_proto 0.16.0", + "plugin_proto 0.17.0", "protobuf 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "qcow 0.1.0", "rand_ish 0.1.0", @@ -101,12 +101,12 @@ dependencies = [ [[package]] name = "crosvm_plugin" -version = "0.16.0" +version = "0.17.0" dependencies = [ "kvm 0.1.0", "kvm_sys 0.1.0", "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", - "plugin_proto 0.16.0", + "plugin_proto 0.17.0", "protobuf 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "sys_util 0.1.0", ] @@ -281,7 +281,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "plugin_proto" -version = "0.16.0" +version = "0.17.0" dependencies = [ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "kvm_sys 0.1.0", diff --git a/crosvm_plugin/Cargo.toml b/crosvm_plugin/Cargo.toml index 9406912..2233b6d 100644 --- a/crosvm_plugin/Cargo.toml +++ b/crosvm_plugin/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "crosvm_plugin" -version = "0.16.0" +version = "0.17.0" authors = ["The Chromium OS Authors"] [lib] diff --git a/crosvm_plugin/crosvm.h b/crosvm_plugin/crosvm.h index 3f58739..81c8ade 100644 --- a/crosvm_plugin/crosvm.h +++ b/crosvm_plugin/crosvm.h @@ -47,7 +47,7 @@ extern "C" { * do not indicate anything about what version of crosvm is running. */ #define CROSVM_API_MAJOR 0 -#define CROSVM_API_MINOR 16 +#define CROSVM_API_MINOR 17 #define CROSVM_API_PATCH 0 enum crosvm_address_space { @@ -252,6 +252,13 @@ int crosvm_get_pit_state(struct crosvm *, struct kvm_pit_state2 *__pit_state); int crosvm_set_pit_state(struct crosvm *, const struct kvm_pit_state2 *__pit_state); +/* Gets the current timestamp of kvmclock as seen by the VM. */ +int crosvm_get_clock(struct crosvm *, struct kvm_clock_data *__clock_data); + +/* Sets the current timestamp of kvmclock for the VM. */ +int crosvm_set_clock(struct crosvm *, + const struct kvm_clock_data *__clock_data); + /* Sets the identity map address as in the KVM_SET_IDENTITY_MAP_ADDR ioctl. */ int crosvm_set_identity_map_addr(struct crosvm*, uint32_t __addr); diff --git a/crosvm_plugin/src/lib.rs b/crosvm_plugin/src/lib.rs index 8fd9623..ac6b358 100644 --- a/crosvm_plugin/src/lib.rs +++ b/crosvm_plugin/src/lib.rs @@ -45,8 +45,9 @@ use sys_util::ScmSocket; use kvm::dirty_log_bitmap_size; use kvm_sys::{ - kvm_cpuid_entry2, kvm_debugregs, kvm_fpu, kvm_ioapic_state, kvm_lapic_state, kvm_mp_state, - kvm_msr_entry, kvm_pic_state, kvm_pit_state2, kvm_regs, kvm_sregs, kvm_vcpu_events, kvm_xcrs, + kvm_clock_data, kvm_cpuid_entry2, kvm_debugregs, kvm_fpu, kvm_ioapic_state, kvm_lapic_state, + kvm_mp_state, kvm_msr_entry, kvm_pic_state, kvm_pit_state2, kvm_regs, kvm_sregs, + kvm_vcpu_events, kvm_xcrs, }; use plugin_proto::*; @@ -151,6 +152,8 @@ enum Stat { SetIoapicState, GetPitState, SetPitState, + GetClock, + SetClock, SetIdentityMapAddr, PauseVcpus, Start, @@ -1356,6 +1359,30 @@ pub unsafe extern "C" fn crosvm_set_pit_state( } #[no_mangle] +pub unsafe extern "C" fn crosvm_get_clock( + this: *mut crosvm, + clock_data: *mut kvm_clock_data, +) -> c_int { + let _u = STATS.record(Stat::GetClock); + let this = &mut *this; + let state = from_raw_parts_mut(clock_data as *mut u8, size_of::<kvm_clock_data>()); + let ret = this.get_state(MainRequest_StateSet::CLOCK, state); + to_crosvm_rc(ret) +} + +#[no_mangle] +pub unsafe extern "C" fn crosvm_set_clock( + this: *mut crosvm, + clock_data: *const kvm_clock_data, +) -> c_int { + let _u = STATS.record(Stat::SetClock); + let this = &mut *this; + let state = from_raw_parts(clock_data as *mut u8, size_of::<kvm_clock_data>()); + let ret = this.set_state(MainRequest_StateSet::CLOCK, state); + to_crosvm_rc(ret) +} + +#[no_mangle] pub unsafe extern "C" fn crosvm_set_identity_map_addr(self_: *mut crosvm, addr: u32) -> c_int { let _u = STATS.record(Stat::SetIdentityMapAddr); let self_ = &mut (*self_); diff --git a/plugin_proto/Cargo.toml b/plugin_proto/Cargo.toml index 5f1c771..bd06b3d 100644 --- a/plugin_proto/Cargo.toml +++ b/plugin_proto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "plugin_proto" -version = "0.16.0" +version = "0.17.0" authors = ["The Chromium OS Authors"] build = "build.rs" diff --git a/plugin_proto/protos/plugin.proto b/plugin_proto/protos/plugin.proto index 005c314..5b6eec2 100644 --- a/plugin_proto/protos/plugin.proto +++ b/plugin_proto/protos/plugin.proto @@ -124,6 +124,8 @@ message MainRequest { IOAPIC = 2; // struct kvm_pit_state2 PIT = 3; + // struct kvm_clock_data + CLOCK = 4; } message GetState { diff --git a/src/plugin/process.rs b/src/plugin/process.rs index 826b8d3..f3045fa 100644 --- a/src/plugin/process.rs +++ b/src/plugin/process.rs @@ -24,7 +24,7 @@ use protobuf::Message; use io_jail::Minijail; use kvm::{dirty_log_bitmap_size, Datamatch, IoeventAddress, IrqRoute, IrqSource, PicId, Vm}; -use kvm_sys::{kvm_ioapic_state, kvm_pic_state, kvm_pit_state2}; +use kvm_sys::{kvm_clock_data, kvm_ioapic_state, kvm_pic_state, kvm_pit_state2}; use plugin_proto::*; use sync::Mutex; use sys_util::{ @@ -45,6 +45,9 @@ unsafe impl DataInit for VmIoapicState {} #[derive(Copy, Clone)] struct VmPitState(kvm_pit_state2); unsafe impl DataInit for VmPitState {} +#[derive(Copy, Clone)] +struct VmClockState(kvm_clock_data); +unsafe impl DataInit for VmClockState {} fn get_vm_state(vm: &Vm, state_set: MainRequest_StateSet) -> SysResult<Vec<u8>> { Ok(match state_set { @@ -56,6 +59,7 @@ fn get_vm_state(vm: &Vm, state_set: MainRequest_StateSet) -> SysResult<Vec<u8>> .to_vec(), MainRequest_StateSet::IOAPIC => VmIoapicState(vm.get_ioapic_state()?).as_slice().to_vec(), MainRequest_StateSet::PIT => VmPitState(vm.get_pit_state()?).as_slice().to_vec(), + MainRequest_StateSet::CLOCK => VmClockState(vm.get_clock()?).as_slice().to_vec(), }) } @@ -83,6 +87,11 @@ fn set_vm_state(vm: &Vm, state_set: MainRequest_StateSet, state: &[u8]) -> SysRe .ok_or(SysError::new(EINVAL))? .0, ), + MainRequest_StateSet::CLOCK => vm.set_clock( + &VmClockState::from_slice(state) + .ok_or(SysError::new(EINVAL))? + .0, + ), } } diff --git a/tests/plugin_vm_state.c b/tests/plugin_vm_state.c index 6026e29..450d324 100644 --- a/tests/plugin_vm_state.c +++ b/tests/plugin_vm_state.c @@ -115,5 +115,33 @@ int main(int argc, char** argv) { return 1; } + // Test retrieving and setting clock state. + struct kvm_clock_data clock_data = { .clock = 0, .flags = -1U, }; + ret = crosvm_get_clock(crosvm, &clock_data); + if (ret < 0) { + fprintf(stderr, "failed to get initial clock state: %d\n", ret); + return 1; + } + + if (clock_data.clock == 0 || clock_data.flags != 0) { + fprintf(stderr, "invalid clock data returned (%llu, %u)\n", + clock_data.clock, clock_data.flags); + } + + clock_data.clock += 10000000; + + ret = crosvm_set_clock(crosvm, &clock_data); + if (ret < 0) { + fprintf(stderr, "failed to update clock: %d\n", ret); + return 1; + } + + clock_data.flags = -1U; + ret = crosvm_set_clock(crosvm, &clock_data); + if (ret >= 0) { + fprintf(stderr, "unexpected success updating clock\n"); + return 1; + } + return 0; } |