@@ -111,6 +111,97 @@ impl VmFd {
111
111
}
112
112
}
113
113
114
+ /// Creates/modifies a guest physical memory slot.
115
+ ///
116
+ /// See the documentation for `KVM_SET_USER_MEMORY_REGION2`.
117
+ ///
118
+ /// # Arguments
119
+ ///
120
+ /// * `user_memory_region2` - Guest physical memory slot. For details check the
121
+ /// `kvm_userspace_memory_region2` structure in the
122
+ ///
123
+ /// # Safety
124
+ ///
125
+ /// This function is unsafe because there is no guarantee `userspace_addr` points to a valid
126
+ /// memory region, nor the memory region lives as long as the kernel needs it to.
127
+ ///
128
+ /// The caller of this method must make sure that:
129
+ /// - the raw pointer (`userspace_addr`) points to valid memory
130
+ /// - the regions provided to KVM are not overlapping other memory regions.
131
+ /// - the guest_memfd points at a file created via KVM_CREATE_GUEST_MEMFD on
132
+ /// the current VM, and the target range must not be bound to any other memory region
133
+ ///
134
+ /// # Example
135
+ ///
136
+ /// ```rust
137
+ /// # extern crate kvm_ioctls;
138
+ /// extern crate kvm_bindings;
139
+ ///
140
+ /// use kvm_bindings::{
141
+ /// kvm_create_guest_memfd, kvm_enable_cap, kvm_userspace_memory_region2, KVM_CAP_GUEST_MEMFD,
142
+ /// KVM_CAP_USER_MEMORY2, KVM_MEM_GUEST_MEMFD,
143
+ /// };
144
+ /// use kvm_ioctls::Kvm;
145
+ /// use std::os::fd::RawFd;
146
+ ///
147
+ /// # #[cfg(target_arch = "x86_64")]
148
+ /// {
149
+ /// let kvm = Kvm::new().unwrap();
150
+ /// let vm = kvm.create_vm().unwrap();
151
+ ///
152
+ /// let address_space = unsafe { libc::mmap(0 as _, 10000, 3, 34, -1, 0) };
153
+ /// let userspace_addr = address_space as *const u8 as u64;
154
+ ///
155
+ /// let mut config = kvm_enable_cap {
156
+ /// cap: KVM_CAP_GUEST_MEMFD,
157
+ /// ..Default::default()
158
+ /// };
159
+ ///
160
+ /// if vm.enable_cap(&config).is_err() {
161
+ /// return;
162
+ /// }
163
+ /// let gmem = kvm_create_guest_memfd {
164
+ /// size: 0x10000,
165
+ /// flags: 0,
166
+ /// reserved: [0; 6],
167
+ /// };
168
+ ///
169
+ /// let fd: RawFd = unsafe { vm.create_guest_memfd(gmem).unwrap() };
170
+ ///
171
+ /// config.cap = KVM_CAP_USER_MEMORY2;
172
+ ///
173
+ /// if vm.enable_cap(&config).is_err() {
174
+ /// return;
175
+ /// }
176
+ ///
177
+ /// let mem_region = kvm_userspace_memory_region2 {
178
+ /// slot: 0,
179
+ /// flags: KVM_MEM_GUEST_MEMFD,
180
+ /// guest_phys_addr: 0x10000 as u64,
181
+ /// memory_size: 0x10000 as u64,
182
+ /// userspace_addr,
183
+ /// guest_memfd_offset: 0,
184
+ /// guest_memfd: fd as u32,
185
+ /// pad1: 0,
186
+ /// pad2: [0; 14],
187
+ /// };
188
+ /// unsafe {
189
+ /// vm.set_user_memory_region2(mem_region).unwrap();
190
+ /// };
191
+ /// }
192
+ /// ```
193
+ pub unsafe fn set_user_memory_region2 (
194
+ & self ,
195
+ user_memory_region2 : kvm_userspace_memory_region2 ,
196
+ ) -> Result < ( ) > {
197
+ let ret = ioctl_with_ref ( self , KVM_SET_USER_MEMORY_REGION2 ( ) , & user_memory_region2) ;
198
+ if ret == 0 {
199
+ Ok ( ( ) )
200
+ } else {
201
+ Err ( errno:: Error :: last ( ) )
202
+ }
203
+ }
204
+
114
205
/// Sets the address of the three-page region in the VM's address space.
115
206
///
116
207
/// See the documentation for `KVM_SET_TSS_ADDR`.
@@ -1877,6 +1968,24 @@ mod tests {
1877
1968
assert ! ( unsafe { vm. set_user_memory_region( invalid_mem_region) } . is_err( ) ) ;
1878
1969
}
1879
1970
1971
+ #[ test]
1972
+ fn test_set_invalid_memory2 ( ) {
1973
+ let kvm = Kvm :: new ( ) . unwrap ( ) ;
1974
+ let vm = kvm. create_vm ( ) . unwrap ( ) ;
1975
+ let invalid_mem_region = kvm_userspace_memory_region2 {
1976
+ slot : 0 ,
1977
+ flags : 0 ,
1978
+ guest_phys_addr : 0 ,
1979
+ memory_size : 0 ,
1980
+ userspace_addr : 0 ,
1981
+ guest_memfd_offset : 0 ,
1982
+ guest_memfd : 0 ,
1983
+ pad1 : 0 ,
1984
+ pad2 : [ 0 ; 14 ] ,
1985
+ } ;
1986
+ assert ! ( unsafe { vm. set_user_memory_region2( invalid_mem_region) } . is_err( ) ) ;
1987
+ }
1988
+
1880
1989
#[ test]
1881
1990
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
1882
1991
fn test_set_tss_address ( ) {
0 commit comments