mmap: add "flags" checks for MAP_HUGE*

This commit is contained in:
NAKAMURA Gou
2016-03-17 20:02:16 +09:00
parent 261bddb999
commit d4d93df032
3 changed files with 43 additions and 10 deletions

View File

@ -27,6 +27,10 @@
#define MAP_STACK 0x00020000 #define MAP_STACK 0x00020000
#define MAP_HUGETLB 0x00040000 #define MAP_HUGETLB 0x00040000
#define MAP_HUGE_SHIFT 26
#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT)
#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT)
/* /*
* for mlockall() * for mlockall()
*/ */

View File

@ -1203,6 +1203,8 @@ SYSCALL_DECLARE(mmap)
| MAP_ANONYMOUS // 20 | MAP_ANONYMOUS // 20
| MAP_LOCKED // 2000 | MAP_LOCKED // 2000
| MAP_POPULATE // 8000 | MAP_POPULATE // 8000
| MAP_HUGETLB // 00040000
| (0x3F << MAP_HUGE_SHIFT) // FC000000
; ;
const int ignored_flags = 0 const int ignored_flags = 0
#ifdef USE_NOCACHE_MMAP #ifdef USE_NOCACHE_MMAP
@ -1219,13 +1221,12 @@ SYSCALL_DECLARE(mmap)
| MAP_GROWSDOWN // 0100 | MAP_GROWSDOWN // 0100
| MAP_EXECUTABLE // 1000 | MAP_EXECUTABLE // 1000
| MAP_NONBLOCK // 00010000 | MAP_NONBLOCK // 00010000
| MAP_HUGETLB // 00040000
; ;
const intptr_t addr0 = ihk_mc_syscall_arg0(ctx); const intptr_t addr0 = ihk_mc_syscall_arg0(ctx);
const size_t len0 = ihk_mc_syscall_arg1(ctx); const size_t len0 = ihk_mc_syscall_arg1(ctx);
const int prot = ihk_mc_syscall_arg2(ctx); const int prot = ihk_mc_syscall_arg2(ctx);
const int flags = ihk_mc_syscall_arg3(ctx); const int flags0 = ihk_mc_syscall_arg3(ctx);
const int fd = ihk_mc_syscall_arg4(ctx); const int fd = ihk_mc_syscall_arg4(ctx);
const off_t off0 = ihk_mc_syscall_arg5(ctx); const off_t off0 = ihk_mc_syscall_arg5(ctx);
struct thread *thread = cpu_local_var(current); struct thread *thread = cpu_local_var(current);
@ -1233,9 +1234,10 @@ SYSCALL_DECLARE(mmap)
int error; int error;
intptr_t addr; intptr_t addr;
size_t len; size_t len;
int flags = flags0;
dkprintf("sys_mmap(%lx,%lx,%x,%x,%d,%lx)\n", dkprintf("sys_mmap(%lx,%lx,%x,%x,%d,%lx)\n",
addr0, len0, prot, flags, fd, off0); addr0, len0, prot, flags0, fd, off0);
/* check constants for flags */ /* check constants for flags */
if (1) { if (1) {
@ -1265,7 +1267,7 @@ SYSCALL_DECLARE(mmap)
|| ((flags & MAP_SHARED) && (flags & MAP_PRIVATE)) || ((flags & MAP_SHARED) && (flags & MAP_PRIVATE))
|| (off0 & (PAGE_SIZE - 1))) { || (off0 & (PAGE_SIZE - 1))) {
ekprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):EINVAL\n", ekprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):EINVAL\n",
addr0, len0, prot, flags, fd, off0); addr0, len0, prot, flags0, fd, off0);
error = -EINVAL; error = -EINVAL;
goto out; goto out;
} }
@ -1274,7 +1276,7 @@ SYSCALL_DECLARE(mmap)
|| (region->user_end <= addr) || (region->user_end <= addr)
|| ((region->user_end - addr) < len)) { || ((region->user_end - addr) < len)) {
ekprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):ENOMEM\n", ekprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):ENOMEM\n",
addr0, len0, prot, flags, fd, off0); addr0, len0, prot, flags0, fd, off0);
error = -ENOMEM; error = -ENOMEM;
goto out; goto out;
} }
@ -1283,18 +1285,37 @@ SYSCALL_DECLARE(mmap)
if ((flags & error_flags) if ((flags & error_flags)
|| (flags & ~(supported_flags | ignored_flags))) { || (flags & ~(supported_flags | ignored_flags))) {
ekprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):unknown flags %x\n", ekprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):unknown flags %x\n",
addr0, len0, prot, flags, fd, off0, addr0, len0, prot, flags0, fd, off0,
(flags & ~(supported_flags | ignored_flags))); (flags & ~(supported_flags | ignored_flags)));
error = -EINVAL; error = -EINVAL;
goto out; goto out;
} }
if (flags & MAP_HUGETLB) {
switch (flags & (0x3F << MAP_HUGE_SHIFT)) {
case 0:
flags |= MAP_HUGE_2MB; /* default hugepage size */
break;
case MAP_HUGE_2MB:
case MAP_HUGE_1GB:
break;
default:
ekprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):"
"not supported page size.\n",
addr0, len0, prot, flags0, fd, off0);
error = -EINVAL;
goto out;
}
}
addr = do_mmap(addr, len, prot, flags, fd, off0); addr = do_mmap(addr, len, prot, flags, fd, off0);
error = 0; error = 0;
out: out:
dkprintf("sys_mmap(%lx,%lx,%x,%x,%d,%lx): %ld %lx\n", dkprintf("sys_mmap(%lx,%lx,%x,%x,%d,%lx): %ld %lx\n",
addr0, len0, prot, flags, fd, off0, error, addr); addr0, len0, prot, flags0, fd, off0, error, addr);
return (!error)? addr: error; return (!error)? addr: error;
} }

