@@ -1908,6 +1908,95 @@ impl VmFd {
1908
1908
}
1909
1909
Ok ( ( ) )
1910
1910
}
1911
+
1912
+ /// Sets a specified piece of vm configuration and/or state.
1913
+ ///
1914
+ /// See the documentation for `KVM_SET_DEVICE_ATTR` in
1915
+ /// [KVM API doc](https://www.kernel.org/doc/Documentation/virtual/kvm/api.txt)
1916
+ /// # Arguments
1917
+ ///
1918
+ /// * `device_attr` - The vm attribute to be set.
1919
+ ///
1920
+ /// # Example
1921
+ ///
1922
+ /// ```rust
1923
+ /// # extern crate kvm_ioctls;
1924
+ /// # extern crate kvm_bindings;
1925
+ /// # use kvm_ioctls::Kvm;
1926
+ /// # use kvm_bindings::{
1927
+ /// PSCI_0_2_FN64_BASE, kvm_smccc_filter_action_KVM_SMCCC_FILTER_FWD_TO_USER,
1928
+ /// KVM_ARM_VM_SMCCC_CTRL, KVM_ARM_VM_SMCCC_FILTER
1929
+ /// };
1930
+ /// let kvm = Kvm::new().unwrap();
1931
+ /// let vm = kvm.create_vm().unwrap();
1932
+ ///
1933
+ /// const PSCI_0_2_FN64_CPU_ON: u32 = PSCI_0_2_FN64_BASE + 3;
1934
+ /// let smccc_filter = kvm_bindings::kvm_smccc_filter {
1935
+ /// base: PSCI_0_2_FN64_CPU_ON,
1936
+ /// nr_functions: 1,
1937
+ /// action: kvm_smccc_filter_action_KVM_SMCCC_FILTER_FWD_TO_USER as u8,
1938
+ /// pad: [0u8; 15],
1939
+ /// };
1940
+ ///
1941
+ /// let dist_attr = kvm_bindings::kvm_device_attr {
1942
+ /// group: KVM_ARM_VM_SMCCC_CTRL,
1943
+ /// attr: KVM_ARM_VM_SMCCC_FILTER as u64,
1944
+ /// addr: &smccc_filter as *const _ as u64,
1945
+ /// flags: 0,
1946
+ /// };
1947
+ ///
1948
+ /// if (vm.has_device_attr(&dist_attr).is_ok()) {
1949
+ /// vm.set_device_attr(&dist_attr).unwrap();
1950
+ /// }
1951
+ /// ```
1952
+ #[ cfg( target_arch = "aarch64" ) ]
1953
+ pub fn set_device_attr ( & self , device_attr : & kvm_device_attr ) -> Result < ( ) > {
1954
+ // SAFETY: Safe because we call this with a Vm fd and we trust the kernel.
1955
+ let ret = unsafe { ioctl_with_ref ( self , KVM_SET_DEVICE_ATTR ( ) , device_attr) } ;
1956
+ if ret != 0 {
1957
+ return Err ( errno:: Error :: last ( ) ) ;
1958
+ }
1959
+ Ok ( ( ) )
1960
+ }
1961
+
1962
+ /// Tests whether a vm supports a particular attribute.
1963
+ ///
1964
+ /// See the documentation for `KVM_HAS_DEVICE_ATTR` in
1965
+ /// [KVM API doc](https://www.kernel.org/doc/Documentation/virtual/kvm/api.txt)
1966
+ /// # Arguments
1967
+ ///
1968
+ /// * `device_attr` - The vm attribute to be tested. `addr` field is ignored.
1969
+ ///
1970
+ /// # Example
1971
+ ///
1972
+ /// ```rust
1973
+ /// # extern crate kvm_ioctls;
1974
+ /// # extern crate kvm_bindings;
1975
+ /// # use kvm_ioctls::Kvm;
1976
+ /// # use kvm_bindings::{
1977
+ /// KVM_ARM_VM_SMCCC_CTRL, KVM_ARM_VM_SMCCC_FILTER
1978
+ /// };
1979
+ /// let kvm = Kvm::new().unwrap();
1980
+ /// let vm = kvm.create_vm().unwrap();
1981
+ ///
1982
+ /// let dist_attr = kvm_bindings::kvm_device_attr {
1983
+ /// group: KVM_ARM_VM_SMCCC_CTRL,
1984
+ /// attr: KVM_ARM_VM_SMCCC_FILTER as u64,
1985
+ /// addr: 0x0,
1986
+ /// flags: 0,
1987
+ /// };
1988
+ ///
1989
+ /// vm.has_device_attr(&dist_attr);
1990
+ /// ```
1991
+ #[ cfg( target_arch = "aarch64" ) ]
1992
+ pub fn has_device_attr ( & self , device_attr : & kvm_device_attr ) -> Result < ( ) > {
1993
+ // SAFETY: Safe because we call this with a Vm fd and we trust the kernel.
1994
+ let ret = unsafe { ioctl_with_ref ( self , KVM_HAS_DEVICE_ATTR ( ) , device_attr) } ;
1995
+ if ret != 0 {
1996
+ return Err ( errno:: Error :: last ( ) ) ;
1997
+ }
1998
+ Ok ( ( ) )
1999
+ }
1911
2000
}
1912
2001
1913
2002
/// Helper function to create a new `VmFd`.
@@ -2787,4 +2876,29 @@ mod tests {
2787
2876
vm. register_enc_memory_region ( & memory_region) . unwrap ( ) ;
2788
2877
vm. unregister_enc_memory_region ( & memory_region) . unwrap ( ) ;
2789
2878
}
2879
+
2880
+ #[ test]
2881
+ #[ cfg( target_arch = "aarch64" ) ]
2882
+ fn test_set_smccc_filter ( ) {
2883
+ let kvm = Kvm :: new ( ) . unwrap ( ) ;
2884
+ let vm = kvm. create_vm ( ) . unwrap ( ) ;
2885
+
2886
+ const PSCI_0_2_FN64_CPU_ON : u32 = PSCI_0_2_FN64_BASE + 3 ;
2887
+ let smccc_filter = kvm_bindings:: kvm_smccc_filter {
2888
+ base : PSCI_0_2_FN64_CPU_ON ,
2889
+ nr_functions : 1 ,
2890
+ action : kvm_smccc_filter_action_KVM_SMCCC_FILTER_FWD_TO_USER as u8 ,
2891
+ pad : [ 0u8 ; 15 ] ,
2892
+ } ;
2893
+
2894
+ let dist_attr = kvm_bindings:: kvm_device_attr {
2895
+ group : KVM_ARM_VM_SMCCC_CTRL ,
2896
+ attr : KVM_ARM_VM_SMCCC_FILTER as u64 ,
2897
+ addr : & smccc_filter as * const _ as u64 ,
2898
+ flags : 0 ,
2899
+ } ;
2900
+
2901
+ vm. has_device_attr ( & dist_attr) . unwrap ( ) ;
2902
+ vm. set_device_attr ( & dist_attr) . unwrap ( ) ;
2903
+ }
2790
2904
}
0 commit comments