From f372a9d046aa741860799e7003e65996d7734103 Mon Sep 17 00:00:00 2001 From: Michael Zhao Date: Tue, 26 Nov 2019 08:54:16 +0000 Subject: [PATCH] Enable KVM_SET/GET_VCPU_EVENTS ioctls for Aarch64. KVM_GET_VCPU_EVENTS and KVM_SET_VCPU_EVENTS ioctls have been supported on Aarch64 from a recent kernel version. This patch enables them on Aarch64 and checked cap KVM_CAP_VCPU_EVENTS before calling them in test code to avoid error in old kernel. Change-Id: I9526b48948cf0cd5d63444a82b8b09970311a3bb Signed-off-by: Michael Zhao --- src/cap.rs | 7 ++++- src/ioctls/vcpu.rs | 67 ++++++++++++++++++++++++++++++++-------------- src/kvm_ioctls.rs | 14 ++++++++-- 3 files changed, 65 insertions(+), 23 deletions(-) diff --git a/src/cap.rs b/src/cap.rs index 5e2ac89e..6d212259 100644 --- a/src/cap.rs +++ b/src/cap.rs @@ -62,7 +62,12 @@ pub enum Cap { XenHvm = KVM_CAP_XEN_HVM, AdjustClock = KVM_CAP_ADJUST_CLOCK, InternalErrorData = KVM_CAP_INTERNAL_ERROR_DATA, - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + #[cfg(any( + target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64" + ))] VcpuEvents = KVM_CAP_VCPU_EVENTS, S390Psw = KVM_CAP_S390_PSW, PpcSegstate = KVM_CAP_PPC_SEGSTATE, diff --git a/src/ioctls/vcpu.rs b/src/ioctls/vcpu.rs index b67a8c97..48eebf42 100644 --- a/src/ioctls/vcpu.rs +++ b/src/ioctls/vcpu.rs @@ -852,14 +852,21 @@ impl VcpuFd { /// /// ```rust /// # extern crate kvm_ioctls; - /// # use kvm_ioctls::Kvm; + /// # use kvm_ioctls::{Kvm, Cap}; /// let kvm = Kvm::new().unwrap(); - /// let vm = kvm.create_vm().unwrap(); - /// let vcpu = vm.create_vcpu(0).unwrap(); - /// let vcpu_events = vcpu.get_vcpu_events().unwrap(); + /// if kvm.check_extension(Cap::VcpuEvents) { + /// let vm = kvm.create_vm().unwrap(); + /// let vcpu = vm.create_vcpu(0).unwrap(); + /// let vcpu_events = vcpu.get_vcpu_events().unwrap(); + /// } /// ``` /// - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + #[cfg(any( + target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64" + ))] pub fn get_vcpu_events(&self) -> Result { let mut vcpu_events = Default::default(); let ret = unsafe { @@ -885,16 +892,24 @@ impl VcpuFd { /// /// ```rust /// # extern crate kvm_ioctls; - /// # use kvm_ioctls::Kvm; + /// # use kvm_ioctls::{Kvm, Cap}; /// let kvm = Kvm::new().unwrap(); - /// let vm = kvm.create_vm().unwrap(); - /// let vcpu = vm.create_vcpu(0).unwrap(); - /// let vcpu_events = Default::default(); - /// // Your `vcpu_events` manipulation here. - /// vcpu.set_vcpu_events(&vcpu_events).unwrap(); + /// if kvm.check_extension(Cap::VcpuEvents) { + /// let vm = kvm.create_vm().unwrap(); + /// let vcpu = vm.create_vcpu(0).unwrap(); + /// let vcpu_events = Default::default(); + /// // Your `vcpu_events` manipulation here. + /// vcpu.set_vcpu_events(&vcpu_events).unwrap(); + /// } /// ``` /// - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + #[cfg(any( + target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64" + ))] + pub fn set_vcpu_events(&self, vcpu_events: &kvm_vcpu_events) -> Result<()> { let ret = unsafe { // Here we trust the kernel not to read past the end of the kvm_vcpu_events struct. @@ -1180,7 +1195,12 @@ mod tests { #[cfg(target_arch = "x86_64")] use super::*; use ioctls::system::Kvm; - #[cfg(target_arch = "x86_64")] + #[cfg(any( + target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64" + ))] use Cap; // Helper function for memory mapping `size` bytes of anonymous memory. @@ -1391,16 +1411,23 @@ mod tests { assert_eq!(debugregs, other_debugregs); } - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + #[cfg(any( + target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64" + ))] #[test] fn vcpu_events_test() { let kvm = Kvm::new().unwrap(); - let vm = kvm.create_vm().unwrap(); - let vcpu = vm.create_vcpu(0).unwrap(); - let vcpu_events = vcpu.get_vcpu_events().unwrap(); - vcpu.set_vcpu_events(&vcpu_events).unwrap(); - let other_vcpu_events = vcpu.get_vcpu_events().unwrap(); - assert_eq!(vcpu_events, other_vcpu_events); + if kvm.check_extension(Cap::VcpuEvents) { + let vm = kvm.create_vm().unwrap(); + let vcpu = vm.create_vcpu(0).unwrap(); + let vcpu_events = vcpu.get_vcpu_events().unwrap(); + vcpu.set_vcpu_events(&vcpu_events).unwrap(); + let other_vcpu_events = vcpu.get_vcpu_events().unwrap(); + assert_eq!(vcpu_events, other_vcpu_events); + } } #[cfg(target_arch = "x86_64")] diff --git a/src/kvm_ioctls.rs b/src/kvm_ioctls.rs index e61b5aa8..e38ff73e 100644 --- a/src/kvm_ioctls.rs +++ b/src/kvm_ioctls.rs @@ -150,10 +150,20 @@ ioctl_ior_nr!(KVM_GET_MP_STATE, KVMIO, 0x98, kvm_mp_state); ))] ioctl_iow_nr!(KVM_SET_MP_STATE, KVMIO, 0x99, kvm_mp_state); /* Available with KVM_CAP_VCPU_EVENTS */ -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#[cfg(any( + target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64" +))] ioctl_ior_nr!(KVM_GET_VCPU_EVENTS, KVMIO, 0x9f, kvm_vcpu_events); /* Available with KVM_CAP_VCPU_EVENTS */ -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#[cfg(any( + target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64" +))] ioctl_iow_nr!(KVM_SET_VCPU_EVENTS, KVMIO, 0xa0, kvm_vcpu_events); /* Available with KVM_CAP_DEBUGREGS */ #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]