mremap: Fix to work correctly when old_page is large_page
Change-Id: I5a589383644a8098d910e49cd7ade6df325e0366 Refs: #1383
This commit is contained in:
committed by
Masamichi Takagi
parent
4bbdee395e
commit
41ea9d16c4
@ -908,10 +908,19 @@ int split_process_memory_range(struct process_vm *vm, struct vm_range *range,
|
||||
{
|
||||
int error;
|
||||
struct vm_range *newrange = NULL;
|
||||
unsigned long page_mask;
|
||||
|
||||
dkprintf("split_process_memory_range(%p,%lx-%lx,%lx,%p)\n",
|
||||
vm, range->start, range->end, addr, splitp);
|
||||
|
||||
if (range->pgshift != 0) {
|
||||
page_mask = (1 << range->pgshift) - 1;
|
||||
if (addr & page_mask) {
|
||||
/* split addr is not aligned */
|
||||
range->pgshift = 0;
|
||||
}
|
||||
}
|
||||
|
||||
error = ihk_mc_pt_split(vm->address_space->page_table, vm, (void *)addr);
|
||||
if (error) {
|
||||
ekprintf("split_process_memory_range:"
|
||||
|
||||
@ -8498,7 +8498,7 @@ SYSCALL_DECLARE(mremap)
|
||||
error = add_process_memory_range(thread->vm, newstart, newend, -1,
|
||||
range->flag, range->memobj,
|
||||
range->objoff + (oldstart - range->start),
|
||||
range->pgshift, NULL, NULL);
|
||||
0, NULL, NULL);
|
||||
if (error) {
|
||||
ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):"
|
||||
"add failed. %d\n",
|
||||
@ -8518,6 +8518,29 @@ SYSCALL_DECLARE(mremap)
|
||||
if (oldsize > 0) {
|
||||
size = (oldsize < newsize)? oldsize: newsize;
|
||||
ihk_mc_spinlock_lock_noirq(&vm->page_table_lock);
|
||||
if (range->start != oldstart) {
|
||||
error = split_process_memory_range(vm,
|
||||
range, oldstart, &range);
|
||||
if (error) {
|
||||
ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):"
|
||||
"split range failed. %d\n",
|
||||
oldaddr, oldsize0, newsize0,
|
||||
flags, newaddr, error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (range->end != oldstart + size) {
|
||||
error = split_process_memory_range(vm,
|
||||
range, oldstart + size, NULL);
|
||||
if (error) {
|
||||
ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):"
|
||||
"split range failed. %d\n",
|
||||
oldaddr, oldsize0, newsize0,
|
||||
flags, newaddr, error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
error = move_pte_range(vm->address_space->page_table, vm,
|
||||
(void *)oldstart, (void *)newstart,
|
||||
size, range);
|
||||
|
||||
48
test/issues/1383/C1383.sh
Executable file
48
test/issues/1383/C1383.sh
Executable file
@ -0,0 +1,48 @@
|
||||
#/bin/sh
|
||||
|
||||
USELTP=1
|
||||
USEOSTEST=0
|
||||
|
||||
. ../../common.sh
|
||||
|
||||
issue="1383"
|
||||
tid=01
|
||||
|
||||
arch=`uname -p`
|
||||
if [ "$arch" == "x86_64" ]; then
|
||||
pgshift=21
|
||||
elif [ "$arch" == "aarch64" ]; then
|
||||
pgshift=29
|
||||
fi
|
||||
|
||||
for tno in 01
|
||||
do
|
||||
tname=`printf "C${issue}T%02d" ${tid}`
|
||||
echo "*** ${tname} start *******************************"
|
||||
sudo ${MCEXEC} ./C1383T${tno} ${pgshift}
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "*** ${tname} PASSED ******************************"
|
||||
else
|
||||
echo "*** ${tname} FAILED ******************************"
|
||||
fi
|
||||
let tid++
|
||||
echo ""
|
||||
done
|
||||
|
||||
for tp in thp02 mremap01 mremap02 mremap03 mremap04 mremap05 move_pages10
|
||||
do
|
||||
tname=`printf "C${issue}T%02d" ${tid}`
|
||||
echo "*** ${tname} start *******************************"
|
||||
sudo $MCEXEC $LTPBIN/$tp 2>&1 | tee $tp.txt
|
||||
ok=`grep PASS $tp.txt | wc -l`
|
||||
ng=`grep FAIL $tp.txt | wc -l`
|
||||
if [ $ng = 0 ]; then
|
||||
echo "*** ${tname} PASSED ($ok)"
|
||||
else
|
||||
echo "*** ${tname} FAILED (ok=$ok ng=$ng)"
|
||||
fi
|
||||
let tid++
|
||||
echo ""
|
||||
done
|
||||
|
||||
93
test/issues/1383/C1383T01.c
Normal file
93
test/issues/1383/C1383T01.c
Normal file
@ -0,0 +1,93 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define PAGES 3
|
||||
#define MAP_HUGE_SHIFT 26
|
||||
|
||||
static unsigned long ps, hps;
|
||||
|
||||
void *hugetlb_mmap(unsigned long size, int pgshift)
|
||||
{
|
||||
return mmap(NULL, size, PROT_WRITE | PROT_READ,
|
||||
MAP_ANONYMOUS | MAP_PRIVATE |
|
||||
MAP_HUGETLB | (pgshift << MAP_HUGE_SHIFT),
|
||||
-1, 0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
void *p1, *p2, *p3, *p4, *old_addr, *new_addr;
|
||||
int i, pgshift, err, ret = 0;
|
||||
unsigned long base_start, base_size, new_start, new_size;
|
||||
size_t size, remap_size;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("error: too few arguments\n");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
pgshift = atoi(argv[1]);
|
||||
hps = (1 << pgshift);
|
||||
ps = getpagesize();
|
||||
size = hps * PAGES;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
p1 = hugetlb_mmap(size, pgshift);
|
||||
if (p1 == MAP_FAILED) {
|
||||
perror("mmap fail: ");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
printf("** mmap p1: %p - %p\n", p1, p1 + size);
|
||||
|
||||
p2 = hugetlb_mmap(size, pgshift);
|
||||
if (p2 == MAP_FAILED) {
|
||||
perror("mmap fail: ");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
printf("** mmap p2: %p - %p\n", p2, p2 + size);
|
||||
|
||||
p3 = hugetlb_mmap(size, pgshift);
|
||||
if (p3 == MAP_FAILED) {
|
||||
perror("mmap fail: ");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
printf("** mmap p3: %p - %p\n", p3, p3 + size);
|
||||
|
||||
/* make page populate */
|
||||
memset(p1, 0xff, size);
|
||||
memset(p2, 0xff, size);
|
||||
memset(p3, 0x77, size);
|
||||
|
||||
remap_size = size - ps;
|
||||
old_addr = p1 + ps * (i >> 1);
|
||||
new_addr = p3 + ps * (i & 1);
|
||||
|
||||
p4 = mremap(old_addr, remap_size, remap_size,
|
||||
MREMAP_FIXED | MREMAP_MAYMOVE, new_addr);
|
||||
if (p4 == MAP_FAILED) {
|
||||
perror("mremap fail: ");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
if (memcmp(p4, p2, remap_size)) {
|
||||
printf("memcmp detect DIFF!!\n");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
printf("*** mremap p4: %p - %p\n", p4, p4 + remap_size);
|
||||
|
||||
}
|
||||
|
||||
printf("[OK] mremap on HUGETLB\n");
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
11
test/issues/1383/Makefile
Normal file
11
test/issues/1383/Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
CFLAGS=-g
|
||||
LDFLAGS=
|
||||
|
||||
TARGET= C1383T01
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
test: all
|
||||
sh ./C1383.sh
|
||||
clean:
|
||||
rm -f $(TARGET) *.o *.txt
|
||||
29
test/issues/1383/README
Normal file
29
test/issues/1383/README
Normal file
@ -0,0 +1,29 @@
|
||||
【Issue#1383 動作確認】
|
||||
□ テスト内容
|
||||
1. MAP_HUGETLB指定でラージページを確保し、スモールページへのsplitが発生する
|
||||
mremapが正常に行えることを確認する。
|
||||
具体的には、Issueで報告されたLTPのthp02相当の処理のmmap部分をthpからMAP_HUGETLB指定に
|
||||
したプログラムを実行し、正常に終了することを確認する。
|
||||
|
||||
2. Issueで報告された以下のLTPを実行し、症状が発生しないことを確認する
|
||||
- thp02
|
||||
|
||||
3. mremapを利用する以下のLTPを用いて既存機能に影響が無いことを確認する
|
||||
- mremap01
|
||||
- mremap02
|
||||
- mremap03
|
||||
- mremap04
|
||||
- mremap05
|
||||
- move_pages10
|
||||
|
||||
□ 実行手順
|
||||
$ make test
|
||||
|
||||
McKernelのインストール先や、OSTEST, LTPの配置場所は、
|
||||
$HOME/.mck_test_config を参照している
|
||||
.mck_test_config は、McKernelをビルドした際に生成されるmck_test_config.sample ファイルを
|
||||
$HOMEにコピーし、適宜編集する
|
||||
|
||||
□ 実行結果
|
||||
x86_64_result.log aarch64_result.log 参照。
|
||||
すべての項目をPASSしていることを確認。
|
||||
65
test/issues/1383/aarch64_result.log
Normal file
65
test/issues/1383/aarch64_result.log
Normal file
@ -0,0 +1,65 @@
|
||||
*** C1383T01 start *******************************
|
||||
** mmap p1: 0x100020000000 - 0x100080000000
|
||||
** mmap p2: 0x1000a0000000 - 0x100100000000
|
||||
** mmap p3: 0x100100000000 - 0x100160000000
|
||||
*** mremap p4: 0x100100000000 - 0x10015fff0000
|
||||
** mmap p1: 0x100160000000 - 0x1001c0000000
|
||||
** mmap p2: 0x1001c0000000 - 0x100220000000
|
||||
** mmap p3: 0x100220000000 - 0x100280000000
|
||||
*** mremap p4: 0x100220010000 - 0x100280000000
|
||||
** mmap p1: 0x100280000000 - 0x1002e0000000
|
||||
** mmap p2: 0x1002e0000000 - 0x100340000000
|
||||
** mmap p3: 0x100340000000 - 0x1003a0000000
|
||||
*** mremap p4: 0x100340000000 - 0x10039fff0000
|
||||
** mmap p1: 0x1003a0000000 - 0x100400000000
|
||||
** mmap p2: 0x100400000000 - 0x100460000000
|
||||
** mmap p3: 0x100460000000 - 0x1004c0000000
|
||||
*** mremap p4: 0x100460010000 - 0x1004c0000000
|
||||
[OK] mremap on HUGETLB
|
||||
*** C1383T01 PASSED ******************************
|
||||
|
||||
*** C1383T02 start *******************************
|
||||
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
|
||||
thp02.c:75: INFO: mremap 0x100040000000 to 0x1001c0000000
|
||||
thp02.c:75: INFO: mremap 0x100280000000 to 0x100400010000
|
||||
thp02.c:75: INFO: mremap 0x1004c0010000 to 0x100640000000
|
||||
thp02.c:75: INFO: mremap 0x100700010000 to 0x100880010000
|
||||
thp02.c:85: PASS: Still alive.
|
||||
|
||||
Summary:
|
||||
passed 1
|
||||
failed 0
|
||||
skipped 0
|
||||
warnings 0
|
||||
*** C1383T02 PASSED (1)
|
||||
|
||||
*** C1383T03 start *******************************
|
||||
mremap01 1 TPASS : Functionality of mremap() is correct
|
||||
*** C1383T03 PASSED (1)
|
||||
|
||||
*** C1383T04 start *******************************
|
||||
mremap02 1 TPASS : mremap() Failed, 'invalid argument specified' - errno 22
|
||||
*** C1383T04 PASSED (1)
|
||||
|
||||
*** C1383T05 start *******************************
|
||||
mremap03 1 TPASS : mremap() Fails, 'old region not mapped', errno 14
|
||||
*** C1383T05 PASSED (1)
|
||||
|
||||
*** C1383T06 start *******************************
|
||||
mremap04 1 TPASS : mremap() failed, 'MREMAP_MAYMOVE flag unset', errno 12
|
||||
*** C1383T06 PASSED (1)
|
||||
|
||||
*** C1383T07 start *******************************
|
||||
mremap05 1 TPASS : MREMAP_FIXED requires MREMAP_MAYMOVE
|
||||
mremap05 2 TPASS : new_addr has to be page aligned
|
||||
mremap05 3 TPASS : old/new area must not overlap
|
||||
mremap05 4 TPASS : mremap #1
|
||||
mremap05 5 TPASS : mremap #1 value OK
|
||||
mremap05 6 TPASS : mremap #2
|
||||
mremap05 7 TPASS : mremap #2 value OK
|
||||
*** C1383T07 PASSED (7)
|
||||
|
||||
*** C1383T08 start *******************************
|
||||
move_pages10 1 TPASS : move_pages failed with EINVAL as expected
|
||||
*** C1383T08 PASSED (1)
|
||||
|
||||
65
test/issues/1383/x86_64_result.log
Normal file
65
test/issues/1383/x86_64_result.log
Normal file
@ -0,0 +1,65 @@
|
||||
*** C1383T01 start *******************************
|
||||
** mmap p1: 0x2aaaaae00000 - 0x2aaaab400000
|
||||
** mmap p2: 0x2aaaab600000 - 0x2aaaabc00000
|
||||
** mmap p3: 0x2aaaabc00000 - 0x2aaaac200000
|
||||
*** mremap p4: 0x2aaaabc00000 - 0x2aaaac1ff000
|
||||
** mmap p1: 0x2aaaac200000 - 0x2aaaac800000
|
||||
** mmap p2: 0x2aaaac800000 - 0x2aaaace00000
|
||||
** mmap p3: 0x2aaaace00000 - 0x2aaaad400000
|
||||
*** mremap p4: 0x2aaaace01000 - 0x2aaaad400000
|
||||
** mmap p1: 0x2aaaad400000 - 0x2aaaada00000
|
||||
** mmap p2: 0x2aaaada00000 - 0x2aaaae000000
|
||||
** mmap p3: 0x2aaaae000000 - 0x2aaaae600000
|
||||
*** mremap p4: 0x2aaaae000000 - 0x2aaaae5ff000
|
||||
** mmap p1: 0x2aaaae600000 - 0x2aaaaec00000
|
||||
** mmap p2: 0x2aaaaec00000 - 0x2aaaaf200000
|
||||
** mmap p3: 0x2aaaaf200000 - 0x2aaaaf800000
|
||||
*** mremap p4: 0x2aaaaf201000 - 0x2aaaaf800000
|
||||
[OK] mremap on HUGETLB
|
||||
*** C1383T01 PASSED ******************************
|
||||
|
||||
*** C1383T02 start *******************************
|
||||
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
|
||||
thp02.c:75: INFO: mremap 0x2aaaab800000 to 0x2aaaad000000
|
||||
thp02.c:75: INFO: mremap 0x2aaaadc00000 to 0x2aaaaf401000
|
||||
thp02.c:75: INFO: mremap 0x2aaab0001000 to 0x2aaab1800000
|
||||
thp02.c:75: INFO: mremap 0x2aaab2401000 to 0x2aaab3c01000
|
||||
thp02.c:85: PASS: Still alive.
|
||||
|
||||
Summary:
|
||||
passed 1
|
||||
failed 0
|
||||
skipped 0
|
||||
warnings 0
|
||||
*** C1383T02 PASSED (1)
|
||||
|
||||
*** C1383T03 start *******************************
|
||||
mremap01 1 TPASS : Functionality of mremap() is correct
|
||||
*** C1383T03 PASSED (1)
|
||||
|
||||
*** C1383T04 start *******************************
|
||||
mremap02 1 TPASS : mremap() Failed, 'invalid argument specified' - errno 22
|
||||
*** C1383T04 PASSED (1)
|
||||
|
||||
*** C1383T05 start *******************************
|
||||
mremap03 1 TPASS : mremap() Fails, 'old region not mapped', errno 14
|
||||
*** C1383T05 PASSED (1)
|
||||
|
||||
*** C1383T06 start *******************************
|
||||
mremap04 1 TPASS : mremap() failed, 'MREMAP_MAYMOVE flag unset', errno 12
|
||||
*** C1383T06 PASSED (1)
|
||||
|
||||
*** C1383T07 start *******************************
|
||||
mremap05 1 TPASS : MREMAP_FIXED requires MREMAP_MAYMOVE
|
||||
mremap05 2 TPASS : new_addr has to be page aligned
|
||||
mremap05 3 TPASS : old/new area must not overlap
|
||||
mremap05 4 TPASS : mremap #1
|
||||
mremap05 5 TPASS : mremap #1 value OK
|
||||
mremap05 6 TPASS : mremap #2
|
||||
mremap05 7 TPASS : mremap #2 value OK
|
||||
*** C1383T07 PASSED (7)
|
||||
|
||||
*** C1383T08 start *******************************
|
||||
move_pages10 1 TPASS : move_pages failed with EINVAL as expected
|
||||
*** C1383T08 PASSED (1)
|
||||
|
||||
Reference in New Issue
Block a user