Skip to content

Commit

Permalink
Enable KVM_SET/GET_VCPU_EVENTS ioctls for Aarch64.
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
michael2012z committed Dec 3, 2019
1 parent 5a50456 commit 1908f99
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 23 deletions.
7 changes: 6 additions & 1 deletion src/cap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
67 changes: 47 additions & 20 deletions src/ioctls/vcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<kvm_vcpu_events> {
let mut vcpu_events = Default::default();
let ret = unsafe {
Expand All @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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")]
Expand Down
14 changes: 12 additions & 2 deletions src/kvm_ioctls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"))]
Expand Down

0 comments on commit 1908f99

Please sign in to comment.