1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright 2017, Anshuman Khandual, IBM Corp.
5 * Works on architectures which support 128TB virtual
6 * address range and beyond.
17 * Maximum address range mapped with a single mmap()
18 * call is little bit more than 16GB. Hence 16GB is
19 * chosen as the single chunk size for address space
22 #define MAP_CHUNK_SIZE 17179869184UL /* 16GB */
25 * Address space till 128TB is mapped without any hint
26 * and is enabled by default. Address space beyond 128TB
27 * till 512TB is obtained by passing hint address as the
28 * first argument into mmap() system call.
30 * The process heap address space is divided into two
31 * different areas one below 128TB and one above 128TB
32 * till it reaches 512TB. One with size 128TB and the
35 * On Arm64 the address space is 256TB and no high mappings
36 * are supported so far.
39 #define NR_CHUNKS_128TB 8192UL /* Number of 16GB chunks for 128TB */
40 #define NR_CHUNKS_256TB (NR_CHUNKS_128TB * 2UL)
41 #define NR_CHUNKS_384TB (NR_CHUNKS_128TB * 3UL)
43 #define ADDR_MARK_128TB (1UL << 47) /* First address beyond 128TB */
44 #define ADDR_MARK_256TB (1UL << 48) /* First address beyond 256TB */
47 #define HIGH_ADDR_MARK ADDR_MARK_256TB
48 #define HIGH_ADDR_SHIFT 49
49 #define NR_CHUNKS_LOW NR_CHUNKS_256TB
50 #define NR_CHUNKS_HIGH 0
52 #define HIGH_ADDR_MARK ADDR_MARK_128TB
53 #define HIGH_ADDR_SHIFT 48
54 #define NR_CHUNKS_LOW NR_CHUNKS_128TB
55 #define NR_CHUNKS_HIGH NR_CHUNKS_384TB
58 static char *hind_addr(void)
60 int bits
= HIGH_ADDR_SHIFT
+ rand() % (63 - HIGH_ADDR_SHIFT
);
62 return (char *) (1UL << bits
);
65 static int validate_addr(char *ptr
, int high_addr
)
67 unsigned long addr
= (unsigned long) ptr
;
70 if (addr
< HIGH_ADDR_MARK
) {
71 printf("Bad address %lx\n", addr
);
77 if (addr
> HIGH_ADDR_MARK
) {
78 printf("Bad address %lx\n", addr
);
84 static int validate_lower_address_hint(void)
88 ptr
= mmap((void *) (1UL << 45), MAP_CHUNK_SIZE
, PROT_READ
|
89 PROT_WRITE
, MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
91 if (ptr
== MAP_FAILED
)
97 int main(int argc
, char *argv
[])
99 char *ptr
[NR_CHUNKS_LOW
];
100 char *hptr
[NR_CHUNKS_HIGH
];
102 unsigned long i
, lchunks
, hchunks
;
104 for (i
= 0; i
< NR_CHUNKS_LOW
; i
++) {
105 ptr
[i
] = mmap(NULL
, MAP_CHUNK_SIZE
, PROT_READ
| PROT_WRITE
,
106 MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
108 if (ptr
[i
] == MAP_FAILED
) {
109 if (validate_lower_address_hint())
114 if (validate_addr(ptr
[i
], 0))
119 for (i
= 0; i
< NR_CHUNKS_HIGH
; i
++) {
121 hptr
[i
] = mmap(hint
, MAP_CHUNK_SIZE
, PROT_READ
| PROT_WRITE
,
122 MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
124 if (hptr
[i
] == MAP_FAILED
)
127 if (validate_addr(hptr
[i
], 1))
132 for (i
= 0; i
< lchunks
; i
++)
133 munmap(ptr
[i
], MAP_CHUNK_SIZE
);
135 for (i
= 0; i
< hchunks
; i
++)
136 munmap(hptr
[i
], MAP_CHUNK_SIZE
);