add error check codes for madvise()
The advice will be ignored even if this madvise() succeed.
This commit is contained in:
@@ -43,4 +43,24 @@
|
|||||||
#define MAP_STACK 0x00020000
|
#define MAP_STACK 0x00020000
|
||||||
#define MAP_HUGETLB 0x00040000
|
#define MAP_HUGETLB 0x00040000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* memory advice
|
||||||
|
*/
|
||||||
|
#define MADV_NORMAL 0
|
||||||
|
#define MADV_RANDOM 1
|
||||||
|
#define MADV_SEQUENTIAL 2
|
||||||
|
#define MADV_WILLNEED 3
|
||||||
|
#define MADV_DONTNEED 4
|
||||||
|
#define MADV_REMOVE 9
|
||||||
|
#define MADV_DONTFORK 10
|
||||||
|
#define MADV_DOFORK 11
|
||||||
|
#define MADV_MERGEABLE 12
|
||||||
|
#define MADV_UNMERGEABLE 13
|
||||||
|
#define MADV_HUGEPAGE 14
|
||||||
|
#define MADV_NOHUGEPAGE 15
|
||||||
|
#define MADV_DONTDUMP 16
|
||||||
|
#define MADV_DODUMP 17
|
||||||
|
#define MADV_HWPOISON 100
|
||||||
|
#define MADV_SOFT_OFFLINE 101
|
||||||
|
|
||||||
#endif /* HEADER_MMAN_H */
|
#endif /* HEADER_MMAN_H */
|
||||||
|
|||||||
129
kernel/syscall.c
129
kernel/syscall.c
@@ -1308,8 +1308,133 @@ SYSCALL_DECLARE(sigaltstack)
|
|||||||
|
|
||||||
SYSCALL_DECLARE(madvise)
|
SYSCALL_DECLARE(madvise)
|
||||||
{
|
{
|
||||||
// kprintf("sys_madvise called. returning zero...\n");
|
const uintptr_t start = (uintptr_t)ihk_mc_syscall_arg0(ctx);
|
||||||
return 0;
|
const size_t len0 = (size_t)ihk_mc_syscall_arg1(ctx);
|
||||||
|
const int advice = (int)ihk_mc_syscall_arg2(ctx);
|
||||||
|
size_t len;
|
||||||
|
uintptr_t end;
|
||||||
|
struct process *proc = cpu_local_var(current);
|
||||||
|
struct vm_regions *region = &proc->vm->region;
|
||||||
|
struct vm_range *first;
|
||||||
|
uintptr_t addr;
|
||||||
|
struct vm_range *range;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
dkprintf("[%d]sys_madvise(%lx,%lx,%x)\n",
|
||||||
|
ihk_mc_get_processor_id(), start, len0, advice);
|
||||||
|
|
||||||
|
len = (len0 + PAGE_SIZE - 1) & PAGE_MASK;
|
||||||
|
end = start + len;
|
||||||
|
|
||||||
|
if ((start & (PAGE_SIZE - 1))
|
||||||
|
|| (len < len0)
|
||||||
|
|| (end < start)) {
|
||||||
|
error = -EINVAL;
|
||||||
|
goto out2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((start < region->user_start)
|
||||||
|
|| (region->user_end <= start)
|
||||||
|
|| (len > (region->user_end - region->user_start))
|
||||||
|
|| ((region->user_end - len) < start)) {
|
||||||
|
error = -ENOMEM;
|
||||||
|
goto out2;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = 0;
|
||||||
|
switch (advice) {
|
||||||
|
default:
|
||||||
|
case MADV_MERGEABLE:
|
||||||
|
case MADV_UNMERGEABLE:
|
||||||
|
case MADV_HUGEPAGE:
|
||||||
|
case MADV_NOHUGEPAGE:
|
||||||
|
case MADV_DONTDUMP:
|
||||||
|
case MADV_DODUMP:
|
||||||
|
error = -EINVAL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MADV_NORMAL:
|
||||||
|
case MADV_RANDOM:
|
||||||
|
case MADV_SEQUENTIAL:
|
||||||
|
case MADV_WILLNEED:
|
||||||
|
case MADV_DONTNEED:
|
||||||
|
case MADV_DONTFORK:
|
||||||
|
case MADV_DOFORK:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MADV_REMOVE:
|
||||||
|
error = -EACCES;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MADV_HWPOISON:
|
||||||
|
case MADV_SOFT_OFFLINE:
|
||||||
|
error = -EPERM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
goto out2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start == end) {
|
||||||
|
error = 0;
|
||||||
|
goto out2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ihk_mc_spinlock_lock_noirq(&proc->vm->memory_range_lock);
|
||||||
|
/* check contiguous map */
|
||||||
|
first = NULL;
|
||||||
|
for (addr = start; addr < end; addr = range->end) {
|
||||||
|
if (first == NULL) {
|
||||||
|
range = lookup_process_memory_range(proc->vm, start, start+PAGE_SIZE);
|
||||||
|
first = range;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
range = next_process_memory_range(proc->vm, range);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((range == NULL) || (addr < range->start)) {
|
||||||
|
/* not contiguous */
|
||||||
|
dkprintf("[%d]sys_madvise(%lx,%lx,%x):not contig "
|
||||||
|
"%lx [%lx-%lx)\n",
|
||||||
|
ihk_mc_get_processor_id(), start,
|
||||||
|
len0, advice, addr, range->start,
|
||||||
|
range->end);
|
||||||
|
error = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MEMOBJ_IS_FILEOBJ(obj) ((obj) != NULL)
|
||||||
|
if (!MEMOBJ_IS_FILEOBJ(range->memobj)) {
|
||||||
|
dkprintf("[%d]sys_madvise(%lx,%lx,%x):not fileobj "
|
||||||
|
"[%lx-%lx) %lx\n",
|
||||||
|
ihk_mc_get_processor_id(), start,
|
||||||
|
len0, advice, range->start,
|
||||||
|
range->end, range->memobj);
|
||||||
|
error = -EBADF;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((advice == MADV_DONTNEED)
|
||||||
|
&& (range->flag & VR_LOCKED)) {
|
||||||
|
dkprintf("[%d]sys_madvise(%lx,%lx,%x):locked"
|
||||||
|
"[%lx-%lx) %lx\n",
|
||||||
|
ihk_mc_get_processor_id(), start,
|
||||||
|
len0, advice, range->start,
|
||||||
|
range->end, range->flag);
|
||||||
|
error = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
error = 0;
|
||||||
|
out:
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&proc->vm->memory_range_lock);
|
||||||
|
|
||||||
|
out2:
|
||||||
|
dkprintf("[%d]sys_madvise(%lx,%lx,%x): %d\n",
|
||||||
|
ihk_mc_get_processor_id(), start, len0, advice, error);
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCALL_DECLARE(futex)
|
SYSCALL_DECLARE(futex)
|
||||||
|
|||||||
Reference in New Issue
Block a user