Skip to content

Commit 9e1e308

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 d22ef1f commit 9e1e308

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

src/cap.rs

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

src/ioctls/system.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,32 @@ impl Kvm {
239239
}
240240
}
241241

242+
/// Returns the "disable idle exiting" capability.
243+
///
244+
/// The `KVM_CAP_X86_DISABLE_EXITS` capability provides userspace with per-VM capability
245+
/// to not intercept MWAIT/HLT/PAUSE/CSTATE, which means though instructions won't cause
246+
/// vm-exits and helps to improve latency in some workloads.
247+
///
248+
/// # Example
249+
///
250+
/// ```
251+
/// # extern crate kvm_bindings;
252+
/// # use kvm_bindings::{KVM_X86_DISABLE_EXITS_HLT, KVM_X86_DISABLE_EXITS_PAUSE};
253+
/// # use kvm_ioctls::Kvm;
254+
/// let kvm = Kvm::new().unwrap();
255+
/// assert!(kvm.get_disable_exits() & KVM_X86_DISABLE_EXITS_HLT != 0);
256+
/// assert!(kvm.get_disable_exits() & KVM_X86_DISABLE_EXITS_PAUSE != 0);
257+
/// ```
258+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
259+
pub fn get_disable_exits(&self) -> u32 {
260+
let x = self.check_extension_int(Cap::DisableExits);
261+
if x > 0 {
262+
x as u32
263+
} else {
264+
0
265+
}
266+
}
267+
242268
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
243269
fn get_cpuid(&self, kind: u64, num_entries: usize) -> Result<CpuId> {
244270
if num_entries > KVM_MAX_CPUID_ENTRIES {
@@ -542,7 +568,9 @@ impl FromRawFd for Kvm {
542568
mod tests {
543569
use super::*;
544570
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
545-
use kvm_bindings::KVM_MAX_CPUID_ENTRIES;
571+
use kvm_bindings::{
572+
KVM_MAX_CPUID_ENTRIES, KVM_X86_DISABLE_EXITS_HLT, KVM_X86_DISABLE_EXITS_PAUSE,
573+
};
546574
use libc::{fcntl, FD_CLOEXEC, F_GETFD};
547575
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
548576
use vmm_sys_util::fam::FamStruct;
@@ -598,6 +626,18 @@ mod tests {
598626
assert!(kvm.get_nr_memslots() >= 32);
599627
}
600628

629+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
630+
#[test]
631+
fn test_kvm_get_disable_exits() {
632+
let kvm = Kvm::new().unwrap();
633+
let disable_exits = kvm.get_disable_exits();
634+
635+
if disable_exits != 0 {
636+
assert!(disable_exits & KVM_X86_DISABLE_EXITS_HLT != 0);
637+
assert!(disable_exits & KVM_X86_DISABLE_EXITS_PAUSE != 0);
638+
}
639+
}
640+
601641
#[test]
602642
fn test_create_vm() {
603643
let kvm = Kvm::new().unwrap();

0 commit comments

Comments
 (0)