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.
This commit is contained in:
@@ -450,7 +450,8 @@ struct vm_range *previous_process_memory_range(
|
|||||||
int extend_up_process_memory_range(struct process_vm *vm,
|
int extend_up_process_memory_range(struct process_vm *vm,
|
||||||
struct vm_range *range, uintptr_t newend);
|
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,
|
int remove_process_region(struct process *proc,
|
||||||
unsigned long start, unsigned long end);
|
unsigned long start, unsigned long end);
|
||||||
struct program_load_desc;
|
struct program_load_desc;
|
||||||
|
|||||||
@@ -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",
|
dkprintf("[%d]page_fault_handler(%p,%lx,%p)\n",
|
||||||
ihk_mc_get_processor_id(), fault_addr, reason, regs);
|
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) {
|
if (error) {
|
||||||
struct siginfo info;
|
struct siginfo info;
|
||||||
|
|
||||||
kprintf("[%d]page_fault_handler(%p,%lx,%p):"
|
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,
|
ihk_mc_get_processor_id(), fault_addr,
|
||||||
reason, regs, error);
|
reason, regs, error);
|
||||||
unhandled_page_fault(proc, fault_addr, regs);
|
unhandled_page_fault(proc, fault_addr, regs);
|
||||||
|
|||||||
@@ -1491,24 +1491,23 @@ out:
|
|||||||
return error;
|
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;
|
int error;
|
||||||
const uintptr_t fault_addr = (uintptr_t)fault_addr0;
|
const uintptr_t fault_addr = (uintptr_t)fault_addr0;
|
||||||
struct vm_range *range;
|
struct vm_range *range;
|
||||||
|
|
||||||
dkprintf("[%d]do_page_fault_process(%p,%lx,%lx)\n",
|
dkprintf("[%d]do_page_fault_process_vm(%p,%lx,%lx)\n",
|
||||||
ihk_mc_get_processor_id(), proc, fault_addr0, reason);
|
ihk_mc_get_processor_id(), vm, fault_addr0, reason);
|
||||||
|
|
||||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||||
|
|
||||||
range = lookup_process_memory_range(vm, fault_addr, fault_addr+1);
|
range = lookup_process_memory_range(vm, fault_addr, fault_addr+1);
|
||||||
if (range == NULL) {
|
if (range == NULL) {
|
||||||
error = -EFAULT;
|
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",
|
"out of range. %d\n",
|
||||||
ihk_mc_get_processor_id(), proc,
|
ihk_mc_get_processor_id(), vm,
|
||||||
fault_addr0, reason, error);
|
fault_addr0, reason, error);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -1519,9 +1518,9 @@ static int do_page_fault_process(struct process *proc, void *fault_addr0, uint64
|
|||||||
|| ((reason & PF_INSTR)
|
|| ((reason & PF_INSTR)
|
||||||
&& !(range->flag & VR_PROT_EXEC))) {
|
&& !(range->flag & VR_PROT_EXEC))) {
|
||||||
error = -EFAULT;
|
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",
|
"access denied. %d\n",
|
||||||
ihk_mc_get_processor_id(), proc,
|
ihk_mc_get_processor_id(), vm,
|
||||||
fault_addr0, reason, error);
|
fault_addr0, reason, error);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -1558,9 +1557,9 @@ static int do_page_fault_process(struct process *proc, void *fault_addr0, uint64
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (error) {
|
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",
|
"fault range failed. %d\n",
|
||||||
ihk_mc_get_processor_id(), proc,
|
ihk_mc_get_processor_id(), vm,
|
||||||
fault_addr0, reason, error);
|
fault_addr0, reason, error);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -1568,22 +1567,19 @@ static int do_page_fault_process(struct process *proc, void *fault_addr0, uint64
|
|||||||
error = 0;
|
error = 0;
|
||||||
out:
|
out:
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||||
dkprintf("[%d]do_page_fault_process(%p,%lx,%lx): %d\n",
|
dkprintf("[%d]do_page_fault_process_vm(%p,%lx,%lx): %d\n",
|
||||||
ihk_mc_get_processor_id(), proc, fault_addr0,
|
ihk_mc_get_processor_id(), vm, fault_addr0,
|
||||||
reason, error);
|
reason, error);
|
||||||
return 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;
|
int error;
|
||||||
|
struct process *proc = cpu_local_var(current);
|
||||||
if (proc != cpu_local_var(current)) {
|
|
||||||
panic("page_fault_process: other process");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
error = do_page_fault_process(proc, fault_addr, reason);
|
error = do_page_fault_process_vm(fault_vm, fault_addr, reason);
|
||||||
if (error != -ERESTART) {
|
if (error != -ERESTART) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1914,9 +1910,9 @@ int populate_process_memory(struct process *proc, void *start, size_t len)
|
|||||||
|
|
||||||
end = (uintptr_t)start + len;
|
end = (uintptr_t)start + len;
|
||||||
for (addr = (uintptr_t)start; addr < end; addr += PAGE_SIZE) {
|
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) {
|
if (error) {
|
||||||
ekprintf("populate_process_range:page_fault_process"
|
ekprintf("populate_process_range:page_fault_process_vm"
|
||||||
"(%p,%lx,%lx) failed %d\n",
|
"(%p,%lx,%lx) failed %d\n",
|
||||||
proc, addr, reason, error);
|
proc, addr, reason, error);
|
||||||
goto out;
|
goto out;
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ long do_syscall(struct syscall_request *req, int cpu, int pid)
|
|||||||
if (res->status == STATUS_PAGE_FAULT) {
|
if (res->status == STATUS_PAGE_FAULT) {
|
||||||
dkprintf("STATUS_PAGE_FAULT in syscall, pid: %d\n",
|
dkprintf("STATUS_PAGE_FAULT in syscall, pid: %d\n",
|
||||||
cpu_local_var(current)->ftn->pid);
|
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,
|
(void *)res->fault_address,
|
||||||
res->fault_reason|PF_POPULATE);
|
res->fault_reason|PF_POPULATE);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user