From 3300e65efc30999a7cfc80ce8767e9b7264ffd10 Mon Sep 17 00:00:00 2001 From: "TOIDA,Suguru" Date: Fri, 6 Mar 2020 15:00:37 +0900 Subject: [PATCH] madvise: Support MADV_WIPEONFORK, MADV_KEEPONFORK and MADV_NORMAL Change-Id: I1d4cf5affa580d7304dfdc34fa4f1707c0df617c refs: #1374 --- kernel/include/mman.h | 2 ++ kernel/include/process.h | 1 + kernel/process.c | 9 ++++++-- kernel/syscall.c | 41 +++++++++++++++++++++++++++++++++++++ test/issues/1374/README | 20 ++++++++++++++++++ test/issues/1374/result.log | 29 ++++++++++++++++++++++++++ test/issues/1374/run.sh | 31 ++++++++++++++++++++++++++++ 7 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 test/issues/1374/README create mode 100644 test/issues/1374/result.log create mode 100755 test/issues/1374/run.sh diff --git a/kernel/include/mman.h b/kernel/include/mman.h index e7d3526b..09f771ec 100644 --- a/kernel/include/mman.h +++ b/kernel/include/mman.h @@ -54,6 +54,8 @@ #define MADV_NOHUGEPAGE 15 #define MADV_DONTDUMP 16 #define MADV_DODUMP 17 +#define MADV_WIPEONFORK 18 /* Zero memory on fork, child only */ +#define MADV_KEEPONFORK 19 /* Undo MADV_WIPEONFORK */ #define MADV_HWPOISON 100 #define MADV_SOFT_OFFLINE 101 diff --git a/kernel/include/process.h b/kernel/include/process.h index 2adb111a..8b8c894a 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -56,6 +56,7 @@ #define VR_PAGEOUT 0x10000000 #define VR_DONTDUMP 0x20000000 #define VR_XPMEM 0x40000000 +#define VR_WIPEONFORK 0x80000000 #define PROT_TO_VR_FLAG(prot) (((unsigned long)(prot) << 16) & VR_PROT_MASK) #define VRFLAG_PROT_TO_MAXPROT(vrflag) (((vrflag) & VR_PROT_MASK) << 4) diff --git a/kernel/process.c b/kernel/process.c index 1bcff5d6..0c144dd4 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -750,8 +750,13 @@ static int copy_user_pte(void *arg0, page_table_t src_pt, pte_t *src_ptep, void src_kvirt = ihk_mc_map_virtual(src_lphys, 1, attr); } - memcpy(virt, src_kvirt, pgsize); - dkprintf("copy_user_pte(): memcpy OK\n"); + if (args->new_vrflag & VR_WIPEONFORK) { + memset(virt, 0, pgsize); + dkprintf("%s(): memset OK\n", __func__); + } else { + memcpy(virt, src_kvirt, pgsize); + dkprintf("%s(): memcpy OK\n", __func__); + } if (!is_mckernel) { ihk_mc_unmap_virtual(src_kvirt, 1); diff --git a/kernel/syscall.c b/kernel/syscall.c index ecc1829b..763fd3f2 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -5324,6 +5324,8 @@ SYSCALL_DECLARE(madvise) case MADV_REMOVE: case MADV_DONTDUMP: case MADV_DODUMP: + case MADV_WIPEONFORK: + case MADV_KEEPONFORK: break; case MADV_HWPOISON: @@ -5376,6 +5378,27 @@ SYSCALL_DECLARE(madvise) } } else if(advice == MADV_DONTFORK || advice == MADV_DOFORK); + else if (advice == MADV_NORMAL) { + /* + * Normally, the settings of MADV_RANDOM and + * MADV_SEQUENTIAL are cleared. + * MADV_RANDOM and MADV_SEQUENTIAL are not supported, + * so do nothing. + */ + } + else if (advice == MADV_WIPEONFORK + || advice == MADV_KEEPONFORK) { + if (range->memobj && memobj_has_pager(range->memobj)) { + /* device mapping, file mapping */ + error = -EINVAL; + goto out; + } + if (!(range->flag & VR_PRIVATE)) { + /* VR_SHARED */ + error = -EINVAL; + goto out; + } + } else if (!range->memobj || !memobj_has_pager(range->memobj)) { dkprintf("[%d]sys_madvise(%lx,%lx,%x):has not pager" "[%lx-%lx) %lx\n", @@ -5463,6 +5486,24 @@ SYSCALL_DECLARE(madvise) advice == MADV_DOFORK){ error = syscall_generic_forwarding(__NR_madvise, ctx); } + if (advice == MADV_WIPEONFORK) { + error = change_attr_process_memory_range( + thread->vm, start, end, + set_memory_range_flag, + VR_WIPEONFORK); + if (error) { + goto out; + } + } + if (advice == MADV_KEEPONFORK) { + error = change_attr_process_memory_range( + thread->vm, start, end, + clear_memory_range_flag, + VR_WIPEONFORK); + if (error) { + goto out; + } + } error = 0; out: diff --git a/test/issues/1374/README b/test/issues/1374/README new file mode 100644 index 00000000..1b83ec1f --- /dev/null +++ b/test/issues/1374/README @@ -0,0 +1,20 @@ +/* REDME COPYRIGHT FUJITSU LIMITED 2020 */ + +ltp: madvise10: MADV_WIPEONFORKが期待通りに動作しない +https://postpeta.pccluster.org/redmine/issues/1374 + +テストセットREADME + +(0) 事前準備 + 1. $HOME/.mck_test_configを用意する + +(1) テスト実行方法 + 1. ./run.sh + +(2) テスト項目詳細 + + LTPの下記項目を実行し期待通りに動作することを確認する + "test OK." が書き出されれば合格判定となる。具体例はresult.logを参照。 + - madvise10 + +以上。 diff --git a/test/issues/1374/result.log b/test/issues/1374/result.log new file mode 100644 index 00000000..b314b6ea --- /dev/null +++ b/test/issues/1374/result.log @@ -0,0 +1,29 @@ +[root@hostname 1374]# ./run.sh +mcstop+release.sh ... done +mcreboot.sh -c 12-59 -m 512M@4 ... done +test run. +tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s +madvise10.c:143: INFO: MADV_WIPEONFORK zeroes memory in child +madvise10.c:117: PASS: madvise(0x1000001c0000, 16384, 0x0) +madvise10.c:117: PASS: madvise(0x1000001c0000, 16384, 0x12) +madvise10.c:98: PASS: In PID 13482, Matched expected pattern +madvise10.c:143: INFO: MADV_WIPEONFORK with zero length does nothing +madvise10.c:117: PASS: madvise(0x1000001d0000, 0, 0x0) +madvise10.c:117: PASS: madvise(0x1000001d0000, 0, 0x12) +madvise10.c:98: PASS: In PID 13532, Matched expected pattern +madvise10.c:143: INFO: MADV_WIPEONFORK zeroes memory in grand-child +madvise10.c:117: PASS: madvise(0x1000001e0000, 16384, 0x0) +madvise10.c:117: PASS: madvise(0x1000001e0000, 16384, 0x12) +madvise10.c:98: PASS: In PID 13635, Matched expected pattern +madvise10.c:143: INFO: MADV_KEEPONFORK will undo MADV_WIPEONFORK +madvise10.c:117: PASS: madvise(0x1000001f0000, 16384, 0x12) +madvise10.c:117: PASS: madvise(0x1000001f0000, 16384, 0x13) +madvise10.c:98: PASS: In PID 13685, Matched expected pattern + +Summary: +passed 12 +failed 0 +skipped 0 +warnings 0 +test OK. +mcstop+release.sh ... done \ No newline at end of file diff --git a/test/issues/1374/run.sh b/test/issues/1374/run.sh new file mode 100755 index 00000000..2023450b --- /dev/null +++ b/test/issues/1374/run.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# run.sh COPYRIGHT FUJITSU LIMITED 2020 + +# load setting and booting mck. +USELTP=1 +. ../../common.sh +chmod 777 /dev/mcos* + +echo "test run." +ltp=`cat <<__EOL__ +madvise10 +__EOL__` + +FAIL=0 +for tp in $ltp +do + pushd ${LTPBIN} > /dev/null + ${MCEXEC} ${LTPBIN}/${tp} + if [ $? -ne 0 ]; then + FAIL=1 + fi + popd > /dev/null +done + +if [ ${FAIL} -eq 1 ]; then + echo "test NG." +else + echo "test OK." +fi + +mcstop