xref: /aosp_15_r20/external/crosvm/swap/tests/main.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2022 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 //! Integration tests for vmm-swap feature
6 
7 #[cfg(all(unix, feature = "enable"))]
8 mod common;
9 
10 #[cfg(all(unix, feature = "enable"))]
11 mod test {
12     use std::time::Duration;
13 
14     use base::pagesize;
15     use base::sys::wait_for_pid;
16     use base::AsRawDescriptor;
17     use base::FromRawDescriptor;
18     use base::IntoRawDescriptor;
19     use base::SafeDescriptor;
20     use base::Tube;
21     use swap::userfaultfd::register_regions;
22     use swap::userfaultfd::unregister_regions;
23     use swap::userfaultfd::Userfaultfd;
24     use swap::SwapController;
25     use swap::SwapState;
26     use vm_memory::GuestAddress;
27     use vm_memory::GuestMemory;
28     use vm_memory::MemoryRegionOptions;
29 
30     use super::common::*;
31 
register_region_skip_obsolete_process()32     pub fn register_region_skip_obsolete_process() {
33         let shm = create_shared_memory("test", 3 * pagesize());
34         let uffd = create_uffd_for_test();
35         let base_addr = shm.base_addr();
36         let region = base_addr..(base_addr + 3 * pagesize());
37         let regions = [region];
38         let (tube_main, tube_child) = Tube::pair().unwrap();
39         // SAFETY: trivially safe
40         let pid = unsafe { libc::fork() };
41         if pid == 0 {
42             // child process
43             let uffd = create_uffd_for_test();
44             // TODO(b/315998194): Add safety comment
45             #[allow(clippy::undocumented_unsafe_blocks)]
46             tube_child
47                 .send(&unsafe { SafeDescriptor::from_raw_descriptor(uffd.as_raw_descriptor()) })
48                 .unwrap();
49             std::process::exit(0);
50         }
51         let uffd_descriptor = tube_main
52             .recv::<SafeDescriptor>()
53             .unwrap()
54             .into_raw_descriptor();
55         wait_for_pid(pid, 0).unwrap();
56         // TODO(b/315998194): Add safety comment
57         #[allow(clippy::undocumented_unsafe_blocks)]
58         let uffd_child = unsafe { Userfaultfd::from_raw_descriptor(uffd_descriptor) };
59 
60         // TODO(b/315998194): Add safety comment
61         #[allow(clippy::undocumented_unsafe_blocks)]
62         let result = unsafe { register_regions(&regions, &[uffd, uffd_child]) };
63 
64         // no error from ENOMEM
65         assert_eq!(result.is_ok(), true);
66     }
67 
unregister_region_skip_obsolete_process()68     pub fn unregister_region_skip_obsolete_process() {
69         let shm = create_shared_memory("test", 3 * pagesize());
70         let uffd = create_uffd_for_test();
71         let base_addr = shm.base_addr();
72         let region = base_addr..(base_addr + 3 * pagesize());
73         let regions = [region];
74         let (tube_main, tube_child) = Tube::pair().unwrap();
75         // SAFETY: trivially safe
76         let pid = unsafe { libc::fork() };
77         if pid == 0 {
78             // child process
79             let uffd = create_uffd_for_test();
80             // TODO(b/315998194): Add safety comment
81             #[allow(clippy::undocumented_unsafe_blocks)]
82             tube_child
83                 .send(&unsafe { SafeDescriptor::from_raw_descriptor(uffd.as_raw_descriptor()) })
84                 .unwrap();
85             tube_child.recv::<u8>().unwrap();
86             std::process::exit(0);
87         }
88         let uffd_descriptor = tube_main
89             .recv::<SafeDescriptor>()
90             .unwrap()
91             .into_raw_descriptor();
92         // TODO(b/315998194): Add safety comment
93         #[allow(clippy::undocumented_unsafe_blocks)]
94         let uffd_child = unsafe { Userfaultfd::from_raw_descriptor(uffd_descriptor) };
95         let uffds = [uffd, uffd_child];
96 
97         // TODO(b/315998194): Add safety comment
98         #[allow(clippy::undocumented_unsafe_blocks)]
99         unsafe { register_regions(&regions, &uffds) }.unwrap();
100         tube_main.send(&0_u8).unwrap();
101         // wait until the child process die and the uffd_child become obsolete.
102         wait_for_pid(pid, 0).unwrap();
103         let result = unregister_regions(&regions, &uffds);
104 
105         // no error from ENOMEM
106         assert_eq!(result.is_ok(), true);
107     }
108 
create_guest_memory() -> GuestMemory109     fn create_guest_memory() -> GuestMemory {
110         // guest memory with 2 regions. The address and size are from a real device.
111         GuestMemory::new_with_options(&[
112             (
113                 GuestAddress(0x0000000000000000),
114                 3489660928,
115                 MemoryRegionOptions::new(),
116             ),
117             (
118                 GuestAddress(0x0000000100000000),
119                 3537895424,
120                 MemoryRegionOptions::new(),
121             ),
122         ])
123         .unwrap()
124     }
125 
wait_for_state(controller: &SwapController, state: SwapState) -> bool126     fn wait_for_state(controller: &SwapController, state: SwapState) -> bool {
127         for _ in 0..20 {
128             if controller.status().unwrap().state == state {
129                 return true;
130             }
131             std::thread::sleep(Duration::from_millis(100));
132         }
133         false
134     }
135 
controller_enable()136     pub fn controller_enable() {
137         let dir = tempfile::tempdir().unwrap();
138         let guest_memory = create_guest_memory();
139 
140         let controller = SwapController::launch(guest_memory.clone(), dir.path(), &None).unwrap();
141 
142         guest_memory
143             .write_all_at_addr(&[1u8; 4096], GuestAddress(0x0000000000000000))
144             .unwrap();
145         guest_memory
146             .write_all_at_addr(&[2u8; 4096], GuestAddress(0x0000000000000000 + 4096))
147             .unwrap();
148         guest_memory
149             .write_all_at_addr(&[3u8; 4096], GuestAddress(0x0000000000000000 + 10 * 4096))
150             .unwrap();
151         guest_memory
152             .write_all_at_addr(
153                 &[4u8; 3 * 1024 * 1024],
154                 GuestAddress(0x0000000000000000 + 20 * 4096),
155             )
156             .unwrap();
157         guest_memory
158             .write_all_at_addr(&[5u8; 4096], GuestAddress(0x0000000100000000))
159             .unwrap();
160         guest_memory
161             .write_all_at_addr(&[6u8; 4096], GuestAddress(0x0000000100000000 + 4096))
162             .unwrap();
163         guest_memory
164             .write_all_at_addr(&[7u8; 4096], GuestAddress(0x0000000100000000 + 10 * 4096))
165             .unwrap();
166         guest_memory
167             .write_all_at_addr(
168                 &[8u8; 3 * 1024 * 1024],
169                 GuestAddress(0x0000000100000000 + 20 * 4096),
170             )
171             .unwrap();
172 
173         controller.enable().unwrap();
174 
175         let status = controller.status().unwrap();
176         assert_eq!(status.state, SwapState::Pending);
177         assert_eq!(status.state_transition.pages, 1542);
178 
179         let mut buf = [0u8; 4096];
180         let mut long_buf = [0u8; 3 * 1024 * 1024];
181 
182         guest_memory
183             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000))
184             .unwrap();
185         assert_eq!(buf, [1u8; 4096]);
186         guest_memory
187             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 4096))
188             .unwrap();
189         assert_eq!(buf, [2u8; 4096]);
190         guest_memory
191             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 2 * 4096))
192             .unwrap();
193         assert_eq!(buf, [0u8; 4096]);
194         guest_memory
195             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 10 * 4096))
196             .unwrap();
197         assert_eq!(buf, [3u8; 4096]);
198         guest_memory
199             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000000000000 + 20 * 4096))
200             .unwrap();
201         assert_eq!(long_buf, [4u8; 3 * 1024 * 1024]);
202 
203         guest_memory
204             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000))
205             .unwrap();
206         assert_eq!(buf, [5u8; 4096]);
207         guest_memory
208             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 4096))
209             .unwrap();
210         assert_eq!(buf, [6u8; 4096]);
211         guest_memory
212             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 2 * 4096))
213             .unwrap();
214         assert_eq!(buf, [0u8; 4096]);
215         guest_memory
216             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 10 * 4096))
217             .unwrap();
218         assert_eq!(buf, [7u8; 4096]);
219         guest_memory
220             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000100000000 + 20 * 4096))
221             .unwrap();
222         assert_eq!(long_buf, [8u8; 3 * 1024 * 1024]);
223 
224         controller.enable().unwrap();
225         assert_eq!(controller.status().unwrap().state_transition.pages, 1544);
226 
227         guest_memory
228             .write_all_at_addr(&[9u8; 4096], GuestAddress(0x0000000000000000 + 4096))
229             .unwrap();
230         guest_memory
231             .write_all_at_addr(&[10u8; 4096], GuestAddress(0x0000000000000000 + 2 * 4096))
232             .unwrap();
233 
234         controller.enable().unwrap();
235         assert_eq!(controller.status().unwrap().state_transition.pages, 2);
236 
237         guest_memory
238             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000))
239             .unwrap();
240         assert_eq!(buf, [1u8; 4096]);
241         guest_memory
242             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 4096))
243             .unwrap();
244         assert_eq!(buf, [9u8; 4096]);
245         guest_memory
246             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 2 * 4096))
247             .unwrap();
248         assert_eq!(buf, [10u8; 4096]);
249         guest_memory
250             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 10 * 4096))
251             .unwrap();
252         assert_eq!(buf, [3u8; 4096]);
253         guest_memory
254             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000000000000 + 20 * 4096))
255             .unwrap();
256         assert_eq!(long_buf, [4u8; 3 * 1024 * 1024]);
257 
258         guest_memory
259             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000))
260             .unwrap();
261         assert_eq!(buf, [5u8; 4096]);
262         guest_memory
263             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 4096))
264             .unwrap();
265         assert_eq!(buf, [6u8; 4096]);
266         guest_memory
267             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 2 * 4096))
268             .unwrap();
269         assert_eq!(buf, [0u8; 4096]);
270         guest_memory
271             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 10 * 4096))
272             .unwrap();
273         assert_eq!(buf, [7u8; 4096]);
274         guest_memory
275             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000100000000 + 20 * 4096))
276             .unwrap();
277         assert_eq!(long_buf, [8u8; 3 * 1024 * 1024]);
278 
279         controller.enable().unwrap();
280         drop(controller);
281 
282         guest_memory
283             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000))
284             .unwrap();
285         assert_eq!(buf, [1u8; 4096]);
286         guest_memory
287             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 4096))
288             .unwrap();
289         assert_eq!(buf, [9u8; 4096]);
290         guest_memory
291             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 2 * 4096))
292             .unwrap();
293         assert_eq!(buf, [10u8; 4096]);
294         guest_memory
295             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 10 * 4096))
296             .unwrap();
297         assert_eq!(buf, [3u8; 4096]);
298         guest_memory
299             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000000000000 + 20 * 4096))
300             .unwrap();
301         assert_eq!(long_buf, [4u8; 3 * 1024 * 1024]);
302 
303         guest_memory
304             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000))
305             .unwrap();
306         assert_eq!(buf, [5u8; 4096]);
307         guest_memory
308             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 4096))
309             .unwrap();
310         assert_eq!(buf, [6u8; 4096]);
311         guest_memory
312             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 2 * 4096))
313             .unwrap();
314         assert_eq!(buf, [0u8; 4096]);
315         guest_memory
316             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 10 * 4096))
317             .unwrap();
318         assert_eq!(buf, [7u8; 4096]);
319         guest_memory
320             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000100000000 + 20 * 4096))
321             .unwrap();
322         assert_eq!(long_buf, [8u8; 3 * 1024 * 1024]);
323     }
324 
controller_swap_out()325     pub fn controller_swap_out() {
326         let dir = tempfile::tempdir().unwrap();
327         let guest_memory = create_guest_memory();
328 
329         let controller = SwapController::launch(guest_memory.clone(), dir.path(), &None).unwrap();
330 
331         guest_memory
332             .write_all_at_addr(&[1u8; 4096], GuestAddress(0x0000000000000000))
333             .unwrap();
334         guest_memory
335             .write_all_at_addr(&[2u8; 4096], GuestAddress(0x0000000000000000 + 4096))
336             .unwrap();
337         guest_memory
338             .write_all_at_addr(&[3u8; 4096], GuestAddress(0x0000000000000000 + 10 * 4096))
339             .unwrap();
340         guest_memory
341             .write_all_at_addr(
342                 &[4u8; 3 * 1024 * 1024],
343                 GuestAddress(0x0000000000000000 + 20 * 4096),
344             )
345             .unwrap();
346         guest_memory
347             .write_all_at_addr(&[5u8; 4096], GuestAddress(0x0000000100000000))
348             .unwrap();
349         guest_memory
350             .write_all_at_addr(&[6u8; 4096], GuestAddress(0x0000000100000000 + 4096))
351             .unwrap();
352         guest_memory
353             .write_all_at_addr(&[7u8; 4096], GuestAddress(0x0000000100000000 + 10 * 4096))
354             .unwrap();
355         guest_memory
356             .write_all_at_addr(
357                 &[8u8; 3 * 1024 * 1024],
358                 GuestAddress(0x0000000100000000 + 20 * 4096),
359             )
360             .unwrap();
361 
362         controller.enable().unwrap();
363         controller.swap_out().unwrap();
364         assert!(wait_for_state(&controller, SwapState::Active));
365         assert_eq!(controller.status().unwrap().state_transition.pages, 1542);
366 
367         let mut buf = [0u8; 4096];
368         let mut long_buf = [0u8; 3 * 1024 * 1024];
369 
370         guest_memory
371             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000))
372             .unwrap();
373         assert_eq!(buf, [1u8; 4096]);
374         guest_memory
375             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 4096))
376             .unwrap();
377         assert_eq!(buf, [2u8; 4096]);
378         guest_memory
379             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 2 * 4096))
380             .unwrap();
381         assert_eq!(buf, [0u8; 4096]);
382         guest_memory
383             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 10 * 4096))
384             .unwrap();
385         assert_eq!(buf, [3u8; 4096]);
386         guest_memory
387             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000000000000 + 20 * 4096))
388             .unwrap();
389         assert_eq!(long_buf, [4u8; 3 * 1024 * 1024]);
390 
391         guest_memory
392             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000))
393             .unwrap();
394         assert_eq!(buf, [5u8; 4096]);
395         guest_memory
396             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 4096))
397             .unwrap();
398         assert_eq!(buf, [6u8; 4096]);
399         guest_memory
400             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 2 * 4096))
401             .unwrap();
402         assert_eq!(buf, [0u8; 4096]);
403         guest_memory
404             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 10 * 4096))
405             .unwrap();
406         assert_eq!(buf, [7u8; 4096]);
407         guest_memory
408             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000100000000 + 20 * 4096))
409             .unwrap();
410         assert_eq!(long_buf, [8u8; 3 * 1024 * 1024]);
411 
412         controller.enable().unwrap();
413         controller.swap_out().unwrap();
414         assert!(wait_for_state(&controller, SwapState::Active));
415         assert_eq!(controller.status().unwrap().state_transition.pages, 1544);
416 
417         guest_memory
418             .write_all_at_addr(&[9u8; 4096], GuestAddress(0x0000000000000000 + 4096))
419             .unwrap();
420         guest_memory
421             .write_all_at_addr(&[10u8; 4096], GuestAddress(0x0000000000000000 + 2 * 4096))
422             .unwrap();
423 
424         controller.enable().unwrap();
425         controller.swap_out().unwrap();
426         assert!(wait_for_state(&controller, SwapState::Active));
427         assert_eq!(controller.status().unwrap().state_transition.pages, 2);
428 
429         guest_memory
430             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000))
431             .unwrap();
432         assert_eq!(buf, [1u8; 4096]);
433         guest_memory
434             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 4096))
435             .unwrap();
436         assert_eq!(buf, [9u8; 4096]);
437         guest_memory
438             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 2 * 4096))
439             .unwrap();
440         assert_eq!(buf, [10u8; 4096]);
441         guest_memory
442             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 10 * 4096))
443             .unwrap();
444         assert_eq!(buf, [3u8; 4096]);
445         guest_memory
446             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000000000000 + 20 * 4096))
447             .unwrap();
448         assert_eq!(long_buf, [4u8; 3 * 1024 * 1024]);
449 
450         guest_memory
451             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000))
452             .unwrap();
453         assert_eq!(buf, [5u8; 4096]);
454         guest_memory
455             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 4096))
456             .unwrap();
457         assert_eq!(buf, [6u8; 4096]);
458         guest_memory
459             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 2 * 4096))
460             .unwrap();
461         assert_eq!(buf, [0u8; 4096]);
462         guest_memory
463             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 10 * 4096))
464             .unwrap();
465         assert_eq!(buf, [7u8; 4096]);
466         guest_memory
467             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000100000000 + 20 * 4096))
468             .unwrap();
469         assert_eq!(long_buf, [8u8; 3 * 1024 * 1024]);
470 
471         controller.enable().unwrap();
472         controller.swap_out().unwrap();
473         assert!(wait_for_state(&controller, SwapState::Active));
474         drop(controller);
475 
476         guest_memory
477             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000))
478             .unwrap();
479         assert_eq!(buf, [1u8; 4096]);
480         guest_memory
481             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 4096))
482             .unwrap();
483         assert_eq!(buf, [9u8; 4096]);
484         guest_memory
485             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 2 * 4096))
486             .unwrap();
487         assert_eq!(buf, [10u8; 4096]);
488         guest_memory
489             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 10 * 4096))
490             .unwrap();
491         assert_eq!(buf, [3u8; 4096]);
492         guest_memory
493             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000000000000 + 20 * 4096))
494             .unwrap();
495         assert_eq!(long_buf, [4u8; 3 * 1024 * 1024]);
496 
497         guest_memory
498             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000))
499             .unwrap();
500         assert_eq!(buf, [5u8; 4096]);
501         guest_memory
502             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 4096))
503             .unwrap();
504         assert_eq!(buf, [6u8; 4096]);
505         guest_memory
506             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 2 * 4096))
507             .unwrap();
508         assert_eq!(buf, [0u8; 4096]);
509         guest_memory
510             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 10 * 4096))
511             .unwrap();
512         assert_eq!(buf, [7u8; 4096]);
513         guest_memory
514             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000100000000 + 20 * 4096))
515             .unwrap();
516         assert_eq!(long_buf, [8u8; 3 * 1024 * 1024]);
517     }
518 
controller_trim()519     pub fn controller_trim() {
520         let dir = tempfile::tempdir().unwrap();
521         let guest_memory = create_guest_memory();
522 
523         let controller = SwapController::launch(guest_memory.clone(), dir.path(), &None).unwrap();
524 
525         guest_memory
526             .write_all_at_addr(&[1u8; 4096], GuestAddress(0x0000000000000000))
527             .unwrap();
528         guest_memory
529             .write_all_at_addr(&[2u8; 4096], GuestAddress(0x0000000000000000 + 4096))
530             .unwrap();
531         guest_memory
532             .write_all_at_addr(&[0u8; 4096], GuestAddress(0x0000000000000000 + 2 * 4096))
533             .unwrap();
534         guest_memory
535             .write_all_at_addr(&[3u8; 4096], GuestAddress(0x0000000000000000 + 10 * 4096))
536             .unwrap();
537         guest_memory
538             .write_all_at_addr(
539                 &[4u8; 3 * 1024 * 1024],
540                 GuestAddress(0x0000000000000000 + 20 * 4096),
541             )
542             .unwrap();
543         guest_memory
544             .write_all_at_addr(&[5u8; 4096], GuestAddress(0x0000000100000000))
545             .unwrap();
546         guest_memory
547             .write_all_at_addr(&[6u8; 4096], GuestAddress(0x0000000100000000 + 4096))
548             .unwrap();
549         guest_memory
550             .write_all_at_addr(&[0u8; 4096], GuestAddress(0x0000000100000000 + 2 * 4096))
551             .unwrap();
552         guest_memory
553             .write_all_at_addr(&[7u8; 4096], GuestAddress(0x0000000100000000 + 10 * 4096))
554             .unwrap();
555         guest_memory
556             .write_all_at_addr(
557                 &[8u8; 3 * 1024 * 1024],
558                 GuestAddress(0x0000000100000000 + 20 * 4096),
559             )
560             .unwrap();
561 
562         controller.enable().unwrap();
563         controller.trim().unwrap();
564         assert!(wait_for_state(&controller, SwapState::Pending));
565         assert_eq!(controller.status().unwrap().state_transition.pages, 2);
566         controller.swap_out().unwrap();
567         assert!(wait_for_state(&controller, SwapState::Active));
568         assert_eq!(controller.status().unwrap().state_transition.pages, 1542);
569 
570         let mut buf = [0u8; 4096];
571         let mut long_buf = [0u8; 3 * 1024 * 1024];
572 
573         guest_memory
574             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000))
575             .unwrap();
576         assert_eq!(buf, [1u8; 4096]);
577         guest_memory
578             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 4096))
579             .unwrap();
580         assert_eq!(buf, [2u8; 4096]);
581         guest_memory
582             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 2 * 4096))
583             .unwrap();
584         assert_eq!(buf, [0u8; 4096]);
585         guest_memory
586             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 3 * 4096))
587             .unwrap();
588         assert_eq!(buf, [0u8; 4096]);
589         guest_memory
590             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 10 * 4096))
591             .unwrap();
592         assert_eq!(buf, [3u8; 4096]);
593         guest_memory
594             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000000000000 + 20 * 4096))
595             .unwrap();
596         assert_eq!(long_buf, [4u8; 3 * 1024 * 1024]);
597 
598         guest_memory
599             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000))
600             .unwrap();
601         assert_eq!(buf, [5u8; 4096]);
602         guest_memory
603             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 4096))
604             .unwrap();
605         assert_eq!(buf, [6u8; 4096]);
606         guest_memory
607             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 2 * 4096))
608             .unwrap();
609         assert_eq!(buf, [0u8; 4096]);
610         guest_memory
611             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 3 * 4096))
612             .unwrap();
613         assert_eq!(buf, [0u8; 4096]);
614         guest_memory
615             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 10 * 4096))
616             .unwrap();
617         assert_eq!(buf, [7u8; 4096]);
618         guest_memory
619             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000100000000 + 20 * 4096))
620             .unwrap();
621         assert_eq!(long_buf, [8u8; 3 * 1024 * 1024]);
622 
623         guest_memory
624             .write_all_at_addr(&[9u8; 4096], GuestAddress(0x0000000000000000 + 4096))
625             .unwrap();
626         guest_memory
627             .write_all_at_addr(&[10u8; 4096], GuestAddress(0x0000000000000000 + 3 * 4096))
628             .unwrap();
629 
630         controller.enable().unwrap();
631         controller.trim().unwrap();
632         assert!(wait_for_state(&controller, SwapState::Pending));
633         assert_eq!(controller.status().unwrap().state_transition.pages, 1544);
634         controller.swap_out().unwrap();
635         assert!(wait_for_state(&controller, SwapState::Active));
636         assert_eq!(controller.status().unwrap().state_transition.pages, 2);
637         drop(controller);
638 
639         guest_memory
640             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000))
641             .unwrap();
642         assert_eq!(buf, [1u8; 4096]);
643         guest_memory
644             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 4096))
645             .unwrap();
646         assert_eq!(buf, [9u8; 4096]);
647         guest_memory
648             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 2 * 4096))
649             .unwrap();
650         assert_eq!(buf, [0u8; 4096]);
651         guest_memory
652             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 3 * 4096))
653             .unwrap();
654         assert_eq!(buf, [10u8; 4096]);
655         guest_memory
656             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 10 * 4096))
657             .unwrap();
658         assert_eq!(buf, [3u8; 4096]);
659         guest_memory
660             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000000000000 + 20 * 4096))
661             .unwrap();
662         assert_eq!(long_buf, [4u8; 3 * 1024 * 1024]);
663 
664         guest_memory
665             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000))
666             .unwrap();
667         assert_eq!(buf, [5u8; 4096]);
668         guest_memory
669             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 4096))
670             .unwrap();
671         assert_eq!(buf, [6u8; 4096]);
672         guest_memory
673             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 2 * 4096))
674             .unwrap();
675         assert_eq!(buf, [0u8; 4096]);
676         guest_memory
677             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 10 * 4096))
678             .unwrap();
679         assert_eq!(buf, [7u8; 4096]);
680         guest_memory
681             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000100000000 + 20 * 4096))
682             .unwrap();
683         assert_eq!(long_buf, [8u8; 3 * 1024 * 1024]);
684     }
685 
controller_disable()686     pub fn controller_disable() {
687         let dir = tempfile::tempdir().unwrap();
688         let guest_memory = create_guest_memory();
689 
690         let controller = SwapController::launch(guest_memory.clone(), dir.path(), &None).unwrap();
691 
692         guest_memory
693             .write_all_at_addr(&[1u8; 4096], GuestAddress(0x0000000000000000))
694             .unwrap();
695         guest_memory
696             .write_all_at_addr(&[2u8; 4096], GuestAddress(0x0000000000000000 + 4096))
697             .unwrap();
698         guest_memory
699             .write_all_at_addr(&[0u8; 4096], GuestAddress(0x0000000000000000 + 2 * 4096))
700             .unwrap();
701         guest_memory
702             .write_all_at_addr(&[3u8; 4096], GuestAddress(0x0000000000000000 + 10 * 4096))
703             .unwrap();
704         guest_memory
705             .write_all_at_addr(
706                 &[4u8; 3 * 1024 * 1024],
707                 GuestAddress(0x0000000000000000 + 20 * 4096),
708             )
709             .unwrap();
710         guest_memory
711             .write_all_at_addr(&[5u8; 4096], GuestAddress(0x0000000100000000))
712             .unwrap();
713         guest_memory
714             .write_all_at_addr(&[6u8; 4096], GuestAddress(0x0000000100000000 + 4096))
715             .unwrap();
716         guest_memory
717             .write_all_at_addr(&[0u8; 4096], GuestAddress(0x0000000100000000 + 2 * 4096))
718             .unwrap();
719         guest_memory
720             .write_all_at_addr(&[7u8; 4096], GuestAddress(0x0000000100000000 + 10 * 4096))
721             .unwrap();
722         guest_memory
723             .write_all_at_addr(
724                 &[8u8; 3 * 1024 * 1024],
725                 GuestAddress(0x0000000100000000 + 20 * 4096),
726             )
727             .unwrap();
728 
729         controller.enable().unwrap();
730         controller.disable(false).unwrap();
731         assert!(wait_for_state(&controller, SwapState::Ready));
732         assert_eq!(controller.status().unwrap().state_transition.pages, 1544);
733 
734         let mut buf = [0u8; 4096];
735         let mut long_buf = [0u8; 3 * 1024 * 1024];
736 
737         guest_memory
738             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000))
739             .unwrap();
740         assert_eq!(buf, [1u8; 4096]);
741         guest_memory
742             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 4096))
743             .unwrap();
744         assert_eq!(buf, [2u8; 4096]);
745         guest_memory
746             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 2 * 4096))
747             .unwrap();
748         assert_eq!(buf, [0u8; 4096]);
749         guest_memory
750             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 3 * 4096))
751             .unwrap();
752         assert_eq!(buf, [0u8; 4096]);
753         guest_memory
754             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 10 * 4096))
755             .unwrap();
756         assert_eq!(buf, [3u8; 4096]);
757         guest_memory
758             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000000000000 + 20 * 4096))
759             .unwrap();
760         assert_eq!(long_buf, [4u8; 3 * 1024 * 1024]);
761 
762         guest_memory
763             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000))
764             .unwrap();
765         assert_eq!(buf, [5u8; 4096]);
766         guest_memory
767             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 4096))
768             .unwrap();
769         assert_eq!(buf, [6u8; 4096]);
770         guest_memory
771             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 2 * 4096))
772             .unwrap();
773         assert_eq!(buf, [0u8; 4096]);
774         guest_memory
775             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 3 * 4096))
776             .unwrap();
777         assert_eq!(buf, [0u8; 4096]);
778         guest_memory
779             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 10 * 4096))
780             .unwrap();
781         assert_eq!(buf, [7u8; 4096]);
782         guest_memory
783             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000100000000 + 20 * 4096))
784             .unwrap();
785         assert_eq!(long_buf, [8u8; 3 * 1024 * 1024]);
786 
787         controller.enable().unwrap();
788         controller.trim().unwrap();
789         assert!(wait_for_state(&controller, SwapState::Pending));
790         controller.swap_out().unwrap();
791         assert!(wait_for_state(&controller, SwapState::Active));
792         controller.disable(false).unwrap();
793         assert!(wait_for_state(&controller, SwapState::Ready));
794         assert_eq!(controller.status().unwrap().state_transition.pages, 1542);
795 
796         guest_memory
797             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000))
798             .unwrap();
799         assert_eq!(buf, [1u8; 4096]);
800         guest_memory
801             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 4096))
802             .unwrap();
803         assert_eq!(buf, [2u8; 4096]);
804         guest_memory
805             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 2 * 4096))
806             .unwrap();
807         assert_eq!(buf, [0u8; 4096]);
808         guest_memory
809             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 3 * 4096))
810             .unwrap();
811         assert_eq!(buf, [0u8; 4096]);
812         guest_memory
813             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000000000000 + 10 * 4096))
814             .unwrap();
815         assert_eq!(buf, [3u8; 4096]);
816         guest_memory
817             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000000000000 + 20 * 4096))
818             .unwrap();
819         assert_eq!(long_buf, [4u8; 3 * 1024 * 1024]);
820 
821         guest_memory
822             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000))
823             .unwrap();
824         assert_eq!(buf, [5u8; 4096]);
825         guest_memory
826             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 4096))
827             .unwrap();
828         assert_eq!(buf, [6u8; 4096]);
829         guest_memory
830             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 2 * 4096))
831             .unwrap();
832         assert_eq!(buf, [0u8; 4096]);
833         guest_memory
834             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 3 * 4096))
835             .unwrap();
836         assert_eq!(buf, [0u8; 4096]);
837         guest_memory
838             .read_exact_at_addr(&mut buf, GuestAddress(0x0000000100000000 + 10 * 4096))
839             .unwrap();
840         assert_eq!(buf, [7u8; 4096]);
841         guest_memory
842             .read_exact_at_addr(&mut long_buf, GuestAddress(0x0000000100000000 + 20 * 4096))
843             .unwrap();
844         assert_eq!(long_buf, [8u8; 3 * 1024 * 1024]);
845     }
846 }
847 
main()848 fn main() {
849     let args = libtest_mimic::Arguments {
850         // Force single-threaded execution to allow safe use of libc::fork in these tests.
851         test_threads: Some(1),
852         ..libtest_mimic::Arguments::from_args()
853     };
854 
855     let tests = vec![
856         #[cfg(all(unix, feature = "enable"))]
857         libtest_mimic::Trial::test("register_region_skip_obsolete_process", move || {
858             base::test_utils::call_test_with_sudo("register_region_skip_obsolete_process_impl");
859             Ok(())
860         }),
861         #[cfg(all(unix, feature = "enable"))]
862         libtest_mimic::Trial::test("unregister_region_skip_obsolete_process", move || {
863             base::test_utils::call_test_with_sudo("unregister_region_skip_obsolete_process_impl");
864             Ok(())
865         }),
866         #[cfg(all(unix, feature = "enable"))]
867         libtest_mimic::Trial::test("register_region_skip_obsolete_process_impl", move || {
868             test::register_region_skip_obsolete_process();
869             Ok(())
870         })
871         .with_ignored_flag(true),
872         #[cfg(all(unix, feature = "enable"))]
873         libtest_mimic::Trial::test("unregister_region_skip_obsolete_process_impl", move || {
874             test::unregister_region_skip_obsolete_process();
875             Ok(())
876         })
877         .with_ignored_flag(true),
878         #[cfg(all(unix, feature = "enable"))]
879         libtest_mimic::Trial::test("controller_enable", move || {
880             base::test_utils::call_test_with_sudo("controller_enable_impl");
881             Ok(())
882         }),
883         #[cfg(all(unix, feature = "enable"))]
884         libtest_mimic::Trial::test("controller_enable_impl", move || {
885             test::controller_enable();
886             Ok(())
887         })
888         .with_ignored_flag(true),
889         #[cfg(all(unix, feature = "enable"))]
890         libtest_mimic::Trial::test("controller_swap_out", move || {
891             base::test_utils::call_test_with_sudo("controller_swap_out_impl");
892             Ok(())
893         }),
894         #[cfg(all(unix, feature = "enable"))]
895         libtest_mimic::Trial::test("controller_swap_out_impl", move || {
896             test::controller_swap_out();
897             Ok(())
898         })
899         .with_ignored_flag(true),
900         #[cfg(all(unix, feature = "enable"))]
901         libtest_mimic::Trial::test("controller_trim", move || {
902             base::test_utils::call_test_with_sudo("controller_trim_impl");
903             Ok(())
904         }),
905         #[cfg(all(unix, feature = "enable"))]
906         libtest_mimic::Trial::test("controller_trim_impl", move || {
907             test::controller_trim();
908             Ok(())
909         })
910         .with_ignored_flag(true),
911         #[cfg(all(unix, feature = "enable"))]
912         libtest_mimic::Trial::test("controller_disable", move || {
913             base::test_utils::call_test_with_sudo("controller_disable_impl");
914             Ok(())
915         }),
916         #[cfg(all(unix, feature = "enable"))]
917         libtest_mimic::Trial::test("controller_disable_impl", move || {
918             test::controller_disable();
919             Ok(())
920         })
921         .with_ignored_flag(true),
922     ];
923     libtest_mimic::run(&args, tests).exit();
924 }
925