/proc/<PID>/mem: support read/write
This commit is contained in:
151
kernel/procfs.c
151
kernel/procfs.c
@@ -94,7 +94,6 @@ process_procfs_request(unsigned long rarg)
|
|||||||
int npages;
|
int npages;
|
||||||
int readwrite = 0;
|
int readwrite = 0;
|
||||||
|
|
||||||
|
|
||||||
dprintf("process_procfs_request: invoked.\n");
|
dprintf("process_procfs_request: invoked.\n");
|
||||||
|
|
||||||
syscall_channel = get_cpu_local_var(0)->syscall_channel;
|
syscall_channel = get_cpu_local_var(0)->syscall_channel;
|
||||||
@@ -162,33 +161,42 @@ process_procfs_request(unsigned long rarg)
|
|||||||
*/
|
*/
|
||||||
ret = sscanf(p, "%d/", &pid);
|
ret = sscanf(p, "%d/", &pid);
|
||||||
if (ret == 1) {
|
if (ret == 1) {
|
||||||
|
struct mcs_rwlock_node tlock;
|
||||||
|
int tids;
|
||||||
|
struct thread *thread1 = NULL;
|
||||||
|
|
||||||
proc = find_process(pid, &lock);
|
proc = find_process(pid, &lock);
|
||||||
if(proc == NULL){
|
if(proc == NULL){
|
||||||
kprintf("process_procfs_request: no such pid %d\n", pid);
|
kprintf("process_procfs_request: no such pid %d\n", pid);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
p = strchr(p, '/') + 1;
|
p = strchr(p, '/') + 1;
|
||||||
ret = sscanf(p, "task/%d/", &tid);
|
if((tids = sscanf(p, "task/%d/", &tid)) == 1){
|
||||||
if(ret == 1){
|
|
||||||
struct mcs_rwlock_node tlock;
|
|
||||||
mcs_rwlock_reader_lock_noirq(&proc->threads_lock, &tlock);
|
|
||||||
list_for_each_entry(thread, &proc->threads_list,
|
|
||||||
siblings_list) {
|
|
||||||
if(thread->tid == tid)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(thread == NULL){
|
|
||||||
mcs_rwlock_reader_unlock_noirq(&proc->threads_lock,
|
|
||||||
&tlock);
|
|
||||||
process_unlock(proc, &lock);
|
|
||||||
kprintf("process_procfs_request: no such tid %d-%d\n", pid, tid);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
hold_thread(thread);
|
|
||||||
mcs_rwlock_reader_unlock_noirq(&proc->threads_lock, &tlock);
|
|
||||||
p = strchr(p, '/') + 1;
|
p = strchr(p, '/') + 1;
|
||||||
p = strchr(p, '/') + 1;
|
p = strchr(p, '/') + 1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
tid = pid;
|
||||||
|
|
||||||
|
mcs_rwlock_reader_lock_noirq(&proc->threads_lock, &tlock);
|
||||||
|
list_for_each_entry(thread, &proc->threads_list, siblings_list){
|
||||||
|
if(thread->tid == tid)
|
||||||
|
break;
|
||||||
|
if(!thread1)
|
||||||
|
thread1 = thread;
|
||||||
|
}
|
||||||
|
if(thread == NULL){
|
||||||
|
kprintf("process_procfs_request: no such tid %d-%d\n", pid, tid);
|
||||||
|
if(tids){
|
||||||
|
process_unlock(proc, &lock);
|
||||||
|
mcs_rwlock_reader_unlock_noirq(&proc->threads_lock, &tlock);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
thread = thread1;
|
||||||
|
}
|
||||||
|
if(thread)
|
||||||
|
hold_thread(thread);
|
||||||
|
mcs_rwlock_reader_unlock_noirq(&proc->threads_lock, &tlock);
|
||||||
hold_process(proc);
|
hold_process(proc);
|
||||||
vm = proc->vm;
|
vm = proc->vm;
|
||||||
if(vm)
|
if(vm)
|
||||||
@@ -235,73 +243,52 @@ process_procfs_request(unsigned long rarg)
|
|||||||
* of the process. The count is the length of the area.
|
* of the process. The count is the length of the area.
|
||||||
*/
|
*/
|
||||||
if (strcmp(p, "mem") == 0) {
|
if (strcmp(p, "mem") == 0) {
|
||||||
struct vm_range *range;
|
uint64_t reason = PF_POPULATE | PF_WRITE | PF_USER;
|
||||||
|
unsigned long offset = r->offset;
|
||||||
|
unsigned long left = r->count;
|
||||||
|
int ret;
|
||||||
|
struct page_table *pt = vm->address_space->page_table;
|
||||||
|
|
||||||
if (proc != cpu_local_var(current)->proc) {
|
ans = 0;
|
||||||
uint64_t reason = PF_POPULATE | PF_WRITE | PF_USER;
|
if(left == 0)
|
||||||
unsigned long offset = r->offset;
|
goto end;
|
||||||
unsigned long left = r->count;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ans = 0;
|
#if 0
|
||||||
if(left == 0)
|
if(!(proc->ptrace & PT_TRACED) ||
|
||||||
goto end;
|
!(proc->status & (PS_STOPPED | PS_TRACED))){
|
||||||
|
ans = -EIO;
|
||||||
while(left){
|
goto end;
|
||||||
unsigned long pa;
|
|
||||||
char *va;
|
|
||||||
int pos = offset & (PAGE_SIZE - 1);
|
|
||||||
int size = PAGE_SIZE - pos;
|
|
||||||
|
|
||||||
if(size > left)
|
|
||||||
size = left;
|
|
||||||
ret = page_fault_process_vm(vm, (void *)offset,
|
|
||||||
reason);
|
|
||||||
if(ret){
|
|
||||||
if(ans == 0)
|
|
||||||
ans = -EIO;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
ret = ihk_mc_pt_virt_to_phys(vm->address_space->page_table,
|
|
||||||
(void *)offset, &pa);
|
|
||||||
if(ret){
|
|
||||||
if(ans == 0)
|
|
||||||
ans = -EIO;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
va = phys_to_virt(pa);
|
|
||||||
memcpy(buf + ans, va, size);
|
|
||||||
offset += size;
|
|
||||||
left -= size;
|
|
||||||
ans += size;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else{
|
#endif
|
||||||
unsigned long offset = r->offset;
|
|
||||||
unsigned long left = r->count;
|
while(left){
|
||||||
unsigned long pos;
|
unsigned long pa;
|
||||||
unsigned long l;
|
char *va;
|
||||||
ans = 0;
|
int pos = offset & (PAGE_SIZE - 1);
|
||||||
list_for_each_entry(range, &vm->vm_range_list, list) {
|
int size = PAGE_SIZE - pos;
|
||||||
dprintf("range: %lx - %lx\n", range->start, range->end);
|
|
||||||
while (left &&
|
if(size > left)
|
||||||
(range->start <= offset) &&
|
size = left;
|
||||||
(offset < range->end)) {
|
ret = page_fault_process_vm(vm, (void *)offset, reason);
|
||||||
pos = offset & (PAGE_SIZE - 1);
|
if(ret){
|
||||||
l = PAGE_SIZE - pos;
|
if(ans == 0)
|
||||||
if(l > left)
|
ans = -EIO;
|
||||||
l = left;
|
goto end;
|
||||||
if(copy_from_user(buf, (void *)offset, l)){
|
|
||||||
if(ans == 0)
|
|
||||||
ans = -EIO;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
buf += l;
|
|
||||||
ans += l;
|
|
||||||
offset += l;
|
|
||||||
left -= l;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ret = ihk_mc_pt_virt_to_phys(pt, (void *)offset, &pa);
|
||||||
|
if(ret){
|
||||||
|
if(ans == 0)
|
||||||
|
ans = -EIO;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
va = phys_to_virt(pa);
|
||||||
|
if(readwrite)
|
||||||
|
memcpy(va, buf + ans, size);
|
||||||
|
else
|
||||||
|
memcpy(buf + ans, va, size);
|
||||||
|
offset += size;
|
||||||
|
left -= size;
|
||||||
|
ans += size;
|
||||||
}
|
}
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user