@@ -876,9 +876,9 @@ impl VcpuFd {
876
876
/// This function is unsafe because there is no guarantee `xsave` is allocated with enough space
877
877
/// to hold the entire xsave state.
878
878
///
879
- /// The required size can be retrieved via `KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2)` and can vary
880
- /// depending on features that have been dynamically enabled by `arch_prctl()`. Thus, any
881
- /// features must not be enabled dynamically after the required size has been confirmed.
879
+ /// The required size in bytes can be retrieved via `KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2)` and
880
+ /// can vary depending on features that have been dynamically enabled by `arch_prctl()`. Thus,
881
+ /// any features must not be enabled dynamically after the required size has been confirmed.
882
882
///
883
883
/// If `xsave` is not large enough, `KVM_GET_XSAVE2` copies data beyond the allocated area,
884
884
/// possibly causing undefined behavior.
@@ -891,14 +891,17 @@ impl VcpuFd {
891
891
/// ```rust
892
892
/// # extern crate kvm_ioctls;
893
893
/// # extern crate kvm_bindings;
894
+ /// # extern crate vmm_sys_util;
894
895
/// # use kvm_ioctls::{Kvm, Cap};
895
- /// # use kvm_bindings::{Xsave, kvm_xsave};
896
+ /// # use kvm_bindings::{Xsave, kvm_xsave, kvm_xsave2};
897
+ /// # use vmm_sys_util::fam::FamStruct;
896
898
/// let kvm = Kvm::new().unwrap();
897
899
/// let vm = kvm.create_vm().unwrap();
898
900
/// let vcpu = vm.create_vcpu(0).unwrap();
899
901
/// let xsave_size = vm.check_extension_int(Cap::Xsave2);
900
902
/// if xsave_size > 0 {
901
- /// let fam_size = xsave_size as usize - std::mem::size_of::<kvm_xsave>();
903
+ /// let fam_size = (xsave_size as usize - std::mem::size_of::<kvm_xsave>())
904
+ /// .div_ceil(std::mem::size_of::<<kvm_xsave2 as FamStruct>::Entry>());
902
905
/// let mut xsave = Xsave::new(fam_size).unwrap();
903
906
/// unsafe { vcpu.get_xsave2(&mut xsave).unwrap() };
904
907
/// }
@@ -981,9 +984,9 @@ impl VcpuFd {
981
984
/// This function is unsafe because there is no guarantee `xsave` is properly allocated with
982
985
/// the size that KVM assumes.
983
986
///
984
- /// The required size can be retrieved via `KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2)` and can vary
985
- /// depending on features that have been dynamically enabled by `arch_prctl()`. Thus, any
986
- /// features must not be enabled after the required size has been confirmed.
987
+ /// The required size in bytes can be retrieved via `KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2)` and
988
+ /// can vary depending on features that have been dynamically enabled by `arch_prctl()`. Thus,
989
+ /// any features must not be enabled after the required size has been confirmed.
987
990
///
988
991
/// If `xsave` is not large enough, `KVM_SET_XSAVE` copies data beyond the allocated area to
989
992
/// the kernel, possibly causing undefined behavior.
@@ -996,14 +999,17 @@ impl VcpuFd {
996
999
/// ```rust
997
1000
/// # extern crate kvm_ioctls;
998
1001
/// # extern crate kvm_bindings;
1002
+ /// # extern crate vmm_sys_util;
999
1003
/// # use kvm_ioctls::{Kvm, Cap};
1000
- /// # use kvm_bindings::{Xsave, kvm_xsave};
1004
+ /// # use kvm_bindings::{Xsave, kvm_xsave, kvm_xsave2};
1005
+ /// # use vmm_sys_util::fam::FamStruct;
1001
1006
/// let kvm = Kvm::new().unwrap();
1002
1007
/// let vm = kvm.create_vm().unwrap();
1003
1008
/// let vcpu = vm.create_vcpu(0).unwrap();
1004
1009
/// let xsave_size = vm.check_extension_int(Cap::Xsave2);
1005
1010
/// if xsave_size > 0 {
1006
- /// let fam_size = xsave_size as usize - std::mem::size_of::<kvm_xsave>();
1011
+ /// let fam_size = (xsave_size as usize - std::mem::size_of::<kvm_xsave>())
1012
+ /// .div_ceil(std::mem::size_of::<<kvm_xsave2 as FamStruct>::Entry>());
1007
1013
/// let xsave = Xsave::new(fam_size).unwrap();
1008
1014
/// // Your `xsave` manipulation here.
1009
1015
/// unsafe { vcpu.set_xsave2(&xsave).unwrap() };
@@ -2343,6 +2349,8 @@ mod tests {
2343
2349
#[ cfg( target_arch = "x86_64" ) ]
2344
2350
#[ test]
2345
2351
fn xsave_test ( ) {
2352
+ use vmm_sys_util:: fam:: FamStruct ;
2353
+
2346
2354
let kvm = Kvm :: new ( ) . unwrap ( ) ;
2347
2355
let vm = kvm. create_vm ( ) . unwrap ( ) ;
2348
2356
let vcpu = vm. create_vcpu ( 0 ) . unwrap ( ) ;
@@ -2355,7 +2363,8 @@ mod tests {
2355
2363
let xsave_size = vm. check_extension_int ( Cap :: Xsave2 ) ;
2356
2364
// only if KVM_CAP_XSAVE2 is supported
2357
2365
if xsave_size > 0 {
2358
- let fam_size = xsave_size as usize - std:: mem:: size_of :: < kvm_xsave > ( ) ;
2366
+ let fam_size = ( xsave_size as usize - std:: mem:: size_of :: < kvm_xsave > ( ) )
2367
+ . div_ceil ( std:: mem:: size_of :: < <kvm_xsave2 as FamStruct >:: Entry > ( ) ) ;
2359
2368
let mut xsave2 = Xsave :: new ( fam_size) . unwrap ( ) ;
2360
2369
// SAFETY: Safe because `xsave2` is allocated with enough space.
2361
2370
unsafe { vcpu. get_xsave2 ( & mut xsave2) . unwrap ( ) } ;
0 commit comments