support madvise(MADV_DONTFORK)
This commit is contained in:
@ -29,6 +29,7 @@
|
||||
#define VR_IO_NOCACHE 0x100
|
||||
#define VR_REMOTE 0x200
|
||||
#define VR_WRITE_COMBINED 0x400
|
||||
#define VR_DONTFORK 0x800
|
||||
#define VR_DEMAND_PAGING 0x1000
|
||||
#define VR_PRIVATE 0x2000
|
||||
#define VR_LOCKED 0x4000
|
||||
|
||||
@ -571,6 +571,9 @@ static int copy_user_ranges(struct process_vm *vm, struct process_vm *orgvm)
|
||||
break;
|
||||
}
|
||||
|
||||
if(src_range->flag & VR_DONTFORK)
|
||||
continue;
|
||||
|
||||
range = kmalloc(sizeof(struct vm_range), IHK_MC_AP_NOWAIT);
|
||||
if (!range) {
|
||||
goto err_rollback;
|
||||
|
||||
106
kernel/syscall.c
106
kernel/syscall.c
@ -3479,6 +3479,90 @@ SYSCALL_DECLARE(mincore)
|
||||
return 0;
|
||||
} /* sys_mincore() */
|
||||
|
||||
static int
|
||||
set_memory_range_flag(struct vm_range *range, unsigned long arg)
|
||||
{
|
||||
range->flag |= arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
clear_memory_range_flag(struct vm_range *range, unsigned long arg)
|
||||
{
|
||||
range->flag &= ~arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
change_attr_process_memory_range(struct process_vm *vm,
|
||||
uintptr_t start, uintptr_t end,
|
||||
int (*change_proc)(struct vm_range *,
|
||||
unsigned long),
|
||||
unsigned long arg)
|
||||
{
|
||||
uintptr_t addr;
|
||||
int error;
|
||||
struct vm_range *range;
|
||||
struct vm_range *prev;
|
||||
struct vm_range *next;
|
||||
int join_flag = 0;
|
||||
|
||||
error = 0;
|
||||
range = lookup_process_memory_range(vm, start, start + PAGE_SIZE);
|
||||
if(!range){
|
||||
error = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
prev = previous_process_memory_range(vm, range);
|
||||
if(!prev)
|
||||
prev = range;
|
||||
for (addr = start; addr < end; addr = range->end) {
|
||||
if (range->start < addr) {
|
||||
if((error = split_process_memory_range(vm, range, addr, &range))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (end < range->end) {
|
||||
if((error = split_process_memory_range(vm, range, end, NULL))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!(error = change_proc(range, arg))){
|
||||
break;
|
||||
}
|
||||
range = next_process_memory_range(vm, range);
|
||||
}
|
||||
if(error){
|
||||
next = next_process_memory_range(vm, range);
|
||||
if(!next)
|
||||
next = range;
|
||||
}
|
||||
else{
|
||||
next = range;
|
||||
}
|
||||
|
||||
while(prev != next){
|
||||
int wkerr;
|
||||
|
||||
range = next_process_memory_range(vm, prev);
|
||||
if(!range)
|
||||
break;
|
||||
wkerr = join_process_memory_range(vm, prev, range);
|
||||
if(range == next)
|
||||
join_flag = 1;
|
||||
if (wkerr) {
|
||||
if(join_flag)
|
||||
break;
|
||||
prev = range;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(madvise)
|
||||
{
|
||||
const uintptr_t start = (uintptr_t)ihk_mc_syscall_arg0(ctx);
|
||||
@ -3587,6 +3671,7 @@ SYSCALL_DECLARE(madvise)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if(advice == MADV_DONTFORK || advice == MADV_DOFORK);
|
||||
else if (!range->memobj || !memobj_has_pager(range->memobj)) {
|
||||
dkprintf("[%d]sys_madvise(%lx,%lx,%x):has not pager"
|
||||
"[%lx-%lx) %lx\n",
|
||||
@ -3631,6 +3716,27 @@ SYSCALL_DECLARE(madvise)
|
||||
}
|
||||
}
|
||||
|
||||
if(advice == MADV_DONTFORK){
|
||||
error = change_attr_process_memory_range(thread->vm, start, end,
|
||||
set_memory_range_flag,
|
||||
VR_DONTFORK);
|
||||
if(error){
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if(advice == MADV_DOFORK){
|
||||
error = change_attr_process_memory_range(thread->vm, start, end,
|
||||
clear_memory_range_flag,
|
||||
VR_DONTFORK);
|
||||
if(error){
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if(advice == MADV_DONTFORK ||
|
||||
advice == MADV_DOFORK){
|
||||
error = syscall_generic_forwarding(__NR_madvise, ctx);
|
||||
}
|
||||
|
||||
error = 0;
|
||||
out:
|
||||
ihk_mc_spinlock_unlock_noirq(&thread->vm->memory_range_lock);
|
||||
|
||||
Reference in New Issue
Block a user