View File

@ -941,6 +941,7 @@ do_mmap(const intptr_t addr0, const size_t len0, const int prot,
int populated_mapping = 0; int populated_mapping = 0;
struct process *proc = thread->proc; struct process *proc = thread->proc;
struct mckfd *fdp = NULL; struct mckfd *fdp = NULL;
int pgshift;
dkprintf("do_mmap(%lx,%lx,%x,%x,%d,%lx)\n", dkprintf("do_mmap(%lx,%lx,%x,%x,%d,%lx)\n",
addr0, len0, prot, flags, fd, off0); addr0, len0, prot, flags, fd, off0);
@ -1117,13 +1118,20 @@ do_mmap(const intptr_t addr0, const size_t len0, const int prot,
} }
vrflags |= VRFLAG_PROT_TO_MAXPROT(PROT_TO_VR_FLAG(maxprot)); vrflags |= VRFLAG_PROT_TO_MAXPROT(PROT_TO_VR_FLAG(maxprot));
if (flags & MAP_HUGETLB) {
pgshift = (flags >> MAP_HUGE_SHIFT) & 0x3F;
}
else {
pgshift = PAGE_SHIFT; /* basic page size */
}
error = add_process_memory_range(thread->vm, addr, addr+len, phys, error = add_process_memory_range(thread->vm, addr, addr+len, phys,
vrflags, memobj, off, PAGE_SHIFT); vrflags, memobj, off, pgshift);
if (error) { if (error) {
ekprintf("do_mmap:add_process_memory_range" ekprintf("do_mmap:add_process_memory_range"
"(%p,%lx,%lx,%lx,%lx) failed %d\n", "(%p,%lx,%lx,%lx,%lx,%d) failed %d\n",
thread->vm, addr, addr+len, thread->vm, addr, addr+len,
virt_to_phys(p), vrflags, error); virt_to_phys(p), vrflags, pgshift, error);
goto out; goto out;
} }