do_process_vm_read_writev: use process hash for remote process search
This commit is contained in:
@@ -5920,18 +5920,22 @@ static int do_process_vm_read_writev(int pid,
|
|||||||
int op)
|
int op)
|
||||||
{
|
{
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
int li, ri, i;
|
int li, ri;
|
||||||
int pli, pri;
|
int pli, pri;
|
||||||
off_t loff, roff;
|
off_t loff, roff;
|
||||||
size_t llen = 0, rlen = 0;
|
size_t llen = 0, rlen = 0;
|
||||||
size_t copied = 0;
|
size_t copied = 0;
|
||||||
size_t to_copy;
|
size_t to_copy;
|
||||||
struct thread *lthread = cpu_local_var(current);
|
struct thread *lthread = cpu_local_var(current);
|
||||||
struct thread *rthread, *p;
|
struct process *rproc;
|
||||||
|
struct process *lproc = lthread->proc;
|
||||||
|
struct process_vm *rvm = NULL;
|
||||||
unsigned long rphys;
|
unsigned long rphys;
|
||||||
unsigned long rpage_left;
|
unsigned long rpage_left;
|
||||||
void *rva;
|
void *rva;
|
||||||
struct vm_range *range;
|
struct vm_range *range;
|
||||||
|
struct mcs_rwlock_node_irqsave lock;
|
||||||
|
struct mcs_rwlock_node update_lock;
|
||||||
|
|
||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
if (flags) {
|
if (flags) {
|
||||||
@@ -5987,40 +5991,37 @@ arg_out:
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find remote process
|
/* Find remote process */
|
||||||
* XXX: are we going to have a hash table/function for this?? */
|
rproc = find_process(pid, &lock);
|
||||||
rthread = NULL;
|
if (!rproc) {
|
||||||
for (i = 0; i < num_processors; i++) {
|
|
||||||
struct cpu_local_var *v = get_cpu_local_var(i);
|
|
||||||
|
|
||||||
ihk_mc_spinlock_lock_noirq(&(v->runq_lock));
|
|
||||||
list_for_each_entry(p, &(v->runq), sched_list) {
|
|
||||||
if (p->proc->pid == pid) {
|
|
||||||
rthread = p;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&(v->runq_lock));
|
|
||||||
|
|
||||||
if (rthread)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rthread) {
|
|
||||||
ret = -ESRCH;
|
ret = -ESRCH;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rthread->proc->ruid != lthread->proc->ruid ||
|
mcs_rwlock_reader_lock_noirq(&rproc->update_lock, &update_lock);
|
||||||
rthread->proc->euid != lthread->proc->euid ||
|
if(rproc->status == PS_EXITED ||
|
||||||
rthread->proc->rgid != lthread->proc->rgid ||
|
rproc->status == PS_ZOMBIE){
|
||||||
rthread->proc->egid != lthread->proc->egid) {
|
mcs_rwlock_reader_unlock_noirq(&rproc->update_lock, &update_lock);
|
||||||
|
process_unlock(rproc, &lock);
|
||||||
|
ret = -ESRCH;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
rvm = rproc->vm;
|
||||||
|
hold_process_vm(rvm);
|
||||||
|
mcs_rwlock_reader_unlock_noirq(&rproc->update_lock, &update_lock);
|
||||||
|
process_unlock(rproc, &lock);
|
||||||
|
|
||||||
|
if (lproc->euid != 0 &&
|
||||||
|
(lproc->ruid != rproc->ruid ||
|
||||||
|
lproc->ruid != rproc->euid ||
|
||||||
|
lproc->ruid != rproc->suid ||
|
||||||
|
lproc->rgid != rproc->rgid ||
|
||||||
|
lproc->rgid != rproc->egid ||
|
||||||
|
lproc->rgid != rproc->sgid)) {
|
||||||
ret = -EPERM;
|
ret = -EPERM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dkprintf("pid %d found, doing %s \n", pid,
|
dkprintf("pid %d found, doing %s \n", pid,
|
||||||
(op == PROCESS_VM_READ) ? "PROCESS_VM_READ" : "PROCESS_VM_WRITE");
|
(op == PROCESS_VM_READ) ? "PROCESS_VM_READ" : "PROCESS_VM_WRITE");
|
||||||
|
|
||||||
@@ -6080,10 +6081,10 @@ pli_out:
|
|||||||
void *addr;
|
void *addr;
|
||||||
struct vm_range *range;
|
struct vm_range *range;
|
||||||
|
|
||||||
ihk_mc_spinlock_lock_noirq(&rthread->vm->memory_range_lock);
|
ihk_mc_spinlock_lock_noirq(&rvm->memory_range_lock);
|
||||||
|
|
||||||
/* Is base valid? */
|
/* Is base valid? */
|
||||||
range = lookup_process_memory_range(rthread->vm,
|
range = lookup_process_memory_range(rvm,
|
||||||
(uintptr_t)remote_iov[li].iov_base,
|
(uintptr_t)remote_iov[li].iov_base,
|
||||||
(uintptr_t)(remote_iov[li].iov_base + 1));
|
(uintptr_t)(remote_iov[li].iov_base + 1));
|
||||||
|
|
||||||
@@ -6110,7 +6111,7 @@ pli_out:
|
|||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
pri_out:
|
pri_out:
|
||||||
ihk_mc_spinlock_unlock_noirq(&rthread->vm->memory_range_lock);
|
ihk_mc_spinlock_unlock_noirq(&rvm->memory_range_lock);
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
goto out;
|
goto out;
|
||||||
@@ -6122,7 +6123,7 @@ pri_out:
|
|||||||
addr < (remote_iov[ri].iov_base + remote_iov[ri].iov_len);
|
addr < (remote_iov[ri].iov_base + remote_iov[ri].iov_len);
|
||||||
addr += PAGE_SIZE) {
|
addr += PAGE_SIZE) {
|
||||||
|
|
||||||
ret = page_fault_process_vm(rthread->vm, addr, reason);
|
ret = page_fault_process_vm(rvm, addr, reason);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -6146,7 +6147,7 @@ pri_out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: remember page and do this only if necessary */
|
/* TODO: remember page and do this only if necessary */
|
||||||
ret = ihk_mc_pt_virt_to_phys(rthread->vm->address_space->page_table,
|
ret = ihk_mc_pt_virt_to_phys(rvm->address_space->page_table,
|
||||||
remote_iov[ri].iov_base + roff, &rphys);
|
remote_iov[ri].iov_base + roff, &rphys);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -6180,9 +6181,13 @@ pri_out:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
release_process_vm(rvm);
|
||||||
|
|
||||||
return copied;
|
return copied;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
if(rvm)
|
||||||
|
release_process_vm(rvm);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user