1 // SPDX-License-Identifier: GPL-2.0+
3 // Copyright 2019, Michael Ellerman, IBM Corp.
5 // Test that allocating memory beyond the memory limit and then forking is
6 // handled correctly, ie. the child is able to access the mappings beyond the
7 // memory limit and the child's writes are not visible to the parent.
12 #include <sys/types.h>
19 #ifndef MAP_FIXED_NOREPLACE
20 #define MAP_FIXED_NOREPLACE MAP_FIXED // "Should be safe" above 512TB
26 int p2c
[2], c2p
[2], rc
, status
, c
, *p
;
27 unsigned long page_size
;
30 page_size
= sysconf(_SC_PAGESIZE
);
31 SKIP_IF(page_size
!= 65536);
33 // Create a mapping at 512TB to allocate an extended_id
34 p
= mmap((void *)(512ul << 40), page_size
, PROT_READ
| PROT_WRITE
,
35 MAP_PRIVATE
| MAP_ANONYMOUS
| MAP_FIXED_NOREPLACE
, -1, 0);
36 if (p
== MAP_FAILED
) {
38 printf("Error: couldn't mmap(), confirm kernel has 4TB support?\n");
42 printf("parent writing %p = 1\n", p
);
45 FAIL_IF(pipe(p2c
) == -1 || pipe(c2p
) == -1);
49 FAIL_IF(read(p2c
[0], &c
, 1) != 1);
52 printf("child writing %p = %d\n", p
, pid
);
55 FAIL_IF(write(c2p
[1], &c
, 1) != 1);
56 FAIL_IF(read(p2c
[0], &c
, 1) != 1);
61 FAIL_IF(write(p2c
[1], &c
, 1) != 1);
62 FAIL_IF(read(c2p
[0], &c
, 1) != 1);
64 // Prevent compiler optimisation
68 printf("parent reading %p = %d\n", p
, *p
);
70 printf("Error: BUG! parent saw child's write! *p = %d\n", *p
);
74 FAIL_IF(write(p2c
[1], &c
, 1) != 1);
75 FAIL_IF(waitpid(pid
, &status
, 0) == -1);
76 FAIL_IF(!WIFEXITED(status
) || WEXITSTATUS(status
));
79 printf("success: test completed OK\n");
86 return test_harness(test
, "large_vm_fork_separation");