[PATCH] /proc/*/mem ioctl(2)

Richard Gooch (Richard.Gooch@atnf.CSIRO.AU)
Mon, 20 Jul 1998 15:21:58 +1000


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