Messages in this thread Patch in this message | | | Date | Mon, 20 Jul 1998 15:21:58 +1000 | From | Richard Gooch <> | Subject | [PATCH] /proc/*/mem ioctl(2) |
| |
Hi, all. I've written another patch which defines an ioctl(2) for /proc/*/mem rather than defining the phys_addr(2) syscall. Thanks to Mitchell Blank Jr <mitch@execpc.com> for pointing out /proc/self/mem when I objected to /dev/mem (/dev/mem is not accessible to everyone whereas /proc/self/mem is accessible to the owning process).
This patch has the advantage of only needing the interface in one place, rather than a syscall for each architecture. Also, it has the added benefit of allowing you to do virtual->physical translations on processes you are tracing. Who knows, someone may figure a cunning use for this.
Anyway, for those who missed the original patch, the reason I've written this is to allow my memory tester to print the physical address of a bad page.
Comments welcome. Patch against 2.1.110-pre2 below.
Regards,
Richard....
diff -urN linux-2.1.110-pre2/fs/proc/mem.c linux/fs/proc/mem.c --- linux-2.1.110-pre2/fs/proc/mem.c Thu Apr 2 10:23:13 1998 +++ linux/fs/proc/mem.c Mon Jul 20 14:36:12 1998 @@ -307,13 +307,53 @@ return 0; } +static int mem_ioctl (struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + unsigned long addr; + pte_t *pte; + struct task_struct *tsk; + + switch (cmd) + { + case PROC_PID_MEM_PHYS_ADDR: + /* Need to be careful: unlock the tasklist in every return path */ + read_lock(&tasklist_lock); + tsk = get_task(inode->i_ino >> 16); + if (!tsk) + { + read_unlock(&tasklist_lock); + return -ESRCH; + } + if ( copy_from_user (&addr, (void *) arg, sizeof addr) ) + { + read_unlock(&tasklist_lock); + return -EFAULT; + } + pte = pte_offset (pmd_offset (pgd_offset (tsk->mm, addr), addr), addr); + if ( !pte_present (*pte) ) + { + read_unlock(&tasklist_lock); + return -EINVAL; + } + addr = __pa (pte_page (*pte)) + (addr & (PAGE_SIZE-1)); + read_unlock(&tasklist_lock); + return copy_to_user ( (void *) arg, &addr, sizeof addr ) ? -EFAULT : 0; + break; + default: + return -ENOIOCTLCMD; + break; + } + return 0; +} /* End Function mem_ioctl */ + static struct file_operations proc_mem_operations = { mem_lseek, mem_read, mem_write, NULL, /* mem_readdir */ NULL, /* mem_poll */ - NULL, /* mem_ioctl */ + mem_ioctl, mem_mmap, /* mmap */ NULL, /* no special open code */ NULL, /* no special release code */ diff -urN linux-2.1.110-pre2/include/linux/proc_fs.h linux/include/linux/proc_fs.h --- linux-2.1.110-pre2/include/linux/proc_fs.h Mon Jul 20 13:49:56 1998 +++ linux/include/linux/proc_fs.h Mon Jul 20 14:33:31 1998 @@ -74,6 +74,10 @@ PROC_PID_CPU, }; +#define PROC_PID_MEM_IOCTL_BASE 'm' +#define PROC_PID_MEM_PHYS_ADDR _IOWR(PROC_PID_MEM_IOCTL_BASE, 0, void *) + + enum pid_subdirectory_inos { PROC_PID_FD_DIR = 0x8000, /* 0x8000-0xffff */ }; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html
| |