|
|
1.1 ! root 1: /* ! 2: * linux/fs/proc/mem.c ! 3: * ! 4: * Copyright (C) 1991, 1992 Linus Torvalds ! 5: */ ! 6: ! 7: #include <linux/types.h> ! 8: #include <linux/errno.h> ! 9: #include <linux/sched.h> ! 10: #include <linux/kernel.h> ! 11: ! 12: #include <asm/segment.h> ! 13: #include <asm/io.h> ! 14: ! 15: static int mem_read(struct inode * inode, struct file * file,char * buf, int count) ! 16: { ! 17: unsigned long addr, pid, cr3; ! 18: char *tmp; ! 19: unsigned long pde, pte, page; ! 20: int i; ! 21: ! 22: if (count < 0) ! 23: return -EINVAL; ! 24: pid = inode->i_ino; ! 25: pid >>= 16; ! 26: cr3 = 0; ! 27: for (i = 1 ; i < NR_TASKS ; i++) ! 28: if (task[i] && task[i]->pid == pid) { ! 29: cr3 = task[i]->tss.cr3; ! 30: break; ! 31: } ! 32: if (!cr3) ! 33: return -EACCES; ! 34: addr = file->f_pos; ! 35: tmp = buf; ! 36: while (count > 0) { ! 37: if (current->signal & ~current->blocked) ! 38: break; ! 39: pde = cr3 + (addr >> 20 & 0xffc); ! 40: pte = *(unsigned long *) pde; ! 41: if (!(pte & PAGE_PRESENT)) ! 42: break; ! 43: pte &= 0xfffff000; ! 44: pte += (addr >> 10) & 0xffc; ! 45: page = *(unsigned long *) pte; ! 46: if (!(page & 1)) ! 47: break; ! 48: page &= 0xfffff000; ! 49: page += addr & 0xfff; ! 50: i = 4096-(addr & 0xfff); ! 51: if (i > count) ! 52: i = count; ! 53: memcpy_tofs(tmp,(void *) page,i); ! 54: addr += i; ! 55: tmp += i; ! 56: count -= i; ! 57: } ! 58: file->f_pos = addr; ! 59: return tmp-buf; ! 60: } ! 61: ! 62: static int mem_write(struct inode * inode, struct file * file,char * buf, int count) ! 63: { ! 64: unsigned long addr, pid, cr3; ! 65: char *tmp; ! 66: unsigned long pde, pte, page; ! 67: int i; ! 68: ! 69: if (count < 0) ! 70: return -EINVAL; ! 71: addr = file->f_pos; ! 72: pid = inode->i_ino; ! 73: pid >>= 16; ! 74: cr3 = 0; ! 75: for (i = 1 ; i < NR_TASKS ; i++) ! 76: if (task[i] && task[i]->pid == pid) { ! 77: cr3 = task[i]->tss.cr3; ! 78: break; ! 79: } ! 80: if (!cr3) ! 81: return -EACCES; ! 82: tmp = buf; ! 83: while (count > 0) { ! 84: if (current->signal & ~current->blocked) ! 85: break; ! 86: pde = cr3 + (addr >> 20 & 0xffc); ! 87: pte = *(unsigned long *) pde; ! 88: if (!(pte & PAGE_PRESENT)) ! 89: break; ! 90: pte &= 0xfffff000; ! 91: pte += (addr >> 10) & 0xffc; ! 92: page = *(unsigned long *) pte; ! 93: if (!(page & PAGE_PRESENT)) ! 94: break; ! 95: if (!(page & 2)) { ! 96: do_wp_page(0,addr,current,0); ! 97: continue; ! 98: } ! 99: page &= 0xfffff000; ! 100: page += addr & 0xfff; ! 101: i = 4096-(addr & 0xfff); ! 102: if (i > count) ! 103: i = count; ! 104: memcpy_fromfs((void *) page,tmp,i); ! 105: addr += i; ! 106: tmp += i; ! 107: count -= i; ! 108: } ! 109: file->f_pos = addr; ! 110: if (tmp != buf) ! 111: return tmp-buf; ! 112: if (current->signal & ~current->blocked) ! 113: return -ERESTARTSYS; ! 114: return 0; ! 115: } ! 116: ! 117: static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int orig) ! 118: { ! 119: switch (orig) { ! 120: case 0: ! 121: file->f_pos = offset; ! 122: return file->f_pos; ! 123: case 1: ! 124: file->f_pos += offset; ! 125: return file->f_pos; ! 126: default: ! 127: return -EINVAL; ! 128: } ! 129: if (file->f_pos < 0) ! 130: return 0; ! 131: return file->f_pos; ! 132: } ! 133: ! 134: static struct file_operations proc_mem_operations = { ! 135: mem_lseek, ! 136: mem_read, ! 137: mem_write, ! 138: NULL, /* mem_readdir */ ! 139: NULL, /* mem_select */ ! 140: NULL, /* mem_ioctl */ ! 141: NULL, /* no special open code */ ! 142: NULL /* no special release code */ ! 143: }; ! 144: ! 145: struct inode_operations proc_mem_inode_operations = { ! 146: &proc_mem_operations, /* default base directory file-ops */ ! 147: NULL, /* create */ ! 148: NULL, /* lookup */ ! 149: NULL, /* link */ ! 150: NULL, /* unlink */ ! 151: NULL, /* symlink */ ! 152: NULL, /* mkdir */ ! 153: NULL, /* rmdir */ ! 154: NULL, /* mknod */ ! 155: NULL, /* rename */ ! 156: NULL, /* readlink */ ! 157: NULL, /* follow_link */ ! 158: NULL, /* bmap */ ! 159: NULL /* truncate */ ! 160: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.