@@ -387,6 +387,52 @@ impl VcpuFd {
387
387
Ok ( cpuid)
388
388
}
389
389
390
+ ///
391
+ /// See the documentation for `KVM_ENABLE_CAP`.
392
+ ///
393
+ /// # Arguments
394
+ ///
395
+ /// * kvm_enable_cap - KVM capability structure. For details check the `kvm_enable_cap`
396
+ /// structure in the
397
+ /// [KVM API doc](https://www.kernel.org/doc/Documentation/virtual/kvm/api.txt).
398
+ ///
399
+ /// # Example
400
+ ///
401
+ /// ```rust
402
+ /// # extern crate kvm_ioctls;
403
+ /// # extern crate kvm_bindings;
404
+ /// # use kvm_bindings::{kvm_enable_cap, KVM_MAX_CPUID_ENTRIES, KVM_CAP_HYPERV_SYNIC, KVM_CAP_SPLIT_IRQCHIP};
405
+ /// # use kvm_ioctls::{Kvm, Cap};
406
+ /// let kvm = Kvm::new().unwrap();
407
+ /// let vm = kvm.create_vm().unwrap();
408
+ /// let mut cap: kvm_enable_cap = Default::default();
409
+ /// if cfg!(target_arch = "x86") || cfg!(target_arch = "x86_64") {
410
+ /// // KVM_CAP_HYPERV_SYNIC needs KVM_CAP_SPLIT_IRQCHIP enabled
411
+ /// cap.cap = KVM_CAP_SPLIT_IRQCHIP;
412
+ /// cap.args[0] = 24;
413
+ /// vm.enable_cap(&cap).unwrap();
414
+ ///
415
+ /// let vcpu = vm.create_vcpu(0).unwrap();
416
+ /// if kvm.check_extension(Cap::HypervSynic) {
417
+ /// let mut cap: kvm_enable_cap = Default::default();
418
+ /// cap.cap = KVM_CAP_HYPERV_SYNIC;
419
+ /// vcpu.enable_cap(&cap).unwrap();
420
+ /// }
421
+ /// }
422
+ /// ```
423
+ ///
424
+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
425
+ pub fn enable_cap ( & self , cap : & kvm_enable_cap ) -> Result < ( ) > {
426
+ // The ioctl is safe because we allocated the struct and we know the
427
+ // kernel will write exactly the size of the struct.
428
+ let ret = unsafe { ioctl_with_ref ( self , KVM_ENABLE_CAP ( ) , cap) } ;
429
+ if ret == 0 {
430
+ Ok ( ( ) )
431
+ } else {
432
+ Err ( errno:: Error :: last ( ) )
433
+ }
434
+ }
435
+
390
436
/// Returns the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
391
437
///
392
438
/// The state is returned in a `kvm_lapic_state` structure as defined in the
@@ -2007,4 +2053,23 @@ mod tests {
2007
2053
vcpu. set_kvm_immediate_exit ( 1 ) ;
2008
2054
assert_eq ! ( vcpu. kvm_run_ptr. as_mut_ref( ) . immediate_exit, 1 ) ;
2009
2055
}
2056
+
2057
+ #[ test]
2058
+ #[ cfg( target_arch = "x86_64" ) ]
2059
+ fn test_enable_cap ( ) {
2060
+ let kvm = Kvm :: new ( ) . unwrap ( ) ;
2061
+ let vm = kvm. create_vm ( ) . unwrap ( ) ;
2062
+ let mut cap: kvm_enable_cap = Default :: default ( ) ;
2063
+ // KVM_CAP_HYPERV_SYNIC needs KVM_CAP_SPLIT_IRQCHIP enabled
2064
+ cap. cap = KVM_CAP_SPLIT_IRQCHIP ;
2065
+ cap. args [ 0 ] = 24 ;
2066
+ vm. enable_cap ( & cap) . unwrap ( ) ;
2067
+
2068
+ let vcpu = vm. create_vcpu ( 0 ) . unwrap ( ) ;
2069
+ if kvm. check_extension ( Cap :: HypervSynic ) {
2070
+ let mut cap: kvm_enable_cap = Default :: default ( ) ;
2071
+ cap. cap = KVM_CAP_HYPERV_SYNIC ;
2072
+ vcpu. enable_cap ( & cap) . unwrap ( ) ;
2073
+ }
2074
+ }
2010
2075
}
0 commit comments