From 6d38c34993fbf15e8db9115761fef136bd2f5613 Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Thu, 31 Jan 2019 11:03:46 +0900 Subject: [PATCH] Merge branch 'postk_topic-contiguous_pte' into development * Merge cd7ab307fae9bc8aa49d23b32becf37368a1603e * Merge commit is changed to one commit for gerrit Change-Id: I75f0f4cf6b8b3286284638ac2c7816c5257551e4 --- arch/arm64/kernel/include/arch-memory.h | 6 +- arch/arm64/kernel/memory.c | 39 ++- arch/x86_64/kernel/include/arch-memory.h | 6 +- kernel/process.c | 3 +- test/contiguous_pte/Makefile | 102 +++++++ test/contiguous_pte/README | 170 +++++++++++ test/contiguous_pte/arm64_4KB_setting.patch | 13 + test/contiguous_pte/go_contiguous_pte_test.sh | 48 +++ test/contiguous_pte/result.log.4K | 37 +++ test/contiguous_pte/result.log.64K | 37 +++ .../src/arch/arm64/include/arch_test_mck.h | 69 +++++ test/contiguous_pte/src/contiguous_pte/000.c | 32 ++ test/contiguous_pte/src/contiguous_pte/001.c | 32 ++ test/contiguous_pte/src/contiguous_pte/002.c | 32 ++ test/contiguous_pte/src/contiguous_pte/003.c | 33 ++ test/contiguous_pte/src/contiguous_pte/004.c | 33 ++ test/contiguous_pte/src/contiguous_pte/005.c | 33 ++ test/contiguous_pte/src/contiguous_pte/006.c | 78 +++++ test/contiguous_pte/src/contiguous_pte/007.c | 64 ++++ test/contiguous_pte/src/contiguous_pte/008.c | 57 ++++ test/contiguous_pte/src/contiguous_pte/009.c | 47 +++ test/contiguous_pte/src/contiguous_pte/100.c | 59 ++++ test/contiguous_pte/src/contiguous_pte/104.c | 65 ++++ test/contiguous_pte/src/contiguous_pte/105.c | 68 +++++ test/contiguous_pte/src/contiguous_pte/106.c | 46 +++ test/contiguous_pte/src/contiguous_pte/107.c | 46 +++ test/contiguous_pte/src/contiguous_pte/200.c | 20 ++ test/contiguous_pte/src/contiguous_pte/201.c | 20 ++ test/contiguous_pte/src/contiguous_pte/202.c | 20 ++ test/contiguous_pte/src/contiguous_pte/203.c | 20 ++ test/contiguous_pte/src/contiguous_pte/204.c | 18 ++ test/contiguous_pte/src/contiguous_pte/205.c | 20 ++ test/contiguous_pte/src/contiguous_pte/206.c | 20 ++ test/contiguous_pte/src/contiguous_pte/207.c | 20 ++ test/contiguous_pte/src/contiguous_pte/208.c | 20 ++ test/contiguous_pte/src/contiguous_pte/2xx.c | 72 +++++ test/contiguous_pte/src/contiguous_pte/300.c | 20 ++ test/contiguous_pte/src/contiguous_pte/301.c | 20 ++ test/contiguous_pte/src/contiguous_pte/302.c | 20 ++ test/contiguous_pte/src/contiguous_pte/303.c | 20 ++ test/contiguous_pte/src/contiguous_pte/304.c | 18 ++ test/contiguous_pte/src/contiguous_pte/305.c | 20 ++ test/contiguous_pte/src/contiguous_pte/306.c | 20 ++ test/contiguous_pte/src/contiguous_pte/307.c | 20 ++ test/contiguous_pte/src/contiguous_pte/308.c | 20 ++ test/contiguous_pte/src/contiguous_pte/309.c | 18 ++ test/contiguous_pte/src/contiguous_pte/3xx.c | 158 ++++++++++ test/contiguous_pte/src/contiguous_pte/404.c | 83 ++++++ test/contiguous_pte/src/contiguous_pte/409.c | 57 ++++ test/contiguous_pte/src/contiguous_pte/410.c | 57 ++++ .../src/contiguous_pte/contiguous_pte.c | 281 ++++++++++++++++++ .../src/contiguous_pte/testsuite.h | 39 +++ test/contiguous_pte/src/test_case.list | 37 +++ test/contiguous_pte/src/test_mck.c | 259 ++++++++++++++++ test/contiguous_pte/src/test_mck.h | 102 +++++++ 55 files changed, 2757 insertions(+), 17 deletions(-) create mode 100644 test/contiguous_pte/Makefile create mode 100644 test/contiguous_pte/README create mode 100644 test/contiguous_pte/arm64_4KB_setting.patch create mode 100644 test/contiguous_pte/go_contiguous_pte_test.sh create mode 100644 test/contiguous_pte/result.log.4K create mode 100644 test/contiguous_pte/result.log.64K create mode 100644 test/contiguous_pte/src/arch/arm64/include/arch_test_mck.h create mode 100644 test/contiguous_pte/src/contiguous_pte/000.c create mode 100644 test/contiguous_pte/src/contiguous_pte/001.c create mode 100644 test/contiguous_pte/src/contiguous_pte/002.c create mode 100644 test/contiguous_pte/src/contiguous_pte/003.c create mode 100644 test/contiguous_pte/src/contiguous_pte/004.c create mode 100644 test/contiguous_pte/src/contiguous_pte/005.c create mode 100644 test/contiguous_pte/src/contiguous_pte/006.c create mode 100644 test/contiguous_pte/src/contiguous_pte/007.c create mode 100644 test/contiguous_pte/src/contiguous_pte/008.c create mode 100644 test/contiguous_pte/src/contiguous_pte/009.c create mode 100644 test/contiguous_pte/src/contiguous_pte/100.c create mode 100644 test/contiguous_pte/src/contiguous_pte/104.c create mode 100644 test/contiguous_pte/src/contiguous_pte/105.c create mode 100644 test/contiguous_pte/src/contiguous_pte/106.c create mode 100644 test/contiguous_pte/src/contiguous_pte/107.c create mode 100644 test/contiguous_pte/src/contiguous_pte/200.c create mode 100644 test/contiguous_pte/src/contiguous_pte/201.c create mode 100644 test/contiguous_pte/src/contiguous_pte/202.c create mode 100644 test/contiguous_pte/src/contiguous_pte/203.c create mode 100644 test/contiguous_pte/src/contiguous_pte/204.c create mode 100644 test/contiguous_pte/src/contiguous_pte/205.c create mode 100644 test/contiguous_pte/src/contiguous_pte/206.c create mode 100644 test/contiguous_pte/src/contiguous_pte/207.c create mode 100644 test/contiguous_pte/src/contiguous_pte/208.c create mode 100644 test/contiguous_pte/src/contiguous_pte/2xx.c create mode 100644 test/contiguous_pte/src/contiguous_pte/300.c create mode 100644 test/contiguous_pte/src/contiguous_pte/301.c create mode 100644 test/contiguous_pte/src/contiguous_pte/302.c create mode 100644 test/contiguous_pte/src/contiguous_pte/303.c create mode 100644 test/contiguous_pte/src/contiguous_pte/304.c create mode 100644 test/contiguous_pte/src/contiguous_pte/305.c create mode 100644 test/contiguous_pte/src/contiguous_pte/306.c create mode 100644 test/contiguous_pte/src/contiguous_pte/307.c create mode 100644 test/contiguous_pte/src/contiguous_pte/308.c create mode 100644 test/contiguous_pte/src/contiguous_pte/309.c create mode 100644 test/contiguous_pte/src/contiguous_pte/3xx.c create mode 100644 test/contiguous_pte/src/contiguous_pte/404.c create mode 100644 test/contiguous_pte/src/contiguous_pte/409.c create mode 100644 test/contiguous_pte/src/contiguous_pte/410.c create mode 100644 test/contiguous_pte/src/contiguous_pte/contiguous_pte.c create mode 100644 test/contiguous_pte/src/contiguous_pte/testsuite.h create mode 100644 test/contiguous_pte/src/test_case.list create mode 100644 test/contiguous_pte/src/test_mck.c create mode 100644 test/contiguous_pte/src/test_mck.h diff --git a/arch/arm64/kernel/include/arch-memory.h b/arch/arm64/kernel/include/arch-memory.h index 5cd0f65c..c690106b 100644 --- a/arch/arm64/kernel/include/arch-memory.h +++ b/arch/arm64/kernel/include/arch-memory.h @@ -781,12 +781,12 @@ static inline int page_is_contiguous_tail(pte_t *ptep, size_t pgsize) return (ptr == ptep); } -void arch_adjust_allocate_page_size(uintptr_t fault_addr, +struct page_table; +void arch_adjust_allocate_page_size(struct page_table *pt, + uintptr_t fault_addr, pte_t *ptep, void **pgaddrp, size_t *pgsizep); - -struct page_table; void set_pte(pte_t *ppte, unsigned long phys, enum ihk_mc_pt_attribute attr); pte_t *get_pte(struct page_table *pt, void *virt, enum ihk_mc_pt_attribute attr); diff --git a/arch/arm64/kernel/memory.c b/arch/arm64/kernel/memory.c index b07994c6..f9fd24d4 100644 --- a/arch/arm64/kernel/memory.c +++ b/arch/arm64/kernel/memory.c @@ -2356,9 +2356,6 @@ static int clear_range(struct page_table *pt, struct process_vm *vm, dkprintf("%s: %p,%lx,%lx,%d,%p\n", __func__, pt, start, end, free_physical, memobj); - dkprintf("%s: %p,%lx,%lx,%d,%p\n", - __func__, pt, start, end, free_physical, memobj); - if ((start < vm->region.user_start) || (vm->region.user_end < end) || (end <= start)) { @@ -3155,7 +3152,8 @@ static int move_one_page(void *arg0, page_table_t pt, pte_t *ptep, attr = apte & ~PT_PHYSMASK; error = ihk_mc_pt_set_range(pt, args->vm, (void *)dest, - (void *)(dest + pgsize), phys, attr, pgshift, args->range, 0); + (void *)(dest + pgsize), phys, attr, + pgshift, args->range, 0); if (error) { kprintf("move_one_page(%p,%p,%p %#lx,%p,%d):" "set failed. %d\n", @@ -3779,16 +3777,38 @@ void remote_flush_tlb_cpumask(struct process_vm *vm, } #endif /* POSTK_DEBUG_ARCH_DEP_8 */ -void arch_adjust_allocate_page_size(uintptr_t fault_addr, +void arch_adjust_allocate_page_size(struct page_table *pt, + uintptr_t fault_addr, pte_t *ptep, void **pgaddrp, size_t *pgsizep) { + int level; + + if (!pgsize_is_contiguous(*pgsizep)) { + return; + } + if (ptep == NULL) { - int level = pgsize_to_tbllv(*pgsizep); - *pgsizep = tbllv_to_pgsize(level); - *pgaddrp = (void *)__page_align(fault_addr, *pgsizep); - } else if (pte_is_null(ptep) && pgsize_is_contiguous(*pgsizep)) { + void *ptr = get_translation_table(pt); + int i; + + // Check the entries of the upper page table. + // When PTE_NULL, do not change from the size of ContiguousPTE. + level = pgsize_to_tbllv(*pgsizep); + for (i = 4; i > 0; i--) { + ptr = ptl_offset(ptr, fault_addr, i); + if (ptl_null(ptr, i)) { + if (level < i) { + return; + } + ptep = ptr; + break; + } + } + } + + if (pte_is_null(ptep)) { struct memobj *obj; uintptr_t zeropage = NOPHYS; pte_t *head; @@ -3803,7 +3823,6 @@ void arch_adjust_allocate_page_size(uintptr_t fault_addr, tail = get_contiguous_tail(ptep, *pgsizep); for (/*nop*/; head <= tail; head++) { uintptr_t phys; - int level; if (pte_is_null(head)) { continue; diff --git a/arch/x86_64/kernel/include/arch-memory.h b/arch/x86_64/kernel/include/arch-memory.h index f3db5045..ed003ae9 100644 --- a/arch/x86_64/kernel/include/arch-memory.h +++ b/arch/x86_64/kernel/include/arch-memory.h @@ -416,14 +416,14 @@ static inline int page_is_contiguous_tail(pte_t *ptep, size_t pgsize) return 0; } -static inline void arch_adjust_allocate_page_size(uintptr_t fault_addr, +struct page_table; +static inline void arch_adjust_allocate_page_size(struct page_table *pt, + uintptr_t fault_addr, pte_t *ptep, void **pgaddrp, size_t *pgsizep) { } - -struct page_table; void set_pte(pte_t *ppte, unsigned long phys, enum ihk_mc_pt_attribute attr); pte_t *get_pte(struct page_table *pt, void *virt, enum ihk_mc_pt_attribute attr); diff --git a/kernel/process.c b/kernel/process.c index b4fe76cf..6a26a72f 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -1861,7 +1861,8 @@ static int page_fault_process_memory_range(struct process_vm *vm, struct vm_rang pgaddr = (void *)(fault_addr & ~(pgsize - 1)); } - arch_adjust_allocate_page_size(fault_addr, ptep, &pgaddr, &pgsize); + arch_adjust_allocate_page_size(vm->address_space->page_table, + fault_addr, ptep, &pgaddr, &pgsize); /*****/ dkprintf("%s: ptep=%lx,pte_is_null=%d,pte_is_fileoff=%d\n", __FUNCTION__, ptep, ptep ? pte_is_null(ptep) : -1, ptep ? pte_is_fileoff(ptep, pgsize) : -1); diff --git a/test/contiguous_pte/Makefile b/test/contiguous_pte/Makefile new file mode 100644 index 00000000..f5b05e76 --- /dev/null +++ b/test/contiguous_pte/Makefile @@ -0,0 +1,102 @@ +# Makefile COPYRIGHT FUJITSU LIMITED 2018 +# +# [own copile] +# $ make +# +# [cross copile] +# $ ARCH=${target_arch} CC=${cross_compiler} make +# + +# target name. +TARGET := test_contiguous_pte +ARCH ?= arm64 + +#--------------- +# path settings. +#--------------- +# directory. +BIN_DIR := bin +SRC_ROOT_DIR := src +DEP_ROOT_DIR := depend +OBJ_ROOT_DIR := obj +INC_DIRS := . $(SRC_ROOT_DIR) $(SRC_ROOT_DIR)/arch/$(ARCH)/include + +TP_LOG_DIR := result + +SRC_DIRS := $(shell find $(SRC_ROOT_DIR) -type d | grep -vw $(SRC_ROOT_DIR)/arch) $(shell find $(SRC_ROOT_DIR)/arch/$(ARCH) -type d) +OBJ_DIRS := $(patsubst $(SRC_ROOT_DIR)%, $(OBJ_ROOT_DIR)%, $(SRC_DIRS)) +DEP_DIRS := $(patsubst $(SRC_ROOT_DIR)%, $(DEP_ROOT_DIR)%, $(SRC_DIRS)) + +# file lists. +BIN := $(TARGET) +PROGRAM := $(BIN_DIR)/$(BIN) +SRCS := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c)) +OBJS := $(patsubst $(SRC_ROOT_DIR)%, $(OBJ_ROOT_DIR)%, $(SRCS:.c=.o)) +DEPS := $(patsubst $(SRC_ROOT_DIR)%, $(DEP_ROOT_DIR)%, $(SRCS:.c=.d)) + +#-------------- +# build otions. +#-------------- +# compile. +CFLAGS += -g +CFLAGS += -O0 +CFLAGS += -Wall +CFLAGS += -Wstrict-prototypes +CFLAGS += -funsigned-char + +# preprocess. +CPPFLAGS += $(foreach dir,$(INC_DIRS),-I$(dir)) +CPPFLAGS += -D_GNU_SOURCE + +# link. +LOADLIBS += + +#-------- +# targets +#-------- +CC ?= gcc +LD := $(CC) + +RM := rm -rf +SED := sed +MKDIR := mkdir -p + +# Default target. +all: $(TARGET) + +# Generate Program. +$(TARGET): $(OBJS) + $(MKDIR) $(BIN_DIR) + $(LD) $(LDFLAGS) $^ $(LOADLIBS) -o $(PROGRAM) + +# Remove any generated file. +clean: + $(RM) $(PROGRAM) $(TP_LOG_DIR) + -@find $(SRC_ROOT_DIR) -name \*~ -exec $(RM) {} +; + -@if [ "." != $(BIN_DIR) ]; then \ + $(RM) $(BIN_DIR); \ + fi + -@if [ "." != $(OBJ_ROOT_DIR) ]; then \ + $(RM) $(OBJ_ROOT_DIR); \ + fi + -@if [ "." != $(DEP_ROOT_DIR) ]; then \ + $(RM) $(DEP_ROOT_DIR); \ + fi + +# Generate object file. +$(OBJS): + -@ $(MKDIR) $(dir $@) + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $(patsubst $(OBJ_ROOT_DIR)%, $(SRC_ROOT_DIR)%, $(@:.o=.c)) \ + -DTEST_SUITE=$(shell echo $@ | sed 's|$(OBJ_ROOT_DIR)/\([^/]*\).*.o|\1|g') \ + -DTEST_NUMBER=$(shell echo $@ | sed 's|$(OBJ_ROOT_DIR)/[^/]*/[0]\{,2\}\([0-9]*\).o|\1|g' | grep -E ^[0-9]+$) + +# Generate dependencies file. +$(DEPS): + -@ $(MKDIR) $(DEP_DIRS) + $(CC) $(CFLAGS) $(CPPFLAGS) -M $(filter %/$(patsubst $(DEP_ROOT_DIR)%, $(SRC_ROOT_DIR)%, $(@:.d=.c)), $(SRCS)) |\ + $(SED) 's|$(subst .d,.o,$(notdir $@)) *:|$(filter %/$(patsubst $(DEP_ROOT_DIR)%, $(OBJ_ROOT_DIR)%, $(@:.d=.o)), $(OBJS)) : Makefile|' >$@ + +.PHONY: all clean +ifneq "$(MAKECMDGOALS)" "clean" + -include $(DEPS) +endif diff --git a/test/contiguous_pte/README b/test/contiguous_pte/README new file mode 100644 index 00000000..613514ea --- /dev/null +++ b/test/contiguous_pte/README @@ -0,0 +1,170 @@ +=================== +Advance preparation +=================== +1) install IHK/McKernel + +2) set up configuration file + $ cp /mck_test_config.sample ~/.mck_test_config + $ emacs ~/.mck_test_config + $ cat ~/.mck_test_config + # Config file for McKernel tests + : ${BIN:=/opt/ppos/bin} + : ${SBIN:=/opt/ppos/sbin} + : ${OSTEST:=} + : ${LTP:=} + : ${BOOTPARAM:=-c 4-7 -m 8192M -e anon_on_demand} + : ${MCKERNEL_VERSION:=1.5.0} + +3) compile test program + $ cd /test/contiguous_pte + $ patch -p1 < arm64_4KB_setting.patch (4KB granule only) + $ make + +========== +How to run +========== + $ cd /test/contiguous_pte + $ sh ./go_contiguous_pte_test.sh | tee result.log + +========== +テストが確認する内容は以下の通り。 + +[基本動作] +ContiguousPTEの基本的な動作を確認する。 + +#0: shmgetのflagにContiguousPTEのサイズが指定可能なこと。 + サイズはSHM_HUGE_FIRST_CONT_BLOCKを指定する。 + +  * 64KiBページサイズにおいては、 +    ARMv8.2-LPA環境の時のみ有効なテスト。 + ARMv8.2-LPA環境では無いときは、 +    TP実行結果がNGになることが期待動作となる。 + +#1: shmgetのflagにContiguous PTEのサイズが指定可能なこと。 + サイズはSHM_HUGE_SECOND_CONT_BLOCKを指定する。 + +#2: shmgetのflagにContiguous PTEのサイズが指定可能なこと。 + サイズはSHM_HUGE_THIRD_CONT_BLOCKを指定する。 + +#3: mapのflagにContiguous PTEのサイズが指定可能なこと。 + サイズはMAP_HUGE_FIRST_CONT_BLOCKを指定する。 + +  * 64KiBページサイズにおいては、 +    ARMv8.2-LPA環境の時のみ有効なテスト。 + ARMv8.2-LPA環境では無いときは、 +    TP実行結果がNGになることが期待動作となる。 + +#4: mmapのflagにContiguous PTEのサイズが指定可能なこと。 + サイズはMAP_HUGE_SECOND_CONT_BLOCKを指定する。 + +#5: mmapのflagにContiguous PTEのサイズが指定可能なこと。 + サイズはSHM_HUGE_THIRD_CONT_BLOCKを指定する。 + +#6: ContiguousPTEが割当てられたプロセスがfork可能なこと。 + +#7: ページテーブルの登録状況が確認できない状況でも、 + 上位のページテーブルの状態をチェックして、 + ContiguousPTEのサイズでメモリを割り当てること。 + +#8: shmgetのTHPでContiguous PTEのメモリ確保が出来ること。 + + * shmgetは拡張THPが使えないのでNGとなる(Issue #1241) + +#9: mmaptのTHPでContiguous PTEのメモリ確保が出来ること。 + + +[メモリ割当て動作] +フラグ指定のmmapでContiguous PTEが割当て動作を確認する。 +(mmapはmnumap,mremapのテストの初期化処理にてメモリ確保動作を確認) +(shmgetはmadviseテストの初期化処理にてメモリ確保動作を確認) + + +#100: 次の条件の下で、ContiguousPTEの割当が行えること。 + 対象テーブル: lv2、隣接PTE: 割り当て無し、端数: なし + +   * 対象ページテーブルのContiguousPTEページサイズよりも + 大きな空きメモリが無い環境ではTPがSIGSEGVでNGになることが +    期待動作となる。 + +#104: 次の条件の下で、ContiguousPTEの割当が行えないこと。 + 対象テーブル: lv3、隣接PTE: 割当てあり(head位置)、端数: なし + +#105: 次の条件の下で、ContiguousPTEの割当が行えないこと。 +   対象テーブル: lv3、隣接PTE: 割当てあり(tail位置)、端数: なし + + +#106: 次の条件の下で、ContiguousPTEの割当が行えないこと。 +   ContiguousPTEのサイズでアラインされているVA/PAだが、 +   割当てページ数(メモリサイズ)が、ContiguousPTEの枚数に満たない。 +   対象テーブルはlv2。 + +#107: 次の条件の下で、ContiguousPTEの割当が行えないこと。 + ContiguousPTEのサイズでアラインされているVA/PAだが、 + 割当てページ数(メモリサイズ)が、ContiguousPTEの枚数に満たない。 + 対象テーブルはlv3。 + +[munmapテスト] +munmapでContiguous PTEでマップされた領域[a, b]に含まれるメモリ範囲[p ,q]をunmapした際に、 +対象領域と、その前後のPTEが期待通りになっているかを確認する。 +以下、<開始アドレス、終了アドレス>の形式で設定の組み合わせを示す。 + +#200:

+ +#201:

+ +#202:

+ +#203:

+ +#204: + +#205:

+ +#206: + +#207:

+ +#208: + +[mremapテスト] +mremapでContiguous PTEでマップされた領域[a, b]に含まれるメモリ範囲[p ,q]をmremapした際に、 +対象領域と、その前後のPTEが期待通りになっているかを確認する。 +以下、<開始アドレス、終了アドレス>の形式で設定の組み合わせを示す。 + +#300:

+ +#301:

+ +#302:

+ +#303:

+ +#304: + +#305:

+ +#306: + +#307:

+ +#308: + +#309: + 移動先アドレスがContiguousPTEのサイズにアラインされないようにし、 +   ContiguousPTEが解除されることが#304と異なる。 + +[madvise(MADV_REMOVE)テスト] +madviseでContiguous PTEでマップした領域を無効化できることを確認する。 + * MADV_REMOVEを使うプログラムを流すと +  McKはプログラムの連続実行が出来なくなり再起動が必要 + +#400 Contiguous PTEを無効化できること + +#409 Contiguous PTEを中抜きするMADV_REMOVEができないこと +   Contiguous PTEのhead PTEのアドレスを対象とする。 + +#410 Contiguous PTEを中抜きするMADV_REMOVEができないこと +   Contiguous PTEのtail PTEのアドレスを対象とする。 + +-- +README COPYRIGHT FUJITSU LIMITED 2018 diff --git a/test/contiguous_pte/arm64_4KB_setting.patch b/test/contiguous_pte/arm64_4KB_setting.patch new file mode 100644 index 00000000..00fe243b --- /dev/null +++ b/test/contiguous_pte/arm64_4KB_setting.patch @@ -0,0 +1,13 @@ +diff --git a/test/contiguous_pte/src/arch/arm64/include/arch_test_mck.h b/test/contiguous_pte/src/arch/arm64/include/arch_test_mck.h +index 9cc59e3..857f9bf 100644 +--- a/src/arch/arm64/include/arch_test_mck.h ++++ b/src/arch/arm64/include/arch_test_mck.h +@@ -7,7 +7,7 @@ + #define CONFIG_ARM64_PGTABLE_LEVELS 3 + #define CONFIG_ARM64_VA_BITS 48 + //#define CONFIG_ARM64_PGTABLE_LEVELS 4 +-#define CONFIG_ARM64_64K_PAGES 1 ++//#define CONFIG_ARM64_64K_PAGES 1 + #define VA_BITS CONFIG_ARM64_VA_BITS + + /* auxv */ diff --git a/test/contiguous_pte/go_contiguous_pte_test.sh b/test/contiguous_pte/go_contiguous_pte_test.sh new file mode 100644 index 00000000..7664e25f --- /dev/null +++ b/test/contiguous_pte/go_contiguous_pte_test.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# go_contiguous_pte_test.sh COPYRIGHT FUJITSU LIMITED 2018 +contiguous_pte_test_dir=$(dirname "${BASH_SOURCE[0]}") + +# read config +. ${contiguous_pte_test_dir}/../common.sh +. ${HOME}/.mck_test_config + +os_num=0 +if [ ! -e "/dev/mcos${os_num}" ]; then + echo "Error: failed to mcreboot" + exit 1 +fi + +logdir="${contiguous_pte_test_dir}/result" +mkdir -p "$logdir" + +# exec test program +user_proc="${contiguous_pte_test_dir}/bin/test_contiguous_pte" + +for test_case in `grep -E '^TEST_CASE_DEF' ${contiguous_pte_test_dir}/src/test_case.list` +do + tp_num=`echo $test_case | sed 's|TEST_CASE_DEF(contiguous_pte,||g' | sed 's|)$||g'` + logfile="${logdir}/${tp_num}.log" + + # run + echo "${MCEXEC} ${os_num} ${user_proc} -n $tp_num" >${logfile} 2>&1 + timeout 20 ${MCEXEC} ${os_num} ${user_proc} -n $tp_num >>${logfile} + rcode=$? + + # check result + grep -q "^RESULT: ok$" ${logfile} + if [ $? -eq 0 -a $rcode -eq 0 ]; then + echo "OK: ${tp_num}" + else + echo "NG: ${tp_num}" + echo "==" >>${logfile} + echo "${IHKOSCTL} ${os_num} kmsg" >>${logfile} + sudo ${IHKOSCTL} ${os_num} kmsg >>${logfile} + fi + + # restart after madvise system call test + if [ 400 -le $tp_num -a $tp_num -lt 500 ]; then + mcstop + mcreboot + fi +done +mcstop diff --git a/test/contiguous_pte/result.log.4K b/test/contiguous_pte/result.log.4K new file mode 100644 index 00000000..e6fcf04b --- /dev/null +++ b/test/contiguous_pte/result.log.4K @@ -0,0 +1,37 @@ +OK: 0 +OK: 1 +OK: 2 +OK: 3 +OK: 4 +OK: 5 +OK: 6 +OK: 7 +NG: 8 +OK: 9 +OK: 100 +OK: 104 +OK: 105 +OK: 106 +OK: 107 +OK: 200 +OK: 201 +OK: 202 +OK: 203 +OK: 204 +OK: 205 +OK: 206 +OK: 207 +OK: 208 +OK: 300 +OK: 301 +OK: 302 +OK: 303 +OK: 304 +OK: 305 +OK: 306 +OK: 307 +OK: 308 +OK: 309 +OK: 404 +OK: 409 +OK: 410 diff --git a/test/contiguous_pte/result.log.64K b/test/contiguous_pte/result.log.64K new file mode 100644 index 00000000..6326a689 --- /dev/null +++ b/test/contiguous_pte/result.log.64K @@ -0,0 +1,37 @@ +NG: 0 +OK: 1 +OK: 2 +NG: 3 +OK: 4 +OK: 5 +OK: 6 +OK: 7 +NG: 8 +OK: 9 +NG: 100 +OK: 104 +OK: 105 +OK: 106 +OK: 107 +OK: 200 +OK: 201 +OK: 202 +OK: 203 +OK: 204 +OK: 205 +OK: 206 +OK: 207 +OK: 208 +OK: 300 +OK: 301 +OK: 302 +OK: 303 +OK: 304 +OK: 305 +OK: 306 +OK: 307 +OK: 308 +OK: 309 +OK: 404 +OK: 409 +OK: 410 diff --git a/test/contiguous_pte/src/arch/arm64/include/arch_test_mck.h b/test/contiguous_pte/src/arch/arm64/include/arch_test_mck.h new file mode 100644 index 00000000..5eb40df5 --- /dev/null +++ b/test/contiguous_pte/src/arch/arm64/include/arch_test_mck.h @@ -0,0 +1,69 @@ +/* arch_test_mck.h COPYRIGHT FUJITSU LIMITED 2018 */ +#ifndef __ARM64_ARCH_TEST_MCK_H +#define __ARM64_ARCH_TEST_MCK_H + +/* config */ +//#define CONFIG_ARM64_VA_BITS 39 +#define CONFIG_ARM64_PGTABLE_LEVELS 3 +#define CONFIG_ARM64_VA_BITS 48 +//#define CONFIG_ARM64_PGTABLE_LEVELS 4 +#define CONFIG_ARM64_64K_PAGES 1 +#define VA_BITS CONFIG_ARM64_VA_BITS + +/* auxv */ +extern char *auxv_name[]; + +/* memory */ +#if !defined(CONFIG_ARM64_64K_PAGES) +# define PAGE_SHIFT 12 //4KB +# define CONT_PAGE_SHIFT (PAGE_SHIFT + 4) +# define CONT_LARGE_PAGE_SHIFT (LARGE_PAGE_SHIFT + 4) +# define CONT_LARGEST_PAGE_SHIFT (LARGEST_PAGE_SHIFT + 4) +#else +# define PAGE_SHIFT 16 //64KB +# define CONT_PAGE_SHIFT (PAGE_SHIFT + 5) +# define CONT_LARGE_PAGE_SHIFT (LARGE_PAGE_SHIFT + 5) +# define CONT_LARGEST_PAGE_SHIFT (LARGEST_PAGE_SHIFT + 5) +#endif + +#define LARGE_PAGE_SHIFT (PAGE_SHIFT + 9 + (PAGE_SHIFT - 12)) +#define LARGEST_PAGE_SHIFT (LARGE_PAGE_SHIFT + 9 + (PAGE_SHIFT - 12)) +#if (PAGE_SHIFT == 12) || (PAGE_SHIFT == 16) +# define ENABLE_LARGEST_PAGE 1 +#else +# define ENABLE_LARGEST_PAGE 0 +#endif + +#if (VA_BITS == 39 && PAGE_SHIFT == 12) + /* in McKernel TASK_UNMAPPED_BASE value */ +# define MMAP_START_ADDR 0x0000000800000000UL + + /* in McKernel USER_END value */ +# define MMAP_END_ADDR 0x0000002000000000UL +#elif (VA_BITS == 42 && PAGE_SHIFT == 16) + + /* in McKernel TASK_UNMAPPED_BASE value */ +# define MMAP_START_ADDR 0x0000004000000000UL + + /* in McKernel USER_END value */ +# define MMAP_END_ADDR 0x0000010000000000UL +#elif (VA_BITS == 48 && PAGE_SHIFT == 12) + + /* in McKernel TASK_UNMAPPED_BASE value */ +# define MMAP_START_ADDR 0x0000100000000000UL + + /* in McKernel USER_END value */ +# define MMAP_END_ADDR 0x0000400000000000UL +#elif (VA_BITS == 48 && PAGE_SHIFT == 16) + + /* in McKernel TASK_UNMAPPED_BASE value */ +# define MMAP_START_ADDR 0x0000100000000000UL + + /* in McKernel USER_END value */ +# define MMAP_END_ADDR 0x0000400000000000UL +#else +# error virtual address space not defined. +#endif +#define MMAP_AREA_SIZE (MMAP_END_ADDR - MMAP_START_ADDR) + +#endif /* __ARM64_ARCH_TEST_MCK_H */ diff --git a/test/contiguous_pte/src/contiguous_pte/000.c b/test/contiguous_pte/src/contiguous_pte/000.c new file mode 100644 index 00000000..90fe73d7 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/000.c @@ -0,0 +1,32 @@ +/* 000.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include +#include +#include +#include +#include +#include "test_mck.h" +#include "testsuite.h" + +static int shmid = -1; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + unsigned long shift = CONT_LARGEST_PAGE_SHIFT; + unsigned long length = 1UL << shift; + unsigned long pgsize_log = shift << MAP_HUGE_SHIFT; + + shmid = shmget(IPC_PRIVATE, length, pgsize_log | SHM_HUGETLB | + IPC_CREAT | SHM_R | SHM_W); + tp_assert(shmid >= 0, "shmget error."); + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (shmid >= 0) { + shmctl(shmid, IPC_RMID, NULL); + } +} diff --git a/test/contiguous_pte/src/contiguous_pte/001.c b/test/contiguous_pte/src/contiguous_pte/001.c new file mode 100644 index 00000000..1ae360b1 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/001.c @@ -0,0 +1,32 @@ +/* 001.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include +#include +#include +#include +#include +#include "test_mck.h" +#include "testsuite.h" + +static int shmid = -1; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + unsigned long shift = CONT_LARGE_PAGE_SHIFT; + unsigned long length = 1UL << shift; + unsigned long pgsize_log = shift << MAP_HUGE_SHIFT; + + shmid = shmget(IPC_PRIVATE, length, pgsize_log | SHM_HUGETLB | + IPC_CREAT | SHM_R | SHM_W); + tp_assert(shmid >= 0, "shmget error."); + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (shmid >= 0) { + shmctl(shmid, IPC_RMID, NULL); + } +} diff --git a/test/contiguous_pte/src/contiguous_pte/002.c b/test/contiguous_pte/src/contiguous_pte/002.c new file mode 100644 index 00000000..2841208a --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/002.c @@ -0,0 +1,32 @@ +/* 002.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include +#include +#include +#include +#include +#include "test_mck.h" +#include "testsuite.h" + +static int shmid = -1; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + unsigned long shift = CONT_PAGE_SHIFT; + unsigned long length = 1UL << shift; + unsigned long pgsize_log = shift << MAP_HUGE_SHIFT; + + shmid = shmget(IPC_PRIVATE, length, pgsize_log | SHM_HUGETLB | + IPC_CREAT | SHM_R | SHM_W); + tp_assert(shmid >= 0, "shmget error."); + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (shmid >= 0) { + shmctl(shmid, IPC_RMID, NULL); + } +} diff --git a/test/contiguous_pte/src/contiguous_pte/003.c b/test/contiguous_pte/src/contiguous_pte/003.c new file mode 100644 index 00000000..ceeca580 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/003.c @@ -0,0 +1,33 @@ +/* 003.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = CONT_LARGEST_PAGE_SHIFT; + +static char *addr = MAP_FAILED; +static size_t length; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + const int prot = PROT_READ | PROT_WRITE; + const int flag = MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | + (shift << MAP_HUGE_SHIFT); + const int fd = -1; + const off_t offset = 0; + + /* mmap */ + length = 1UL << shift; + addr = mmap(NULL, length, prot, flag, fd, offset); + tp_assert(addr != MAP_FAILED, "mmap error."); + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (addr != MAP_FAILED) { + munmap(addr, length); + } +} diff --git a/test/contiguous_pte/src/contiguous_pte/004.c b/test/contiguous_pte/src/contiguous_pte/004.c new file mode 100644 index 00000000..52d633ec --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/004.c @@ -0,0 +1,33 @@ +/* 004.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = CONT_LARGE_PAGE_SHIFT; + +static char *addr = MAP_FAILED; +static size_t length; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + const int prot = PROT_READ | PROT_WRITE; + const int flag = MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | + (shift << MAP_HUGE_SHIFT); + const int fd = -1; + const off_t offset = 0; + + /* mmap */ + length = 1UL << shift; + addr = mmap(NULL, length, prot, flag, fd, offset); + tp_assert(addr != MAP_FAILED, "mmap error."); + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (addr != MAP_FAILED) { + munmap(addr, length); + } +} diff --git a/test/contiguous_pte/src/contiguous_pte/005.c b/test/contiguous_pte/src/contiguous_pte/005.c new file mode 100644 index 00000000..b3bb2247 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/005.c @@ -0,0 +1,33 @@ +/* 005.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = CONT_PAGE_SHIFT; + +static char *addr = MAP_FAILED; +static size_t length; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + const int prot = PROT_READ | PROT_WRITE; + const int flag = MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | + (shift << MAP_HUGE_SHIFT); + const int fd = -1; + const off_t offset = 0; + + /* mmap */ + length = 1UL << shift; + addr = mmap(NULL, length, prot, flag, fd, offset); + tp_assert(addr != MAP_FAILED, "mmap error."); + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (addr != MAP_FAILED) { + munmap(addr, length); + } +} diff --git a/test/contiguous_pte/src/contiguous_pte/006.c b/test/contiguous_pte/src/contiguous_pte/006.c new file mode 100644 index 00000000..c2d48177 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/006.c @@ -0,0 +1,78 @@ +/* 006.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include +#include +#include +#include +#include +#include +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +static char *none_addr = MAP_FAILED; +static size_t none_length; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + const size_t pgsize = 1UL << shift; + const size_t contpgsize = 1UL << contshift; + char *aligned_addr = MAP_FAILED; + char *fixed_addr = MAP_FAILED; + + pid_t pid; + + /* reserve */ + none_length = contpgsize * 2; + none_addr = mmap(NULL, none_length, + PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + tp_assert(none_addr != MAP_FAILED, "mmap(none) error."); + aligned_addr = (void *)align_up((unsigned long)none_addr, contpgsize); + + /* alloc */ + // aligned_addr/fixed_addr + // | + // V + // +-----------------------+ + // | !present | + // +-----------------------+ + // |<---- vm_range ---->| + // A + // | + // 'z' + fixed_addr = mmap(aligned_addr, contpgsize, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | + MAP_HUGETLB | (contshift << MAP_HUGE_SHIFT), + -1, 0); + tp_assert(fixed_addr != MAP_FAILED, "mmap(rw) error."); + aligned_addr[0] = 'z'; + check_page_size((unsigned long)aligned_addr, contpgsize); + + /* do fork */ + pid = fork(); + tp_assert(pid >= 0, "fork error."); + + if (pid == 0) { + check_page_size((unsigned long)aligned_addr, contpgsize); + _exit(0); + } else { + int status; + + wait(&status); + } + UNUSED_VARIABLE(pgsize); + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (none_addr != MAP_FAILED) { + munmap(none_addr, none_length); + } +} diff --git a/test/contiguous_pte/src/contiguous_pte/007.c b/test/contiguous_pte/src/contiguous_pte/007.c new file mode 100644 index 00000000..ddd8e0c9 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/007.c @@ -0,0 +1,64 @@ +/* 007.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = LARGE_PAGE_SHIFT; + +static char *addr = MAP_FAILED; +static size_t length; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + int prot = PROT_NONE; + int flag = MAP_PRIVATE + | MAP_ANONYMOUS + | MAP_HUGETLB + | (shift << MAP_HUGE_SHIFT); + int fd = -1; + off_t offset = 0; + + char *alloc; + + /* reserve */ + length = 1UL << shift; + addr = mmap(NULL, length, prot, flag, fd, offset); + tp_assert(addr != MAP_FAILED, "mmap error.(addr)"); + + /* allocate */ + { + size_t alloc_len; + + alloc_len = 1UL << CONT_PAGE_SHIFT; + prot = PROT_READ | PROT_WRITE; + flag = MAP_PRIVATE + | MAP_ANONYMOUS + | MAP_FIXED; + + alloc = mmap(addr, alloc_len, + prot, flag, fd, offset); + tp_assert(alloc != MAP_FAILED, + "mmap error.(alloc)"); + *alloc = 'z'; + } + + /* check*/ + { + struct memory_info info = {0}; + + get_memory_info_self((unsigned long)alloc, &info); + tp_assert(info.present == 1, "alloc error."); + tp_assert(info.pgsize == (1UL << CONT_PAGE_SHIFT), + "pgsize error."); + } + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (addr != MAP_FAILED) { + munmap(addr, length); + } +} diff --git a/test/contiguous_pte/src/contiguous_pte/008.c b/test/contiguous_pte/src/contiguous_pte/008.c new file mode 100644 index 00000000..91672e23 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/008.c @@ -0,0 +1,57 @@ +/* 008.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include +#include +#include +#include +#include +#include "test_mck.h" +#include "testsuite.h" + +static int shmid = -1; +static char *shm_addr = (void *)-1; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + unsigned long shift = CONT_PAGE_SHIFT; + unsigned long length = (1UL << shift) * 2; + char *aligned_addr; + + shmid = shmget(IPC_PRIVATE, length, + IPC_CREAT | SHM_R | SHM_W); + tp_assert(shmid >= 0, "shmget error."); + + shm_addr = shmat(shmid, NULL, 0); + tp_assert(shm_addr != (void *)-1, + "shmat error.\n"); + + aligned_addr = (void *)align_up((unsigned long)shm_addr, + (1UL << shift)); + aligned_addr[0] = 'z'; + + // check + { + struct memory_info info = {0}; + + get_memory_info_self((unsigned long)aligned_addr, + &info); + tp_assert(info.present == 1, + "alloc error."); + tp_assert(info.pgsize == (1UL << shift), + "size error."); + } + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (shm_addr != (void *)-1) { + shmdt(shm_addr); + } + + if (shmid >= 0) { + shmctl(shmid, IPC_RMID, NULL); + } +} diff --git a/test/contiguous_pte/src/contiguous_pte/009.c b/test/contiguous_pte/src/contiguous_pte/009.c new file mode 100644 index 00000000..f462dcf7 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/009.c @@ -0,0 +1,47 @@ +/* 009.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = CONT_PAGE_SHIFT; + +static char *addr = MAP_FAILED; +static size_t length; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + char *aligned_addr; + + /* mmap */ + length = (1UL << shift) * 2; + addr = mmap(NULL, length, PROT_READ|PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + tp_assert(addr != MAP_FAILED, "mmap error."); + + aligned_addr = (void *)align_up((unsigned long)addr, + (1UL << shift)); + aligned_addr[0] = 'z'; + + // check + { + struct memory_info info = {0}; + + get_memory_info_self((unsigned long)aligned_addr, + &info); + tp_assert(info.present == 1, + "alloc error."); + tp_assert(info.pgsize == (1UL << shift), + "size error."); + } + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (addr != MAP_FAILED) { + munmap(addr, length); + } +} diff --git a/test/contiguous_pte/src/contiguous_pte/100.c b/test/contiguous_pte/src/contiguous_pte/100.c new file mode 100644 index 00000000..7f5c0645 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/100.c @@ -0,0 +1,59 @@ +/* 100.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = LARGE_PAGE_SHIFT; +static const size_t contshift = CONT_LARGE_PAGE_SHIFT; + +static char *none_addr = MAP_FAILED; +static size_t none_length; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + const size_t pgsize = 1UL << shift; + const size_t contpgsize = 1UL << contshift; + char *aligned_addr = MAP_FAILED; + char *fixed_addr = MAP_FAILED; + + /* reserve */ + none_length = contpgsize * 2; + none_addr = mmap(NULL, none_length, + PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + tp_assert(none_addr != MAP_FAILED, "mmap(none) error."); + aligned_addr = (void *)align_up((unsigned long)none_addr, contpgsize); + + /* alloc */ + // aligned_addr/fixed_addr + // | + // V + // +-----------------------+ + // | !present | + // +-----------------------+ + // |<---- vm_range ---->| + // A + // | + // 'z' + fixed_addr = mmap(aligned_addr, contpgsize, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | + MAP_HUGETLB | (contshift << MAP_HUGE_SHIFT), + -1, 0); + tp_assert(fixed_addr != MAP_FAILED, "mmap(rw) error."); + aligned_addr[0] = 'z'; + + check_page_size((unsigned long)aligned_addr, contpgsize); + + UNUSED_VARIABLE(pgsize); + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (none_addr != MAP_FAILED) { + munmap(none_addr, none_length); + } +} diff --git a/test/contiguous_pte/src/contiguous_pte/104.c b/test/contiguous_pte/src/contiguous_pte/104.c new file mode 100644 index 00000000..3807a099 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/104.c @@ -0,0 +1,65 @@ +/* 104.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +static char *none_addr = MAP_FAILED; +static size_t none_length; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + const size_t pgsize = 1UL << shift; + const size_t contpgsize = 1UL << contshift; + char *aligned_addr = MAP_FAILED; + int res = -1; + + /* reserve */ + none_length = contpgsize * 2; + none_addr = mmap(NULL, none_length, + PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | + (contshift << MAP_HUGE_SHIFT), + -1, 0); + tp_assert(none_addr != MAP_FAILED, "mmap(none) error."); + aligned_addr = (void *)align_up((unsigned long)none_addr, contpgsize); + + /* neighbor */ + { + char *neighbor_addr; + + neighbor_addr = aligned_addr; + res = mprotect(neighbor_addr, pgsize, PROT_READ|PROT_WRITE); + tp_assert(res != -1, "mprotect(neighbor) error."); + neighbor_addr[0] = -1; + } + + /* alloc */ + // aligned_addr + // | + // V + // +---------+-----------------------+ + // | present | !present | + // +---------+-----------------------+ + // |<---- vm_range ---->| + // A + // | + // 'z' + res = mprotect(aligned_addr, contpgsize, PROT_READ|PROT_WRITE); + tp_assert(res != -1, "mprotect(fixed) error."); + *(aligned_addr + pgsize) = 'z'; + + check_page_size((unsigned long)aligned_addr + pgsize, pgsize); + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (none_addr != MAP_FAILED) { + munmap(none_addr, none_length); + } +} diff --git a/test/contiguous_pte/src/contiguous_pte/105.c b/test/contiguous_pte/src/contiguous_pte/105.c new file mode 100644 index 00000000..8a5b8b91 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/105.c @@ -0,0 +1,68 @@ +/* 105.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +static char *none_addr = MAP_FAILED; +static size_t none_length; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + const size_t pgsize = 1UL << shift; + const size_t contpgsize = 1UL << contshift; + char *aligned_addr = MAP_FAILED; + int res = -1; + int flags; + + /* reserve */ + none_length = contpgsize * 2; + flags = MAP_PRIVATE + | MAP_ANONYMOUS + | MAP_HUGETLB + | (contshift << MAP_HUGE_SHIFT); + none_addr = mmap(NULL, none_length, + PROT_NONE, + flags, -1, 0); + tp_assert(none_addr != MAP_FAILED, "mmap(none) error."); + aligned_addr = (void *)align_up((unsigned long)none_addr, contpgsize); + + /* neighbor */ + { + char *neighbor_addr; + + neighbor_addr = aligned_addr + (contpgsize - pgsize); + res = mprotect(neighbor_addr, pgsize, PROT_READ|PROT_WRITE); + tp_assert(res != -1, "mprotect(neighbor) error."); + neighbor_addr[0] = -1; + } + + /* alloc */ + // aligned_addr + // | + // V + // +-----------------------+---------+ + // | !present | present | + // +-----------------------+---------+ + // |<---- vm_range ---->| + // A + // | + // 'z' + res = mprotect(aligned_addr, contpgsize, PROT_READ|PROT_WRITE); + tp_assert(res != -1, "mprotect(fixed) error."); + *(aligned_addr) = 'z'; + + check_page_size((unsigned long)aligned_addr, pgsize); + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (none_addr != MAP_FAILED) { + munmap(none_addr, none_length); + } +} diff --git a/test/contiguous_pte/src/contiguous_pte/106.c b/test/contiguous_pte/src/contiguous_pte/106.c new file mode 100644 index 00000000..4098fbfc --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/106.c @@ -0,0 +1,46 @@ +/* 106.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = LARGE_PAGE_SHIFT; +static const size_t contshift = CONT_LARGE_PAGE_SHIFT; + +static char *none_addr = MAP_FAILED; +static size_t none_length; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + const size_t pgsize = 1UL << shift; + const size_t contpgsize = 1UL << contshift; + char *aligned_addr = MAP_FAILED; + int flags; + + /* reserve */ + none_length = contpgsize * 2; + none_addr = mmap(NULL, none_length, + PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + tp_assert(none_addr != MAP_FAILED, "mmap(none) error."); + aligned_addr = (void *)align_up((unsigned long)none_addr, contpgsize); + + /* alloc */ + flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_POPULATE; + aligned_addr = mmap(aligned_addr, pgsize, + PROT_READ|PROT_WRITE, + flags, -1, 0); + tp_assert(aligned_addr != MAP_FAILED, "mmap(rw) error."); + + check_page_size((unsigned long)aligned_addr, pgsize); + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (none_addr != MAP_FAILED) { + munmap(none_addr, none_length); + } +} diff --git a/test/contiguous_pte/src/contiguous_pte/107.c b/test/contiguous_pte/src/contiguous_pte/107.c new file mode 100644 index 00000000..7219881d --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/107.c @@ -0,0 +1,46 @@ +/* 107.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +static char *none_addr = MAP_FAILED; +static size_t none_length; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + const size_t pgsize = 1UL << shift; + const size_t contpgsize = 1UL << contshift; + char *aligned_addr = MAP_FAILED; + int flags; + + /* reserve */ + none_length = contpgsize * 2; + none_addr = mmap(NULL, none_length, + PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + tp_assert(none_addr != MAP_FAILED, "mmap(none) error."); + aligned_addr = (void *)align_up((unsigned long)none_addr, contpgsize); + + /* alloc */ + flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_POPULATE; + aligned_addr = mmap(aligned_addr, pgsize, + PROT_READ|PROT_WRITE, + flags, -1, 0); + tp_assert(aligned_addr != MAP_FAILED, "mmap(rw) error."); + + check_page_size((unsigned long)aligned_addr, pgsize); + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (none_addr != MAP_FAILED) { + munmap(none_addr, none_length); + } +} diff --git a/test/contiguous_pte/src/contiguous_pte/200.c b/test/contiguous_pte/src/contiguous_pte/200.c new file mode 100644 index 00000000..242ef3f1 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/200.c @@ -0,0 +1,20 @@ +/* 200.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + ssize_t pgsize = 1UL << shift; + + return do_2xx(shift, contshift, 2, -pgsize, pgsize); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_2xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/201.c b/test/contiguous_pte/src/contiguous_pte/201.c new file mode 100644 index 00000000..56298a3d --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/201.c @@ -0,0 +1,20 @@ +/* 201.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + ssize_t pgsize = 1UL << shift; + + return do_2xx(shift, contshift, 1, pgsize, pgsize); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_2xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/202.c b/test/contiguous_pte/src/contiguous_pte/202.c new file mode 100644 index 00000000..5bb28a1a --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/202.c @@ -0,0 +1,20 @@ +/* 202.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + ssize_t pgsize = 1UL << shift; + + return do_2xx(shift, contshift, 1, -pgsize, -pgsize); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_2xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/203.c b/test/contiguous_pte/src/contiguous_pte/203.c new file mode 100644 index 00000000..6bbe6edc --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/203.c @@ -0,0 +1,20 @@ +/* 203.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + ssize_t pgsize = 1UL << shift; + + return do_2xx(shift, contshift, 2, pgsize, 0); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_2xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/204.c b/test/contiguous_pte/src/contiguous_pte/204.c new file mode 100644 index 00000000..76511e4d --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/204.c @@ -0,0 +1,18 @@ +/* 204.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + return do_2xx(shift, contshift, 1, 0, 0); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_2xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/205.c b/test/contiguous_pte/src/contiguous_pte/205.c new file mode 100644 index 00000000..df7ccb91 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/205.c @@ -0,0 +1,20 @@ +/* 205.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + ssize_t pgsize = 1UL << shift; + + return do_2xx(shift, contshift, 1, -pgsize, 0); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_2xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/206.c b/test/contiguous_pte/src/contiguous_pte/206.c new file mode 100644 index 00000000..eb022bc3 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/206.c @@ -0,0 +1,20 @@ +/* 206.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + ssize_t pgsize = 1UL << shift; + + return do_2xx(shift, contshift, 2, 0, pgsize); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_2xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/207.c b/test/contiguous_pte/src/contiguous_pte/207.c new file mode 100644 index 00000000..f237d013 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/207.c @@ -0,0 +1,20 @@ +/* 207.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + ssize_t pgsize = 1UL << shift; + + return do_2xx(shift, contshift, 2, pgsize, -pgsize); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_2xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/208.c b/test/contiguous_pte/src/contiguous_pte/208.c new file mode 100644 index 00000000..357f4ffe --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/208.c @@ -0,0 +1,20 @@ +/* 208.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + ssize_t pgsize = 1UL << shift; + + return do_2xx(shift, contshift, 2, 0, -pgsize); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_2xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/2xx.c b/test/contiguous_pte/src/contiguous_pte/2xx.c new file mode 100644 index 00000000..ac3c12c4 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/2xx.c @@ -0,0 +1,72 @@ +/* 200.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include "test_mck.h" +#include "testsuite.h" + +static char *addr = MAP_FAILED; +static size_t length; + +char *do_2xx(int shift, int contshift, int nr_contpage, + ssize_t adjust_lower, ssize_t adjust_upper) +{ + size_t pgsize = 1UL << shift; + size_t contpgsize = 1UL << contshift; + + char *cmpaddr; + char *loaddr; + char *hiaddr; + + char *unmap_addr; + char *unmap_end; + size_t unmap_length; + + int res; + + // alloc + addr = map_contiguous_pte(&length, &cmpaddr, &loaddr, &hiaddr, + contpgsize, nr_contpage); + tp_assert(addr != MAP_FAILED, "map contiguous error."); + + // test + unmap_addr = (cmpaddr) + adjust_lower; + unmap_end = (cmpaddr + contpgsize * nr_contpage) + adjust_upper; + unmap_length = (unsigned long)unmap_end - (unsigned long)unmap_addr; + res = munmap(unmap_addr, unmap_length); + tp_assert(res != -1, "munmap error."); + + // check + { + struct memory_info info; + + if (cmpaddr <= unmap_addr) { + info.present = 0; + get_memory_info_self((unsigned long)unmap_addr - 1, + &info); + tp_assert(info.present == 1 && info.pgsize == pgsize, + "unmap_addr - 1 error."); + } + + info.present = 1; + get_memory_info_self((unsigned long)unmap_addr, &info); + tp_assert(info.present == 0, "unmap_addr error."); + + info.present = 1; + get_memory_info_self((unsigned long)unmap_end - 1, &info); + tp_assert(info.present == 0, "unmap_end - 1 error."); + + if (unmap_end <= (cmpaddr + contpgsize * nr_contpage)) { + info.present = 0; + get_memory_info_self((unsigned long)unmap_end, &info); + tp_assert(info.present == 1 && info.pgsize == pgsize, + "unmap_end error."); + } + } + return NULL; +} + +void teardown_2xx(void) +{ + if (addr != MAP_FAILED) { + munmap(addr, length); + } +} diff --git a/test/contiguous_pte/src/contiguous_pte/300.c b/test/contiguous_pte/src/contiguous_pte/300.c new file mode 100644 index 00000000..8a99c0bb --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/300.c @@ -0,0 +1,20 @@ +/* 300.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + ssize_t pgsize = 1UL << shift; + + return do_3xx(shift, contshift, 2, -pgsize, pgsize, 1); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_3xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/301.c b/test/contiguous_pte/src/contiguous_pte/301.c new file mode 100644 index 00000000..4498f7f1 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/301.c @@ -0,0 +1,20 @@ +/* 301.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + ssize_t pgsize = 1UL << shift; + + return do_3xx(shift, contshift, 1, pgsize, pgsize, 1); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_3xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/302.c b/test/contiguous_pte/src/contiguous_pte/302.c new file mode 100644 index 00000000..0676032a --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/302.c @@ -0,0 +1,20 @@ +/* 302.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + ssize_t pgsize = 1UL << shift; + + return do_3xx(shift, contshift, 1, -pgsize, -pgsize, 1); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_3xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/303.c b/test/contiguous_pte/src/contiguous_pte/303.c new file mode 100644 index 00000000..097cdde0 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/303.c @@ -0,0 +1,20 @@ +/* 303.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + ssize_t pgsize = 1UL << shift; + + return do_3xx(shift, contshift, 2, pgsize, 0, 1); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_3xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/304.c b/test/contiguous_pte/src/contiguous_pte/304.c new file mode 100644 index 00000000..5d4cdaf8 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/304.c @@ -0,0 +1,18 @@ +/* 304.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + return do_3xx(shift, contshift, 1, 0, 0, 1); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_3xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/305.c b/test/contiguous_pte/src/contiguous_pte/305.c new file mode 100644 index 00000000..d1f3951a --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/305.c @@ -0,0 +1,20 @@ +/* 305.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + ssize_t pgsize = 1UL << shift; + + return do_3xx(shift, contshift, 1, -pgsize, 0, 1); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_3xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/306.c b/test/contiguous_pte/src/contiguous_pte/306.c new file mode 100644 index 00000000..9bd7eda3 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/306.c @@ -0,0 +1,20 @@ +/* 306.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + ssize_t pgsize = 1UL << shift; + + return do_3xx(shift, contshift, 2, 0, pgsize, 1); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_3xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/307.c b/test/contiguous_pte/src/contiguous_pte/307.c new file mode 100644 index 00000000..71739537 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/307.c @@ -0,0 +1,20 @@ +/* 307.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + ssize_t pgsize = 1UL << shift; + + return do_3xx(shift, contshift, 2, pgsize, -pgsize, 1); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_3xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/308.c b/test/contiguous_pte/src/contiguous_pte/308.c new file mode 100644 index 00000000..df0a8c99 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/308.c @@ -0,0 +1,20 @@ +/* 308.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + ssize_t pgsize = 1UL << shift; + + return do_3xx(shift, contshift, 2, 0, -pgsize, 1); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_3xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/309.c b/test/contiguous_pte/src/contiguous_pte/309.c new file mode 100644 index 00000000..eeb83044 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/309.c @@ -0,0 +1,18 @@ +/* 309.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + return do_3xx(shift, contshift, 2, 0, 0, 0); +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + teardown_3xx(); +} diff --git a/test/contiguous_pte/src/contiguous_pte/3xx.c b/test/contiguous_pte/src/contiguous_pte/3xx.c new file mode 100644 index 00000000..6a1a23fb --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/3xx.c @@ -0,0 +1,158 @@ +/* 300.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include "test_mck.h" +#include "testsuite.h" + +static char *addr = MAP_FAILED; +static size_t length; + +static char *remap_addr = MAP_FAILED; +static size_t remap_length; + +char *do_3xx(size_t shift, size_t contshift, int nr_contpage, + ssize_t adjust_lower, ssize_t adjust_upper, int keep_align) +{ + size_t pgsize = 1UL << shift; + size_t contpgsize = 1UL << contshift; + + char *cmpaddr; + char *loaddr; + char *hiaddr; + + char *from_addr; + char *from_end; + size_t from_length; + + char *to_addr; + char *to_end; + size_t to_length; + + int flags; + + struct { + char *addr; + unsigned long pgsize; + } to_exp[10]; + int nr_to_exp; + + // alloc + addr = map_contiguous_pte(&length, &cmpaddr, &loaddr, &hiaddr, + contpgsize, nr_contpage); + tp_assert(addr != MAP_FAILED, "map contiguous error."); + + remap_length = contpgsize + (contpgsize * nr_contpage) + contpgsize; + flags = MAP_PRIVATE + | MAP_ANONYMOUS + | MAP_HUGETLB + | (contshift << MAP_HUGE_SHIFT); + remap_addr = mmap(NULL, remap_length, + PROT_NONE, + flags, + -1, 0); + tp_assert(remap_addr != MAP_FAILED, "allocate remap area error."); + + // test + from_addr = (cmpaddr) + adjust_lower; + from_end = (cmpaddr + contpgsize * nr_contpage) + adjust_upper; + from_length = (unsigned long)from_end - (unsigned long)from_addr; + + to_addr = (void *)align_up((unsigned long)remap_addr, contpgsize); + to_addr += contpgsize + (from_addr - cmpaddr); + if (!keep_align) { + if (!((unsigned long)to_addr & (contpgsize - 1))) { + to_addr -= pgsize; + } + } + to_length = from_length; + to_end = to_addr + to_length; + { + unsigned long from = (unsigned long)from_addr; + unsigned long to = (unsigned long)to_addr; + struct memory_info info; + int i = 0; + + while (from < (unsigned long)from_end) { + unsigned long next; + + tp_assert(i < ARRAY_SIZE(to_exp), + "to_exp index error."); + + to_exp[i].addr = (void *)to; + if ((unsigned long)to_exp[i].addr & (contpgsize - 1)) { + to_exp[i].pgsize = pgsize; + } else { + to_exp[i].pgsize = contpgsize; + } + if (to_end < (to_exp[i].addr + to_exp[i].pgsize)) { + to_exp[i].pgsize = pgsize; + } + if (!keep_align) { + to_exp[i].pgsize = pgsize; + } + + get_memory_info_self(from, &info); + next = align_up(from + 1, info.pgsize); + + to += (next - from); + from = next; + i++; + } + nr_to_exp = i; + } + + to_addr = mremap(from_addr, from_length, + to_length, MREMAP_MAYMOVE|MREMAP_FIXED, to_addr); + tp_assert(to_addr != MAP_FAILED, "mremap error."); + + // check + { + struct memory_info info; + int i; + + // from + if (cmpaddr <= from_addr) { + info.present = 0; + get_memory_info_self((unsigned long)from_addr - 1, + &info); + tp_assert(info.present == 1 && info.pgsize == pgsize, + "from_addr - 1 error."); + } + + info.present = 1; + get_memory_info_self((unsigned long)from_addr, &info); + tp_assert(info.present == 0, "from_addr error."); + + info.present = 1; + get_memory_info_self((unsigned long)from_end - 1, &info); + tp_assert(info.present == 0, "from_end - 1 error."); + + if (from_end <= (cmpaddr + contpgsize * nr_contpage)) { + info.present = 0; + get_memory_info_self((unsigned long)from_end, &info); + tp_assert(info.present == 1 && info.pgsize == pgsize, + "from_end error."); + } + + // to + for (i = 0; i < nr_to_exp; i++) { + info.present = 0; + get_memory_info_self((unsigned long)to_exp[i].addr, + &info); + tp_assert(info.present == 1 && + info.pgsize == to_exp[i].pgsize, + "to error."); + } + } + return NULL; +} + +void teardown_3xx(void) +{ + if (addr != MAP_FAILED) { + munmap(addr, length); + } + + if (remap_addr != MAP_FAILED) { + munmap(remap_addr, remap_length); + } +} diff --git a/test/contiguous_pte/src/contiguous_pte/404.c b/test/contiguous_pte/src/contiguous_pte/404.c new file mode 100644 index 00000000..6817d9d2 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/404.c @@ -0,0 +1,83 @@ +/* 400.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include +#include +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +static int shmid = -1; +static char *shm_addr = (void *)-1; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + size_t pgsize = 1UL << shift; + size_t contpgsize = 1UL << contshift; + + int nr_contpage = 1; + + char *cmpaddr; + char *loaddr; + char *hiaddr; + + char *madvise_addr; + char *madvise_end; + size_t madvise_length; + + int res; + + UNUSED_VARIABLE(pgsize); + + // alloc + shmid = shm_contiguous_pte(&shm_addr, &cmpaddr, &loaddr, &hiaddr, + contpgsize, nr_contpage); + tp_assert(shmid != -1, "alloc contiguous error."); + + // test + madvise_addr = (cmpaddr); + madvise_end = (cmpaddr + contpgsize * nr_contpage); + madvise_length = (unsigned long)(madvise_end - madvise_addr); + res = madvise(madvise_addr, madvise_length, MADV_REMOVE); + tp_assert(res != -1, "madvise error."); + + // check + { + struct memory_info info; + + info.present = 0; + get_memory_info_self((unsigned long)madvise_addr - 1, &info); + tp_assert(info.present == 1 && info.pgsize == contpgsize, + "madvise_addr - 1 error."); + + info.present = 1; + get_memory_info_self((unsigned long)madvise_addr, &info); + tp_assert(info.present == 0, "madvise_addr error."); + + info.present = 1; + get_memory_info_self((unsigned long)madvise_end - 1, &info); + tp_assert(info.present == 0, "madvise_end - 1 error."); + + info.present = 0; + get_memory_info_self((unsigned long)madvise_end, &info); + tp_assert(info.present == 1 && info.pgsize == contpgsize, + "madvise_end error."); + } + + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (shm_addr != (void *)-1) { + shmdt(shm_addr); + } + + if (shmid != -1) { + shmctl(shmid, IPC_RMID, 0); + } +} + diff --git a/test/contiguous_pte/src/contiguous_pte/409.c b/test/contiguous_pte/src/contiguous_pte/409.c new file mode 100644 index 00000000..6906a7de --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/409.c @@ -0,0 +1,57 @@ +/* 409.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include +#include +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +static int shmid = -1; +static char *shm_addr = (void *)-1; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + size_t pgsize = 1UL << shift; + size_t contpgsize = 1UL << contshift; + + int nr_contpage = 2; + + char *cmpaddr; + char *loaddr; + char *hiaddr; + + char *madvise_addr; + char *madvise_end; + size_t madvise_length; + + int res; + + // alloc + shmid = shm_contiguous_pte(&shm_addr, &cmpaddr, &loaddr, &hiaddr, + contpgsize, nr_contpage); + tp_assert(shmid != -1, "alloc contiguous error."); + + // test + madvise_addr = (cmpaddr) - pgsize; + madvise_end = (cmpaddr + contpgsize * nr_contpage); + madvise_length = (unsigned long)(madvise_end - madvise_addr); + res = madvise(madvise_addr, madvise_length, MADV_REMOVE); + tp_assert(res == -1, "madvise error."); + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (shm_addr != (void *)-1) { + shmdt(shm_addr); + } + + if (shmid != -1) { + shmctl(shmid, IPC_RMID, 0); + } +} + diff --git a/test/contiguous_pte/src/contiguous_pte/410.c b/test/contiguous_pte/src/contiguous_pte/410.c new file mode 100644 index 00000000..daee492e --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/410.c @@ -0,0 +1,57 @@ +/* 410.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include +#include +#include "test_mck.h" +#include "testsuite.h" + +static const size_t shift = PAGE_SHIFT; +static const size_t contshift = CONT_PAGE_SHIFT; + +static int shmid = -1; +static char *shm_addr = (void *)-1; + +SETUP_EMPTY(TEST_SUITE, TEST_NUMBER) + +RUN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + size_t pgsize = 1UL << shift; + size_t contpgsize = 1UL << contshift; + + int nr_contpage = 1; + + char *cmpaddr; + char *loaddr; + char *hiaddr; + + char *madvise_addr; + char *madvise_end; + size_t madvise_length; + + int res; + + // alloc + shmid = shm_contiguous_pte(&shm_addr, &cmpaddr, &loaddr, &hiaddr, + contpgsize, nr_contpage); + tp_assert(shmid != -1, "alloc contiguous error."); + + // test + madvise_addr = (cmpaddr); + madvise_end = (cmpaddr + contpgsize * nr_contpage) + pgsize; + madvise_length = (unsigned long)(madvise_end - madvise_addr); + res = madvise(madvise_addr, madvise_length, MADV_REMOVE); + tp_assert(res == -1, "madvise error."); + return NULL; +} + +TEARDOWN_FUNC(TEST_SUITE, TEST_NUMBER) +{ + if (shm_addr != (void *)-1) { + shmdt(shm_addr); + } + + if (shmid != -1) { + shmctl(shmid, IPC_RMID, 0); + } +} + diff --git a/test/contiguous_pte/src/contiguous_pte/contiguous_pte.c b/test/contiguous_pte/src/contiguous_pte/contiguous_pte.c new file mode 100644 index 00000000..501a3481 --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/contiguous_pte.c @@ -0,0 +1,281 @@ +/* contiguous_pte.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include +#include +#include "test_mck.h" +#include "testsuite.h" + + + +/* + * lo_addr cmp_addr hi_addr + * V V V + * +------+-------------+------------------+-------------+------+ + * | NONE | !contig * 1 | contig * nr_comp | !contig * 1 | NONE | + * +------+-------------+------------------+-------------+------+ + * A A + * | or | + * return addr + * + */ +void *map_contiguous_pte(size_t *length, + char **cmp_addr, char **lo_addr, char **hi_addr, + size_t contpgsize, int nr_contiguous) +{ + char *ptr = MAP_FAILED; + + char *none_addr; + size_t none_length; + + char *aligned_addr; + char *lo_normal_page; + char *hi_normal_page; + + size_t pgsize; + int contshift; + int res; + + int i; + + int flags; + + if (length == NULL) { + goto out; + } + + switch (contpgsize) { + case CONT_PAGE_SIZE: + pgsize = PAGE_SIZE; + contshift = CONT_PAGE_SHIFT; + break; + case CONT_LARGE_PAGE_SIZE: + pgsize = LARGE_PAGE_SIZE; + contshift = CONT_LARGE_PAGE_SHIFT; + break; + case CONT_LARGEST_PAGE_SIZE: + pgsize = LARGEST_PAGE_SIZE; + contshift = CONT_LARGEST_PAGE_SHIFT; + break; + default: + goto out; + } + + // reserve + none_length = contpgsize + (contpgsize * nr_contiguous) + contpgsize; + flags = MAP_PRIVATE + | MAP_ANONYMOUS + | MAP_HUGETLB + | (contshift << MAP_HUGE_SHIFT); + + none_addr = mmap(NULL, none_length, + PROT_NONE, + flags, + -1, 0); + if (none_addr == MAP_FAILED) { + fprintf(stderr, "mmap(none) error.\n"); + goto out; + } + + // map contiguous + aligned_addr = (void *)align_up((unsigned long)none_addr, contpgsize); + aligned_addr += contpgsize; + res = mprotect(aligned_addr, + contpgsize * nr_contiguous, + PROT_READ | PROT_WRITE); + if (res == -1) { + fprintf(stderr, "mprotect(aligned) error.\n"); + goto out; + } + for (i = 0; i < nr_contiguous; i++) { + *(aligned_addr + contpgsize * i) = 'z'; + } + + // map neighbor + lo_normal_page = aligned_addr - pgsize; + hi_normal_page = aligned_addr + contpgsize * nr_contiguous; + + res = mprotect(lo_normal_page, pgsize, PROT_READ|PROT_WRITE); + if (res == -1) { + fprintf(stderr, "mprotect(lo) error.\n"); + goto out; + } + *(lo_normal_page) = 'z'; + + res = mprotect(hi_normal_page, pgsize, PROT_READ|PROT_WRITE); + if (res == -1) { + fprintf(stderr, "mprotect(hi) error.\n"); + goto out; + } + *(hi_normal_page) = 'z'; + + // join + res = mprotect(lo_normal_page, + pgsize + (contpgsize * nr_contiguous) + pgsize, + PROT_READ | PROT_WRITE); + if (res == -1) { + fprintf(stderr, "mprotect(join) error.\n"); + goto out; + } + + //check + check_page_size((unsigned long)lo_normal_page, pgsize); + for (i = 0; i < nr_contiguous; i++) { + check_page_size((unsigned long)aligned_addr + contpgsize * i, + contpgsize); + } + check_page_size((unsigned long)hi_normal_page, pgsize); + + if (cmp_addr) { + *cmp_addr = aligned_addr; + } + if (lo_addr) { + *lo_addr = lo_normal_page; + } + if (hi_addr) { + *hi_addr = hi_normal_page; + } + ptr = none_addr; + *length = none_length; + none_addr = MAP_FAILED; +out: + if (none_addr != MAP_FAILED) { + munmap(none_addr, none_length); + } + return ptr; +} + +/* + * lo_addr cmp_addr hi_addr + * V V V + * +------+------------+------------------+------------+------+ + * | | contig * 1 | contig * nr_comp | contig * 1 | | + * +------+------------+------------------+------------+------+ + * A A + * | or | + * __shm_addr + * + */ +int shm_contiguous_pte(char **__shm_addr, + char **cmp_addr, char **lo_addr, char **hi_addr, + size_t contpgsize, int nr_contiguous) +{ + int ret = -1; + int shmid = -1; + char *shm_addr = (void *)-1; + size_t shm_length; + + char *aligned_addr; + char *lo_page; + char *hi_page; + + size_t pgsize; + int contshift; + int res; + + int i; + int huge = 1; + + int shmflg; + + UNUSED_VARIABLE(pgsize); + + if (__shm_addr == NULL) { + goto out; + } + + switch (contpgsize) { + case CONT_PAGE_SIZE: + pgsize = PAGE_SIZE; + contshift = CONT_PAGE_SHIFT; + break; + case CONT_LARGE_PAGE_SIZE: + pgsize = LARGE_PAGE_SIZE; + contshift = CONT_LARGE_PAGE_SHIFT; + break; + case CONT_LARGEST_PAGE_SIZE: + pgsize = LARGEST_PAGE_SIZE; + contshift = CONT_LARGEST_PAGE_SHIFT; + break; + default: + goto out; + } + + // reserve + shm_length = contpgsize + (contpgsize * nr_contiguous) + contpgsize; + shm_length += contpgsize; + if (huge) { + shmflg = IPC_CREAT + | SHM_R + | SHM_HUGETLB + | (contshift << MAP_HUGE_SHIFT); + } else { + shmflg = IPC_CREAT + | SHM_R; + } + + shmid = shmget(IPC_PRIVATE, shm_length, shmflg); + if (shmid == -1) { + fprintf(stderr, "shmget error.\n"); + goto out; + } + + shm_addr = shmat(shmid, NULL, 0); + if (shm_addr == (void *)-1) { + fprintf(stderr, "shmat error.\n"); + goto out; + } + + // calc contiguous + aligned_addr = (void *)align_up((unsigned long)shm_addr, contpgsize); + aligned_addr += contpgsize; + + // calc neighbor + lo_page = aligned_addr - contpgsize; + hi_page = aligned_addr + contpgsize * nr_contiguous; + + // map + res = mprotect(lo_page, + contpgsize + (contpgsize * nr_contiguous) + contpgsize, + PROT_READ | PROT_WRITE); + if (res == -1) { + fprintf(stderr, "mprotect error.\n"); + goto out; + } + for (i = 0; i < nr_contiguous; i++) { + *(aligned_addr + contpgsize * i) = 'z'; + } + *(lo_page) = 'z'; + *(hi_page) = 'z'; + + //check + check_page_size((unsigned long)lo_page, contpgsize); + for (i = 0; i < nr_contiguous; i++) { + check_page_size((unsigned long)aligned_addr + contpgsize * i, + contpgsize); + } + check_page_size((unsigned long)hi_page, contpgsize); + + if (__shm_addr) { + *__shm_addr = shm_addr; + } + if (cmp_addr) { + *cmp_addr = aligned_addr; + } + if (lo_addr) { + *lo_addr = lo_page; + } + if (hi_addr) { + *hi_addr = hi_page; + } + ret = shmid; + shmid = -1; + shm_addr = (void *)-1; +out: + if (shm_addr != (void *)-1) { + shmdt(shm_addr); + } + if (shmid != -1) { + shmctl(shmid, IPC_RMID, 0); + } + return ret; +} diff --git a/test/contiguous_pte/src/contiguous_pte/testsuite.h b/test/contiguous_pte/src/contiguous_pte/testsuite.h new file mode 100644 index 00000000..ce7bbdeb --- /dev/null +++ b/test/contiguous_pte/src/contiguous_pte/testsuite.h @@ -0,0 +1,39 @@ +/* testsuite.h COPYRIGHT FUJITSU LIMITED 2015-2016 */ +#ifndef __TEST_SUITE_H__ +#define __TEST_SUITE_H__ + +#ifndef MAP_HUGE_SHIFT +# define MAP_HUGE_SHIFT 26 +#endif + +#ifndef SHM_HUGETLB +# define SHM_HUGETLB 04000 +#endif + +/* Only ia64 requires this */ +#ifdef __ia64__ +# define ADDR (void *)(0x8000000000000000UL) +# define SHMAT_FLAGS (SHM_RND) +#else +# define ADDR (void *)(0x0UL) +# define SHMAT_FLAGS (0) +#endif + +void *map_contiguous_pte(size_t *length, + char **cmp_addr, char **lo_addr, char **hi_addr, + size_t contpgsize, int nr_contiguous); + +int shm_contiguous_pte(char **__shm_addr, + char **cmp_addr, char **lo_addr, char **hi_addr, + size_t contpgsize, int nr_contiguous); + +char *do_2xx(int shift, int contshift, int nr_contpage, + ssize_t adjust_lower, ssize_t adjust_upper); +void teardown_2xx(void); + + +char *do_3xx(size_t shift, size_t contshift, int nr_contpage, + ssize_t adjust_lower, ssize_t adjust_upper, int keep_align); +void teardown_3xx(void); + +#endif /*__TEST_SUITE_H__*/ diff --git a/test/contiguous_pte/src/test_case.list b/test/contiguous_pte/src/test_case.list new file mode 100644 index 00000000..a8b9fc3e --- /dev/null +++ b/test/contiguous_pte/src/test_case.list @@ -0,0 +1,37 @@ +TEST_CASE_DEF(contiguous_pte,0) +TEST_CASE_DEF(contiguous_pte,1) +TEST_CASE_DEF(contiguous_pte,2) +TEST_CASE_DEF(contiguous_pte,3) +TEST_CASE_DEF(contiguous_pte,4) +TEST_CASE_DEF(contiguous_pte,5) +TEST_CASE_DEF(contiguous_pte,6) +TEST_CASE_DEF(contiguous_pte,7) +TEST_CASE_DEF(contiguous_pte,8) +TEST_CASE_DEF(contiguous_pte,9) +TEST_CASE_DEF(contiguous_pte,100) +TEST_CASE_DEF(contiguous_pte,104) +TEST_CASE_DEF(contiguous_pte,105) +TEST_CASE_DEF(contiguous_pte,106) +TEST_CASE_DEF(contiguous_pte,107) +TEST_CASE_DEF(contiguous_pte,200) +TEST_CASE_DEF(contiguous_pte,201) +TEST_CASE_DEF(contiguous_pte,202) +TEST_CASE_DEF(contiguous_pte,203) +TEST_CASE_DEF(contiguous_pte,204) +TEST_CASE_DEF(contiguous_pte,205) +TEST_CASE_DEF(contiguous_pte,206) +TEST_CASE_DEF(contiguous_pte,207) +TEST_CASE_DEF(contiguous_pte,208) +TEST_CASE_DEF(contiguous_pte,300) +TEST_CASE_DEF(contiguous_pte,301) +TEST_CASE_DEF(contiguous_pte,302) +TEST_CASE_DEF(contiguous_pte,303) +TEST_CASE_DEF(contiguous_pte,304) +TEST_CASE_DEF(contiguous_pte,305) +TEST_CASE_DEF(contiguous_pte,306) +TEST_CASE_DEF(contiguous_pte,307) +TEST_CASE_DEF(contiguous_pte,308) +TEST_CASE_DEF(contiguous_pte,309) +TEST_CASE_DEF(contiguous_pte,404) +TEST_CASE_DEF(contiguous_pte,409) +TEST_CASE_DEF(contiguous_pte,410) diff --git a/test/contiguous_pte/src/test_mck.c b/test/contiguous_pte/src/test_mck.c new file mode 100644 index 00000000..ed51fb74 --- /dev/null +++ b/test/contiguous_pte/src/test_mck.c @@ -0,0 +1,259 @@ +/* test_mck.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include "test_mck.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * test case function declaration + */ +#define TEST_CASE_DEF(ts, number) \ + void *ts ## number ## _setup(int tp_num, \ + int argc, \ + char **argv); \ + const char *ts ## number(int tp_num, void *arg); \ + void ts ## number ## _teardown(int tp_num, void *arg); +#include "test_case.list" +#undef TEST_CASE_DEF + +/* + * test case + */ +struct test_case { + const char *test_suite; + int num; + void* (*setup)(int tp_num, int argc, char **argv); + const char* (*run)(int tp_num, void *arg); + void (*teardown)(int tp_num, void *arg); +}; + +#define TEST_CASE_DEF(ts, number) \ + { \ + .test_suite = #ts, \ + .num = number, \ + .setup = ts ## number ## _setup, \ + .run = ts ## number, \ + .teardown = ts ## number ## _teardown, \ + }, +const struct test_case test_cases[] = { +#include "test_case.list" +}; +#undef TEST_CASE_DEF + +char *the_app; + +static const char *run_test_case( + const struct test_case *tc, + int argc, char **argv) +{ + void *args = NULL; + const char *msg = NULL; + + /* setup */ + args = tc->setup(tc->num, argc, argv); + + /* run */ + msg = tc->run(tc->num, args); + + /* tear_down */ + tc->teardown(tc->num, args); + + /* result */ + return msg; +} + +const struct test_case *find_test_case(const char *test_suite, int num) +{ + const struct test_case *ret = NULL; + int i; + + for (i = 0; i < ARRAY_SIZE(test_cases); i++) { + const struct test_case *tc = test_cases + i; + + if (tc->num == num && strcmp(tc->test_suite, test_suite) == 0) { + ret = tc; + break; + } + } + return ret; +} + +static void usage(void) +{ + printf("Usage: %s -n test_number [-h] -- [args]\n" + " -n test case number.\n" + " -h show this message.\n" + " args test case arguments.\n", + the_app); +} + +int main(int argc, char **argv) +{ + const struct test_case *tc; + const char *result; + const char *ts = "contiguous_pte"; + int num = INT_MIN; + int opt; + int i; + + the_app = argv[0]; + while ((opt = getopt(argc, argv, "n:h")) != -1) { + switch (opt) { + case 'n': + if (!strcmp("null", optarg)) { + return EXIT_SUCCESS; + } + num = atoi(optarg); + break; + case 'h': + usage(); + return EXIT_SUCCESS; + default: + usage(); + return EXIT_FAILURE; + } + } + argv[optind - 1] = argv[0]; + argv += (optind - 1); + argc -= (optind - 1); + optind = 1; + + /* validate */ + if (ts == NULL || num == INT_MIN) { + usage(); + return EXIT_FAILURE; + } + + /* find */ + tc = find_test_case(ts, num); + if (tc == NULL) { + printf("%s#%d is not found.\n", ts, num); + return EXIT_FAILURE; + } + + /* print info */ + printf("TEST_SUITE: %s\n", tc->test_suite); + printf("TEST_NUMBER: %d\n", tc->num); + printf("ARGS: "); + for (i = 1; i < argc; i++) { + printf("%s ", argv[i]); + } + printf("\n"); + + /* run */ + result = run_test_case(tc, argc, argv); + if (result) { + printf("RESULT: %s\n", result); + return EXIT_FAILURE; + } + printf("RESULT: ok\n"); + return EXIT_SUCCESS; +} + +#define PM_ENTRY_BYTES sizeof(unsigned long) +#define PM_STATUS_BITS 3 +#define PM_STATUS_OFFSET (64 - PM_STATUS_BITS) +#define PM_STATUS_MASK (((1LL << PM_STATUS_BITS) - 1) << PM_STATUS_OFFSET) +#define PM_STATUS(nr) (((nr) << PM_STATUS_OFFSET) & PM_STATUS_MASK) +#define PM_PSHIFT_BITS 6 +#define PM_PSHIFT_OFFSET (PM_STATUS_OFFSET - PM_PSHIFT_BITS) +#define PM_PSHIFT_MASK (((1LL << PM_PSHIFT_BITS) - 1) << PM_PSHIFT_OFFSET) +#define PM_PSHIFT(x) (((uint64_t)(x) << PM_PSHIFT_OFFSET) & PM_PSHIFT_MASK) +#define PM_PFRAME_MASK ((1LL << PM_PSHIFT_OFFSET) - 1) +#define PM_PFRAME(x) ((x) & PM_PFRAME_MASK) +#define PM_PRESENT PM_STATUS(4LL) +#define PM_SWAP PM_STATUS(2LL) + +static int __get_memory_info(const char *path, + unsigned long virt, + struct memory_info *info) +{ + int ret = 0; + int fd = -1; + unsigned long pagemap = 0; + off_t offset = 0; + + if (info == NULL) { + ret = -EINVAL; + goto out; + } + memset(info, 0, sizeof(*info)); + + /* open */ + if ((fd = open(path, O_RDONLY)) == -1) { + printf("%s open() failed. %d\n", path, errno); + ret = -EIO; + goto out; + } + + /* calc offset */ + offset = virt & PAGE_MASK; + offset /= PAGE_SIZE; + offset *= PM_ENTRY_BYTES; + + /* lseek */ + if ((lseek(fd, offset, SEEK_SET)) == -1) { + printf("%s lseek() failed. %d\n", path, errno); + ret = -EIO; + goto out_close; + } + + /* read */ + if ((read(fd, &pagemap, sizeof(pagemap))) == -1) { + printf("%s offset:%lx read() failed. %d\n", + path, offset, errno); + ret = -EIO; + goto out_close; + } + + info->phys = (pagemap & PM_PFRAME_MASK) << PAGE_SHIFT; + info->phys |= virt & PAGE_OFFSET; + info->pgsize = 1UL << ((pagemap & PM_PSHIFT_MASK) >> PM_PSHIFT_OFFSET); + info->present = !!(pagemap & PM_PRESENT); + info->swap = !!(pagemap & PM_SWAP); +out_close: + if (fd != -1) { + close(fd); + } +out: + return ret; +} + +int get_memory_info_self(unsigned long virt, struct memory_info *info) +{ + const char *path = "/proc/self/pagemap"; + + return __get_memory_info(path, virt, info); +} + +int get_memory_info(pid_t pid, unsigned long virt, struct memory_info *info) +{ + char path[64]; + + snprintf(path, sizeof(path), "/proc/%d/pagemap", pid); + return __get_memory_info(path, virt, info); +} + +int check_page_size(unsigned long va, unsigned long pagesize) +{ + struct memory_info info; + int stat; + + stat = get_memory_info_self(va, &info); + if (stat != 0) { + printf("get memory info failed.\n"); + return 0; + } + if (info.pgsize != pagesize) { + printf("pagesize = 0x%lx, Not as expected.\n", info.pgsize); + return 0; + } + return 1; +} diff --git a/test/contiguous_pte/src/test_mck.h b/test/contiguous_pte/src/test_mck.h new file mode 100644 index 00000000..25291683 --- /dev/null +++ b/test/contiguous_pte/src/test_mck.h @@ -0,0 +1,102 @@ +/* test_mck.h COPYRIGHT FUJITSU LIMITED 2018 */ +#ifndef __TEST_MCK_H__ +#define __TEST_MCK_H__ + +#include +#include +#include "arch_test_mck.h" + +extern char *the_app; + +/* test case interface */ +#define SETUP_NAME(ts, num) ts ## num ## _setup + +#define RUN_NAME(ts, num) ts ## num + +#define TEARDOWN_NAME(ts, num) ts ## num ## _teardown + +#define SETUP_FUNC(ts, num) \ + void *SETUP_NAME(ts, num)(int tc_num, int tc_argc, char **tc_argv) + +#define RUN_FUNC(ts, num) \ + const char *RUN_NAME(ts, num)(int tc_num, void *tc_arg) + +#define TEARDOWN_FUNC(ts, num) \ + void TEARDOWN_NAME(ts, num)(int tc_num, void *tc_arg) + +#define SETUP_EMPTY(ts, num) SETUP_FUNC(ts, num) {return NULL; } + +#define RUN_EMPTY(ts, num) RUN_FUNC(ts, num) { return NULL; } + +#define TEARDOWN_EMPTY(ts, num) TEARDOWN_FUNC(ts, num) { } + +/* util */ +#define tp_assert(test, msg) \ + _tp_assert(TEST_SUITE, TEST_NUMBER, \ + __LINE__, test, msg) + +#define _tp_assert(ts, num, line, test, msg) \ + __tp_assert(ts, num, line, test, msg) + +#define __tp_assert(ts, num, line, test, msg) \ + do { \ + if (!(test)) \ + return (msg); \ + } while (0) + +#define align_down(addr, size) ((addr)&(~((size)-1))) +#define align_up(addr, size) align_down((addr) + (size) - 1, size) + +#define UNUSED_VARIABLE(v) (void)(v) + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) +#endif + +/* memory */ +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_OFFSET (PAGE_SIZE - 1UL) +#define PAGE_MASK (~PAGE_OFFSET) + +#define CONT_PAGE_SIZE (1UL << CONT_PAGE_SHIFT) +#define CONT_PAGE_OFFSET (CONT_PAGE_SIZE - 1UL) +#define CONT_PAGE_MASK (~CONT_PAGE_OFFSET) + +#define LARGE_PAGE_SIZE (1UL << LARGE_PAGE_SHIFT) +#define LARGE_PAGE_OFFSET (LARGE_PAGE_SIZE - 1UL) +#define LARGE_PAGE_MASK (~LARGE_PAGE_OFFSET) + +#define CONT_LARGE_PAGE_SIZE (1UL << CONT_LARGE_PAGE_SHIFT) +#define CONT_LARGE_PAGE_OFFSET (CONT_LARGE_PAGE_SIZE - 1UL) +#define CONT_LARGE_PAGE_MASK (~CONT_LARGE_PAGE_OFFSET) + +#define LARGEST_PAGE_SIZE (1UL << LARGEST_PAGE_SHIFT) +#define LARGEST_PAGE_OFFSET (LARGEST_PAGE_SIZE - 1UL) +#define LARGEST_PAGE_MASK (~LARGEST_PAGE_OFFSET) + +#define CONT_LARGEST_PAGE_SIZE (1UL << CONT_LARGEST_PAGE_SHIFT) +#define CONT_LARGEST_PAGE_OFFSET (CONT_LARGEST_PAGE_SIZE - 1UL) +#define CONT_LARGEST_PAGE_MASK (~CONT_LARGEST_PAGE_OFFSET) + +#define PAGE_ALIGN(addr) align_up(addr, PAGE_SIZE) +#define LARGE_PAGE_ALIGN(addr) align_up(addr, LARGE_PAGE_SIZE) +#define LARGEST_PAGE_ALIGN(addr) align_up(addr, LARGEST_PAGE_SIZE) + +#define CONT_PAGE_ALIGN(addr) align_up(addr, CONT_PAGE_SIZE) +#define CONT_LARGE_PAGE_ALIGN(addr) align_up(addr, CONT_LARGE_PAGE_SIZE) +#define CONT_LARGEST_PAGE_ALIGN(addr) align_up(addr, CONT_LARGEST_PAGE_SIZE) + +/* procfs */ +struct memory_info { + unsigned long phys; + unsigned long pgsize; + unsigned long present; + unsigned long swap; +}; +int get_memory_info_self(unsigned long virt, struct memory_info *info); +int get_memory_info(pid_t pid, + unsigned long virt, + struct memory_info *info); +int check_page_size(unsigned long va, unsigned long pagesize); + +#endif /*__TEST_MCK_H__*/