Skip to content

Commit 6768c7c

Browse files
committed
Add method to query KVM_CAP_X86_DISABLE_EXITS
Add method to query KVM_CAP_X86_DISABLE_EXITS for x86 platforms. Signed-off-by: Liu Jiang <gerry@linux.alibaba.com>
1 parent 808dd4b commit 6768c7c

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

src/cap.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ pub enum Cap {
140140
S390UserSigp = KVM_CAP_S390_USER_SIGP,
141141
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
142142
SplitIrqchip = KVM_CAP_SPLIT_IRQCHIP,
143+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
144+
DisableExits = KVM_CAP_X86_DISABLE_EXITS,
143145
ImmediateExit = KVM_CAP_IMMEDIATE_EXIT,
144146
ArmVmIPASize = KVM_CAP_ARM_VM_IPA_SIZE,
145147
MsiDevid = KVM_CAP_MSI_DEVID,

src/ioctls/system.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,33 @@ impl Kvm {
248248
}
249249
}
250250

251+
/// Returns the "disable idle exiting" capability.
252+
///
253+
/// The `KVM_CAP_X86_DISABLE_EXITS` capability provides userspace with per-VM capability
254+
/// to not intercept MWAIT/HLT/PAUSE/CSTATE, which means though instructions won't cause
255+
/// vm-exits and helps to improve latency in some workloads.
256+
///
257+
/// # Example
258+
///
259+
/// ```
260+
/// # extern crate kvm_bindings;
261+
/// # use kvm_bindings::{KVM_X86_DISABLE_EXITS_HLT, KVM_X86_DISABLE_EXITS_PAUSE};
262+
/// # use kvm_ioctls::Kvm;
263+
/// let kvm = Kvm::new().unwrap();
264+
/// assert!(kvm.get_disable_exits() & KVM_X86_DISABLE_EXITS_HLT != 0);
265+
/// assert!(kvm.get_disable_exits() & KVM_X86_DISABLE_EXITS_PAUSE != 0);
266+
/// ```
267+
///
268+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
269+
pub fn get_disable_exits(&self) -> u32 {
270+
let x = self.check_extension_int(Cap::DisableExits);
271+
if x > 0 {
272+
x as u32
273+
} else {
274+
0
275+
}
276+
}
277+
251278
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
252279
fn get_cpuid(&self, kind: u64, num_entries: usize) -> Result<CpuId> {
253280
if num_entries > KVM_MAX_CPUID_ENTRIES {
@@ -559,7 +586,9 @@ impl FromRawFd for Kvm {
559586
mod tests {
560587
use super::*;
561588
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
562-
use kvm_bindings::KVM_MAX_CPUID_ENTRIES;
589+
use kvm_bindings::{
590+
KVM_MAX_CPUID_ENTRIES, KVM_X86_DISABLE_EXITS_HLT, KVM_X86_DISABLE_EXITS_PAUSE,
591+
};
563592
use libc::{fcntl, FD_CLOEXEC, F_GETFD};
564593
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
565594
use vmm_sys_util::fam::FamStruct;
@@ -615,6 +644,18 @@ mod tests {
615644
assert!(kvm.get_nr_memslots() >= 32);
616645
}
617646

647+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
648+
#[test]
649+
fn test_kvm_get_disable_exits() {
650+
let kvm = Kvm::new().unwrap();
651+
let disable_exits = kvm.get_disable_exits();
652+
653+
if disable_exits != 0 {
654+
assert!(disable_exits & KVM_X86_DISABLE_EXITS_HLT != 0);
655+
assert!(disable_exits & KVM_X86_DISABLE_EXITS_PAUSE != 0);
656+
}
657+
}
658+
618659
#[test]
619660
fn test_create_vm() {
620661
let kvm = Kvm::new().unwrap();

0 commit comments

Comments
 (0)