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(®ions, &[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(®ions, &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(®ions, &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