diff --git a/test/mcexec_options/arm64/Makefile b/test/mcexec_options/arm64/Makefile new file mode 100644 index 00000000..6d6d1037 --- /dev/null +++ b/test/mcexec_options/arm64/Makefile @@ -0,0 +1,28 @@ +# Makefile COPYRIGHT FUJITSU LIMITED 2018 +CC = gcc +TARGET = extend_heap node_bind allow_oversubscribe stack_premap +LDFLAGS = + +all: $(TARGET) + +extend_heap: extend_heap.c + $(CC) -o $@ $^ $(LDFLAGS) + +node_bind: node_bind.c + $(CC) -o $@ $^ $(LDFLAGS) -lnuma + +allow_oversubscribe: allow_oversubscribe.c + $(CC) -o $@ $^ $(LDFLAGS) + +stack_premap: stack_premap.c + $(CC) -o $@ $^ $(LDFLAGS) + +test: all + ./run_extend_heap.sh + ./run_node_bind.sh + ./run_nr_partitions.sh + ./run_allow_oversubscribe.sh + ./run_stack_premap.sh + +clean: + rm -f $(TARGET) diff --git a/test/mcexec_options/arm64/README b/test/mcexec_options/arm64/README new file mode 100644 index 00000000..9a9a99a1 --- /dev/null +++ b/test/mcexec_options/arm64/README @@ -0,0 +1,74 @@ +/* README COPYRIGHT FUJITSU LIMITED 2018 */ + +mcexecへの追加実装オプションテストセットREADME + +(1) テストの実行方法 + 以下の手順でテストを実行する + 1. $HOME/.mck_test_configを用意する + 当該ファイルは、McKernelをビルドした際に生成されるmck_test_config.sample ファイルを + $HOMEにコピーし、適宜編集する + 2. configのページサイズ変数群の定義を環境に合わせる(デフォルトでは64K-page設定が有効) + 3. make testを実行する + +(2) テスト項目詳細 + 【-h オプション】 + TEST001 "-h xxK"指定のヒープ拡張確認(サイズはページサイズより小さい値) + TEST002 "-h xxM"指定のヒープ拡張確認(サイズはラージページサイズより小さい値) + TEST003 "-h 1G"指定のヒープ拡張確認 + TEST004 "-h xxk"指定のヒープ拡張確認(サイズはページサイズより大きく、ラージページサイズより小さい値) + TEST005 "-h xxm"指定のヒープ拡張確認(サイズはラージページサイズより大きい値) + TEST006 "-h 2g"指定のヒープ拡張確認 + TEST007 "-h xx"指定のヒープ拡張確認(サイズはノーマルページサイズ) + TEST008 "-h xx"指定のヒープ拡張確認(サイズはラージページサイズ) + + 【-m オプション】 + TEST009 任意のMcKernelに含むnodeを-mで指定する + TEST010 HOST上には存在するが、McKernelには割り当たっていないnodeを-mで指定する + TEST011 「-」を含む指定を行い、連続したnodeを割り当てる + TEST012 「,」で区切った指定を行い、nodeを割り当てる + TEST013 「!」を使用し、指定除外を含むnodeを割り当てる + TEST014 「+」を使用したnode指定を含むnodeを割り当てる + TEST015 allを指定したnodeを割り当てる + TEST016 存在しないnode番号を指定する + + 【-n オプション】 + TEST017 -n 2を指定して、任意のa.outを実行して動作することを確認する + TEST018 -n 4(McKernel割り当てコア数と同一)を指定して、任意のa.outを実行して動作することを確認する + TEST019 McKernel割り当てコア数より大きい数値を指定して、エラーになることを確認する + TEST020 数値以外を含む文字列を指定して、エラーになることを確認する + + 【-O オプション】 + TEST021 mcreboot.shの-Oオプション無効時、McKernelコア数を越えるforkがEINVALで失敗すること + TEST022 mcreboot.shの-Oオプション有効時、McKernelコア数を越えるforkが成功すること + + 【-s(--stack-premap) オプション】 + TEST023 "-s xxK"指定のpremap領域確認(サイズはページサイズより小さい値) + TEST024 "-s xxM"指定のpremap領域確認(サイズはラージページサイズより小さい値) + TEST025 "-s 1G"指定のpremap領域確認 + TEST026 "--stack-premap xxk"指定のpremap領域確認(サイズはページサイズより大きく、ラージページサイズより小さい値) + TEST027 "--stack-premap xxm"指定のpremap領域確認(サイズはラージページサイズより大きい値) + TEST028 "--stack-premap 2g"指定のpremap領域確認 + TEST029 "-s xx"指定のpremap領域確認(サイズはノーマルページサイズ) + TEST030 max指定値がsize指定値よりも小さい場合、max値分でpremapする事を確認 + +(3) 実行結果ログ + result.logファイル内に実行時のログを記載する。 + 実行に利用したIHK/McKernelは、IA版における下記の版数相当の + arm64版移植IHK/McKernelである。 + + IHK + commit d6fcbee8cb91f9ec4b49f97c918e696ac0335aaf + Author: Shiratori, Takehiro + Date: Tue Oct 16 16:25:33 2018 +0900 + + McKernel + commit 6f9fef2b13447c74c36d15cf5ebd186f8395ccca + Author: Ken Sato + Date: Tue Sep 25 10:05:41 2018 +0900 + +(4) 備考 + 本テストセットは一部IHK/McKernelの実装挙動を期待としてテスト項目を作成しているため、 + 全ての項目がHOST-Linux上でもOKになるとは限らない。 + + +以上。 diff --git a/test/mcexec_options/arm64/allow_oversubscribe.c b/test/mcexec_options/arm64/allow_oversubscribe.c new file mode 100644 index 00000000..ce275007 --- /dev/null +++ b/test/mcexec_options/arm64/allow_oversubscribe.c @@ -0,0 +1,71 @@ +/* allow_oversubscribe.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include +#include +#include +#include + +#define PROG "/usr/bin/date" + +static int +do_fork(int proc_num) +{ + int i; + + for (i = 0; i < proc_num; i += 1) { + pid_t pid = fork(); + + if (pid < 0) { + perror("fork failed"); + return -1; + } + else if (0 == pid) { + printf("%d: in child (%d/%d)\n", + getpid(), (i+1), proc_num); + execl(PROG, PROG, NULL); + exit(0); + /* NOTREACHED */ + } + } + + return 0; +} + +static int +do_wait(int proc_num) +{ + pid_t mypid = getpid(); + int i; + + printf("%d: in parent\n", mypid); + for (i = 0; i < proc_num; i += 1) { + int status; + pid_t pid = waitpid(-1, &status, 0); + + if (pid < 0) { + perror("waitpid failed"); + return -1; + } + printf("%d: waited %d (%d/%d)\n", + mypid, pid, (i+1), proc_num); + } + printf("%d: all done\n", mypid); + + return 0; +} + +int +main(int argc, char *argv[]) +{ + int result = 0; + int proc_num = atoi(argv[1]); + + if (do_fork(proc_num)) { + result = -1; + } + + if (do_wait(proc_num)) { + result = -1; + } + return result; +} diff --git a/test/mcexec_options/arm64/config b/test/mcexec_options/arm64/config new file mode 100644 index 00000000..12961387 --- /dev/null +++ b/test/mcexec_options/arm64/config @@ -0,0 +1,29 @@ +## config COPYRIGHT FUJITSU LIMITED 2018 ## + +## set size pattern +## 64K-page +PGSZ="$((64*1024))" +NEAR_PGSZ_LOW="63K" +NEAR_PGSZ_LOW_VAL="$((63*1024))" +NEAR_PGSZ_HIGH="65k" +NEAR_PGSZ_HIGH_VAL="$((65*1024))" + +LPGSZ="$((512*1024*1024))" +NEAR_LPGSZ_LOW="511M" +NEAR_LPGSZ_LOW_VAL="$((511*1024*1024))" +NEAR_LPGSZ_HIGH="513m" +NEAR_LPGSZ_HIGH_VAL="$((513*1024*1024))" + +## 4K-page +# PGSZ="$((4*1024))" +# NEAR_PGSZ_LOW="3K" +# NEAR_PGSZ_LOW_VAL="$((3*1024))" +# NEAR_PGSZ_HIGH="5k" +# NEAR_PGSZ_HIGH_VAL="$((5*1024))" +# +# LPGSZ="$((2*1024*1024))" +# NEAR_LPGSZ_LOW="1M" +# NEAR_LPGSZ_LOW_VAL="$((1024*1024))" +# NEAR_LPGSZ_HIGH="3m" +# NEAR_LPGSZ_HIGH_VAL="$((3*1024*1024))" + diff --git a/test/mcexec_options/arm64/extend_heap.c b/test/mcexec_options/arm64/extend_heap.c new file mode 100644 index 00000000..b6dfa414 --- /dev/null +++ b/test/mcexec_options/arm64/extend_heap.c @@ -0,0 +1,97 @@ +/* extend_heap.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include +#include +#include +#include + +static void show_usage(void) +{ + printf("./extend_heap \n"); +} + +int main(int argc, char *argv[]) +{ + FILE *fp = 0; + int result = -1; + unsigned long exheap = 0; + unsigned long start = 0; /* dummy */ + unsigned long bf_end = 0; + unsigned long af_end = 0; + char buf[4096]; + char *tmp = NULL; + const unsigned long page_size = sysconf(_SC_PAGESIZE); + unsigned long align_size = page_size; + + if (argc != 2) { + show_usage(); + result = 0; + goto err; + } + exheap = atoll(argv[1]); + + /* check default heap-end */ + fp = fopen("/proc/self/maps", "r"); + if (fp == NULL) { + printf("fopen() failed. %d\n", errno); + goto err; + } + + while (fgets(buf, sizeof(buf), fp) != NULL) { + if (strstr(buf, "[heap]")) { + sscanf(buf, "%lx-%lx", &start, &bf_end); + } + } + + if (fclose(fp)) { + printf("fclose() failed. %d\n", errno); + goto err; + } + + /* heap-end adjustment */ + if (brk((void *)bf_end)) { + printf("brk() failed. %d\n", errno); + goto err; + } + + /* heap extend 1byte */ + if (sbrk(1) == (void *)-1) { + printf("sbrk() failed. %d\n", errno); + goto err; + } + + /* check extended heap-end */ + fp = fopen("/proc/self/maps", "r"); + if (fp == NULL) { + printf("fopen() failed. %d\n", errno); + goto err; + } + + while (fgets(buf, sizeof(buf), fp) != NULL) { + if (strstr(buf, "[heap]")) { + sscanf(buf, "%lx-%lx", &start, &af_end); + } + } + + if (fclose(fp)) { + printf("fclose() failed. %d\n", errno); + goto err; + } + + if (page_size < exheap) { + align_size = page_size / 8 * page_size; + } + + if ((af_end - bf_end) < exheap) { + printf("extend size ng.\n"); + goto err; + } + + if (af_end & (align_size - 1)) { + printf("extend align ng.\n"); + goto err; + } + result = 0; +err: + return result; +} diff --git a/test/mcexec_options/arm64/node_bind.c b/test/mcexec_options/arm64/node_bind.c new file mode 100644 index 00000000..8c4be65b --- /dev/null +++ b/test/mcexec_options/arm64/node_bind.c @@ -0,0 +1,52 @@ +/* node_bind.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include +#include +#include +#include + +static void show_usage(void) +{ + printf("./node_bind \n"); +} + +int main(int argc, char *argv[]) +{ + int mode = 0; + int result = -1; + unsigned long mask = 0; + unsigned long exp_mask = 0; + struct bitmask *bind_mask; + + if (argc != 2) { + show_usage(); + result = 0; + goto err; + } + + bind_mask = numa_parse_nodestring_all(argv[1]); + if (bind_mask) { + int node; + + for (node = 0; node <= numa_max_possible_node(); ++node) { + if (numa_bitmask_isbitset(bind_mask, node)) { + exp_mask |= (1UL << node); + } + } + } + + if (get_mempolicy(&mode, &mask, sizeof(mask) * 8, 0, MPOL_F_NODE)) { + printf("get_mempolicy() failed. %d\n", errno); + goto err; + } + + if (mask != exp_mask) { + printf("node_bind mask mismatch, ng. (exp:%lx, mask:%lx)\n", + exp_mask, mask); + goto err; + } + result = 0; + +err: + return result; +} diff --git a/test/mcexec_options/arm64/result.log b/test/mcexec_options/arm64/result.log new file mode 100644 index 00000000..4f6a2069 --- /dev/null +++ b/test/mcexec_options/arm64/result.log @@ -0,0 +1,76 @@ +gcc -o extend_heap extend_heap.c +gcc -o node_bind node_bind.c -lnuma +gcc -o allow_oversubscribe allow_oversubscribe.c +gcc -o stack_premap stack_premap.c +./run_extend_heap.sh +mcstop+release.sh ... done +mcreboot.sh -c 4-7 -m 4G@0,4G@1,4G@2,4G@3 ... done +TEST001: OK +TEST002: OK +TEST003: OK +TEST004: OK +TEST005: OK +TEST006: OK +TEST007: OK +TEST008: OK +./run_node_bind.sh +mcstop+release.sh ... done +mcreboot.sh -c 4-7 -m 4G@0,4G@1,4G@2,4G@3 ... done +TEST009: OK +TEST010: OK +TEST011: OK +TEST012: OK +TEST013: OK +TEST014: OK +TEST015: OK +libnuma: Warning: node argument 63 is out of range + +libnuma: Warning: node argument 63 is out of range + +TEST016: OK +./run_nr_partitions.sh +mcstop+release.sh ... done +mcreboot.sh -c 4-7 -m 4G@0,4G@1,4G@2,4G@3 ... done +TEST017: OK +TEST018: OK +error: nr_processes can't exceed nr. of CPUs +TEST019: OK +error: -n: invalid number of processes +TEST020: OK +./run_allow_oversubscribe.sh +mcstop+release.sh ... done +mcreboot.sh -c 4-7 -m 4G@0,4G@1,4G@2,4G@3 ... done +fork failed: Invalid argument +2018年 11月 21日 水曜日 02:44:04 JST +2018年 11月 21日 水曜日 02:44:04 JST +2018年 11月 21日 水曜日 02:44:04 JST +waitpid failed: No child processes +9907: in parent +9907: waited 9920 (1/4) +9907: waited 9914 (2/4) +9907: waited 9926 (3/4) +TEST021: OK +mcstop+release.sh ... done +mcreboot.sh -c 4-7 -m 4G@0,4G@1,4G@2,4G@3 -O ... done +2018年 11月 21日 水曜日 02:44:18 JST +2018年 11月 21日 水曜日 02:44:18 JST +2018年 11月 21日 水曜日 02:44:18 JST +2018年 11月 21日 水曜日 02:44:18 JST +10076: in parent +10076: waited 10083 (1/4) +10076: waited 10089 (2/4) +10076: waited 10095 (3/4) +10076: waited 10102 (4/4) +10076: all done +TEST022: OK +./run_stack_premap.sh +mcstop+release.sh ... done +mcreboot.sh -c 4-7 -m 4G@0,4G@1,4G@2,4G@3 ... done +TEST023: OK +TEST024: OK +TEST025: OK +TEST026: OK +TEST027: OK +TEST028: OK +TEST029: OK +TEST030: OK diff --git a/test/mcexec_options/arm64/run_allow_oversubscribe.sh b/test/mcexec_options/arm64/run_allow_oversubscribe.sh new file mode 100755 index 00000000..633e1c3c --- /dev/null +++ b/test/mcexec_options/arm64/run_allow_oversubscribe.sh @@ -0,0 +1,37 @@ +#!/bin/sh +## run_allow_oversubscribe.sh COPYRIGHT FUJITSU LIMITED 2018 ## + +USELTP=0 +USEOSTEST=0 + +. ../../common.sh + +. ./config + +result=0 + +#################### +## -O option test ## +#################### + +${MCEXEC} ./allow_oversubscribe 4 +if [ `echo $?` != 0 ]; then + echo "TEST021: OK" +else + echo "TEST021: NG, not -O setting mcexec." + result=-1 +fi + +BOOTPARAM="${BOOTPARAM} -O" +((${MCSTOP-1})) && mcstop +((${MCREBOOT-1})) && mcreboot + +${MCEXEC} ./allow_oversubscribe 4 +if [ `echo $?` == 0 ]; then + echo "TEST022: OK" +else + echo "TEST022: NG, -O setting mcexec." + result=-1 +fi + +exit ${result} diff --git a/test/mcexec_options/arm64/run_extend_heap.sh b/test/mcexec_options/arm64/run_extend_heap.sh new file mode 100755 index 00000000..e34c2e19 --- /dev/null +++ b/test/mcexec_options/arm64/run_extend_heap.sh @@ -0,0 +1,81 @@ +#!/bin/sh +## run_extend_heap.sh COPYRIGHT FUJITSU LIMITED 2018 ## + +USELTP=0 +USEOSTEST=0 + +. ../../common.sh + +. ./config + +result=0 + +#################### +## -h option test ## +#################### + +${MCEXEC} -h ${NEAR_PGSZ_LOW} ./extend_heap ${NEAR_PGSZ_LOW_VAL} +if [ `echo $?` == 0 ]; then + echo "TEST001: OK" +else + echo "TEST001: NG, -h ${NEAR_PGSZ_LOW} options failed." + result=-1 +fi + +${MCEXEC} -h ${NEAR_LPGSZ_LOW} ./extend_heap ${NEAR_LPGSZ_LOW_VAL} +if [ `echo $?` == 0 ]; then + echo "TEST002: OK" +else + echo "TEST002: NG, -h ${NEAR_LPGSZ_LOW} options failed." + result=-1 +fi + +${MCEXEC} -h 1G ./extend_heap $((1024*1024*1024)) +if [ `echo $?` == 0 ]; then + echo "TEST003: OK" +else + echo "TEST003: NG, -h 1G options failed." + result=-1 +fi + +${MCEXEC} -h ${NEAR_PGSZ_HIGH} ./extend_heap ${NEAR_PGSZ_HIGH_VAL} +if [ `echo $?` == 0 ]; then + echo "TEST004: OK" +else + echo "TEST004: NG, -h ${NEAR_PGSZ_HIGH} options failed." + result=-1 +fi + +${MCEXEC} -h ${NEAR_LPGSZ_HIGH} ./extend_heap ${NEAR_LPGSZ_HIGH_VAL} +if [ `echo $?` == 0 ]; then + echo "TEST005: OK" +else + echo "TEST005: NG, -h ${NEAR_LPGSZ_HIGH} options failed." + result=-1 +fi + +${MCEXEC} -h 2g ./extend_heap $((2*1024*1024*1024)) +if [ `echo $?` == 0 ]; then + echo "TEST006: OK" +else + echo "TEST006: NG, -h 2g options failed." + result=-1 +fi + +${MCEXEC} -h ${PGSZ} ./extend_heap ${PGSZ} +if [ `echo $?` == 0 ]; then + echo "TEST007: OK" +else + echo "TEST007: NG, -h ${PGSZ} options failed." + result=-1 +fi + +${MCEXEC} -h ${LPGSZ} ./extend_heap ${LPGSZ} +if [ `echo $?` == 0 ]; then + echo "TEST008: OK" +else + echo "TEST008: NG, -h ${LPGSZ} options failed." + result=-1 +fi + +exit ${result} diff --git a/test/mcexec_options/arm64/run_node_bind.sh b/test/mcexec_options/arm64/run_node_bind.sh new file mode 100755 index 00000000..d991c3cd --- /dev/null +++ b/test/mcexec_options/arm64/run_node_bind.sh @@ -0,0 +1,81 @@ +#!/bin/sh +## run_node_bind.sh COPYRIGHT FUJITSU LIMITED 2018 ## + +USELTP=0 +USEOSTEST=0 + +. ../../common.sh + +. ./config + +result=0 + +#################### +## -m option test ## +#################### + +${MCEXEC} -m 1 ./node_bind 1 +if [ `echo $?` == 0 ]; then + echo "TEST009: OK" +else + echo "TEST009: NG, -m 1 setting." + result=-1 +fi + +${MCEXEC} -m 3 ./node_bind 3 +if [ `echo $?` == 0 ]; then + echo "TEST010: OK" +else + echo "TEST010: NG, -m out of McKernel node setting." + result=-1 +fi + +${MCEXEC} -m 0-2 ./node_bind 0-2 +if [ `echo $?` == 0 ]; then + echo "TEST011: OK" +else + echo "TEST011: NG, -m 0-2 setting." + result=-1 +fi + +${MCEXEC} -m 0,2 ./node_bind 0,2 +if [ `echo $?` == 0 ]; then + echo "TEST012: OK" +else + echo "TEST012: NG, -m 0,2 setting." + result=-1 +fi + +${MCEXEC} -m \!0,1,2 ./node_bind \!0,1,2 +if [ `echo $?` == 0 ]; then + echo "TEST013: OK" +else + echo "TEST013: NG, -m \!0,1,2 setting." + result=-1 +fi + +${MCEXEC} -m +0,1 ./node_bind +0,1 +if [ `echo $?` == 0 ]; then + echo "TEST014: OK" +else + echo "TEST014: NG, -m +0,1 setting." + result=-1 +fi + +${MCEXEC} -m all ./node_bind all +if [ `echo $?` == 0 ]; then + echo "TEST015: OK" +else + echo "TEST015: NG, -m all setting." + result=-1 +fi + +${MCEXEC} -m 63 ./node_bind 63 +if [ `echo $?` == 0 ]; then + echo "TEST016: OK" +else + echo "TEST016: NG, -m 63 setting." + result=-1 +fi + +exit ${result} diff --git a/test/mcexec_options/arm64/run_nr_partitions.sh b/test/mcexec_options/arm64/run_nr_partitions.sh new file mode 100755 index 00000000..3b37f9f5 --- /dev/null +++ b/test/mcexec_options/arm64/run_nr_partitions.sh @@ -0,0 +1,57 @@ +#!/bin/sh +## run_nr_partitions.sh COPYRIGHT FUJITSU LIMITED 2018 ## + +USELTP=0 +USEOSTEST=0 + +. ../../common.sh + +. ./config + +result=0 + +#################### +## -n option test ## +#################### + +${MCEXEC} -n 2 ls > /dev/null & +sleep 1 +${MCEXEC} -n 2 ls > /dev/null +if [ `echo $?` == 0 ]; then + echo "TEST017: OK" +else + echo "TEST017: NG, -n 2 setting." + result=-1 +fi + +${MCEXEC} -n 4 ls > /dev/null & +sleep 1 +${MCEXEC} -n 4 ls > /dev/null & +sleep 1 +${MCEXEC} -n 4 ls > /dev/null & +sleep 1 +${MCEXEC} -n 4 ls > /dev/null +if [ `echo $?` == 0 ]; then + echo "TEST018: OK" +else + echo "TEST018: NG, -n 4 setting." + result=-1 +fi + +${MCEXEC} -n 8 ls +if [ `echo $?` != 0 ]; then + echo "TEST019: OK" +else + echo "TEST019: NG, -n setting." + result=-1 +fi + +${MCEXEC} -n abcde ls +if [ `echo $?` != 0 ]; then + echo "TEST020: OK" +else + echo "TEST020: NG, -n setting." + result=-1 +fi + +exit ${result} diff --git a/test/mcexec_options/arm64/run_stack_premap.sh b/test/mcexec_options/arm64/run_stack_premap.sh new file mode 100755 index 00000000..078131c2 --- /dev/null +++ b/test/mcexec_options/arm64/run_stack_premap.sh @@ -0,0 +1,81 @@ +#!/bin/sh +## run_stack_premap.sh COPYRIGHT FUJITSU LIMITED 2018 ## + +USELTP=0 +USEOSTEST=0 + +. ../../common.sh + +. ./config + +result=0 + +#################################### +## -s(--stack-premap) option test ## +#################################### + +${MCEXEC} -s ${NEAR_PGSZ_LOW},${LPGSZ} ./stack_premap ${NEAR_PGSZ_LOW_VAL} +if [ `echo $?` == 0 ]; then + echo "TEST023: OK" +else + echo "TEST023: NG, -s ${NEAR_PGSZ_LOW},${LPGSZ} setting." + result=-1 +fi + +${MCEXEC} -s ${NEAR_LPGSZ_LOW},${LPGSZ} ./stack_premap ${NEAR_LPGSZ_LOW_VAL} +if [ `echo $?` == 0 ]; then + echo "TEST024: OK" +else + echo "TEST024: NG, -s ${NEAR_LPGSZ_LOW},${LPGSZ} setting." + result=-1 +fi + +${MCEXEC} -s 1G,2G ./stack_premap $((1024*1024*1024)) +if [ `echo $?` == 0 ]; then + echo "TEST025: OK" +else + echo "TEST025: NG, -s 1G,2G setting." + result=-1 +fi + +${MCEXEC} --stack-premap ${NEAR_PGSZ_HIGH},${LPGSZ} ./stack_premap ${NEAR_PGSZ_HIGH_VAL} +if [ `echo $?` == 0 ]; then + echo "TEST026: OK" +else + echo "TEST026: NG, -s ${NEAR_PGSZ_HIGH},${LPGSZ} setting." + result=-1 +fi + +${MCEXEC} --stack-premap ${NEAR_LPGSZ_HIGH},2g ./stack_premap ${NEAR_LPGSZ_HIGH_VAL} +if [ `echo $?` == 0 ]; then + echo "TEST027: OK" +else + echo "TEST027: NG, -s ${NEAR_LPGSZ_HIGH},2g setting." + result=-1 +fi + +${MCEXEC} --stack-premap 2g,3g ./stack_premap $((2*1024*1024*1024)) +if [ `echo $?` == 0 ]; then + echo "TEST028: OK" +else + echo "TEST028: NG, -s 2g,3g setting." + result=-1 +fi + +${MCEXEC} -s ${PGSZ},${LPGSZ} ./stack_premap ${PGSZ} +if [ `echo $?` == 0 ]; then + echo "TEST029: OK" +else + echo "TEST029: NG, -s ${PGSZ},${LPGSZ} setting." + result=-1 +fi + +${MCEXEC} --stack-premap ${LPGSZ},${PGSZ} ./stack_premap ${PGSZ} +if [ `echo $?` == 0 ]; then + echo "TEST030: OK" +else + echo "TEST030: NG, -s ${LPGSZ},${PGSZ} setting." + result=-1 +fi + +exit ${result} diff --git a/test/mcexec_options/arm64/stack_premap.c b/test/mcexec_options/arm64/stack_premap.c new file mode 100644 index 00000000..dc181432 --- /dev/null +++ b/test/mcexec_options/arm64/stack_premap.c @@ -0,0 +1,102 @@ +/* stack_premap.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include +#include +#include +#include + +#define PAGEMAP_PRESENT (1UL << 63) + +static void show_usage(void) +{ + printf("./stack_premap \n"); +} + +int main(int argc, char *argv[]) +{ + FILE *fp_maps = 0; + FILE *fp_pgmap = 0; + int result = -1; + unsigned long premap = 0; + unsigned long start = 0; + unsigned long end = 0; + char buf[4096]; + char *tmp = NULL; + const unsigned long page_size = sysconf(_SC_PAGESIZE); + unsigned long align_size = 0; + unsigned long pagemap = 0; + long offset = 0; + + if (argc != 2) { + show_usage(); + result = 0; + goto err; + } + premap = atoll(argv[1]); + + /* alignment check */ + if (premap & (page_size - 1)) { + align_size = ((premap + page_size) & ~(page_size - 1)); + } else { + align_size = premap; + } + + fp_maps = fopen("/proc/self/maps", "r"); + if (fp_maps == NULL) { + printf("fopen() failed. %d\n", errno); + goto err; + } + + fp_pgmap = fopen("/proc/self/pagemap", "r"); + if (fp_pgmap == NULL) { + printf("fopen() failed. %d\n", errno); + goto maps_close; + } + + /* check stack area */ + while (fgets(buf, sizeof(buf), fp_maps) != NULL) { + if (strstr(buf, "[stack]")) { + sscanf(buf, "%lx-%lx", &start, &end); + } + } + + /* check premapping */ + offset = (end - align_size) / page_size * 8; + if (fseek(fp_pgmap, offset, SEEK_SET)) { + printf("fseek() failed. %d\n", errno); + goto pgmap_close; + } + + if (fread(&pagemap, 8, 1, fp_pgmap) != 1) { + printf("fread() failed. %d\n", errno); + goto pgmap_close; + } + + if (!(pagemap & PAGEMAP_PRESENT)) { + printf("not premapped. (stack(0x%lx-0x%lx), va=0x%lx)\n", + start, end, end - align_size); + goto pgmap_close; + } + result = 0; + +pgmap_close: + if (fp_pgmap) { + if (fclose(fp_pgmap)) { + printf("fclose() failed. %d\n", errno); + result = -1; + goto err; + } + } + +maps_close: + if (fp_maps) { + if (fclose(fp_maps)) { + printf("fclose() failed. %d\n", errno); + result = -1; + goto err; + } + } + +err: + return result; +}