From 2239a6b09be9fd9fd66acb630a6e3ac6410e3e25 Mon Sep 17 00:00:00 2001 From: NAKAMURA Gou Date: Tue, 3 Mar 2015 14:41:48 +0900 Subject: [PATCH] modify page_fault_process() - change its argument from 'struct process *' to 'struct process_vm *'. - change its name from 'page_fault_process()' to 'page_fault_process_vm()'. - allow to resolve a fault on the process_vm of another process. --- kernel/include/process.h | 3 ++- kernel/mem.c | 4 ++-- kernel/process.c | 36 ++++++++++++++++-------------------- kernel/syscall.c | 2 +- 4 files changed, 21 insertions(+), 24 deletions(-) diff --git a/kernel/include/process.h b/kernel/include/process.h index 79edaf9c..f8fcaeea 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -450,7 +450,8 @@ struct vm_range *previous_process_memory_range( int extend_up_process_memory_range(struct process_vm *vm, struct vm_range *range, uintptr_t newend); -int page_fault_process(struct process *proc, void *fault_addr, uint64_t reason); +int page_fault_process_vm(struct process_vm *fault_vm, void *fault_addr, + uint64_t reason); int remove_process_region(struct process *proc, unsigned long start, unsigned long end); struct program_load_desc; diff --git a/kernel/mem.c b/kernel/mem.c index a9229fd4..9691ccc5 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -370,12 +370,12 @@ static void page_fault_handler(void *fault_addr, uint64_t reason, void *regs) dkprintf("[%d]page_fault_handler(%p,%lx,%p)\n", ihk_mc_get_processor_id(), fault_addr, reason, regs); - error = page_fault_process(proc, fault_addr, reason); + error = page_fault_process_vm(proc->vm, fault_addr, reason); if (error) { struct siginfo info; kprintf("[%d]page_fault_handler(%p,%lx,%p):" - "fault proc failed. %d\n", + "fault vm failed. %d\n", ihk_mc_get_processor_id(), fault_addr, reason, regs, error); unhandled_page_fault(proc, fault_addr, regs); diff --git a/kernel/process.c b/kernel/process.c index e7edb98e..a7f309d0 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -1491,24 +1491,23 @@ out: return error; } -static int do_page_fault_process(struct process *proc, void *fault_addr0, uint64_t reason) +static int do_page_fault_process_vm(struct process_vm *vm, void *fault_addr0, uint64_t reason) { - struct process_vm *vm = proc->vm; int error; const uintptr_t fault_addr = (uintptr_t)fault_addr0; struct vm_range *range; - dkprintf("[%d]do_page_fault_process(%p,%lx,%lx)\n", - ihk_mc_get_processor_id(), proc, fault_addr0, reason); + dkprintf("[%d]do_page_fault_process_vm(%p,%lx,%lx)\n", + ihk_mc_get_processor_id(), vm, fault_addr0, reason); ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock); range = lookup_process_memory_range(vm, fault_addr, fault_addr+1); if (range == NULL) { error = -EFAULT; - kprintf("[%d]do_page_fault_process(%p,%lx,%lx):" + kprintf("[%d]do_page_fault_process_vm(%p,%lx,%lx):" "out of range. %d\n", - ihk_mc_get_processor_id(), proc, + ihk_mc_get_processor_id(), vm, fault_addr0, reason, error); goto out; } @@ -1519,9 +1518,9 @@ static int do_page_fault_process(struct process *proc, void *fault_addr0, uint64 || ((reason & PF_INSTR) && !(range->flag & VR_PROT_EXEC))) { error = -EFAULT; - kprintf("[%d]do_page_fault_process(%p,%lx,%lx):" + kprintf("[%d]do_page_fault_process_vm(%p,%lx,%lx):" "access denied. %d\n", - ihk_mc_get_processor_id(), proc, + ihk_mc_get_processor_id(), vm, fault_addr0, reason, error); goto out; } @@ -1558,9 +1557,9 @@ static int do_page_fault_process(struct process *proc, void *fault_addr0, uint64 goto out; } if (error) { - kprintf("[%d]do_page_fault_process(%p,%lx,%lx):" + kprintf("[%d]do_page_fault_process_vm(%p,%lx,%lx):" "fault range failed. %d\n", - ihk_mc_get_processor_id(), proc, + ihk_mc_get_processor_id(), vm, fault_addr0, reason, error); goto out; } @@ -1568,22 +1567,19 @@ static int do_page_fault_process(struct process *proc, void *fault_addr0, uint64 error = 0; out: ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock); - dkprintf("[%d]do_page_fault_process(%p,%lx,%lx): %d\n", - ihk_mc_get_processor_id(), proc, fault_addr0, + dkprintf("[%d]do_page_fault_process_vm(%p,%lx,%lx): %d\n", + ihk_mc_get_processor_id(), vm, fault_addr0, reason, error); return error; } -int page_fault_process(struct process *proc, void *fault_addr, uint64_t reason) +int page_fault_process_vm(struct process_vm *fault_vm, void *fault_addr, uint64_t reason) { int error; - - if (proc != cpu_local_var(current)) { - panic("page_fault_process: other process"); - } + struct process *proc = cpu_local_var(current); for (;;) { - error = do_page_fault_process(proc, fault_addr, reason); + error = do_page_fault_process_vm(fault_vm, fault_addr, reason); if (error != -ERESTART) { break; } @@ -1914,9 +1910,9 @@ int populate_process_memory(struct process *proc, void *start, size_t len) end = (uintptr_t)start + len; for (addr = (uintptr_t)start; addr < end; addr += PAGE_SIZE) { - error = page_fault_process(proc, (void *)addr, reason); + error = page_fault_process_vm(proc->vm, (void *)addr, reason); if (error) { - ekprintf("populate_process_range:page_fault_process" + ekprintf("populate_process_range:page_fault_process_vm" "(%p,%lx,%lx) failed %d\n", proc, addr, reason, error); goto out; diff --git a/kernel/syscall.c b/kernel/syscall.c index 513e8357..6d838c02 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -226,7 +226,7 @@ long do_syscall(struct syscall_request *req, int cpu, int pid) if (res->status == STATUS_PAGE_FAULT) { dkprintf("STATUS_PAGE_FAULT in syscall, pid: %d\n", cpu_local_var(current)->ftn->pid); - error = page_fault_process(get_cpu_local_var(cpu)->current, + error = page_fault_process_vm(proc->vm, (void *)res->fault_address, res->fault_reason|PF_POPULATE);