@@ -1067,6 +1067,62 @@ impl VcpuFd {
10671067 Ok ( ( ) )
10681068 }
10691069
1070+ /// Finalizes the configuration of the specified vcpu feature.
1071+ ///
1072+ /// The vcpu must already have been initialised, enabling the affected feature,
1073+ /// by means of a successful KVM_ARM_VCPU_INIT call with the appropriate flag set
1074+ /// in features[].
1075+ ///
1076+ /// For affected vcpu features, this is a mandatory step that must be performed before
1077+ /// the vcpu is fully usable.
1078+ ///
1079+ /// Between KVM_ARM_VCPU_INIT and KVM_ARM_VCPU_FINALIZE, the feature may be configured
1080+ /// by use of ioctls such as KVM_SET_ONE_REG. The exact configuration that should be
1081+ /// performaned and how to do it are feature-dependent.
1082+ ///
1083+ /// Other calls that depend on a particular feature being finalized, such as KVM_RUN,
1084+ /// KVM_GET_REG_LIST, KVM_GET_ONE_REG and KVM_SET_ONE_REG, will fail with -EPERM unless
1085+ /// the feature has already been finalized by means of a KVM_ARM_VCPU_FINALIZE call.
1086+ ///
1087+ /// See KVM_ARM_VCPU_INIT for details of vcpu features that require finalization using this ioctl.
1088+ /// [KVM_ARM_VCPU_FINALIZE](https://www.kernel.org/doc/html/latest/virt/kvm/api.html#kvm-arm-vcpu-finalize).
1089+ ///
1090+ /// # Arguments
1091+ ///
1092+ /// * `feature` - vCPU features that needs to be finalized.
1093+ ///
1094+ /// # Example
1095+ /// ```rust
1096+ /// # extern crate kvm_ioctls;
1097+ /// # extern crate kvm_bindings;
1098+ /// # use kvm_ioctls::Kvm;
1099+ /// use std::arch::is_aarch64_feature_detected;
1100+ ///
1101+ /// use kvm_bindings::{kvm_vcpu_init, KVM_ARM_VCPU_SVE};
1102+ /// let kvm = Kvm::new().unwrap();
1103+ /// let vm = kvm.create_vm().unwrap();
1104+ /// let vcpu = vm.create_vcpu(0).unwrap();
1105+ ///
1106+ /// let mut kvi = kvm_vcpu_init::default();
1107+ /// vm.get_preferred_target(&mut kvi).unwrap();
1108+ /// kvi.features[0] |= 1 << KVM_ARM_VCPU_SVE;
1109+ /// if is_aarch64_feature_detected!("sve2") || is_aarch64_feature_detected!("sve") {
1110+ /// vcpu.vcpu_init(&kvi).unwrap();
1111+ /// let feature = KVM_ARM_VCPU_SVE as i32;
1112+ /// vcpu.vcpu_finalize(&feature).unwrap();
1113+ /// }
1114+ /// ```
1115+ #[ cfg( target_arch = "aarch64" ) ]
1116+ pub fn vcpu_finalize ( & self , feature : & std:: os:: raw:: c_int ) -> Result < ( ) > {
1117+ // SAFETY: This is safe because we know the kernel will only read this
1118+ // parameter to select the correct finalization case in KVM.
1119+ let ret = unsafe { ioctl_with_ref ( self , KVM_ARM_VCPU_FINALIZE ( ) , feature) } ;
1120+ if ret < 0 {
1121+ return Err ( errno:: Error :: last ( ) ) ;
1122+ }
1123+ Ok ( ( ) )
1124+ }
1125+
10701126 /// Returns the guest registers that are supported for the
10711127 /// KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.
10721128 ///
0 commit comments