support madvise(MADV_DONTFORK)
This commit is contained in:
@ -29,6 +29,7 @@
|
|||||||
#define VR_IO_NOCACHE 0x100
|
#define VR_IO_NOCACHE 0x100
|
||||||
#define VR_REMOTE 0x200
|
#define VR_REMOTE 0x200
|
||||||
#define VR_WRITE_COMBINED 0x400
|
#define VR_WRITE_COMBINED 0x400
|
||||||
|
#define VR_DONTFORK 0x800
|
||||||
#define VR_DEMAND_PAGING 0x1000
|
#define VR_DEMAND_PAGING 0x1000
|
||||||
#define VR_PRIVATE 0x2000
|
#define VR_PRIVATE 0x2000
|
||||||
#define VR_LOCKED 0x4000
|
#define VR_LOCKED 0x4000
|
||||||
|
|||||||
@ -571,6 +571,9 @@ static int copy_user_ranges(struct process_vm *vm, struct process_vm *orgvm)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(src_range->flag & VR_DONTFORK)
|
||||||
|
continue;
|
||||||
|
|
||||||
range = kmalloc(sizeof(struct vm_range), IHK_MC_AP_NOWAIT);
|
range = kmalloc(sizeof(struct vm_range), IHK_MC_AP_NOWAIT);
|
||||||
if (!range) {
|
if (!range) {
|
||||||
goto err_rollback;
|
goto err_rollback;
|
||||||
|
|||||||
106
kernel/syscall.c
106
kernel/syscall.c
@ -3479,6 +3479,90 @@ SYSCALL_DECLARE(mincore)
|
|||||||
return 0;
|
return 0;
|
||||||
} /* sys_mincore() */
|
} /* 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)
|
SYSCALL_DECLARE(madvise)
|
||||||
{
|
{
|
||||||
const uintptr_t start = (uintptr_t)ihk_mc_syscall_arg0(ctx);
|
const uintptr_t start = (uintptr_t)ihk_mc_syscall_arg0(ctx);
|
||||||
@ -3587,6 +3671,7 @@ SYSCALL_DECLARE(madvise)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(advice == MADV_DONTFORK || advice == MADV_DOFORK);
|
||||||
else if (!range->memobj || !memobj_has_pager(range->memobj)) {
|
else if (!range->memobj || !memobj_has_pager(range->memobj)) {
|
||||||
dkprintf("[%d]sys_madvise(%lx,%lx,%x):has not pager"
|
dkprintf("[%d]sys_madvise(%lx,%lx,%x):has not pager"
|
||||||
"[%lx-%lx) %lx\n",
|
"[%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;
|
error = 0;
|
||||||
out:
|
out:
|
||||||
ihk_mc_spinlock_unlock_noirq(&thread->vm->memory_range_lock);
|
ihk_mc_spinlock_unlock_noirq(&thread->vm->memory_range_lock);
|
||||||
|
|||||||
Reference in New Issue
Block a user