mmap: add "flags" checks for MAP_HUGE*
This commit is contained in:
@ -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()
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user