Merge branch 'postk_topic-contiguous_pte' into development

* Merge cd7ab307fae9bc8aa49d23b32becf37368a1603e
* Merge commit is changed to one commit for gerrit

Change-Id: I75f0f4cf6b8b3286284638ac2c7816c5257551e4
This commit is contained in:
Dominique Martinet
2019-01-31 11:03:46 +09:00
parent 7f1c17fc4c
commit 6d38c34993
55 changed files with 2757 additions and 17 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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

170
test/contiguous_pte/README Normal file
View File

@ -0,0 +1,170 @@
===================
Advance preparation
===================
1) install IHK/McKernel
2) set up configuration file
$ cp <mckernel>/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 <mckernel>/test/contiguous_pte
$ patch -p1 < arm64_4KB_setting.patch (4KB granule only)
$ make
==========
How to run
==========
$ cd <mckernel>/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: <p - PAGE_SIZE, p + PAGE_SIZE>
#201: <p + PAGE_SIZE, p + PAGE_SIZE>
#202: <p - PAGE_SIZE, p - PAGE_SIZE>
#203: <p + PAGE_SIZE, p>
#204: <p, p>
#205: <p - PAGE_SIZE, p>
#206: <p, p + PAGE_SIZE>
#207: <p + PAGE_SIZE, p - PAGE_SIZE>
#208: <p, p - PAGE_SIZE>
[mremapテスト]
mremapでContiguous PTEでマップされた領域[a, b]に含まれるメモリ範囲[p ,q]をmremapした際に、
対象領域と、その前後のPTEが期待通りになっているかを確認する。
以下、<開始アドレス、終了アドレス>の形式で設定の組み合わせを示す。
#300: <p - PAGE_SIZE, p + PAGE_SIZE>
#301: <p + PAGE_SIZE, p + PAGE_SIZE>
#302: <p - PAGE_SIZE, p - PAGE_SIZE>
#303: <p + PAGE_SIZE, p>
#304: <p, p>
#305: <p - PAGE_SIZE, p>
#306: <p, p + PAGE_SIZE>
#307: <p + PAGE_SIZE, p - PAGE_SIZE>
#308: <p, p - PAGE_SIZE>
#309: <p, p>
移動先アドレスが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

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -0,0 +1,32 @@
/* 000.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,32 @@
/* 001.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,32 @@
/* 002.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,33 @@
/* 003.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,33 @@
/* 004.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,33 @@
/* 005.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,78 @@
/* 006.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,64 @@
/* 007.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,57 @@
/* 008.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,47 @@
/* 009.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,59 @@
/* 100.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,65 @@
/* 104.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,68 @@
/* 105.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,46 @@
/* 106.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,46 @@
/* 107.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <sys/mman.h>
#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);
}
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -0,0 +1,72 @@
/* 200.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <sys/mman.h>
#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);
}
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -0,0 +1,158 @@
/* 300.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,83 @@
/* 400.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,57 @@
/* 409.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,57 @@
/* 410.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#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);
}
}

View File

@ -0,0 +1,281 @@
/* contiguous_pte.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#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;
}

View File

@ -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__*/

View File

@ -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)

View File

@ -0,0 +1,259 @@
/* test_mck.c COPYRIGHT FUJITSU LIMITED 2018 */
#include "test_mck.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include <syscall.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/*
* 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;
}

View File

@ -0,0 +1,102 @@
/* test_mck.h COPYRIGHT FUJITSU LIMITED 2018 */
#ifndef __TEST_MCK_H__
#define __TEST_MCK_H__
#include <stdio.h>
#include <sys/types.h>
#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__*/