From 9f7425c152abd9baeaca026c310dcafcbb605935 Mon Sep 17 00:00:00 2001 From: Masamichi Takagi Date: Fri, 7 Dec 2018 19:28:51 +0900 Subject: [PATCH] Add test programs for lage page Tests arm64 specific, contiguous bit based large pages as well. Change-Id: I09edad8cfde6c23a259f1f32cfc97974d9cb63c3 --- test/large_page/README | 88 ++++++ test/large_page/arm64/001_4K.c | 72 +++++ test/large_page/arm64/001_64K.c | 56 ++++ test/large_page/arm64/101_4K.c | 75 +++++ test/large_page/arm64/101_64K.c | 59 ++++ test/large_page/arm64/201_4K.c | 81 +++++ test/large_page/arm64/201_64K.c | 66 +++++ test/large_page/arm64/301_4K.c | 84 ++++++ test/large_page/arm64/301_64K.c | 69 +++++ test/large_page/arm64/401_4K.c | 35 +++ test/large_page/arm64/401_64K.c | 35 +++ test/large_page/arm64/402_4K.c | 35 +++ test/large_page/arm64/402_64K.c | 35 +++ test/large_page/arm64/403_4K.c | 35 +++ test/large_page/arm64/404_4K.c | 35 +++ test/large_page/arm64/501_4K.c | 50 ++++ test/large_page/arm64/501_4K.lds | 224 ++++++++++++++ test/large_page/arm64/501_64K.c | 50 ++++ test/large_page/arm64/501_64K.lds | 224 ++++++++++++++ test/large_page/arm64/501_64K.org.lds | 268 +++++++++++++++++ test/large_page/arm64/502_4K.c | 50 ++++ test/large_page/arm64/502_4K.lds | 224 ++++++++++++++ test/large_page/arm64/502_64K.c | 41 +++ test/large_page/arm64/502_64K.lds | 224 ++++++++++++++ test/large_page/arm64/503_4K.c | 50 ++++ test/large_page/arm64/503_4K.lds | 224 ++++++++++++++ test/large_page/arm64/504_4K.c | 41 +++ test/large_page/arm64/504_4K.lds | 224 ++++++++++++++ test/large_page/arm64/601_4K.c | 77 +++++ test/large_page/arm64/601_64K.c | 63 ++++ test/large_page/arm64/Makefile | 46 +++ test/large_page/arm64/fini/601_4K.fini | 4 + test/large_page/arm64/fini/601_64K.fini | 2 + test/large_page/arm64/init/001_4K.init | 2 + test/large_page/arm64/init/001_64K.init | 1 + test/large_page/arm64/init/101_4K.init | 2 + test/large_page/arm64/init/101_64K.init | 1 + test/large_page/arm64/init/201_4K.init | 2 + test/large_page/arm64/init/201_64K.init | 1 + test/large_page/arm64/init/301_4K.init | 2 + test/large_page/arm64/init/301_64K.init | 1 + test/large_page/arm64/init/401_4K.init | 2 + test/large_page/arm64/init/401_64K.init | 2 + test/large_page/arm64/init/402_4K.init | 2 + test/large_page/arm64/init/402_64K.init | 2 + test/large_page/arm64/init/403_4K.init | 2 + test/large_page/arm64/init/404_4K.init | 2 + test/large_page/arm64/init/501_4K.init | 2 + test/large_page/arm64/init/501_64K.init | 2 + test/large_page/arm64/init/502_4K.init | 2 + test/large_page/arm64/init/502_64K.init | 2 + test/large_page/arm64/init/503_4K.init | 2 + test/large_page/arm64/init/504_4K.init | 2 + test/large_page/arm64/init/601_4K.init | 14 + test/large_page/arm64/init/601_64K.init | 7 + test/large_page/arm64/test_set.conf | 57 ++++ test/large_page/check.sh | 28 ++ test/large_page/driver.sh | 41 +++ test/large_page/large_page.patch | 374 ++++++++++++++++++++++++ test/large_page/run.sh | 69 +++++ test/large_page/util.h | 56 ++++ test/large_page/x86_64/001_4K.c | 58 ++++ test/large_page/x86_64/101_4K.c | 61 ++++ test/large_page/x86_64/201_4K.c | 67 +++++ test/large_page/x86_64/301_4K.c | 70 +++++ test/large_page/x86_64/401_4K.c | 35 +++ test/large_page/x86_64/402_4K.c | 35 +++ test/large_page/x86_64/501_4K.c | 50 ++++ test/large_page/x86_64/501_4K.lds | 255 ++++++++++++++++ test/large_page/x86_64/501_4K.org.lds | 292 ++++++++++++++++++ test/large_page/x86_64/502_4K.c | 49 ++++ test/large_page/x86_64/502_4K.lds | 252 ++++++++++++++++ test/large_page/x86_64/601_4K.c | 63 ++++ test/large_page/x86_64/Makefile | 30 ++ test/large_page/x86_64/fini/601_4K.fini | 2 + test/large_page/x86_64/init/001_4K.init | 1 + test/large_page/x86_64/init/101_4K.init | 1 + test/large_page/x86_64/init/201_4K.init | 1 + test/large_page/x86_64/init/301_4K.init | 1 + test/large_page/x86_64/init/401_4K.init | 2 + test/large_page/x86_64/init/402_4K.init | 2 + test/large_page/x86_64/init/501_4K.init | 2 + test/large_page/x86_64/init/502_4K.init | 2 + test/large_page/x86_64/init/601_4K.init | 5 + test/large_page/x86_64/result.log | 38 +++ test/large_page/x86_64/test_set.conf | 22 ++ 86 files changed, 5024 insertions(+) create mode 100644 test/large_page/README create mode 100644 test/large_page/arm64/001_4K.c create mode 100644 test/large_page/arm64/001_64K.c create mode 100644 test/large_page/arm64/101_4K.c create mode 100644 test/large_page/arm64/101_64K.c create mode 100644 test/large_page/arm64/201_4K.c create mode 100644 test/large_page/arm64/201_64K.c create mode 100644 test/large_page/arm64/301_4K.c create mode 100644 test/large_page/arm64/301_64K.c create mode 100644 test/large_page/arm64/401_4K.c create mode 100644 test/large_page/arm64/401_64K.c create mode 100644 test/large_page/arm64/402_4K.c create mode 100644 test/large_page/arm64/402_64K.c create mode 100644 test/large_page/arm64/403_4K.c create mode 100644 test/large_page/arm64/404_4K.c create mode 100644 test/large_page/arm64/501_4K.c create mode 100644 test/large_page/arm64/501_4K.lds create mode 100644 test/large_page/arm64/501_64K.c create mode 100644 test/large_page/arm64/501_64K.lds create mode 100644 test/large_page/arm64/501_64K.org.lds create mode 100644 test/large_page/arm64/502_4K.c create mode 100644 test/large_page/arm64/502_4K.lds create mode 100644 test/large_page/arm64/502_64K.c create mode 100644 test/large_page/arm64/502_64K.lds create mode 100644 test/large_page/arm64/503_4K.c create mode 100644 test/large_page/arm64/503_4K.lds create mode 100644 test/large_page/arm64/504_4K.c create mode 100644 test/large_page/arm64/504_4K.lds create mode 100644 test/large_page/arm64/601_4K.c create mode 100644 test/large_page/arm64/601_64K.c create mode 100644 test/large_page/arm64/Makefile create mode 100644 test/large_page/arm64/fini/601_4K.fini create mode 100644 test/large_page/arm64/fini/601_64K.fini create mode 100644 test/large_page/arm64/init/001_4K.init create mode 100644 test/large_page/arm64/init/001_64K.init create mode 100644 test/large_page/arm64/init/101_4K.init create mode 100644 test/large_page/arm64/init/101_64K.init create mode 100644 test/large_page/arm64/init/201_4K.init create mode 100644 test/large_page/arm64/init/201_64K.init create mode 100644 test/large_page/arm64/init/301_4K.init create mode 100644 test/large_page/arm64/init/301_64K.init create mode 100644 test/large_page/arm64/init/401_4K.init create mode 100644 test/large_page/arm64/init/401_64K.init create mode 100644 test/large_page/arm64/init/402_4K.init create mode 100644 test/large_page/arm64/init/402_64K.init create mode 100644 test/large_page/arm64/init/403_4K.init create mode 100644 test/large_page/arm64/init/404_4K.init create mode 100644 test/large_page/arm64/init/501_4K.init create mode 100644 test/large_page/arm64/init/501_64K.init create mode 100644 test/large_page/arm64/init/502_4K.init create mode 100644 test/large_page/arm64/init/502_64K.init create mode 100644 test/large_page/arm64/init/503_4K.init create mode 100644 test/large_page/arm64/init/504_4K.init create mode 100644 test/large_page/arm64/init/601_4K.init create mode 100644 test/large_page/arm64/init/601_64K.init create mode 100644 test/large_page/arm64/test_set.conf create mode 100755 test/large_page/check.sh create mode 100755 test/large_page/driver.sh create mode 100644 test/large_page/large_page.patch create mode 100755 test/large_page/run.sh create mode 100644 test/large_page/util.h create mode 100644 test/large_page/x86_64/001_4K.c create mode 100644 test/large_page/x86_64/101_4K.c create mode 100644 test/large_page/x86_64/201_4K.c create mode 100644 test/large_page/x86_64/301_4K.c create mode 100644 test/large_page/x86_64/401_4K.c create mode 100644 test/large_page/x86_64/402_4K.c create mode 100644 test/large_page/x86_64/501_4K.c create mode 100644 test/large_page/x86_64/501_4K.lds create mode 100644 test/large_page/x86_64/501_4K.org.lds create mode 100644 test/large_page/x86_64/502_4K.c create mode 100644 test/large_page/x86_64/502_4K.lds create mode 100644 test/large_page/x86_64/601_4K.c create mode 100644 test/large_page/x86_64/Makefile create mode 100644 test/large_page/x86_64/fini/601_4K.fini create mode 100644 test/large_page/x86_64/init/001_4K.init create mode 100644 test/large_page/x86_64/init/101_4K.init create mode 100644 test/large_page/x86_64/init/201_4K.init create mode 100644 test/large_page/x86_64/init/301_4K.init create mode 100644 test/large_page/x86_64/init/401_4K.init create mode 100644 test/large_page/x86_64/init/402_4K.init create mode 100644 test/large_page/x86_64/init/501_4K.init create mode 100644 test/large_page/x86_64/init/502_4K.init create mode 100644 test/large_page/x86_64/init/601_4K.init create mode 100644 test/large_page/x86_64/result.log create mode 100644 test/large_page/x86_64/test_set.conf diff --git a/test/large_page/README b/test/large_page/README new file mode 100644 index 00000000..580ab6ef --- /dev/null +++ b/test/large_page/README @@ -0,0 +1,88 @@ +========== +How to run +========== + +(1) cd && patch -p0 < /test/large_page/large_page.patch +(2) Build McKernel +(3) cd /test/large_page/ && make test + +============ +What to test +============ + +Check the large page allocation with the following settings. + +------ +x86_64 +------ + +ID Program sections Size +--------------------------------------- +001 mmap + THP 2M, 1G +101 mmap + flag 2M, 1G +201 shmget + THP 2M, 1G +301 shmget + flag 2M, 1G +401 heap 2M +402 heap 1G +501 .data, .bss, stack 2M +601 mmap + hugetlbfs 2M, 1G +-------------------------------------- + +* 1 GiB for .data, .bss, stack is not tested because it's impossible to + align symbol to 1 GiB due to relocation restrictions. + +----- +arm64 +----- + +(1) Granule size: 64 KiB + +ID Program sections Size +--------------------------------------- +001 mmap + THP 2M, 512M +101 mmap + flag 2M, 512M +201 shmget + THP 2M, 512M +301 shmget + flag 2M, 512M +401 heap 2M +402 heap 512M +501 .data, .bss, stack 2M +502 .data, .bss 512M +601 mmap + hugetlbfs 2M, 512M + +* 512 MiB for stack is not tested because it's impossible to + align symbol to 512 MiB due to relocation restrictions. + +(2) Granule size: 4 KiB + +ID Program sections Size +--------------------------------------- +001 mmap + THP 64K, 2M, 32M, 1G +101 mmap + flag 64K, 2M, 32M, 1G +201 shmget + THP 64K, 2M, 32M, 1G +301 shmget + flag 64K, 2M, 32M, 1G +401 heap 64K +402 heap 2M +403 heap 32M +404 heap 1G +501 .data, .bss, stack 64K +502 .data, .bss, stack 2M +503 .data, .bss, stack 32M +504 .data, .bss 1G +601 mmap + hugetlbfs 64K, 2M, 32M, 1G + +* 1 GiB for stack is not tested because it's impossible to + align symbol to 1 GiB due to relocation restrictions. + +====== +Detail +====== + +With the patch, McKernel does the followings for the test: +(1) Align heap with the value passed via mcexec -h option +(2) Map stack and .data with the page with the size of the value + passed via mcexec -s option +(3) Enable THP via shmget +(5) Report large page allocations + +Alignment of symbols in .data, .bss is done by using the modified +linker scripts. diff --git a/test/large_page/arm64/001_4K.c b/test/large_page/arm64/001_4K.c new file mode 100644 index 00000000..98b0fb15 --- /dev/null +++ b/test/large_page/arm64/001_4K.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define PAGE_SHIFT_64K 16 +#define PAGE_SIZE_64K (1UL << PAGE_SHIFT_64K) + +#define PAGE_SHIFT_2M 21 +#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M) + +#define PAGE_SHIFT_32M 25 +#define PAGE_SIZE_32M (1UL << PAGE_SHIFT_32M) + +#define PAGE_SHIFT_1G 30 +#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G) + +int trial_num; + +int mmap_thp(size_t page_size) +{ + char *addr_mmap; + + addr_mmap = mmap(0, page_size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, + -1, 0); + NG(addr_mmap != (void *)-1, "mmap failed\n"); + + addr_mmap[0] = 'z'; + NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_mmap, page_size); + + munmap(addr_mmap, page_size); + + return 0; + fn_fail: + return 1; +} + +int main(int argc, char **argv) +{ + int ret; + + ret = mmap_thp(PAGE_SIZE_64K); + NG(ret == 0, "mmap_thp failed, size: %ld\n", + PAGE_SIZE_64K); + + ret = mmap_thp(PAGE_SIZE_2M); + NG(ret == 0, "mmap_thp failed, size: %ld\n", + PAGE_SIZE_2M); + + ret = mmap_thp(PAGE_SIZE_32M); + NG(ret == 0, "mmap_thp failed, size: %ld\n", + PAGE_SIZE_32M); + + ret = mmap_thp(PAGE_SIZE_1G); + NG(ret == 0, "mmap_thp failed, size: %ld\n", + PAGE_SIZE_1G); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/001_64K.c b/test/large_page/arm64/001_64K.c new file mode 100644 index 00000000..8900a747 --- /dev/null +++ b/test/large_page/arm64/001_64K.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define PAGE_SHIFT_2M 21 +#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M) + +#define PAGE_SHIFT_512M 29 +#define PAGE_SIZE_512M (1UL << PAGE_SHIFT_512M) + +int trial_num; + +int mmap_thp(size_t page_size) +{ + char *addr_mmap; + + addr_mmap = mmap(0, page_size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, + -1, 0); + NG(addr_mmap != (void *)-1, "mmap failed\n"); + addr_mmap[0] = 'z'; + NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_mmap, page_size); + + munmap(addr_mmap, page_size); + + return 0; + fn_fail: + return 1; +} + +int main(int argc, char **argv) +{ + int ret; + + ret = mmap_thp(PAGE_SIZE_2M); + NG(ret == 0, "mmap_thp failed, size: %ld\n", + PAGE_SIZE_2M); + + ret = mmap_thp(PAGE_SIZE_512M); + NG(ret == 0, "mmap_thp failed, size: %ld\n", + PAGE_SIZE_512M); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/101_4K.c b/test/large_page/arm64/101_4K.c new file mode 100644 index 00000000..ff363e85 --- /dev/null +++ b/test/large_page/arm64/101_4K.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define PAGE_SHIFT_64K 16 +#define PAGE_SIZE_64K (1UL << PAGE_SHIFT_64K) + +#define PAGE_SHIFT_2M 21 +#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M) + +#define PAGE_SHIFT_32M 25 +#define PAGE_SIZE_32M (1UL << PAGE_SHIFT_32M) + +#define PAGE_SHIFT_1G 30 +#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G) + +#define MAP_HUGE_SHIFT 26 + +int trial_num; + +int mmap_flag(size_t page_size, unsigned long page_shift) +{ + char *addr_mmap; + + addr_mmap = mmap(0, page_size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (page_shift << MAP_HUGE_SHIFT), + -1, 0); + NG(addr_mmap != (void *)-1, "mmap failed\n"); + + addr_mmap[0] = 'z'; + NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_mmap, page_size); + + munmap(addr_mmap, page_size); + + return 0; + fn_fail: + return 1; +} + +int main(int argc, char **argv) +{ + int ret; + + ret = mmap_flag(PAGE_SIZE_64K, PAGE_SHIFT_64K); + NG(ret == 0, "mmap_flag failed, size: %ld\n", + PAGE_SIZE_64K); + + ret = mmap_flag(PAGE_SIZE_2M, PAGE_SHIFT_2M); + NG(ret == 0, "mmap_flag failed, size: %ld\n", + PAGE_SIZE_2M); + + ret = mmap_flag(PAGE_SIZE_32M, PAGE_SHIFT_32M); + NG(ret == 0, "mmap_flag failed, size: %ld\n", + PAGE_SIZE_32M); + + ret = mmap_flag(PAGE_SIZE_1G, PAGE_SHIFT_1G); + NG(ret == 0, "mmap_flag failed, size: %ld\n", + PAGE_SIZE_1G); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/101_64K.c b/test/large_page/arm64/101_64K.c new file mode 100644 index 00000000..eae549fa --- /dev/null +++ b/test/large_page/arm64/101_64K.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define PAGE_SHIFT_2M 21 +#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M) + +#define PAGE_SHIFT_512M 29 +#define PAGE_SIZE_512M (1UL << PAGE_SHIFT_512M) + +#define MAP_HUGE_SHIFT 26 + +int trial_num; + +int mmap_flag(size_t page_size, unsigned long page_shift) +{ + char *addr_mmap; + + addr_mmap = mmap(0, page_size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (page_shift << MAP_HUGE_SHIFT), + -1, 0); + NG(addr_mmap != (void *)-1, "mmap failed\n"); + addr_mmap[0] = 'z'; + NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_mmap, page_size); + + munmap(addr_mmap, page_size); + + return 0; + fn_fail: + return 1; +} + +int main(int argc, char **argv) +{ + int ret; + + ret = mmap_flag(PAGE_SIZE_2M, PAGE_SHIFT_2M); + NG(ret == 0, "mmap_flag failed, size: %ld\n", + PAGE_SIZE_2M); + + ret = mmap_flag(PAGE_SIZE_512M, PAGE_SHIFT_512M); + NG(ret == 0, "mmap_flag failed, size: %ld\n", + PAGE_SIZE_512M); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/201_4K.c b/test/large_page/arm64/201_4K.c new file mode 100644 index 00000000..7933f987 --- /dev/null +++ b/test/large_page/arm64/201_4K.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define PAGE_SHIFT_64K 16 +#define PAGE_SIZE_64K (1UL << PAGE_SHIFT_64K) + +#define PAGE_SHIFT_2M 21 +#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M) + +#define PAGE_SHIFT_32M 25 +#define PAGE_SIZE_32M (1UL << PAGE_SHIFT_32M) + +#define PAGE_SHIFT_1G 30 +#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G) + +int trial_num; + +int shmat_thp(char **argv, size_t page_size) +{ + int ret; + key_t key; + int shmid; + struct shmid_ds shmid_ds; + char *addr_shmget; + + key = ftok(argv[0], 0); + + shmid = shmget(key, page_size, IPC_CREAT | 0660); + NG(shmid != -1, "shmget failed\n"); + + addr_shmget = shmat(shmid, NULL, 0); + NG(addr_shmget != (void *)-1, "shmat failed\n"); + + addr_shmget[0] = 'z'; + NG(__atomic_load_n(addr_shmget, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_shmget, page_size); + + ret = shmdt(addr_shmget); + NG(ret != -1, "shmdt failed\n"); + + ret = shmctl(shmid, IPC_RMID, &shmid_ds); + NG(ret != -1, "shmctl failed\n"); + + return 0; + fn_fail: + return 1; +} + +int main(int argc, char **argv) +{ + int ret; + + ret = shmat_thp(argv, PAGE_SIZE_64K); + NG(ret == 0, "shmat_thp failed, size: %ld\n", + PAGE_SIZE_64K); + + ret = shmat_thp(argv, PAGE_SIZE_2M); + NG(ret == 0, "shmat_thp failed, size: %ld\n", + PAGE_SIZE_2M); + + ret = shmat_thp(argv, PAGE_SIZE_32M); + NG(ret == 0, "shmat_thp failed, size: %ld\n", + PAGE_SIZE_32M); + + ret = shmat_thp(argv, PAGE_SIZE_1G); + NG(ret == 0, "shmat_thp failed, size: %ld\n", + PAGE_SIZE_1G); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/201_64K.c b/test/large_page/arm64/201_64K.c new file mode 100644 index 00000000..05082a66 --- /dev/null +++ b/test/large_page/arm64/201_64K.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define PAGE_SHIFT_2M 21 +#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M) + +#define PAGE_SHIFT_512M 29 +#define PAGE_SIZE_512M (1UL << PAGE_SHIFT_512M) + +int trial_num; + +int shmat_thp(char **argv, size_t page_size) +{ + int ret; + key_t key; + int shmid; + struct shmid_ds shmid_ds; + char *addr_shmget; + + key = ftok(argv[0], 0); + + shmid = shmget(key, page_size, IPC_CREAT | 0660); + NG(shmid != -1, "shmget failed\n"); + + addr_shmget = shmat(shmid, NULL, 0); + NG(addr_shmget != (void *)-1, "shmat failed\n"); + + addr_shmget[0] = 'z'; + NG(__atomic_load_n(addr_shmget, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_shmget, page_size); + + ret = shmctl(shmid, IPC_RMID, &shmid_ds); + NG(ret != -1, "shmctl failed\n"); + + ret = shmdt(addr_shmget); + NG(ret != -1, "shmdt failed\n"); + + return 0; + fn_fail: + return 1; +} + +int main(int argc, char **argv) +{ + int ret; + + ret = shmat_thp(argv, PAGE_SIZE_2M); + NG(ret == 0, "shmat_thp failed, size: %ld\n", + PAGE_SIZE_2M); + + ret = shmat_thp(argv, PAGE_SIZE_512M); + NG(ret == 0, "shmat_thp failed, size: %ld\n", + PAGE_SIZE_512M); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/301_4K.c b/test/large_page/arm64/301_4K.c new file mode 100644 index 00000000..08f24d08 --- /dev/null +++ b/test/large_page/arm64/301_4K.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define PAGE_SHIFT_64K 16 +#define PAGE_SIZE_64K (1UL << PAGE_SHIFT_64K) + +#define PAGE_SHIFT_2M 21 +#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M) + +#define PAGE_SHIFT_32M 25 +#define PAGE_SIZE_32M (1UL << PAGE_SHIFT_32M) + +#define PAGE_SHIFT_1G 30 +#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G) + +#define SHM_HUGE_SHIFT 26 + +int trial_num; + +int shmat_thp(char **argv, size_t page_size, unsigned long page_shift) +{ + int ret; + key_t key; + int shmid; + struct shmid_ds shmid_ds; + char *addr_shmget; + + key = ftok(argv[0], 0); + + shmid = shmget(key, page_size, IPC_CREAT | 0660 | + SHM_HUGETLB | (page_shift << SHM_HUGE_SHIFT)); + NG(shmid != -1, "shmget failed\n"); + + addr_shmget = shmat(shmid, NULL, 0); + NG(addr_shmget != (void *)-1, "shmat failed\n"); + + addr_shmget[0] = 'z'; + NG(__atomic_load_n(addr_shmget, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_shmget, page_size); + + ret = shmctl(shmid, IPC_RMID, &shmid_ds); + NG(ret != -1, "shmctl failed\n"); + + ret = shmdt(addr_shmget); + NG(ret != -1, "shmdt failed\n"); + + return 0; + fn_fail: + return 1; +} + +int main(int argc, char **argv) +{ + int ret; + + ret = shmat_thp(argv, PAGE_SIZE_64K, PAGE_SHIFT_64K); + NG(ret == 0, "shmat_thp failed, size: %ld\n", + PAGE_SIZE_64K); + + ret = shmat_thp(argv, PAGE_SIZE_2M, PAGE_SHIFT_2M); + NG(ret == 0, "shmat_thp failed, size: %ld\n", + PAGE_SIZE_2M); + + ret = shmat_thp(argv, PAGE_SIZE_32M, PAGE_SHIFT_32M); + NG(ret == 0, "shmat_thp failed, size: %ld\n", + PAGE_SIZE_32M); + + ret = shmat_thp(argv, PAGE_SIZE_1G, PAGE_SHIFT_1G); + NG(ret == 0, "shmat_thp failed, size: %ld\n", + PAGE_SIZE_1G); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/301_64K.c b/test/large_page/arm64/301_64K.c new file mode 100644 index 00000000..b3507cdb --- /dev/null +++ b/test/large_page/arm64/301_64K.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define PAGE_SHIFT_2M 21 +#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M) + +#define PAGE_SHIFT_512M 29 +#define PAGE_SIZE_512M (1UL << PAGE_SHIFT_512M) + +#define SHM_HUGE_SHIFT 26 + +int trial_num; + +int shmat_thp(char **argv, size_t page_size, unsigned long page_shift) +{ + int ret; + key_t key; + int shmid; + struct shmid_ds shmid_ds; + char *addr_shmget; + + key = ftok(argv[0], 0); + + shmid = shmget(key, page_size, IPC_CREAT | 0660 | + SHM_HUGETLB | (page_shift << SHM_HUGE_SHIFT)); + NG(shmid != -1, "shmget failed\n"); + + addr_shmget = shmat(shmid, NULL, 0); + NG(addr_shmget != (void *)-1, "shmat failed\n"); + + addr_shmget[0] = 'z'; + NG(__atomic_load_n(addr_shmget, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_shmget, page_size); + + ret = shmctl(shmid, IPC_RMID, &shmid_ds); + NG(ret != -1, "shmctl failed\n"); + + ret = shmdt(addr_shmget); + NG(ret != -1, "shmdt failed\n"); + + return 0; + fn_fail: + return 1; +} + +int main(int argc, char **argv) +{ + int ret; + + ret = shmat_thp(argv, PAGE_SIZE_2M, PAGE_SHIFT_2M); + NG(ret == 0, "shmat_thp failed, size: %ld\n", + PAGE_SIZE_2M); + + ret = shmat_thp(argv, PAGE_SIZE_512M, PAGE_SHIFT_512M); + NG(ret == 0, "shmat_thp failed, size: %ld\n", + PAGE_SIZE_512M); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/401_4K.c b/test/large_page/arm64/401_4K.c new file mode 100644 index 00000000..8abdec9e --- /dev/null +++ b/test/large_page/arm64/401_4K.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define TARGET_PAGE_SHIFT 16 +#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT) + +int main(int argc, char **argv) +{ + char *addr_brk; + int trial_num = 0; + + /* Assuming heap size starts from zero and + * incremented by the amount specified with mcexec -h + */ + addr_brk = sbrk(TARGET_PAGE_SIZE); + NG(addr_brk != (void *)-1, "sbrk failed"); + + addr_brk[0] = 'z'; + NG(__atomic_load_n(addr_brk, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_brk, TARGET_PAGE_SIZE); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/401_64K.c b/test/large_page/arm64/401_64K.c new file mode 100644 index 00000000..7ca5e2af --- /dev/null +++ b/test/large_page/arm64/401_64K.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define TARGET_PAGE_SHIFT 21 +#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT) + +int main(int argc, char **argv) +{ + char *addr_brk; + int trial_num = 0; + + /* Assuming heap size starts from zero and + * incremented by the amount specified with mcexec -h + */ + addr_brk = sbrk(TARGET_PAGE_SIZE); + NG(addr_brk != (void *)-1, "sbrk failed\n"); + + addr_brk[0] = 'z'; + NG(__atomic_load_n(addr_brk, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_brk, TARGET_PAGE_SIZE); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/402_4K.c b/test/large_page/arm64/402_4K.c new file mode 100644 index 00000000..51f2e9bd --- /dev/null +++ b/test/large_page/arm64/402_4K.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define TARGET_PAGE_SHIFT 21 +#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT) + +int main(int argc, char **argv) +{ + char *addr_brk; + int trial_num = 0; + + /* Assuming heap size starts from zero and + * incremented by the amount specified with mcexec -h + */ + addr_brk = sbrk(TARGET_PAGE_SIZE); + NG(addr_brk != (void *)-1, "sbrk failed"); + + addr_brk[0] = 'z'; + NG(__atomic_load_n(addr_brk, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_brk, TARGET_PAGE_SIZE); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/402_64K.c b/test/large_page/arm64/402_64K.c new file mode 100644 index 00000000..3b74eb0c --- /dev/null +++ b/test/large_page/arm64/402_64K.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define TARGET_PAGE_SHIFT 29 +#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT) + +int main(int argc, char **argv) +{ + char *addr_brk; + int trial_num = 0; + + /* Assuming heap size starts from zero and + * incremented by the amount specified with mcexec -h + */ + addr_brk = sbrk(TARGET_PAGE_SIZE); + NG(addr_brk != (void *)-1, "sbrk failed\n"); + + addr_brk[0] = 'z'; + NG(__atomic_load_n(addr_brk, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_brk, TARGET_PAGE_SIZE); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/403_4K.c b/test/large_page/arm64/403_4K.c new file mode 100644 index 00000000..0bbf7892 --- /dev/null +++ b/test/large_page/arm64/403_4K.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define TARGET_PAGE_SHIFT 25 +#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT) + +int main(int argc, char **argv) +{ + char *addr_brk; + int trial_num = 0; + + /* Assuming heap size starts from zero and + * incremented by the amount specified with mcexec -h + */ + addr_brk = sbrk(TARGET_PAGE_SIZE); + NG(addr_brk != (void *)-1, "sbrk failed"); + + addr_brk[0] = 'z'; + NG(__atomic_load_n(addr_brk, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_brk, TARGET_PAGE_SIZE); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/404_4K.c b/test/large_page/arm64/404_4K.c new file mode 100644 index 00000000..24904120 --- /dev/null +++ b/test/large_page/arm64/404_4K.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define TARGET_PAGE_SHIFT 30 +#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT) + +int main(int argc, char **argv) +{ + char *addr_brk; + int trial_num = 0; + + /* Assuming heap size starts from zero and + * incremented by the amount specified with mcexec -h + */ + addr_brk = sbrk(TARGET_PAGE_SIZE); + NG(addr_brk != (void *)-1, "sbrk failed"); + + addr_brk[0] = 'z'; + NG(__atomic_load_n(addr_brk, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_brk, TARGET_PAGE_SIZE); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/501_4K.c b/test/large_page/arm64/501_4K.c new file mode 100644 index 00000000..cd51b8f9 --- /dev/null +++ b/test/large_page/arm64/501_4K.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define TARGET_PAGE_SHIFT 16 +#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT) + +/* .data */ +char addr_data[TARGET_PAGE_SIZE] = { 1 }; + +/* .bss */ +char addr_bss[TARGET_PAGE_SIZE]; + +int main(int argc, char **argv) +{ + int trial_num = 0; + char addr_stack[TARGET_PAGE_SIZE] + __attribute__((aligned(TARGET_PAGE_SIZE))); + + /* .data */ + addr_data[0] = 'z'; + NG(__atomic_load_n(addr_data, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_data, TARGET_PAGE_SIZE); + + /* .bss */ + addr_bss[0] = 'z'; + NG(__atomic_load_n(addr_bss, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_bss, TARGET_PAGE_SIZE); + + /* stack */ + addr_stack[0] = 'z'; + NG(__atomic_load_n(addr_stack, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_stack, TARGET_PAGE_SIZE); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/501_4K.lds b/test/large_page/arm64/501_4K.lds new file mode 100644 index 00000000..66ab605c --- /dev/null +++ b/test/large_page/arm64/501_4K.lds @@ -0,0 +1,224 @@ +/* Script for -z combreloc: combine and sort reloc sections */ +/* Copyright (C) 2014-2016 Free Software Foundation, Inc. + Copying and distribution of this script, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. */ +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64", + "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(_start) +SEARCH_DIR("=/usr/aarch64-redhat-linux/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/aarch64-redhat-linux/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS; + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.ifunc) + } + .rela.plt : + { + *(.rela.plt) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .init : + { + KEEP (*(SORT_NONE(.init))) + } =0 + .plt : ALIGN(16) { *(.plt) *(.iplt) } + .text : + { + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } =0 + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table + .gcc_except_table.*) } + .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges + .exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gnu_extab : ONLY_IF_RW { *(.gnu_extab) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + . = ALIGN(0x10000); + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got) *(.igot) } + . = DATA_SEGMENT_RELRO_END (24, .); + .got.plt : { *(.got.plt) *(.igot.plt) } + . = ALIGN(0x10000); + .data : + { + addr_data = .; + PROVIDE (__data_start = .); + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + . = ALIGN(0x10000); + } + .data1 : { *(.data1) } + _edata = .; PROVIDE (edata = .); + . = .; + . = ALIGN(0x10000); + __bss_start = .; + __bss_start__ = .; + .bss : + { + addr_bss = .; + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we don't + pad the .data section. */ + . = ALIGN(. != 0 ? 64 / 8 : 1); + . = ALIGN(0x10000); + } + _bss_end__ = . ; __bss_end__ = . ; + . = ALIGN(64 / 8); + . = SEGMENT_START("ldata-segment", .); + . = ALIGN(64 / 8); + __end__ = . ; + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} + + diff --git a/test/large_page/arm64/501_64K.c b/test/large_page/arm64/501_64K.c new file mode 100644 index 00000000..b438d0c7 --- /dev/null +++ b/test/large_page/arm64/501_64K.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define TARGET_PAGE_SHIFT 21 +#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT) + +/* .data */ +char addr_data[TARGET_PAGE_SIZE] = { 1 }; + +/* .bss */ +char addr_bss[TARGET_PAGE_SIZE]; + +int main(int argc, char **argv) +{ + int trial_num = 0; + char addr_stack[TARGET_PAGE_SIZE] + __attribute__((aligned(TARGET_PAGE_SIZE))); + + /* .data */ + addr_data[0] = 'z'; + NG(__atomic_load_n(addr_data, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_data, TARGET_PAGE_SIZE); + + /* .bss */ + addr_bss[0] = 'z'; + NG(__atomic_load_n(addr_bss, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_bss, TARGET_PAGE_SIZE); + + /* stack */ + addr_stack[0] = 'z'; + NG(__atomic_load_n(addr_stack, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_stack, TARGET_PAGE_SIZE); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/501_64K.lds b/test/large_page/arm64/501_64K.lds new file mode 100644 index 00000000..924b8486 --- /dev/null +++ b/test/large_page/arm64/501_64K.lds @@ -0,0 +1,224 @@ +/* Script for -z combreloc: combine and sort reloc sections */ +/* Copyright (C) 2014-2016 Free Software Foundation, Inc. + Copying and distribution of this script, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. */ +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64", + "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(_start) +SEARCH_DIR("=/usr/aarch64-redhat-linux/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/aarch64-redhat-linux/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS; + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.ifunc) + } + .rela.plt : + { + *(.rela.plt) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .init : + { + KEEP (*(SORT_NONE(.init))) + } =0 + .plt : ALIGN(16) { *(.plt) *(.iplt) } + .text : + { + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } =0 + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table + .gcc_except_table.*) } + .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges + .exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gnu_extab : ONLY_IF_RW { *(.gnu_extab) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + . = ALIGN(0x200000); + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got) *(.igot) } + . = DATA_SEGMENT_RELRO_END (24, .); + .got.plt : { *(.got.plt) *(.igot.plt) } + . = ALIGN(0x200000); + .data : + { + addr_data = .; + PROVIDE (__data_start = .); + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + . = ALIGN(0x200000); + } + .data1 : { *(.data1) } + _edata = .; PROVIDE (edata = .); + . = .; + . = ALIGN(0x200000); + __bss_start = .; + __bss_start__ = .; + .bss : + { + addr_bss = .; + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we don't + pad the .data section. */ + . = ALIGN(. != 0 ? 64 / 8 : 1); + . = ALIGN(0x200000); + } + _bss_end__ = . ; __bss_end__ = . ; + . = ALIGN(64 / 8); + . = SEGMENT_START("ldata-segment", .); + . = ALIGN(64 / 8); + __end__ = . ; + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} + + diff --git a/test/large_page/arm64/501_64K.org.lds b/test/large_page/arm64/501_64K.org.lds new file mode 100644 index 00000000..f2252eb9 --- /dev/null +++ b/test/large_page/arm64/501_64K.org.lds @@ -0,0 +1,268 @@ +GNU ld version 2.27-27.base.el7 + Supported emulations: + aarch64linux + aarch64elf + aarch64elf32 + aarch64elf32b + aarch64elfb + armelf + armelfb + aarch64linuxb + aarch64linux32 + aarch64linux32b + armelfb_linux_eabi + armelf_linux_eabi +using internal linker script: +================================================== +/* Script for -z combreloc: combine and sort reloc sections */ +/* Copyright (C) 2014-2016 Free Software Foundation, Inc. + Copying and distribution of this script, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. */ +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64", + "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(_start) +SEARCH_DIR("=/usr/aarch64-redhat-linux/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/aarch64-redhat-linux/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS; + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.ifunc) + } + .rela.plt : + { + *(.rela.plt) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .init : + { + KEEP (*(SORT_NONE(.init))) + } =0 + .plt : ALIGN(16) { *(.plt) *(.iplt) } + .text : + { + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } =0 + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table + .gcc_except_table.*) } + .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges + .exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gnu_extab : ONLY_IF_RW { *(.gnu_extab) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got) *(.igot) } + . = DATA_SEGMENT_RELRO_END (24, .); + .got.plt : { *(.got.plt) *(.igot.plt) } + .data : + { + PROVIDE (__data_start = .); + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + _edata = .; PROVIDE (edata = .); + . = .; + __bss_start = .; + __bss_start__ = .; + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we don't + pad the .data section. */ + . = ALIGN(. != 0 ? 64 / 8 : 1); + } + _bss_end__ = . ; __bss_end__ = . ; + . = ALIGN(64 / 8); + . = SEGMENT_START("ldata-segment", .); + . = ALIGN(64 / 8); + __end__ = . ; + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} + + +================================================== +attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crt1.o succeeded +/usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crt1.o +attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crti.o succeeded +/usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crti.o +attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/crtbegin.o succeeded +/usr/lib/gcc/aarch64-redhat-linux/4.8.5/crtbegin.o +attempt to open 501_64K.o succeeded +501_64K.o +attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/libgcc.so failed +attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/libgcc.a succeeded +attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/libgcc_s.so succeeded +-lgcc_s (/usr/lib/gcc/aarch64-redhat-linux/4.8.5/libgcc_s.so) +attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/libc.so failed +attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/libc.a failed +attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/libc.so succeeded +opened script file /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/libc.so +opened script file /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/libc.so +attempt to open /lib64/libc.so.6 succeeded +/lib64/libc.so.6 +attempt to open /usr/lib64/libc_nonshared.a succeeded +(/usr/lib64/libc_nonshared.a)elf-init.oS +attempt to open /lib/ld-linux-aarch64.so.1 succeeded +/lib/ld-linux-aarch64.so.1 +/lib/ld-linux-aarch64.so.1 +attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/libgcc.so failed +attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/libgcc.a succeeded +attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/libgcc_s.so succeeded +-lgcc_s (/usr/lib/gcc/aarch64-redhat-linux/4.8.5/libgcc_s.so) +attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/crtend.o succeeded +/usr/lib/gcc/aarch64-redhat-linux/4.8.5/crtend.o +attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crtn.o succeeded +/usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crtn.o +ld-linux-aarch64.so.1 needed by /lib64/libc.so.6 +found ld-linux-aarch64.so.1 at /lib/ld-linux-aarch64.so.1 diff --git a/test/large_page/arm64/502_4K.c b/test/large_page/arm64/502_4K.c new file mode 100644 index 00000000..b438d0c7 --- /dev/null +++ b/test/large_page/arm64/502_4K.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define TARGET_PAGE_SHIFT 21 +#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT) + +/* .data */ +char addr_data[TARGET_PAGE_SIZE] = { 1 }; + +/* .bss */ +char addr_bss[TARGET_PAGE_SIZE]; + +int main(int argc, char **argv) +{ + int trial_num = 0; + char addr_stack[TARGET_PAGE_SIZE] + __attribute__((aligned(TARGET_PAGE_SIZE))); + + /* .data */ + addr_data[0] = 'z'; + NG(__atomic_load_n(addr_data, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_data, TARGET_PAGE_SIZE); + + /* .bss */ + addr_bss[0] = 'z'; + NG(__atomic_load_n(addr_bss, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_bss, TARGET_PAGE_SIZE); + + /* stack */ + addr_stack[0] = 'z'; + NG(__atomic_load_n(addr_stack, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_stack, TARGET_PAGE_SIZE); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/502_4K.lds b/test/large_page/arm64/502_4K.lds new file mode 100644 index 00000000..924b8486 --- /dev/null +++ b/test/large_page/arm64/502_4K.lds @@ -0,0 +1,224 @@ +/* Script for -z combreloc: combine and sort reloc sections */ +/* Copyright (C) 2014-2016 Free Software Foundation, Inc. + Copying and distribution of this script, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. */ +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64", + "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(_start) +SEARCH_DIR("=/usr/aarch64-redhat-linux/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/aarch64-redhat-linux/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS; + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.ifunc) + } + .rela.plt : + { + *(.rela.plt) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .init : + { + KEEP (*(SORT_NONE(.init))) + } =0 + .plt : ALIGN(16) { *(.plt) *(.iplt) } + .text : + { + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } =0 + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table + .gcc_except_table.*) } + .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges + .exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gnu_extab : ONLY_IF_RW { *(.gnu_extab) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + . = ALIGN(0x200000); + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got) *(.igot) } + . = DATA_SEGMENT_RELRO_END (24, .); + .got.plt : { *(.got.plt) *(.igot.plt) } + . = ALIGN(0x200000); + .data : + { + addr_data = .; + PROVIDE (__data_start = .); + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + . = ALIGN(0x200000); + } + .data1 : { *(.data1) } + _edata = .; PROVIDE (edata = .); + . = .; + . = ALIGN(0x200000); + __bss_start = .; + __bss_start__ = .; + .bss : + { + addr_bss = .; + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we don't + pad the .data section. */ + . = ALIGN(. != 0 ? 64 / 8 : 1); + . = ALIGN(0x200000); + } + _bss_end__ = . ; __bss_end__ = . ; + . = ALIGN(64 / 8); + . = SEGMENT_START("ldata-segment", .); + . = ALIGN(64 / 8); + __end__ = . ; + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} + + diff --git a/test/large_page/arm64/502_64K.c b/test/large_page/arm64/502_64K.c new file mode 100644 index 00000000..ec61105c --- /dev/null +++ b/test/large_page/arm64/502_64K.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define TARGET_PAGE_SHIFT 29 +#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT) + +/* .data */ +char addr_data[TARGET_PAGE_SIZE] = { 1 }; + +/* .bss */ +char addr_bss[TARGET_PAGE_SIZE]; + +int main(int argc, char **argv) +{ + int trial_num = 0; + + /* .data */ + addr_data[0] = 'z'; + NG(__atomic_load_n(addr_data, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_data, TARGET_PAGE_SIZE); + + /* .bss */ + addr_bss[0] = 'z'; + NG(__atomic_load_n(addr_bss, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_bss, TARGET_PAGE_SIZE); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/502_64K.lds b/test/large_page/arm64/502_64K.lds new file mode 100644 index 00000000..d5fcfa86 --- /dev/null +++ b/test/large_page/arm64/502_64K.lds @@ -0,0 +1,224 @@ +/* Script for -z combreloc: combine and sort reloc sections */ +/* Copyright (C) 2014-2016 Free Software Foundation, Inc. + Copying and distribution of this script, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. */ +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64", + "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(_start) +SEARCH_DIR("=/usr/aarch64-redhat-linux/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/aarch64-redhat-linux/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS; + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.ifunc) + } + .rela.plt : + { + *(.rela.plt) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .init : + { + KEEP (*(SORT_NONE(.init))) + } =0 + .plt : ALIGN(16) { *(.plt) *(.iplt) } + .text : + { + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } =0 + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table + .gcc_except_table.*) } + .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges + .exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gnu_extab : ONLY_IF_RW { *(.gnu_extab) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + . = ALIGN(0x20000000); + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got) *(.igot) } + . = DATA_SEGMENT_RELRO_END (24, .); + .got.plt : { *(.got.plt) *(.igot.plt) } + . = ALIGN(0x20000000); + .data : + { + addr_data = .; + PROVIDE (__data_start = .); + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + . = ALIGN(0x20000000); + } + .data1 : { *(.data1) } + _edata = .; PROVIDE (edata = .); + . = .; + . = ALIGN(0x20000000); + __bss_start = .; + __bss_start__ = .; + .bss : + { + addr_bss = .; + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we don't + pad the .data section. */ + . = ALIGN(. != 0 ? 64 / 8 : 1); + . = ALIGN(0x20000000); + } + _bss_end__ = . ; __bss_end__ = . ; + . = ALIGN(64 / 8); + . = SEGMENT_START("ldata-segment", .); + . = ALIGN(64 / 8); + __end__ = . ; + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} + + diff --git a/test/large_page/arm64/503_4K.c b/test/large_page/arm64/503_4K.c new file mode 100644 index 00000000..3a1f9708 --- /dev/null +++ b/test/large_page/arm64/503_4K.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define TARGET_PAGE_SHIFT 25 +#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT) + +/* .data */ +char addr_data[TARGET_PAGE_SIZE] = { 1 }; + +/* .bss */ +char addr_bss[TARGET_PAGE_SIZE]; + +int main(int argc, char **argv) +{ + int trial_num = 0; + char addr_stack[TARGET_PAGE_SIZE] + __attribute__((aligned(TARGET_PAGE_SIZE))); + + /* .data */ + addr_data[0] = 'z'; + NG(__atomic_load_n(addr_data, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_data, TARGET_PAGE_SIZE); + + /* .bss */ + addr_bss[0] = 'z'; + NG(__atomic_load_n(addr_bss, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_bss, TARGET_PAGE_SIZE); + + /* stack */ + addr_stack[0] = 'z'; + NG(__atomic_load_n(addr_stack, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_stack, TARGET_PAGE_SIZE); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/503_4K.lds b/test/large_page/arm64/503_4K.lds new file mode 100644 index 00000000..2b9872df --- /dev/null +++ b/test/large_page/arm64/503_4K.lds @@ -0,0 +1,224 @@ +/* Script for -z combreloc: combine and sort reloc sections */ +/* Copyright (C) 2014-2016 Free Software Foundation, Inc. + Copying and distribution of this script, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. */ +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64", + "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(_start) +SEARCH_DIR("=/usr/aarch64-redhat-linux/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/aarch64-redhat-linux/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS; + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.ifunc) + } + .rela.plt : + { + *(.rela.plt) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .init : + { + KEEP (*(SORT_NONE(.init))) + } =0 + .plt : ALIGN(16) { *(.plt) *(.iplt) } + .text : + { + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } =0 + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table + .gcc_except_table.*) } + .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges + .exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gnu_extab : ONLY_IF_RW { *(.gnu_extab) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + . = ALIGN(0x2000000); + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got) *(.igot) } + . = DATA_SEGMENT_RELRO_END (24, .); + .got.plt : { *(.got.plt) *(.igot.plt) } + . = ALIGN(0x2000000); + .data : + { + addr_data = .; + PROVIDE (__data_start = .); + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + . = ALIGN(0x2000000); + } + .data1 : { *(.data1) } + _edata = .; PROVIDE (edata = .); + . = .; + . = ALIGN(0x2000000); + __bss_start = .; + __bss_start__ = .; + .bss : + { + addr_bss = .; + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we don't + pad the .data section. */ + . = ALIGN(. != 0 ? 64 / 8 : 1); + . = ALIGN(0x2000000); + } + _bss_end__ = . ; __bss_end__ = . ; + . = ALIGN(64 / 8); + . = SEGMENT_START("ldata-segment", .); + . = ALIGN(64 / 8); + __end__ = . ; + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} + + diff --git a/test/large_page/arm64/504_4K.c b/test/large_page/arm64/504_4K.c new file mode 100644 index 00000000..47525948 --- /dev/null +++ b/test/large_page/arm64/504_4K.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define TARGET_PAGE_SHIFT 30 +#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT) + +/* .data */ +char addr_data[TARGET_PAGE_SIZE] = { 1 }; + +/* .bss */ +char addr_bss[TARGET_PAGE_SIZE]; + +int main(int argc, char **argv) +{ + int trial_num = 0; + + /* .data */ + addr_data[0] = 'z'; + NG(__atomic_load_n(addr_data, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_data, TARGET_PAGE_SIZE); + + /* .bss */ + addr_bss[0] = 'z'; + NG(__atomic_load_n(addr_bss, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_bss, TARGET_PAGE_SIZE); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/504_4K.lds b/test/large_page/arm64/504_4K.lds new file mode 100644 index 00000000..1f79f93e --- /dev/null +++ b/test/large_page/arm64/504_4K.lds @@ -0,0 +1,224 @@ +/* Script for -z combreloc: combine and sort reloc sections */ +/* Copyright (C) 2014-2016 Free Software Foundation, Inc. + Copying and distribution of this script, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. */ +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64", + "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(_start) +SEARCH_DIR("=/usr/aarch64-redhat-linux/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/aarch64-redhat-linux/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS; + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.ifunc) + } + .rela.plt : + { + *(.rela.plt) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .init : + { + KEEP (*(SORT_NONE(.init))) + } =0 + .plt : ALIGN(16) { *(.plt) *(.iplt) } + .text : + { + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } =0 + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table + .gcc_except_table.*) } + .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges + .exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gnu_extab : ONLY_IF_RW { *(.gnu_extab) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + . = ALIGN(0x40000000); + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got) *(.igot) } + . = DATA_SEGMENT_RELRO_END (24, .); + .got.plt : { *(.got.plt) *(.igot.plt) } + . = ALIGN(0x40000000); + .data : + { + addr_data = .; + PROVIDE (__data_start = .); + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + . = ALIGN(0x40000000); + } + .data1 : { *(.data1) } + _edata = .; PROVIDE (edata = .); + . = .; + . = ALIGN(0x40000000); + __bss_start = .; + __bss_start__ = .; + .bss : + { + addr_bss = .; + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we don't + pad the .data section. */ + . = ALIGN(. != 0 ? 64 / 8 : 1); + . = ALIGN(0x40000000); + } + _bss_end__ = . ; __bss_end__ = . ; + . = ALIGN(64 / 8); + . = SEGMENT_START("ldata-segment", .); + . = ALIGN(64 / 8); + __end__ = . ; + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} + + diff --git a/test/large_page/arm64/601_4K.c b/test/large_page/arm64/601_4K.c new file mode 100644 index 00000000..8bb0f101 --- /dev/null +++ b/test/large_page/arm64/601_4K.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define PAGE_SHIFT_64K 16 +#define PAGE_SIZE_64K (1UL << PAGE_SHIFT_64K) +char fn_64K[] = "/mnt/hugetlbfs-64K/tmp"; + +#define PAGE_SHIFT_2M 21 +#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M) +char fn_2M[] = "/mnt/hugetlbfs-2M/tmp"; + +#define PAGE_SHIFT_32M 25 +#define PAGE_SIZE_32M (1UL << PAGE_SHIFT_32M) +char fn_32M[] = "/mnt/hugetlbfs-32M/tmp"; + +#define PAGE_SHIFT_1G 30 +#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G) +char fn_1G[] = "/mnt/hugetlbfs-1G/tmp"; + +int trial_num; + +int mmap_hugetlbfs(char *fn, size_t page_size) +{ + int fd; + char *addr_mmap; + + fd = open(fn, O_CREAT | O_RDWR, 0755); + NG(fd != -1, "open failed, fn: %s\n", fn); + + addr_mmap = mmap(0, page_size, + PROT_READ | PROT_WRITE, + MAP_SHARED, + fd, 0); + NG(addr_mmap != (void *)-1, "mmap failed\n"); + addr_mmap[0] = 'z'; + NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_mmap, page_size); + + munmap(addr_mmap, page_size); + close(fd); + unlink(fn); + + return 0; + fn_fail: + return 1; +} + +int main(int argc, char **argv) +{ + int ret; + + ret = mmap_hugetlbfs(fn_64K, PAGE_SIZE_64K); + NG(ret == 0, "mmap_hugetlbfs failed, fn: %s", fn_64K); + + ret = mmap_hugetlbfs(fn_2M, PAGE_SIZE_2M); + NG(ret == 0, "mmap_hugetlbfs failed, fn: %s", fn_2M); + + ret = mmap_hugetlbfs(fn_32M, PAGE_SIZE_32M); + NG(ret == 0, "mmap_hugetlbfs failed, fn: %s", fn_32M); + + ret = mmap_hugetlbfs(fn_1G, PAGE_SIZE_1G); + NG(ret == 0, "mmap_hugetlbfs failed, fn: %s", fn_1G); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/601_64K.c b/test/large_page/arm64/601_64K.c new file mode 100644 index 00000000..8b735773 --- /dev/null +++ b/test/large_page/arm64/601_64K.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define PAGE_SHIFT_2M 21 +#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M) +char fn_2M[] = "/mnt/hugetlbfs-2M/tmp"; + +#define PAGE_SHIFT_512M 29 +#define PAGE_SIZE_512M (1UL << PAGE_SHIFT_512M) +char fn_512M[] = "/mnt/hugetlbfs-512M/tmp"; + +int trial_num; + +int mmap_hugetlbfs(char *fn, size_t page_size) +{ + int fd; + char *addr_mmap; + + fd = open(fn, O_CREAT | O_RDWR, 0755); + NG(fd != -1, "open failed, fn: %s\n", fn); + + addr_mmap = mmap(0, page_size, + PROT_READ | PROT_WRITE, + MAP_SHARED, + fd, 0); + NG(addr_mmap != (void *)-1, "mmap failed\n"); + addr_mmap[0] = 'z'; + NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_mmap, page_size); + + munmap(addr_mmap, page_size); + close(fd); + unlink(fn); + + return 0; + fn_fail: + return 1; +} + +int main(int argc, char **argv) +{ + int ret; + + ret = mmap_hugetlbfs(fn_2M, PAGE_SIZE_2M); + NG(ret == 0, "mmap_hugetlbfs failed, fn: %s", fn_2M); + + ret = mmap_hugetlbfs(fn_512M, PAGE_SIZE_512M); + NG(ret == 0, "mmap_hugetlbfs failed, fn: %s", fn_512M); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/arm64/Makefile b/test/large_page/arm64/Makefile new file mode 100644 index 00000000..8523aa48 --- /dev/null +++ b/test/large_page/arm64/Makefile @@ -0,0 +1,46 @@ +include $(HOME)/.mck_test_config.mk + +CC = gcc + +CPPFLAGS = +CFLAGS = -Wall -Werror -g +LDFLAGS = + +PAGESIZE = $(shell getconf PAGESIZE) +ifeq ($(PAGESIZE),65536) +SRCS = $(shell ls *_64K.c) +endif + +ifeq ($(PAGESIZE),4096) +SRCS = $(shell ls *_4K.c) +endif + +EXES = $(SRCS:.c=) +OBJS = $(SRCS:.c=.o) + +all: $(EXES) + +test:: $(EXES) + ../driver.sh $(TESTSET) + +501_64K: 501_64K.o 501_64K.lds + $(CC) -o $@ $< $(LDFLAGS) -T 501_64K.lds + +502_64K: 502_64K.o 502_64K.lds + $(CC) -o $@ $< $(LDFLAGS) -T 502_64K.lds + +501_4K: 501_4K.o 501_4K.lds + $(CC) -o $@ $< $(LDFLAGS) -T 501_4K.lds + +502_4K: 502_4K.o 502_4K.lds + $(CC) -o $@ $< $(LDFLAGS) -T 502_4K.lds + +503_4K: 503_4K.o 503_4K.lds + $(CC) -o $@ $< $(LDFLAGS) -T 503_4K.lds + +504_4K: 504_4K.o 504_4K.lds + $(CC) -o $@ $< $(LDFLAGS) -T 504_4K.lds + +clean: + rm -f core $(EXES) $(OBJS) + diff --git a/test/large_page/arm64/fini/601_4K.fini b/test/large_page/arm64/fini/601_4K.fini new file mode 100644 index 00000000..2e04a411 --- /dev/null +++ b/test/large_page/arm64/fini/601_4K.fini @@ -0,0 +1,4 @@ +sudo umount /mnt/hugetlbfs-64K +sudo umount /mnt/hugetlbfs-2M +sudo umount /mnt/hugetlbfs-32M +sudo umount /mnt/hugetlbfs-1G diff --git a/test/large_page/arm64/fini/601_64K.fini b/test/large_page/arm64/fini/601_64K.fini new file mode 100644 index 00000000..f32f6be8 --- /dev/null +++ b/test/large_page/arm64/fini/601_64K.fini @@ -0,0 +1,2 @@ +sudo umount /mnt/hugetlbfs-2M +sudo umount /mnt/hugetlbfs-512M diff --git a/test/large_page/arm64/init/001_4K.init b/test/large_page/arm64/init/001_4K.init new file mode 100644 index 00000000..9070fa8e --- /dev/null +++ b/test/large_page/arm64/init/001_4K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" +MCEXECOPT="-s 4K,16G" diff --git a/test/large_page/arm64/init/001_64K.init b/test/large_page/arm64/init/001_64K.init new file mode 100644 index 00000000..b1588dd9 --- /dev/null +++ b/test/large_page/arm64/init/001_64K.init @@ -0,0 +1 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" diff --git a/test/large_page/arm64/init/101_4K.init b/test/large_page/arm64/init/101_4K.init new file mode 100644 index 00000000..e502247b --- /dev/null +++ b/test/large_page/arm64/init/101_4K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" +MCEXECOPT="-s 4K,16G" \ No newline at end of file diff --git a/test/large_page/arm64/init/101_64K.init b/test/large_page/arm64/init/101_64K.init new file mode 100644 index 00000000..b1588dd9 --- /dev/null +++ b/test/large_page/arm64/init/101_64K.init @@ -0,0 +1 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" diff --git a/test/large_page/arm64/init/201_4K.init b/test/large_page/arm64/init/201_4K.init new file mode 100644 index 00000000..9070fa8e --- /dev/null +++ b/test/large_page/arm64/init/201_4K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" +MCEXECOPT="-s 4K,16G" diff --git a/test/large_page/arm64/init/201_64K.init b/test/large_page/arm64/init/201_64K.init new file mode 100644 index 00000000..b1588dd9 --- /dev/null +++ b/test/large_page/arm64/init/201_64K.init @@ -0,0 +1 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" diff --git a/test/large_page/arm64/init/301_4K.init b/test/large_page/arm64/init/301_4K.init new file mode 100644 index 00000000..9070fa8e --- /dev/null +++ b/test/large_page/arm64/init/301_4K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" +MCEXECOPT="-s 4K,16G" diff --git a/test/large_page/arm64/init/301_64K.init b/test/large_page/arm64/init/301_64K.init new file mode 100644 index 00000000..b1588dd9 --- /dev/null +++ b/test/large_page/arm64/init/301_64K.init @@ -0,0 +1 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" diff --git a/test/large_page/arm64/init/401_4K.init b/test/large_page/arm64/init/401_4K.init new file mode 100644 index 00000000..0bbf77b4 --- /dev/null +++ b/test/large_page/arm64/init/401_4K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" +MCEXECOPT="-s 4K,16G -h 64K" diff --git a/test/large_page/arm64/init/401_64K.init b/test/large_page/arm64/init/401_64K.init new file mode 100644 index 00000000..fa456232 --- /dev/null +++ b/test/large_page/arm64/init/401_64K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" +MCEXECOPT="-h 2M" diff --git a/test/large_page/arm64/init/402_4K.init b/test/large_page/arm64/init/402_4K.init new file mode 100644 index 00000000..e85ed8aa --- /dev/null +++ b/test/large_page/arm64/init/402_4K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" +MCEXECOPT="-s 4K,16G -h 2M" diff --git a/test/large_page/arm64/init/402_64K.init b/test/large_page/arm64/init/402_64K.init new file mode 100644 index 00000000..801766ba --- /dev/null +++ b/test/large_page/arm64/init/402_64K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" +MCEXECOPT="-h 512M" diff --git a/test/large_page/arm64/init/403_4K.init b/test/large_page/arm64/init/403_4K.init new file mode 100644 index 00000000..b4acd822 --- /dev/null +++ b/test/large_page/arm64/init/403_4K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" +MCEXECOPT="-s 4K,16G -h 32M" diff --git a/test/large_page/arm64/init/404_4K.init b/test/large_page/arm64/init/404_4K.init new file mode 100644 index 00000000..b7a01657 --- /dev/null +++ b/test/large_page/arm64/init/404_4K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" +MCEXECOPT="-s 4K,16G -h 1G" diff --git a/test/large_page/arm64/init/501_4K.init b/test/large_page/arm64/init/501_4K.init new file mode 100644 index 00000000..b8fe4aa6 --- /dev/null +++ b/test/large_page/arm64/init/501_4K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" +MCEXECOPT="-s 64K,16G" diff --git a/test/large_page/arm64/init/501_64K.init b/test/large_page/arm64/init/501_64K.init new file mode 100644 index 00000000..45549c15 --- /dev/null +++ b/test/large_page/arm64/init/501_64K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" +MCEXECOPT="-s 2M,16G" diff --git a/test/large_page/arm64/init/502_4K.init b/test/large_page/arm64/init/502_4K.init new file mode 100644 index 00000000..45549c15 --- /dev/null +++ b/test/large_page/arm64/init/502_4K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" +MCEXECOPT="-s 2M,16G" diff --git a/test/large_page/arm64/init/502_64K.init b/test/large_page/arm64/init/502_64K.init new file mode 100644 index 00000000..0aa7e250 --- /dev/null +++ b/test/large_page/arm64/init/502_64K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" +MCEXECOPT="-s 512M,16G" diff --git a/test/large_page/arm64/init/503_4K.init b/test/large_page/arm64/init/503_4K.init new file mode 100644 index 00000000..c9f4703d --- /dev/null +++ b/test/large_page/arm64/init/503_4K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" +MCEXECOPT="-s 32M,16G" diff --git a/test/large_page/arm64/init/504_4K.init b/test/large_page/arm64/init/504_4K.init new file mode 100644 index 00000000..e05dd4be --- /dev/null +++ b/test/large_page/arm64/init/504_4K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" +MCEXECOPT="-s 1G,16G" diff --git a/test/large_page/arm64/init/601_4K.init b/test/large_page/arm64/init/601_4K.init new file mode 100644 index 00000000..970391b6 --- /dev/null +++ b/test/large_page/arm64/init/601_4K.init @@ -0,0 +1,14 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" +MCEXECOPT="-s 4K,16G" + +sudo mkdir -p /mnt/hugetlbfs-64K +sudo mount -t hugetlbfs -o mode=777,pagesize=64k none /mnt/hugetlbfs-64K + +sudo mkdir -p /mnt/hugetlbfs-2M +sudo mount -t hugetlbfs -o mode=777,pagesize=2m none /mnt/hugetlbfs-2M + +sudo mkdir -p /mnt/hugetlbfs-32M +sudo mount -t hugetlbfs -o mode=777,pagesize=32m none /mnt/hugetlbfs-32M + +sudo mkdir -p /mnt/hugetlbfs-1G +sudo mount -t hugetlbfs -o mode=777,pagesize=1g none /mnt/hugetlbfs-1G diff --git a/test/large_page/arm64/init/601_64K.init b/test/large_page/arm64/init/601_64K.init new file mode 100644 index 00000000..c92cb5a8 --- /dev/null +++ b/test/large_page/arm64/init/601_64K.init @@ -0,0 +1,7 @@ +BOOTPARAM="-c 1-7 -m 16G -r 1-7:0" + +sudo mkdir -p /mnt/hugetlbfs-2M +sudo mount -t hugetlbfs -o mode=777,pagesize=2m none /mnt/hugetlbfs-2M + +sudo mkdir -p /mnt/hugetlbfs-512M +sudo mount -t hugetlbfs -o mode=777,pagesize=512m none /mnt/hugetlbfs-512M diff --git a/test/large_page/arm64/test_set.conf b/test/large_page/arm64/test_set.conf new file mode 100644 index 00000000..0ba85663 --- /dev/null +++ b/test/large_page/arm64/test_set.conf @@ -0,0 +1,57 @@ +pagesize=$(getconf PAGESIZE) + +case $pagesize in + 65536) + # mmap + THP: 2MB, 512MB + test_set="${test_set} 001" + + # shget + THP: 2MB, 512MB + test_set="${test_set} 101" + + # mmap + flag: 2MB, 512MB + test_set="${test_set} 201" + + # shmget + flag: 2MB, 512MB + test_set="${test_set} 301" + + # brk: 2MB, 512MB + test_set="${test_set} 401 402" + + # .data, .bss, .stack: 2MB + test_set="${test_set} 501" + + # .data, .bss: 512M + test_set="${test_set} 502" + + # hugetlbfs: 2MB, 512MB + test_set="${test_set} 601" + ;; + 4096) + # mmap + THP: 64KB, 2MB, 32MB, 1GB + test_set="${test_set} 001" + + # shget + THP: 64KB, 2MB, 32MB, 1GB + test_set="${test_set} 101" + + # mmap + flag: 64KB, 2MB, 32MB, 1GB + test_set="${test_set} 201" + + # shmget + flag: 64KB, 2MB, 32MB, 1GB + test_set="${test_set} 301" + + # brk: 64KB, 2MB, 32MB. 1GB + test_set="${test_set} 401 402 403 404" + + # .data, .bss, .stack: 64KB, 2MB, 32MB + test_set="${test_set} 501 502 503" + + # .data, .bss: 1GB + test_set="${test_set} 504" + + # hugetlbfs: 64KB, 2MB, 32MB, 1GB + test_set="${test_set} 601" + ;; + *) echo "Error: Unknown page size: $pagesize" + exit 1 + ;; +esac diff --git a/test/large_page/check.sh b/test/large_page/check.sh new file mode 100755 index 00000000..8d6c2d90 --- /dev/null +++ b/test/large_page/check.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +test_id=$1 +log_file="./log/${test_id}.log" + +num_addrs=`grep -c1 "large page request" $log_file` + +for i in `seq 0 $((num_addrs - 1))` +do + + addr=`grep "large page request" $log_file | grep -e "trial#: $(printf "%03d" $i)" | tail -1 | grep -oE 'addr: \w{16}' | sed 's/addr: //'` + pgsize_requested=`grep "large page request" $log_file | grep -e "trial#: $(printf "%03d" $i)" | tail -1 | grep -oE 'size: \w*' | sed 's/size: //'` + pgsize_allocated=`grep "large page allocation" $log_file | grep -e $addr | tail -1 | grep -oE 'size: \w*' | sed 's/size: //'` + + if [ "$pgsize_requested" != "$pgsize_allocated" ]; then + printf "\t[ NG ] " + else + printf "\t[ OK ] " + fi + + printf "trial #: $(printf "%03d" $i), addr: $addr, requested size: $pgsize_requested, allocated size: $pgsize_allocated\n" + + if [ "$pgsize_requested" != "$pgsize_allocated" ]; then + exit 1 + fi +done + +exit 0 diff --git a/test/large_page/driver.sh b/test/large_page/driver.sh new file mode 100755 index 00000000..eea9f994 --- /dev/null +++ b/test/large_page/driver.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +# driver.sh [] + +test_set=$1 + +if [ "`git diff | grep -c 'large page allocation'`" == "0" ]; then + echo "Perform \"patch -p0 < large_page.patch\"" + exit 1 +fi + +if [ "$test_set" == "" ]; then + source ./test_set.conf +fi + +if [ ! -d ./log ]; then + mkdir log +fi + +for i in $test_set +do + test_id=$(printf "%03d" $i) + + echo "[INFO] ${test_id} started" + + ../run.sh ${test_id} &> ./log/${test_id}.log + + if [ $? -ne 0 ]; then + echo "[ NG ] ${test_id} run failed" + continue + fi + + ../check.sh ${test_id} + + if [ $? -ne 0 ]; then + echo "[ NG ] ${test_id} result check failed" + continue + fi + + echo "[ OK ] ${test_id} passed" +done diff --git a/test/large_page/large_page.patch b/test/large_page/large_page.patch new file mode 100644 index 00000000..56b43e5a --- /dev/null +++ b/test/large_page/large_page.patch @@ -0,0 +1,374 @@ +diff --git arch/arm64/kernel/memory.c arch/arm64/kernel/memory.c +index ceca343..5e6c137 100644 +--- arch/arm64/kernel/memory.c ++++ arch/arm64/kernel/memory.c +@@ -2701,6 +2701,13 @@ int set_range_l1(void *args0, pte_t *ptep, uintptr_t base, uintptr_t start, + ptl1_set(ptep, pte); + + error = 0; ++ ++ if (args->attr[0] & PTE_CONT && ++ __page_offset(base, PTL1_CONT_SIZE) == 0) { ++ kprintf("%s: large page allocation, addr: %016lx, size: %d, phys: %lx\n", ++ __func__, base, PTL1_CONT_SIZE, phys); ++ } ++ + // call memory_stat_rss_add() here because pgshift is resolved here + if (rusage_memory_stat_add(args->range, phys, PTL1_SIZE, PTL1_SIZE)) { + dkprintf("%lx+,%s: calling memory_stat_rss_add(),base=%lx,phys=%lx,size=%ld,pgsize=%ld\n", phys, __FUNCTION__, base, phys, PTL1_SIZE, PTL1_SIZE); +@@ -2791,6 +2798,17 @@ retry: + + ptl_set(ptep, phys | args->attr[level-1], level); + error = 0; ++ ++ if (args->attr[level-1] & PTE_CONT) { ++ if (__page_offset(base, tbl.cont_pgsize) == 0) { ++ kprintf("%s: large page allocation, addr: %016lx, size: %d, phys: %lx\n", ++ __func__, base, tbl.cont_pgsize, phys); ++ } ++ } else { ++ kprintf("%s: large page allocation, addr: %016lx, size: %d, phys: %lx\n", ++ __func__, base, tbl.pgsize, phys); ++ } ++ + dkprintf("set_range_middle(%lx,%lx,%lx,%d):" + "large page. %d %lx\n", + base, start, end, level, error, *ptep); +diff --git arch/x86_64/kernel/memory.c arch/x86_64/kernel/memory.c +index 980d935..4fea4b0 100644 +--- arch/x86_64/kernel/memory.c ++++ arch/x86_64/kernel/memory.c +@@ -2030,6 +2030,10 @@ retry: + dkprintf("set_range_l2(%lx,%lx,%lx):" + "2MiB page. %d %lx\n", + base, start, end, error, *ptep); ++ ++ kprintf("%s: large page allocation, addr: %016lx, size: %d\n", ++ __func__, base, PTL2_SIZE); ++ + // Call memory_stat_rss_add() here because pgshift is resolved here + if (rusage_memory_stat_add(args->range, phys, PTL2_SIZE, PTL2_SIZE)) { + dkprintf("%lx+,%s: calling memory_stat_rss_add(),base=%lx,phys=%lx,size=%ld,pgsize=%ld\n", phys, __FUNCTION__, base, phys, PTL2_SIZE, PTL2_SIZE); +@@ -2119,6 +2123,9 @@ retry: + "1GiB page. %d %lx\n", + base, start, end, error, *ptep); + ++ kprintf("%s: large page allocation, addr: %016lx, size: %d\n", ++ __func__, base, PTL3_SIZE); ++ + // Call memory_stat_rss_add() here because pgshift is resolved here + if (rusage_memory_stat_add(args->range, phys, PTL3_SIZE, PTL3_SIZE)) { + dkprintf("%lx+,%s: calling memory_stat_rss_add(),base=%lx,phys=%lx,size=%ld,pgsize=%ld\n", phys, __FUNCTION__, base, phys, PTL3_SIZE, PTL3_SIZE); +diff --git kernel/host.c kernel/host.c +index 0de0a08..6fb906e 100644 +--- kernel/host.c ++++ kernel/host.c +@@ -96,10 +96,34 @@ int prepare_process_ranges_args_envs(struct thread *thread, + unsigned long ap_flags; + enum ihk_mc_pt_attribute ptattr; + ++ unsigned long stack_page_size = pn->stack_premap; ++ unsigned long stack_page_mask = ~(stack_page_size - 1); ++ unsigned long stack_page_shift = 63 - __builtin_clzl(stack_page_size); ++ unsigned long stack_page_p2align = stack_page_shift - PAGE_SHIFT; ++ ++ unsigned long section_page_size; ++ unsigned long section_page_mask; ++ unsigned long section_page_shift; ++ int section_page_p2align; ++ + n = p->num_sections; + + aout_base = (pn->reloc)? vm->region.map_end: 0; + for (i = 0; i < n; i++) { ++ if (stack_page_size > PAGE_SIZE && ++ pn->sections[i].len >= stack_page_size && ++ !(pn->sections[i].len & ~stack_page_mask)) { ++ section_page_size = stack_page_size; ++ section_page_mask = stack_page_mask; ++ section_page_shift = stack_page_shift; ++ section_page_p2align = stack_page_p2align; ++ } else { ++ section_page_size = PAGE_SIZE; ++ section_page_mask = PAGE_MASK; ++ section_page_shift = PAGE_SHIFT; ++ section_page_p2align = PAGE_P2ALIGN; ++ } ++ + ap_flags = 0; + if (pn->sections[i].interp && (interp_nbase == (uintptr_t)-1)) { + interp_obase = pn->sections[i].vaddr; +@@ -118,11 +142,22 @@ int prepare_process_ranges_args_envs(struct thread *thread, + pn->sections[i].vaddr += aout_base; + p->sections[i].vaddr = pn->sections[i].vaddr; + } +- s = (pn->sections[i].vaddr) & PAGE_MASK; ++ s = (pn->sections[i].vaddr & section_page_mask); + e = (pn->sections[i].vaddr + pn->sections[i].len +- + PAGE_SIZE - 1) & PAGE_MASK; +- range_npages = ((pn->sections[i].vaddr - s) + +- pn->sections[i].filesz + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ + section_page_size - 1) & section_page_mask; ++ ++ if (section_page_size > PAGE_SIZE) { ++ /* Pre-map .bss as well */ ++ range_npages = (((pn->sections[i].vaddr - s) + ++ pn->sections[i].len + section_page_size - 1) >> ++ section_page_shift) << ++ section_page_p2align; ++ } else { ++ range_npages = ((pn->sections[i].vaddr - s) + ++ pn->sections[i].filesz + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ ++ } ++ + flags = VR_NONE; + flags |= PROT_TO_VR_FLAG(pn->sections[i].prot); + flags |= VRFLAG_PROT_TO_MAXPROT(flags); +@@ -138,18 +173,37 @@ int prepare_process_ranges_args_envs(struct thread *thread, + flags |= VR_AP_USER; + } + +- if (add_process_memory_range(vm, s, e, NOPHYS, flags, NULL, 0, +- pn->sections[i].len > LARGE_PAGE_SIZE ? +- LARGE_PAGE_SHIFT : PAGE_SHIFT, +- &range) != 0) { +- kprintf("ERROR: adding memory range for ELF section %i\n", i); +- goto err; ++ if (section_page_size > PAGE_SIZE) { ++ if (add_process_memory_range(vm, s, e, NOPHYS, flags, NULL, 0, ++ section_page_shift, ++ &range) != 0) { ++ kprintf("ERROR: adding memory range for ELF section %i\n", i); ++ goto err; ++ } ++ } else { ++ if (add_process_memory_range(vm, s, e, NOPHYS, flags, NULL, 0, ++ pn->sections[i].len > LARGE_PAGE_SIZE ? ++ LARGE_PAGE_SHIFT : PAGE_SHIFT, ++ &range) != 0) { ++ kprintf("ERROR: adding memory range for ELF section %i\n", i); ++ goto err; ++ } + } + +- if ((up_v = ihk_mc_alloc_pages_user(range_npages, +- IHK_MC_AP_NOWAIT | ap_flags, s)) == NULL) { +- kprintf("ERROR: alloc pages for ELF section %i\n", i); +- goto err; ++ ++ if (section_page_size > PAGE_SIZE) { ++ if ((up_v = ihk_mc_alloc_aligned_pages_user(range_npages, ++ section_page_p2align, ++ IHK_MC_AP_NOWAIT | ap_flags, s)) == NULL) { ++ kprintf("ERROR: alloc pages for ELF section %i\n", i); ++ goto err; ++ } ++ } else { ++ if ((up_v = ihk_mc_alloc_pages_user(range_npages, ++ IHK_MC_AP_NOWAIT | ap_flags, s)) == NULL) { ++ kprintf("ERROR: alloc pages for ELF section %i\n", i); ++ goto err; ++ } + } + + up = virt_to_phys(up_v); +@@ -212,8 +266,19 @@ int prepare_process_ranges_args_envs(struct thread *thread, + pn->at_entry += aout_base; + } + ++ unsigned long heap_page_size; ++ unsigned long heap_page_mask; ++ ++ if (proc->heap_extension > PAGE_SIZE) { ++ heap_page_size = proc->heap_extension; ++ heap_page_mask = ~(heap_page_size - 1); ++ } else { ++ heap_page_size = PAGE_SIZE; ++ heap_page_mask = PAGE_MASK; ++ } ++ + vm->region.brk_start = vm->region.brk_end = +- (vm->region.data_end + LARGE_PAGE_SIZE - 1) & LARGE_PAGE_MASK; ++ (vm->region.data_end + heap_page_size - 1) & heap_page_mask; + + #if 0 + { +diff --git kernel/include/rusage_private.h kernel/include/rusage_private.h +index 7da7728..14253b2 100644 +--- kernel/include/rusage_private.h ++++ kernel/include/rusage_private.h +@@ -12,7 +12,7 @@ + #include + #include + +-#ifdef ENABLE_RUSAGE ++#if 0 /* def ENABLE_RUSAGE */ + + #define RUSAGE_OOM_MARGIN (2 * 1024 * 1024) // 2MB + +diff --git kernel/process.c kernel/process.c +index 32a8ef6..24f262a 100644 +--- kernel/process.c ++++ kernel/process.c +@@ -2030,6 +2030,12 @@ retry: + #endif /* POSTK_DEBUG_TEMP_FIX_86 */ + + dkprintf("%s: attr=%x\n", __FUNCTION__, attr); ++ ++ if (pgsize > PAGE_SIZE) { ++ kprintf("large page allocation, addr: %016lx, size: %d, phys: %lx\n", ++ pgaddr, pgsize, phys); ++ } ++ + error = ihk_mc_pt_set_pte(vm->address_space->page_table, ptep, + pgsize, phys, attr); + if (error) { +@@ -2256,15 +2262,20 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn, + int stack_populated_size = 0; + int stack_align_padding = 0; + ++ ++ unsigned long stack_page_size = pn->stack_premap; ++ unsigned long stack_page_mask = ~(stack_page_size - 1); ++ unsigned long stack_page_shift = 63 - __builtin_clzl(stack_page_size); ++ unsigned long stack_page_p2align = stack_page_shift - PAGE_SHIFT; ++ + /* Create stack range */ + #ifdef POSTK_DEBUG_ARCH_DEP_104 /* user stack prepage size fix */ +- end = STACK_TOP(&thread->vm->region) & USER_STACK_PAGE_MASK; +- minsz = (pn->stack_premap + USER_STACK_PREPAGE_SIZE - 1) & +- USER_STACK_PAGE_MASK; ++ end = STACK_TOP(&thread->vm->region) & stack_page_mask; ++ minsz = stack_page_size; + #else /* POSTK_DEBUG_ARCH_DEP_104 */ +- end = STACK_TOP(&thread->vm->region) & LARGE_PAGE_MASK; ++ end = STACK_TOP(&thread->vm->region) & stack_page_mask; + minsz = (pn->stack_premap +- + LARGE_PAGE_SIZE - 1) & LARGE_PAGE_MASK; ++ + stack_page_size - 1) & stack_page_mask; + #endif /* POSTK_DEBUG_ARCH_DEP_104 */ + maxsz = (end - thread->vm->region.map_start) / 2; + size = proc->rlimit[MCK_RLIMIT_STACK].rlim_cur; +@@ -2275,9 +2286,9 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn, + size = minsz; + } + #ifdef POSTK_DEBUG_ARCH_DEP_104 /* user stack prepage size fix */ +- size = (size + USER_STACK_PREPAGE_SIZE - 1) & USER_STACK_PAGE_MASK; ++ size = (size + stack_page_size - 1) & stack_page_mask; + #else /* POSTK_DEBUG_ARCH_DEP_104 */ +- size = (size + LARGE_PAGE_SIZE - 1) & LARGE_PAGE_MASK; ++ size = (size + stack_page_size - 1) & stack_page_mask; + #endif /* POSTK_DEBUG_ARCH_DEP_104 */ + dkprintf("%s: stack_premap: %lu, rlim_cur: %lu, minsz: %lu, size: %lu\n", + __FUNCTION__, +@@ -2285,9 +2296,9 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn, + proc->rlimit[MCK_RLIMIT_STACK].rlim_cur, + minsz, size); + #ifdef POSTK_DEBUG_ARCH_DEP_104 /* user stack prepage size fix */ +- start = (end - size) & USER_STACK_PAGE_MASK; ++ start = (end - size) & stack_page_mask; + #else /* POSTK_DEBUG_ARCH_DEP_104 */ +- start = (end - size) & LARGE_PAGE_MASK; ++ start = (end - size) & stack_page_mask; + #endif /* POSTK_DEBUG_ARCH_DEP_104 */ + + /* Apply user allocation policy to stacks */ +@@ -2300,10 +2311,10 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn, + + #ifdef POSTK_DEBUG_ARCH_DEP_104 /* user stack prepage size fix */ + stack = ihk_mc_alloc_aligned_pages_user(minsz >> PAGE_SHIFT, +- USER_STACK_PAGE_P2ALIGN, IHK_MC_AP_NOWAIT | ap_flag, start); ++ stack_page_p2align, IHK_MC_AP_NOWAIT | ap_flag, start); + #else /* POSTK_DEBUG_ARCH_DEP_104 */ + stack = ihk_mc_alloc_aligned_pages_user(minsz >> PAGE_SHIFT, +- LARGE_PAGE_P2ALIGN, IHK_MC_AP_NOWAIT | ap_flag, start); ++ stack_page_p2align, IHK_MC_AP_NOWAIT | ap_flag, start); + #endif /* POSTK_DEBUG_ARCH_DEP_104 */ + + if (!stack) { +@@ -2321,13 +2332,13 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn, + #define NOPHYS ((uintptr_t)-1) + #ifdef POSTK_DEBUG_ARCH_DEP_104 /* user stack prepage size fix */ + if ((rc = add_process_memory_range(thread->vm, start, end, NOPHYS, +- vrflag, NULL, 0, USER_STACK_PAGE_SHIFT, &range)) != 0) { ++ vrflag, NULL, 0, stack_page_shift, &range)) != 0) { + ihk_mc_free_pages_user(stack, minsz >> PAGE_SHIFT); + return rc; + } + #else /* POSTK_DEBUG_ARCH_DEP_104 */ + if ((rc = add_process_memory_range(thread->vm, start, end, NOPHYS, +- vrflag, NULL, 0, LARGE_PAGE_SHIFT, &range)) != 0) { ++ vrflag, NULL, 0, stack_page_shift, &range)) != 0) { + ihk_mc_free_pages_user(stack, minsz >> PAGE_SHIFT); + kprintf("%s: error addding process memory range: %d\n", rc); + return rc; +@@ -2340,14 +2351,14 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn, + thread->vm, (void *)(end - minsz), + (void *)end, virt_to_phys(stack), + arch_vrflag_to_ptattr(vrflag, PF_POPULATE, NULL), +- USER_STACK_PAGE_SHIFT, range, 0 ++ stack_page_shift, range, 0 + ); + #else /* POSTK_DEBUG_ARCH_DEP_104 */ + error = ihk_mc_pt_set_range(thread->vm->address_space->page_table, + thread->vm, (void *)(end - minsz), + (void *)end, virt_to_phys(stack), + arch_vrflag_to_ptattr(vrflag, PF_POPULATE, NULL), +- LARGE_PAGE_SHIFT, range, 0 ++ stack_page_shift, range, 0 + ); + #endif /* POSTK_DEBUG_ARCH_DEP_104 */ + +@@ -2464,14 +2475,15 @@ unsigned long extend_process_region(struct process_vm *vm, + void *p; + int rc; + +- size_t align_size = vm->proc->heap_extension > PAGE_SIZE ? +- LARGE_PAGE_SIZE : PAGE_SIZE; +- unsigned long align_mask = vm->proc->heap_extension > PAGE_SIZE ? +- LARGE_PAGE_MASK : PAGE_MASK; +- unsigned long align_p2align = vm->proc->heap_extension > PAGE_SIZE ? +- LARGE_PAGE_P2ALIGN : PAGE_P2ALIGN; +- int align_shift = vm->proc->heap_extension > PAGE_SIZE ? +- LARGE_PAGE_SHIFT : PAGE_SHIFT; ++ unsigned long heap_page_size = vm->proc->heap_extension; ++ unsigned long heap_page_mask = ~(heap_page_size - 1); ++ unsigned long heap_page_shift = 63 - __builtin_clzl(heap_page_size); ++ unsigned long heap_page_p2align = heap_page_shift - PAGE_SHIFT; ++ ++ size_t align_size = heap_page_size; ++ unsigned long align_mask = heap_page_mask; ++ unsigned long align_p2align = heap_page_p2align; ++ int align_shift = heap_page_shift; + + new_end_allocated = (address + (PAGE_SIZE - 1)) & PAGE_MASK; + if ((new_end_allocated - end_allocated) < vm->proc->heap_extension) { +diff --git kernel/syscall.c kernel/syscall.c +index 449c931..10a9039 100644 +--- kernel/syscall.c ++++ kernel/syscall.c +@@ -5228,9 +5228,22 @@ int do_shmget(const key_t key, const size_t size, const int shmflg) + return -ENOSPC; + } + +- pgshift = PAGE_SHIFT; + if (shmflg & SHM_HUGETLB) { + pgshift = (shmflg >> SHM_HUGE_SHIFT) & 0x3F; ++ } else { ++ size_t pgsize; ++ ++ if (size > PAGE_SIZE) { ++ error = arch_get_smaller_page_size(NULL, size + 1, &pgsize, NULL); ++ if (error) { ++ ekprintf("%s: arch_get_smaller_page_size failed. %d\n", error); ++ return error; ++ } ++ ++ pgshift = 63 - __builtin_clzl(pgsize);; ++ } else { ++ pgshift = PAGE_SHIFT; ++ } + } + + memset(&ads, 0, sizeof(ads)); diff --git a/test/large_page/run.sh b/test/large_page/run.sh new file mode 100755 index 00000000..78369230 --- /dev/null +++ b/test/large_page/run.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +source ${HOME}/.mck_test_config + +if [ $# -lt 1 ]; then + echo "Error: too few arguments." + echo "usage: `basename $0` " +fi + +test_id=$1 + +pagesize=$(getconf PAGESIZE) +case $pagesize in + 4096) base_name="${test_id}_4K" + ;; + 65536) base_name="${test_id}_64K" + ;; + *) echo "Error: Unknown page size" + exit 1 + ;; +esac + +init="init/${base_name}.init" + +if [ ! -e $init ]; then + echo "$init not found" + exit 1 +fi +source $init + +# kill mcexec +pidof 'mcexec ' | xargs -r kill -9 + +# stop mckernel +echo "sudo ${MCK_DIR}/sbin/mcstop+release.sh" +sudo ${MCK_DIR}/sbin/mcstop+release.sh + +# boot mckernel +echo "sudo ${MCK_DIR}/sbin/mcreboot.sh ${BOOTPARAM}" +sudo ${MCK_DIR}/sbin/mcreboot.sh ${BOOTPARAM} + +if [ ! -e "/dev/mcos0" ]; then + echo "Error: failed to mcreboot" + exit 1 +fi + +# run test program +echo "${MCK_DIR}/bin/mcexec ${MCEXECOPT} ./$base_name" +${MCK_DIR}/bin/mcexec ${MCEXECOPT} ./$base_name + +ret=$? +if [ $ret == 0 ]; then + echo "${MCK_DIR}/sbin/ihkosctl 0 kmsg" + sudo ${MCK_DIR}/sbin/ihkosctl 0 kmsg +else + echo "Error: mcexec returned $ret" +fi + +fini="fini/${base_name}.fini" +if [ -e $fini ]; then + source $fini +fi + +if [ $ret == 0 ]; then + exit 0 +else + exit 1 +fi + diff --git a/test/large_page/util.h b/test/large_page/util.h new file mode 100644 index 00000000..25415a65 --- /dev/null +++ b/test/large_page/util.h @@ -0,0 +1,56 @@ +#ifndef __UTIL_H_INCLUDED__ +#define __UTIL_H_INCLUDED__ + +#define DEBUG + +#ifdef DEBUG +#define dprintf(...) do { \ + char msg[1024]; \ + sprintf(msg, __VA_ARGS__); \ + fprintf(stderr, "%s: %s", __func__, msg); \ +} while (0) +#else +#define dprintf(...) do { } while (0) +#endif + +#define eprintf(...) do { \ + char msg[1024]; \ + sprintf(msg, __VA_ARGS__); \ + fprintf(stderr, "%s: ERROR: %s", __func__, msg); \ +} while (0) + +#define CHKANDJUMP(cond, err, ...) do { \ + if (cond) { \ + eprintf(__VA_ARGS__); \ + ret = err; \ + goto fn_fail; \ + } \ +} while (0) + +#define _OKNG(verb, jump, cond, fmt, args...) do { \ + if (cond) { \ + if (verb) \ + printf("\t[ OK ] " fmt, ##args); \ + } else { \ + printf("\t[ NG ] " fmt, ##args); \ + if (jump) \ + goto fn_fail; \ + } \ +} while (0) + +#define OKNG(args...) _OKNG(1, 1, ##args) +#define NG(args...) _OKNG(0, 1, ##args) +#define OKNGNOJUMP(args...) _OKNG(1, 0, ##args) + +#define Q(x) #x +#define QUOTE(x) Q(x) + +extern char *mck_dir; +extern char *arch; +extern char *target; + +int get_config(void); +void destroy_config(void); + +#endif + diff --git a/test/large_page/x86_64/001_4K.c b/test/large_page/x86_64/001_4K.c new file mode 100644 index 00000000..023688d3 --- /dev/null +++ b/test/large_page/x86_64/001_4K.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define PAGE_SHIFT_2M 21 +#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M) + +#define PAGE_SHIFT_1G 30 +#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G) + +int trial_num; + +int mmap_thp(size_t page_size) +{ + char *addr_mmap; + + addr_mmap = mmap(0, page_size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, + -1, 0); + NG(addr_mmap != (void *)-1, "mmap failed\n"); + + addr_mmap[0] = 'z'; + NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_mmap, page_size); + + munmap(addr_mmap, page_size); + + return 0; + fn_fail: + return 1; +} + +int main(int argc, char **argv) +{ + int ret; + + ret = mmap_thp(PAGE_SIZE_2M); + NG(ret == 0, "mmap_thp failed, size: %ld\n", + PAGE_SIZE_2M); + + ret = mmap_thp(PAGE_SIZE_1G); + NG(ret == 0, "mmap_thp failed, size: %ld\n", + PAGE_SIZE_1G); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/x86_64/101_4K.c b/test/large_page/x86_64/101_4K.c new file mode 100644 index 00000000..a6093dbc --- /dev/null +++ b/test/large_page/x86_64/101_4K.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define PAGE_SHIFT_2M 21 +#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M) + +#define PAGE_SHIFT_1G 30 +#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G) + +#define MAP_HUGE_SHIFT 26 + +int trial_num; + +int mmap_flag(size_t page_size, unsigned long page_shift) +{ + char *addr_mmap; + + addr_mmap = mmap(0, page_size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (page_shift << MAP_HUGE_SHIFT), + -1, 0); + NG(addr_mmap != (void *)-1, "mmap failed\n"); + + addr_mmap[0] = 'z'; + NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_mmap, page_size); + + munmap(addr_mmap, page_size); + + return 0; + fn_fail: + return 1; +} + +int main(int argc, char **argv) +{ + int ret; + + ret = mmap_flag(PAGE_SIZE_2M, PAGE_SHIFT_2M); + NG(ret == 0, "mmap_flag failed, size: %ld\n", + PAGE_SIZE_2M); + + ret = mmap_flag(PAGE_SIZE_1G, PAGE_SHIFT_1G); + NG(ret == 0, "mmap_flag failed, size: %ld\n", + PAGE_SIZE_1G); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/x86_64/201_4K.c b/test/large_page/x86_64/201_4K.c new file mode 100644 index 00000000..28f44f67 --- /dev/null +++ b/test/large_page/x86_64/201_4K.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define PAGE_SHIFT_2M 21 +#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M) + +#define PAGE_SHIFT_1G 30 +#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G) + +int trial_num; + +int shmat_thp(char **argv, size_t page_size) +{ + int ret; + key_t key; + int shmid; + struct shmid_ds shmid_ds; + char *addr_shmget; + + key = ftok(argv[0], 0); + + shmid = shmget(key, page_size, IPC_CREAT | 0660); + NG(shmid != -1, "shmget failed\n"); + + addr_shmget = shmat(shmid, NULL, 0); + NG(addr_shmget != (void *)-1, "shmat failed\n"); + + addr_shmget[0] = 'z'; + NG(__atomic_load_n(addr_shmget, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_shmget, page_size); + + ret = shmctl(shmid, IPC_RMID, &shmid_ds); + NG(ret != -1, "shmctl failed\n"); + + ret = shmdt(addr_shmget); + NG(ret != -1, "shmdt failed\n"); + + return 0; + fn_fail: + return 1; +} + +int main(int argc, char **argv) +{ + int ret; + + ret = shmat_thp(argv, PAGE_SIZE_2M); + NG(ret == 0, "shmat_thp failed, size: %ld\n", + PAGE_SIZE_2M); + + ret = shmat_thp(argv, PAGE_SIZE_1G); + NG(ret == 0, "shmat_thp failed, size: %ld\n", + PAGE_SIZE_1G); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/x86_64/301_4K.c b/test/large_page/x86_64/301_4K.c new file mode 100644 index 00000000..9a25b5ba --- /dev/null +++ b/test/large_page/x86_64/301_4K.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define PAGE_SHIFT_2M 21 +#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M) + +#define PAGE_SHIFT_1G 30 +#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G) + +#define SHM_HUGE_SHIFT 26 + +int trial_num; + +int shmat_thp(char **argv, size_t page_size, unsigned long page_shift) +{ + int ret; + key_t key; + int shmid; + struct shmid_ds shmid_ds; + char *addr_shmget; + + key = ftok(argv[0], 0); + + shmid = shmget(key, page_size, IPC_CREAT | 0660 | + SHM_HUGETLB | (page_shift << SHM_HUGE_SHIFT)); + NG(shmid != -1, "shmget failed\n"); + + addr_shmget = shmat(shmid, NULL, 0); + NG(addr_shmget != (void *)-1, "shmat failed\n"); + + addr_shmget[0] = 'z'; + NG(__atomic_load_n(addr_shmget, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_shmget, page_size); + + ret = shmctl(shmid, IPC_RMID, &shmid_ds); + NG(ret != -1, "shmctl failed\n"); + + ret = shmdt(addr_shmget); + NG(ret != -1, "shmdt failed\n"); + + return 0; + fn_fail: + return 1; +} + +int main(int argc, char **argv) +{ + int ret; + + ret = shmat_thp(argv, PAGE_SIZE_2M, PAGE_SHIFT_2M); + NG(ret == 0, "shmat_thp failed, size: %ld\n", + PAGE_SIZE_2M); + + ret = shmat_thp(argv, PAGE_SIZE_1G, PAGE_SHIFT_1G); + NG(ret == 0, "shmat_thp failed, size: %ld\n", + PAGE_SIZE_1G); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/x86_64/401_4K.c b/test/large_page/x86_64/401_4K.c new file mode 100644 index 00000000..7ca5e2af --- /dev/null +++ b/test/large_page/x86_64/401_4K.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define TARGET_PAGE_SHIFT 21 +#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT) + +int main(int argc, char **argv) +{ + char *addr_brk; + int trial_num = 0; + + /* Assuming heap size starts from zero and + * incremented by the amount specified with mcexec -h + */ + addr_brk = sbrk(TARGET_PAGE_SIZE); + NG(addr_brk != (void *)-1, "sbrk failed\n"); + + addr_brk[0] = 'z'; + NG(__atomic_load_n(addr_brk, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_brk, TARGET_PAGE_SIZE); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/x86_64/402_4K.c b/test/large_page/x86_64/402_4K.c new file mode 100644 index 00000000..683c3429 --- /dev/null +++ b/test/large_page/x86_64/402_4K.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define TARGET_PAGE_SHIFT 30 +#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT) + +int main(int argc, char **argv) +{ + char *addr_brk; + int trial_num = 0; + + /* Assuming heap size starts from zero and + * incremented by the amount specified with mcexec -h + */ + addr_brk = sbrk(TARGET_PAGE_SIZE); + NG(addr_brk != (void *)-1, "sbrk failed\n"); + + addr_brk[0] = 'z'; + NG(__atomic_load_n(addr_brk, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_brk, TARGET_PAGE_SIZE); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/x86_64/501_4K.c b/test/large_page/x86_64/501_4K.c new file mode 100644 index 00000000..b438d0c7 --- /dev/null +++ b/test/large_page/x86_64/501_4K.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define TARGET_PAGE_SHIFT 21 +#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT) + +/* .data */ +char addr_data[TARGET_PAGE_SIZE] = { 1 }; + +/* .bss */ +char addr_bss[TARGET_PAGE_SIZE]; + +int main(int argc, char **argv) +{ + int trial_num = 0; + char addr_stack[TARGET_PAGE_SIZE] + __attribute__((aligned(TARGET_PAGE_SIZE))); + + /* .data */ + addr_data[0] = 'z'; + NG(__atomic_load_n(addr_data, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_data, TARGET_PAGE_SIZE); + + /* .bss */ + addr_bss[0] = 'z'; + NG(__atomic_load_n(addr_bss, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_bss, TARGET_PAGE_SIZE); + + /* stack */ + addr_stack[0] = 'z'; + NG(__atomic_load_n(addr_stack, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_stack, TARGET_PAGE_SIZE); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/x86_64/501_4K.lds b/test/large_page/x86_64/501_4K.lds new file mode 100644 index 00000000..4563b045 --- /dev/null +++ b/test/large_page/x86_64/501_4K.lds @@ -0,0 +1,255 @@ +/* Script for -z combreloc: combine and sort reloc sections */ +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", + "elf64-x86-64") +OUTPUT_ARCH(i386:x86-64) +ENTRY(_start) +SEARCH_DIR("/usr/x86_64-redhat-linux/lib64"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/x86_64-redhat-linux/lib"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS; + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.sharable_data .rela.sharable_data.* .rela.gnu.linkonce.shrd.*) + *(.rela.sharable_bss .rela.sharable_bss.* .rela.gnu.linkonce.shrb.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*) + *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*) + *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*) + *(.rela.ifunc) + } + .rela.plt : + { + *(.rela.plt) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .init : + { + KEEP (*(SORT_NONE(.init))) + } + .plt : { *(.plt) *(.iplt) } + .text : + { + *(.text.unlikely .text.*_unlikely) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table + .gcc_except_table.*) } + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges + .exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + . = ALIGN(0x200000); + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got) *(.igot) } + . = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .); + .got.plt : { *(.got.plt) *(.igot.plt) } + . = ALIGN(0x200000); + .data : + { + addr_data = .; + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + . = ALIGN(0x200000); + } + .data1 : { *(.data1) } + /* Sharable data sections. */ + .sharable_data : ALIGN(CONSTANT (MAXPAGESIZE)) + { + PROVIDE_HIDDEN (__sharable_data_start = .); + *(.sharable_data .sharable_data.* .gnu.linkonce.shrd.*) + /* Align here to ensure that the sharable data section ends at the + page boundary. */ + . = ALIGN(. != 0 ? CONSTANT (MAXPAGESIZE) : 1); + PROVIDE_HIDDEN (__sharable_data_end = .); + } + _edata = .; PROVIDE (edata = .); + . = .; + . = ALIGN(0x200000); + __bss_start = .; + .bss : + { + addr_bss = .; + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we don't + pad the .data section. */ + . = ALIGN(. != 0 ? 64 / 8 : 1); + . = ALIGN(0x200000); + } + /* Sharable bss sections */ + .sharable_bss : ALIGN(CONSTANT (MAXPAGESIZE)) + { + PROVIDE_HIDDEN (__sharable_bss_start = .); + *(.dynsharablebss) + *(.sharable_bss .sharable_bss.* .gnu.linkonce.shrb.*) + *(SHARABLE_COMMON) + /* Align here to ensure that the sharable bss section ends at the + page boundary. */ + . = ALIGN(. != 0 ? CONSTANT (MAXPAGESIZE) : 1); + PROVIDE_HIDDEN (__sharable_bss_end = .); + } + .lbss : + { + *(.dynlbss) + *(.lbss .lbss.* .gnu.linkonce.lb.*) + *(LARGE_COMMON) + } + . = ALIGN(64 / 8); + . = SEGMENT_START("ldata-segment", .); + .lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : + { + *(.lrodata .lrodata.* .gnu.linkonce.lr.*) + } + .ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : + { + *(.ldata .ldata.* .gnu.linkonce.l.*) + . = ALIGN(. != 0 ? 64 / 8 : 1); + } + . = ALIGN(64 / 8); + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu_object_only) } +} + + diff --git a/test/large_page/x86_64/501_4K.org.lds b/test/large_page/x86_64/501_4K.org.lds new file mode 100644 index 00000000..51511b3a --- /dev/null +++ b/test/large_page/x86_64/501_4K.org.lds @@ -0,0 +1,292 @@ +GNU ld version 2.23.52.0.1-55.el7 20130226 + Supported emulations: + elf_x86_64 + elf32_x86_64 + elf_i386 + i386linux + elf_l1om + elf_k1om +using internal linker script: +================================================== +/* Script for -z combreloc: combine and sort reloc sections */ +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", + "elf64-x86-64") +OUTPUT_ARCH(i386:x86-64) +ENTRY(_start) +SEARCH_DIR("/usr/x86_64-redhat-linux/lib64"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/x86_64-redhat-linux/lib"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS; + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.sharable_data .rela.sharable_data.* .rela.gnu.linkonce.shrd.*) + *(.rela.sharable_bss .rela.sharable_bss.* .rela.gnu.linkonce.shrb.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*) + *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*) + *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*) + *(.rela.ifunc) + } + .rela.plt : + { + *(.rela.plt) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .init : + { + KEEP (*(SORT_NONE(.init))) + } + .plt : { *(.plt) *(.iplt) } + .text : + { + *(.text.unlikely .text.*_unlikely) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table + .gcc_except_table.*) } + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges + .exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got) *(.igot) } + . = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .); + .got.plt : { *(.got.plt) *(.igot.plt) } + .data : + { + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + /* Sharable data sections. */ + .sharable_data : ALIGN(CONSTANT (MAXPAGESIZE)) + { + PROVIDE_HIDDEN (__sharable_data_start = .); + *(.sharable_data .sharable_data.* .gnu.linkonce.shrd.*) + /* Align here to ensure that the sharable data section ends at the + page boundary. */ + . = ALIGN(. != 0 ? CONSTANT (MAXPAGESIZE) : 1); + PROVIDE_HIDDEN (__sharable_data_end = .); + } + _edata = .; PROVIDE (edata = .); + . = .; + __bss_start = .; + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we don't + pad the .data section. */ + . = ALIGN(. != 0 ? 64 / 8 : 1); + } + /* Sharable bss sections */ + .sharable_bss : ALIGN(CONSTANT (MAXPAGESIZE)) + { + PROVIDE_HIDDEN (__sharable_bss_start = .); + *(.dynsharablebss) + *(.sharable_bss .sharable_bss.* .gnu.linkonce.shrb.*) + *(SHARABLE_COMMON) + /* Align here to ensure that the sharable bss section ends at the + page boundary. */ + . = ALIGN(. != 0 ? CONSTANT (MAXPAGESIZE) : 1); + PROVIDE_HIDDEN (__sharable_bss_end = .); + } + .lbss : + { + *(.dynlbss) + *(.lbss .lbss.* .gnu.linkonce.lb.*) + *(LARGE_COMMON) + } + . = ALIGN(64 / 8); + . = SEGMENT_START("ldata-segment", .); + .lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : + { + *(.lrodata .lrodata.* .gnu.linkonce.lr.*) + } + .ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : + { + *(.ldata .ldata.* .gnu.linkonce.l.*) + . = ALIGN(. != 0 ? 64 / 8 : 1); + } + . = ALIGN(64 / 8); + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu_object_only) } +} + + +================================================== +attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o succeeded +/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o +attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o succeeded +/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o +attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o succeeded +/usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o +attempt to open 501_4K.o succeeded +501_4K.o +attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.so failed +attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.a succeeded +attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so succeeded +-lgcc_s (/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so) +attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libc.so failed +attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libc.a failed +attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libc.so succeeded +opened script file /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libc.so +opened script file /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libc.so +attempt to open /lib64/libc.so.6 succeeded +/lib64/libc.so.6 +attempt to open /usr/lib64/libc_nonshared.a succeeded +(/usr/lib64/libc_nonshared.a)elf-init.oS +attempt to open /lib64/ld-linux-x86-64.so.2 succeeded +/lib64/ld-linux-x86-64.so.2 +attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.so failed +attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.a succeeded +attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so succeeded +-lgcc_s (/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so) +attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o succeeded +/usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o +attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o succeeded +/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o +ld-linux-x86-64.so.2 needed by /lib64/libc.so.6 +found ld-linux-x86-64.so.2 at /lib64/ld-linux-x86-64.so.2 diff --git a/test/large_page/x86_64/502_4K.c b/test/large_page/x86_64/502_4K.c new file mode 100644 index 00000000..128842a0 --- /dev/null +++ b/test/large_page/x86_64/502_4K.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define TARGET_PAGE_SHIFT 30 +#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT) + +/* .data */ +char addr_data[TARGET_PAGE_SIZE] = { 1 }; + +/* .bss */ +char addr_bss[TARGET_PAGE_SIZE]; + +int main(int argc, char **argv) +{ + int trial_num = 0; + char addr_stack[TARGET_PAGE_SIZE]; + + /* .data */ + addr_data[0] = 'z'; + NG(__atomic_load_n(addr_data, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_data, TARGET_PAGE_SIZE); + + /* .bss */ + addr_bss[0] = 'z'; + NG(__atomic_load_n(addr_bss, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_bss, TARGET_PAGE_SIZE); + + /* stack */ + addr_stack[0] = 'z'; + NG(__atomic_load_n(addr_stack, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_stack, TARGET_PAGE_SIZE); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/x86_64/502_4K.lds b/test/large_page/x86_64/502_4K.lds new file mode 100644 index 00000000..b7854c9f --- /dev/null +++ b/test/large_page/x86_64/502_4K.lds @@ -0,0 +1,252 @@ +/* Script for -z combreloc: combine and sort reloc sections */ +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", + "elf64-x86-64") +OUTPUT_ARCH(i386:x86-64) +ENTRY(_start) +SEARCH_DIR("/usr/x86_64-redhat-linux/lib64"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/x86_64-redhat-linux/lib"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS; + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.sharable_data .rela.sharable_data.* .rela.gnu.linkonce.shrd.*) + *(.rela.sharable_bss .rela.sharable_bss.* .rela.gnu.linkonce.shrb.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*) + *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*) + *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*) + *(.rela.ifunc) + } + .rela.plt : + { + *(.rela.plt) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .init : + { + KEEP (*(SORT_NONE(.init))) + } + .plt : { *(.plt) *(.iplt) } + .text : + { + *(.text.unlikely .text.*_unlikely) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table + .gcc_except_table.*) } + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges + .exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got) *(.igot) } + . = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .); + .got.plt : { *(.got.plt) *(.igot.plt) } + . = ALIGN(0x40000000); + .data : + { + addr_data = .; + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + /* Sharable data sections. */ + .sharable_data : ALIGN(CONSTANT (MAXPAGESIZE)) + { + PROVIDE_HIDDEN (__sharable_data_start = .); + *(.sharable_data .sharable_data.* .gnu.linkonce.shrd.*) + /* Align here to ensure that the sharable data section ends at the + page boundary. */ + . = ALIGN(. != 0 ? CONSTANT (MAXPAGESIZE) : 1); + PROVIDE_HIDDEN (__sharable_data_end = .); + } + _edata = .; PROVIDE (edata = .); + . = .; + . = ALIGN(0x40000000); + __bss_start = .; + .bss : + { + addr_bss = .; + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we don't + pad the .data section. */ + . = ALIGN(. != 0 ? 64 / 8 : 1); + } + /* Sharable bss sections */ + .sharable_bss : ALIGN(CONSTANT (MAXPAGESIZE)) + { + PROVIDE_HIDDEN (__sharable_bss_start = .); + *(.dynsharablebss) + *(.sharable_bss .sharable_bss.* .gnu.linkonce.shrb.*) + *(SHARABLE_COMMON) + /* Align here to ensure that the sharable bss section ends at the + page boundary. */ + . = ALIGN(. != 0 ? CONSTANT (MAXPAGESIZE) : 1); + PROVIDE_HIDDEN (__sharable_bss_end = .); + } + .lbss : + { + *(.dynlbss) + *(.lbss .lbss.* .gnu.linkonce.lb.*) + *(LARGE_COMMON) + } + . = ALIGN(64 / 8); + . = SEGMENT_START("ldata-segment", .); + .lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : + { + *(.lrodata .lrodata.* .gnu.linkonce.lr.*) + } + .ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : + { + *(.ldata .ldata.* .gnu.linkonce.l.*) + . = ALIGN(. != 0 ? 64 / 8 : 1); + } + . = ALIGN(64 / 8); + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu_object_only) } +} + + diff --git a/test/large_page/x86_64/601_4K.c b/test/large_page/x86_64/601_4K.c new file mode 100644 index 00000000..fd5fc13e --- /dev/null +++ b/test/large_page/x86_64/601_4K.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util.h" + +#define PAGE_SHIFT_2M 21 +#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M) +char fn_2M[] = "/mnt/hugetlbfs-2M/tmp"; + +#define PAGE_SHIFT_1G 30 +#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G) +char fn_1G[] = "/mnt/hugetlbfs-1G/tmp"; + +int trial_num; + +int mmap_hugetlbfs(char *fn, size_t page_size) +{ + int fd; + char *addr_mmap; + + fd = open(fn, O_CREAT | O_RDWR, 0755); + NG(fd != -1, "open failed, fn: %s\n", fn); + + addr_mmap = mmap(0, page_size, + PROT_READ | PROT_WRITE, + MAP_SHARED, + fd, 0); + NG(addr_mmap != (void *)-1, "mmap failed\n"); + addr_mmap[0] = 'z'; + NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z', + "memory access failed\n"); + + printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n", + trial_num++, (unsigned long)addr_mmap, page_size); + + munmap(addr_mmap, page_size); + close(fd); + unlink(fn); + + return 0; + fn_fail: + return 1; +} + +int main(int argc, char **argv) +{ + int ret; + + ret = mmap_hugetlbfs(fn_2M, PAGE_SIZE_2M); + NG(ret == 0, "mmap_hugetlbfs failed, fn: %s", fn_2M); + + ret = mmap_hugetlbfs(fn_1G, PAGE_SIZE_1G); + NG(ret == 0, "mmap_hugetlbfs failed, fn: %s", fn_1G); + + return 0; + fn_fail: + return 1; +} diff --git a/test/large_page/x86_64/Makefile b/test/large_page/x86_64/Makefile new file mode 100644 index 00000000..da71cfc2 --- /dev/null +++ b/test/large_page/x86_64/Makefile @@ -0,0 +1,30 @@ +include $(HOME)/.mck_test_config.mk + +CC = gcc + +CPPFLAGS = +CFLAGS = -Wall -Werror -g +LDFLAGS = + +PAGESIZE = $(shell getconf PAGESIZE) +ifeq ($(PAGESIZE),4096) +SRCS = $(shell ls *_4K.c | grep -v 502) +endif + +EXES = $(SRCS:.c=) +OBJS = $(SRCS:.c=.o) + +all: $(EXES) + +test:: $(EXES) + ../driver.sh $(TESTSET) + +501_4K: 501_4K.o 501_4K.lds + $(CC) -o $@ $< $(LDFLAGS) -T 501_4K.lds + +502_4K: 502_4K.o 502_4K.lds + $(CC) -o $@ $< $(LDFLAGS) -T 502_4K.lds + +clean: + rm -f core $(EXES) $(OBJS) + diff --git a/test/large_page/x86_64/fini/601_4K.fini b/test/large_page/x86_64/fini/601_4K.fini new file mode 100644 index 00000000..05cfe79e --- /dev/null +++ b/test/large_page/x86_64/fini/601_4K.fini @@ -0,0 +1,2 @@ +sudo umount /mnt/hugetlbfs-2M +sudo umount /mnt/hugetlbfs-1G diff --git a/test/large_page/x86_64/init/001_4K.init b/test/large_page/x86_64/init/001_4K.init new file mode 100644 index 00000000..c5591a6e --- /dev/null +++ b/test/large_page/x86_64/init/001_4K.init @@ -0,0 +1 @@ +BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 28G@0,28G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24" diff --git a/test/large_page/x86_64/init/101_4K.init b/test/large_page/x86_64/init/101_4K.init new file mode 100644 index 00000000..c5591a6e --- /dev/null +++ b/test/large_page/x86_64/init/101_4K.init @@ -0,0 +1 @@ +BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 28G@0,28G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24" diff --git a/test/large_page/x86_64/init/201_4K.init b/test/large_page/x86_64/init/201_4K.init new file mode 100644 index 00000000..c5591a6e --- /dev/null +++ b/test/large_page/x86_64/init/201_4K.init @@ -0,0 +1 @@ +BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 28G@0,28G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24" diff --git a/test/large_page/x86_64/init/301_4K.init b/test/large_page/x86_64/init/301_4K.init new file mode 100644 index 00000000..c5591a6e --- /dev/null +++ b/test/large_page/x86_64/init/301_4K.init @@ -0,0 +1 @@ +BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 28G@0,28G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24" diff --git a/test/large_page/x86_64/init/401_4K.init b/test/large_page/x86_64/init/401_4K.init new file mode 100644 index 00000000..74aba726 --- /dev/null +++ b/test/large_page/x86_64/init/401_4K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 28G@0,28G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24" +MCEXECOPT="-h 2M" diff --git a/test/large_page/x86_64/init/402_4K.init b/test/large_page/x86_64/init/402_4K.init new file mode 100644 index 00000000..7726b6e1 --- /dev/null +++ b/test/large_page/x86_64/init/402_4K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 28G@0,28G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24" +MCEXECOPT="-h 1G" diff --git a/test/large_page/x86_64/init/501_4K.init b/test/large_page/x86_64/init/501_4K.init new file mode 100644 index 00000000..de21f73e --- /dev/null +++ b/test/large_page/x86_64/init/501_4K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 28G@0,28G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24" +MCEXECOPT="-s 2M,16G" diff --git a/test/large_page/x86_64/init/502_4K.init b/test/large_page/x86_64/init/502_4K.init new file mode 100644 index 00000000..a43ddc32 --- /dev/null +++ b/test/large_page/x86_64/init/502_4K.init @@ -0,0 +1,2 @@ +BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 28G@0,28G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24" +MCEXECOPT="-s 1G,16G" diff --git a/test/large_page/x86_64/init/601_4K.init b/test/large_page/x86_64/init/601_4K.init new file mode 100644 index 00000000..14743987 --- /dev/null +++ b/test/large_page/x86_64/init/601_4K.init @@ -0,0 +1,5 @@ +sudo mkdir -p /mnt/hugetlbfs-2M +sudo mount -t hugetlbfs -o mode=777,pagesize=2m none /mnt/hugetlbfs-2M + +sudo mkdir -p /mnt/hugetlbfs-1G +sudo mount -t hugetlbfs -o mode=777,pagesize=1g none /mnt/hugetlbfs-1G diff --git a/test/large_page/x86_64/result.log b/test/large_page/x86_64/result.log new file mode 100644 index 00000000..4493667e --- /dev/null +++ b/test/large_page/x86_64/result.log @@ -0,0 +1,38 @@ +Script started on Sun Dec 9 14:59:15 2018 +]0;m-takagi@wallaby14:~/project/os/mckernel/test/large_page/x86_64[?1034h[m-takagi@wallaby14 x86_64]$ makt e test +../driver.sh +[INFO] 001 started + [ OK ] trial #: 000, addr: 00002aaaab200000, requested size: 2097152, allocated size: 2097152 + [ OK ] trial #: 001, addr: 00002aaac0000000, requested size: 1073741824, allocated size: 1073741824 +[ OK ] 001 passed +[INFO] 101 started + [ OK ] trial #: 000, addr: 00002aaaab200000, requested size: 2097152, allocated size: 2097152 + [ OK ] trial #: 001, addr: 00002aaac0000000, requested size: 1073741824, allocated size: 1073741824 +[ OK ] 101 passed +[INFO] 201 started + [ OK ] trial #: 000, addr: 00002aaaab200000, requested size: 2097152, allocated size: 2097152 + [ OK ] trial #: 001, addr: 00002aaac0000000, requested size: 1073741824, allocated size: 1073741824 +[ OK ] 201 passed +[INFO] 301 started + [ OK ] trial #: 000, addr: 00002aaaab200000, requested size: 2097152, allocated size: 2097152 + [ OK ] trial #: 001, addr: 00002aaac0000000, requested size: 1073741824, allocated size: 1073741824 +[ OK ] 301 passed +[INFO] 401 started + [ OK ] trial #: 000, addr: 0000000000800000, requested size: 2097152, allocated size: 2097152 +[ OK ] 401 passed +[INFO] 402 started + [ OK ] trial #: 000, addr: 0000000040000000, requested size: 1073741824, allocated size: 1073741824 +[ OK ] 402 passed +[INFO] 501 started + [ OK ] trial #: 000, addr: 0000000000a00000, requested size: 2097152, allocated size: 2097152 + [ OK ] trial #: 001, addr: 0000000000e00000, requested size: 2097152, allocated size: 2097152 + [ OK ] trial #: 002, addr: 0000547fffa00000, requested size: 2097152, allocated size: 2097152 +[ OK ] 501 passed +[INFO] 601 started + [ OK ] trial #: 000, addr: 00002aaaab200000, requested size: 2097152, allocated size: 2097152 + [ OK ] trial #: 001, addr: 00002aaac0000000, requested size: 1073741824, allocated size: 1073741824 +[ OK ] 601 passed +]0;m-takagi@wallaby14:~/project/os/mckernel/test/large_page/x86_64[m-takagi@wallaby14 x86_64]$ exu it +exit + +Script done on Sun Dec 9 15:00:22 2018 diff --git a/test/large_page/x86_64/test_set.conf b/test/large_page/x86_64/test_set.conf new file mode 100644 index 00000000..a5a790a1 --- /dev/null +++ b/test/large_page/x86_64/test_set.conf @@ -0,0 +1,22 @@ + +# mmap + THP: 2MB, 1GB +test_set="001" + +# mmap + flag: 2MB, 1GB +test_set="${test_set} 101" + +# shget + THP: 2MB, 1GB +test_set="${test_set} 201" + +# shmget + flag: 2MB, 1GB +test_set="${test_set} 301" + +# heap: 2MB, 1GB +test_set="${test_set} 401 402" + +# .data, .bss, .stack: 2MB +test_set="${test_set} 501" + +# hugetlbfs: 2MB, 1GB +test_set="${test_set} 601" +