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_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 */
|
||||
|
||||
129
kernel/syscall.c
129
kernel/syscall.c
@ -1308,8 +1308,133 @@ SYSCALL_DECLARE(sigaltstack)
|
||||
|
||||
SYSCALL_DECLARE(madvise)
|
||||
{
|
||||
// kprintf("sys_madvise called. returning zero...\n");
|
||||
return 0;
|
||||
const uintptr_t start = (uintptr_t)ihk_mc_syscall_arg0(ctx);
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user