From f07e20a38173917dad8131f3f576dc47437447b8 Mon Sep 17 00:00:00 2001 From: Masamichi Takagi Date: Sun, 24 Feb 2019 17:24:22 +0900 Subject: [PATCH] copy_user_pte: vmap area not owned by McKernel Refs: #1166 Fujitsu: POSTK_DEBUG_TEMP_FIX_14 Change-Id: Iae0f1145d58ec2c14cecc14409b08a1db3b067b7 --- kernel/process.c | 19 ++++++++++-- test/issues/1166/CT1166.c | 22 +++++-------- test/issues/1166/CT1166.sh | 20 ++++++++++-- test/issues/1166/CT1166.txt | 62 +++++++++++++++++++++++++++++-------- test/issues/1166/README | 20 ++++++++---- 5 files changed, 105 insertions(+), 38 deletions(-) diff --git a/kernel/process.c b/kernel/process.c index bf809a52..d1a70c09 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -644,6 +644,7 @@ static int copy_user_pte(void *arg0, page_table_t src_pt, pte_t *src_ptep, void int error; intptr_t src_phys; struct page *src_page; + unsigned long src_lphys; void *src_kvirt; size_t pgsize = (size_t)1 << pgshift; int npages; @@ -651,6 +652,7 @@ static int copy_user_pte(void *arg0, page_table_t src_pt, pte_t *src_ptep, void intptr_t phys; int pgalign = pgshift - PAGE_SHIFT; enum ihk_mc_pt_attribute attr; + int is_mckernel; if (!pte_is_present(src_ptep)) { error = 0; @@ -659,7 +661,6 @@ static int copy_user_pte(void *arg0, page_table_t src_pt, pte_t *src_ptep, void src_phys = pte_get_phys(src_ptep); src_page = phys_to_page(src_phys); - src_kvirt = phys_to_virt(src_phys); if (src_page && page_is_in_memobj(src_page)) { error = 0; @@ -698,10 +699,24 @@ static int copy_user_pte(void *arg0, page_table_t src_pt, pte_t *src_ptep, void phys = virt_to_phys(virt); dkprintf("copy_user_pte(): phys page allocated\n"); + attr = arch_vrflag_to_ptattr(args->new_vrflag, PF_POPULATE, + NULL); + + is_mckernel = is_mckernel_memory(src_phys, src_phys + pgsize); + if (is_mckernel) { + src_kvirt = phys_to_virt(src_phys); + } else { + src_lphys = ihk_mc_map_memory(NULL, src_phys, pgsize); + src_kvirt = ihk_mc_map_virtual(src_lphys, 1, attr); + } + memcpy(virt, src_kvirt, pgsize); dkprintf("copy_user_pte(): memcpy OK\n"); - attr = arch_vrflag_to_ptattr(args->new_vrflag, PF_POPULATE, NULL); + if (!is_mckernel) { + ihk_mc_unmap_virtual(src_kvirt, 1); + ihk_mc_unmap_memory(NULL, src_lphys, pgsize); + } } error = ihk_mc_pt_set_range(args->new_vm->address_space->page_table, diff --git a/test/issues/1166/CT1166.c b/test/issues/1166/CT1166.c index e13b8663..282ba82f 100644 --- a/test/issues/1166/CT1166.c +++ b/test/issues/1166/CT1166.c @@ -39,14 +39,14 @@ main(int argc, char **argv) close(fd); p2[0] = 50; - printf("CT1166T03: OK store private fb0\n"); + printf("CT1166T03: OK store to parent fb0\n"); ok++; if (p2[0] == 50) { - printf("CT1166T04: OK load private fb0\n"); + printf("CT1166T04: OK load from parent fb0\n"); ok++; } else { - printf("CT1166T04: NG load private fb0\n"); + printf("CT1166T04: NG load from parent fb0\n"); ng++; } @@ -63,14 +63,14 @@ main(int argc, char **argv) ok++; p2[0] = 10; - printf("CT1166T06: OK store private fb0 by child\n"); + printf("CT1166T06: OK store to child fb0\n"); ok++; if (p2[0] == 10) { - printf("CT1166T07: OK load private fb0 by child\n"); + printf("CT1166T07: OK load from child fb0\n"); ok++; } else { - printf("CT1166T07: NG load private fb0 by child\n"); + printf("CT1166T07: NG load from child fb0\n"); ng++; } exit(0); @@ -80,18 +80,12 @@ main(int argc, char **argv) ; if (p2[0] == 50) { - printf("CT1166T08: OK private fb0 do not updated\n"); + printf("CT1166T08: OK parent fb0 isn't modified\n"); ok++; } else { - printf("CT1166T08: NG private fb0 updated %d\n", p2[0]); + printf("CT1166T08: NG private fb0 is modified (%d)\n", p2[0]); ng++; } - if (ng == 0) { - printf("CT1166 all tests are OK\n"); - } - else { - printf("CT1166 OK=%d NG=%d\n", ok, ng); - } exit(0); } diff --git a/test/issues/1166/CT1166.sh b/test/issues/1166/CT1166.sh index f82a819f..9efaa154 100644 --- a/test/issues/1166/CT1166.sh +++ b/test/issues/1166/CT1166.sh @@ -1,9 +1,23 @@ #!/bin/sh -USELTP=0 +USELTP=1 USEOSTEST=0 -BOOTPARAM="-c 1-3 -m 1G" +BOOTPARAM="-s -c 1-3 -m 1G" . ../../common.sh ################################################################################ -$MCEXEC ./CT1166 +sudo $MCEXEC ./CT1166 + +for i in fork01:09 fork02:10 fork03:11 fork04:12 fork07:13 fork08:14 fork09:15 \ + fork10:16 fork11:17; do + tp=`echo $i|sed 's/:.*//'` + id=`echo $i|sed 's/.*://'` + sudo $MCEXEC $LTPBIN/$tp 2>&1 | tee $tp.txt + ok=`grep TPASS $tp.txt | wc -l` + ng=`grep TFAIL $tp.txt | wc -l` + if [ $ng = 0 ]; then + echo "*** CT1166$id: $tp OK ($ok)" + else + echo "*** CT1166$id: $tp NG (ok=$ok ng=%ng)" + fi +done diff --git a/test/issues/1166/CT1166.txt b/test/issues/1166/CT1166.txt index 2a0f6862..0d433c74 100644 --- a/test/issues/1166/CT1166.txt +++ b/test/issues/1166/CT1166.txt @@ -1,19 +1,55 @@ -Script started on Mon Jan 7 16:10:54 2019 -[sira@localhost 1166]$ make test sh ./CT1166.sh mcstop+release.sh ... done -mcreboot.sh -c 1-3 -m 1G ... done +mcreboot.sh -s -c 1-3 -m 1G ... done CT1166 START CT1166T01: OK open(/dev/fb0) CT1166T02: OK mmap(MAP_PRIVATE) -CT1166T03: OK store private fb0 -CT1166T04: OK load private fb0 +CT1166T03: OK store to parent fb0 +CT1166T04: OK load from parent fb0 CT1166T05: OK fork -CT1166T06: OK store private fb0 by child -CT1166T07: OK load private fb0 by child -CT1166T08: OK private fb0 do not updated -CT1166 all tests are OK -[sira@localhost 1166]$ exit -exit - -Script done on Mon Jan 7 16:11:05 2019 +CT1166T06: OK store to child fb0 +CT1166T07: OK load from child fb0 +CT1166T08: OK parent fb0 isn't modified +fork01 1 TPASS : fork() returned 111237 +fork01 2 TPASS : child pid and fork() return agree: 111237 +*** CT116609: fork01 OK (2) +fork02 0 TINFO : Inside parent +fork02 0 TINFO : Inside child +fork02 0 TINFO : exit status of wait 0 +fork02 1 TPASS : test 1 PASSED +*** CT116610: fork02 OK (1) +fork03 0 TINFO : process id in parent of child from fork : 111287 +fork03 1 TPASS : test 1 PASSED +*** CT116611: fork03 OK (1) +fork04 1 TPASS : Env var TERM unchanged after fork(): xterm +fork04 2 TPASS : Env var NoTSetzWq unchanged after fork(): getenv() does not find variable set +fork04 3 TPASS : Env var TESTPROG unchanged after fork(): FRKTCS04 +*** CT116612: fork04 OK (3) +fork07 0 TINFO : Forking 100 children +fork07 0 TINFO : Forked all 100 children, now collecting +fork07 0 TINFO : Collected all 100 children +fork07 1 TPASS : 100/100 children read correctly from an inheritted fd +*** CT116613: fork07 OK (1) +fork08 0 TINFO : parent forksval: 1 +fork08 0 TINFO : parent forksval: 2 +fork08 0 TINFO : exit status of wait expected 0 got 0 +fork08 1 TPASS : parent test PASSED +fork08 0 TINFO : second child got char: b +fork08 1 TPASS : Test passed in childnumber 2 +fork08 0 TINFO : exit status of wait expected 0 got 0 +fork08 2 TPASS : parent test PASSED +fork08 0 TINFO : exit status of wait expected 0 got 0 +fork08 3 TPASS : parent test PASSED +fork08 0 TINFO : Number of processes forked is 2 +*** CT116614: fork08 OK (4) +fork09 0 TINFO : OPEN_MAX is 1024 +fork09 0 TINFO : first file descriptor is 8 +fork09 0 TINFO : Parent reporting 1023 files open +fork09 0 TINFO : Child opened new file #1023 +fork09 1 TPASS : test 1 PASSED +*** CT116615: fork09 OK (1) +fork10 0 TINFO : fork child A +fork10 1 TPASS : test 1 PASSED +*** CT116616: fork10 OK (1) +fork11 1 TPASS : fork test passed, 100 processes +*** CT116617: fork11 OK (1) diff --git a/test/issues/1166/README b/test/issues/1166/README index 06f0d745..1770a672 100644 --- a/test/issues/1166/README +++ b/test/issues/1166/README @@ -1,11 +1,7 @@ 【Issue#1166 動作確認】 □ テスト内容 -調査の結果、Issue#1166 の指摘は本来発生しない現象なことが判明したため、 -プログラムの変更は行わなかった。 - -Issue#1166 の指摘の状況を起こすプログラムを実行し、Linux と同様の結果に -なることを確認する。 - +1. /dev/fb0をprivateマップした後にforkを行い、複製が行われていること + を確認する。 CT1166T01 /dev/fb0 をオープンできる CT1166T02 /dev/fb0 を mmap を使って仮想空間にマップできる CT1166T03 マップした領域に書き込みできる @@ -16,6 +12,18 @@ CT1166T07 子プロセス側で親プロセスがマップした領域に書き CT1166T08 CT1166T06 の子プロセスの書き込みが親プロセスのマップ領域に影響 しない (親プロセスでは CT1166T03 のデータが参照されることを確認) +2. LTP を用いて既存処理に影響しないことを確認 + ユーザメモリ領域複製処理を変更したため、fork のテストを選定した。 +C1166T09 fork01 が PASS すること +C1166T10 fork02 が PASS すること +C1166T11 fork03 が PASS すること +C1166T12 fork04 が PASS すること +C1166T13 fork07 が PASS すること +C1166T14 fork08 が PASS すること +C1166T15 fork09 が PASS すること +C1166T16 fork10 が PASS すること +C1166T17 fork11 が PASS すること + □ 実行手順 $ make test