summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorThorsten Lockert <tholo@cvs.openbsd.org>2001-04-09 07:14:24 +0000
committerThorsten Lockert <tholo@cvs.openbsd.org>2001-04-09 07:14:24 +0000
commit9b1fe5fc1ac937b51295538f4b165a1d9fc9ac95 (patch)
treec6461a4d96f7af1694080600ef5db641bf8ac344 /sys
parent6f2fdb9ba0804df4f105421d41cd208c8b2f1807 (diff)
Add emulation of Linux features to procfs; mostly from NetBSD. ok deraadt@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/i386/conf/files.i3863
-rw-r--r--sys/arch/i386/i386/machdep.c5
-rw-r--r--sys/arch/i386/i386/procfs_machdep.c147
-rw-r--r--sys/arch/i386/isa/npx.c12
-rw-r--r--sys/conf/files3
-rw-r--r--sys/kern/sys_process.c6
-rw-r--r--sys/miscfs/procfs/procfs.h38
-rw-r--r--sys/miscfs/procfs/procfs_fpregs.c5
-rw-r--r--sys/miscfs/procfs/procfs_linux.c140
-rw-r--r--sys/miscfs/procfs/procfs_regs.c5
-rw-r--r--sys/miscfs/procfs/procfs_subr.c13
-rw-r--r--sys/miscfs/procfs/procfs_vfsops.c29
-rw-r--r--sys/miscfs/procfs/procfs_vnops.c142
13 files changed, 513 insertions, 35 deletions
diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386
index 47e9204fac3..bae1525b30b 100644
--- a/sys/arch/i386/conf/files.i386
+++ b/sys/arch/i386/conf/files.i386
@@ -1,4 +1,4 @@
-# $OpenBSD: files.i386,v 1.81 2001/04/07 17:17:27 niklas Exp $
+# $OpenBSD: files.i386,v 1.82 2001/04/09 07:14:14 tholo Exp $
# $NetBSD: files.i386,v 1.73 1996/05/07 00:58:36 thorpej Exp $
#
# new style config file for i386 architecture
@@ -33,6 +33,7 @@ file arch/i386/i386/ns_cksum.c ns
file arch/i386/i386/pmap.c !pmap_old & uvm
file arch/i386/i386/pmap.old.c pmap_old | !uvm
file arch/i386/i386/process_machdep.c
+file arch/i386/i386/procfs_machdep.c procfs
file arch/i386/i386/random.s
file arch/i386/i386/sys_machdep.c
file arch/i386/i386/trap.c
diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c
index 5548dadbe13..500f07d7805 100644
--- a/sys/arch/i386/i386/machdep.c
+++ b/sys/arch/i386/i386/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.154 2001/03/30 22:18:29 mickey Exp $ */
+/* $OpenBSD: machdep.c,v 1.155 2001/04/09 07:14:15 tholo Exp $ */
/* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */
/*-
@@ -248,6 +248,9 @@ int dumpsize = 0; /* pages */
long dumplo = 0; /* blocks */
int cpu_class;
+int i386_fpu_present;
+int i386_fpu_exception;
+int i386_fpu_fdivbug;
bootarg_t *bootargp;
vm_offset_t avail_end;
diff --git a/sys/arch/i386/i386/procfs_machdep.c b/sys/arch/i386/i386/procfs_machdep.c
new file mode 100644
index 00000000000..111b6e082c8
--- /dev/null
+++ b/sys/arch/i386/i386/procfs_machdep.c
@@ -0,0 +1,147 @@
+/* $OpenBSD: procfs_machdep.c,v 1.1 2001/04/09 07:14:16 tholo Exp $ */
+/* $NetBSD: procfs_machdep.c,v 1.6 2001/02/21 21:39:59 jdolecek Exp $ */
+
+/*
+ * Copyright (c) 2001 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Frank van der Linden for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mount.h>
+#include <sys/vnode.h>
+#include <miscfs/procfs/procfs.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/specialreg.h>
+
+extern int i386_fpu_present, i386_fpu_exception, i386_fpu_fdivbug;
+extern int cpu_feature;
+extern char cpu_model[];
+extern char cpu_vendor[];
+extern int cpu_id, cpu_class;
+
+static const char * const i386_features[] = {
+ "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+ "cx8", "apic", "10", "sep", "mtrr", "pge", "mca", "cmov",
+ "fgpat", "pse36", "psn", "19", "20", "21", "22", "mmx",
+ "fxsr", "xmm", "26", "27", "28", "29", "30", "31"
+};
+
+
+/*
+ * Linux-style /proc/cpuinfo.
+ * Only used when procfs is mounted with -o linux.
+ *
+ * In the multiprocessor case, this should be a loop over all CPUs.
+ */
+int
+procfs_getcpuinfstr(char *buf, int *len)
+{
+ int left, l, i;
+ char featurebuf[256], *p;
+
+ p = featurebuf;
+ left = sizeof featurebuf;
+ for (i = 0; i < 32; i++) {
+ if (cpu_feature & (1 << i)) {
+ l = snprintf(p, left, "%s ", i386_features[i]);
+ left -= l;
+ p += l;
+ if (left <= 0)
+ break;
+ }
+ }
+
+ p = buf;
+ left = *len;
+ l = snprintf(p, left,
+ "processor\t: %d\n"
+ "vendor_id\t: %s\n"
+ "cpu family\t: %d\n"
+ "model\t\t: %d\n"
+ "model name\t: %s\n"
+ "stepping\t: ",
+ 0,
+ cpu_vendor,
+ cpuid_level >= 0 ? ((cpu_id >> 8) & 15) : cpu_class + 3,
+ cpuid_level >= 0 ? ((cpu_id >> 4) & 15) : 0,
+ cpu_model
+ );
+
+ left -= l;
+ p += l;
+ if (left <= 0)
+ return 0;
+
+ if (cpuid_level >= 0)
+ l = snprintf(p, left, "%d\n", cpu_id & 15);
+ else
+ l = snprintf(p, left, "unknown\n");
+
+ left -= l;
+ p += l;
+ if (left <= 0)
+ return 0;
+
+
+ if (pentium_mhz != 0)
+ l = snprintf(p, left, "cpu MHz\t\t: %d\n",
+ pentium_mhz);
+ else
+ l = snprintf(p, left, "cpu MHz\t\t: unknown\n");
+
+ left -= l;
+ p += l;
+ if (left <= 0)
+ return 0;
+
+ l = snprintf(p, left,
+ "fdiv_bug\t: %s\n"
+ "fpu\t\t: %s\n"
+ "fpu_exception:\t: %s\n"
+ "cpuid level\t: %d\n"
+ "wp\t\t: %s\n"
+ "flags\t\t: %s\n",
+ i386_fpu_fdivbug ? "yes" : "no",
+ i386_fpu_present ? "yes" : "no",
+ i386_fpu_exception ? "yes" : "no",
+ cpuid_level,
+ (rcr0() & CR0_WP) ? "yes" : "no",
+ featurebuf);
+
+ *len = (p + l) - buf;
+
+ return 0;
+}
diff --git a/sys/arch/i386/isa/npx.c b/sys/arch/i386/isa/npx.c
index 2fc02ddc9c9..2a267fa63c2 100644
--- a/sys/arch/i386/isa/npx.c
+++ b/sys/arch/i386/isa/npx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: npx.c,v 1.17 2000/06/08 22:25:19 niklas Exp $ */
+/* $OpenBSD: npx.c,v 1.18 2001/04/09 07:14:16 tholo Exp $ */
/* $NetBSD: npx.c,v 1.57 1996/05/12 23:12:24 mycroft Exp $ */
#if 0
@@ -144,6 +144,10 @@ static int npx_nointr;
static volatile u_int npx_intrs_while_probing;
static volatile u_int npx_traps_while_probing;
+extern int i386_fpu_present;
+extern int i386_fpu_exception;
+extern int i386_fpu_fdivbug;
+
/*
* Special interrupt handlers. Someday intr0-intr15 will be used to count
* interrupts. We'll still need a special exception 16 handler. The busy
@@ -221,6 +225,7 @@ npxprobe1(ia)
*/
npx_type = NPX_EXCEPTION;
ia->ia_irq = IRQUNK; /* zap the interrupt */
+ i386_fpu_exception = 1;
} else if (npx_intrs_while_probing != 0) {
/*
* Bad, we are stuck with IRQ13.
@@ -354,9 +359,12 @@ npxattach(parent, self, aux)
lcr0(rcr0() & ~(CR0_EM|CR0_TS));
fninit();
- if (npx586bug1(4195835, 3145727) != 0)
+ if (npx586bug1(4195835, 3145727) != 0) {
+ i386_fpu_fdivbug = 1;
printf("WARNING: Pentium FDIV bug detected!\n");
+ }
lcr0(rcr0() | (CR0_TS));
+ i386_fpu_present = 1;
}
/*
diff --git a/sys/conf/files b/sys/conf/files
index a5d10adc8d4..266c1409c03 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,4 +1,4 @@
-# $OpenBSD: files,v 1.194 2001/03/29 01:39:31 aaron Exp $
+# $OpenBSD: files,v 1.195 2001/04/09 07:14:17 tholo Exp $
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@@ -504,6 +504,7 @@ file miscfs/portal/portal_vnops.c portal
file miscfs/procfs/procfs_cmdline.c procfs
file miscfs/procfs/procfs_ctl.c procfs
file miscfs/procfs/procfs_fpregs.c
+file miscfs/procfs/procfs_linux.c procfs
file miscfs/procfs/procfs_mem.c
file miscfs/procfs/procfs_note.c procfs
file miscfs/procfs/procfs_regs.c
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index 696371e28f4..bbe5b104ca3 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_process.c,v 1.9 2000/11/10 15:33:10 provos Exp $ */
+/* $OpenBSD: sys_process.c,v 1.10 2001/04/09 07:14:18 tholo Exp $ */
/* $NetBSD: sys_process.c,v 1.55 1996/05/15 06:17:47 tls Exp $ */
/*-
@@ -338,7 +338,7 @@ sys_ptrace(p, v, retval)
/* write = 0 done above. */
#endif
#if defined(PT_SETREGS) || defined(PT_GETREGS)
- if (!procfs_validregs(t))
+ if (!procfs_validregs(t, NULL))
return (EINVAL);
else {
iov.iov_base = SCARG(uap, addr);
@@ -363,7 +363,7 @@ sys_ptrace(p, v, retval)
/* write = 0 done above. */
#endif
#if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
- if (!procfs_validfpregs(t))
+ if (!procfs_validfpregs(t, NULL))
return (EINVAL);
else {
iov.iov_base = SCARG(uap, addr);
diff --git a/sys/miscfs/procfs/procfs.h b/sys/miscfs/procfs/procfs.h
index aa648a03e42..f59c0d9f6ec 100644
--- a/sys/miscfs/procfs/procfs.h
+++ b/sys/miscfs/procfs/procfs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: procfs.h,v 1.10 2000/08/15 02:44:12 ericj Exp $ */
+/* $OpenBSD: procfs.h,v 1.11 2001/04/09 07:14:21 tholo Exp $ */
/* $NetBSD: procfs.h,v 1.17 1996/02/12 15:01:41 christos Exp $ */
/*
@@ -46,6 +46,7 @@
typedef enum {
Proot, /* the filesystem root */
Pcurproc, /* symbolic link for curproc */
+ Pself, /* like curproc, but this is the Linux name */
Pproc, /* a process-specific sub-directory */
Pfile, /* the executable file */
Pmem, /* the process's memory image */
@@ -55,7 +56,9 @@ typedef enum {
Pstatus, /* process status */
Pnote, /* process notifier */
Pnotepg, /* process group notifier */
- Pcmdline /* process command line args */
+ Pcmdline, /* process command line args */
+ Pmeminfo, /* system memory info (if -o linux) */
+ Pcpuinfo /* CPU info (if -o linux) */
} pfstype;
/*
@@ -74,6 +77,15 @@ struct pfsnode {
#define PROCFS_NOTELEN 64 /* max length of a note (/proc/$pid/note) */
#define PROCFS_CTLLEN 8 /* max length of a ctl msg (/proc/$pid/ctl */
+struct procfs_args {
+ int version;
+ int flags;
+};
+
+#define PROCFS_ARGSVERSION 1
+
+#define PROCFSMNT_LINUXCOMPAT 0x01
+
/*
* Kernel stuff follows
*/
@@ -86,8 +98,15 @@ struct pfsnode {
#define PROCFS_FILENO(pid, type) \
(((type) < Pproc) ? \
- ((type) + 2) : \
- ((((pid)+1) << 4) + ((int) (type))))
+ ((type) + 4) : \
+ ((((pid)+1) << 5) + ((int) (type))))
+
+struct procfsmount {
+ void *pmnt_exechook;
+ int pmnt_flags;
+};
+
+#define VFSTOPROC(mp) ((struct procfsmount *)(mp)->mnt_data)
/*
* Convert between pfsnode vnode
@@ -114,17 +133,22 @@ int procfs_donote __P((struct proc *, struct proc *, struct pfsnode *pfsp, struc
int procfs_doregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
int procfs_docmdline __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
+int procfs_domeminfo __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
+int procfs_docpuinfo __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
+int procfs_domap __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio, int));
struct vnode *procfs_findtextvp __P((struct proc *));
int procfs_freevp __P((struct vnode *));
+int procfs_getcpuinfstr __P((char *, int *));
#if !defined(UVM)
int procfs_rwmem __P((struct proc *, struct uio *));
#endif
/* functions to check whether or not files should be displayed */
-int procfs_validfile __P((struct proc *));
-int procfs_validfpregs __P((struct proc *));
-int procfs_validregs __P((struct proc *));
+int procfs_validfile __P((struct proc *, struct mount *));
+int procfs_validfpregs __P((struct proc *, struct mount *));
+int procfs_validregs __P((struct proc *, struct mount *));
+int procfs_validmap __P((struct proc *, struct mount *));
int procfs_rw __P((void *));
diff --git a/sys/miscfs/procfs/procfs_fpregs.c b/sys/miscfs/procfs/procfs_fpregs.c
index 233d69cb820..db1df77c02e 100644
--- a/sys/miscfs/procfs/procfs_fpregs.c
+++ b/sys/miscfs/procfs/procfs_fpregs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: procfs_fpregs.c,v 1.4 1997/08/29 04:24:37 millert Exp $ */
+/* $OpenBSD: procfs_fpregs.c,v 1.5 2001/04/09 07:14:21 tholo Exp $ */
/* $NetBSD: procfs_fpregs.c,v 1.4 1995/08/13 09:06:05 mycroft Exp $ */
/*
@@ -99,8 +99,9 @@ procfs_dofpregs(curp, p, pfs, uio)
}
int
-procfs_validfpregs(p)
+procfs_validfpregs(p, mp)
struct proc *p;
+ struct mount *mp;
{
#if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
diff --git a/sys/miscfs/procfs/procfs_linux.c b/sys/miscfs/procfs/procfs_linux.c
new file mode 100644
index 00000000000..81428f4baa6
--- /dev/null
+++ b/sys/miscfs/procfs/procfs_linux.c
@@ -0,0 +1,140 @@
+/* $OpenBSD: procfs_linux.c,v 1.1 2001/04/09 07:14:22 tholo Exp $ */
+/* $NetBSD: procfs_linux.c,v 1.2.4.1 2001/03/30 21:48:11 he Exp $ */
+
+/*
+ * Copyright (c) 2001 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Frank van der Linden for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/vnode.h>
+
+#include <miscfs/procfs/procfs.h>
+
+#include <vm/vm.h>
+#include <uvm/uvm_extern.h>
+
+#define PGTOB(p) ((unsigned long)(p) << PAGE_SHIFT)
+#define PGTOKB(p) ((unsigned long)(p) << (PAGE_SHIFT - 10))
+
+/*
+ * Linux compatible /proc/meminfo. Only active when the -o linux
+ * mountflag is used.
+ */
+int
+procfs_domeminfo(struct proc *curp, struct proc *p, struct pfsnode *pfs,
+ struct uio *uio)
+{
+ char buf[512], *cp;
+ int len, error;
+
+ len = snprintf(buf, sizeof buf,
+ " total: used: free: shared: buffers: cached:\n"
+ "Mem: %8lu %8lu %8lu %8lu %8lu %8lu\n"
+ "Swap: %8lu %8lu %8lu\n"
+ "MemTotal: %8lu kB\n"
+ "MemFree: %8lu kB\n"
+ "MemShared: %8lu kB\n"
+ "Buffers: %8lu kB\n"
+ "Cached: %8lu kB\n"
+ "SwapTotal: %8lu kB\n"
+ "SwapFree: %8lu kB\n",
+ PGTOB(uvmexp.npages),
+ PGTOB(uvmexp.npages - uvmexp.free),
+ PGTOB(uvmexp.free),
+ 0L,
+ 0L,
+ 0L,
+ PGTOB(uvmexp.swpages),
+ PGTOB(uvmexp.swpginuse),
+ PGTOB(uvmexp.swpages - uvmexp.swpginuse),
+ PGTOKB(uvmexp.npages),
+ PGTOKB(uvmexp.free),
+ 0L,
+ 0L,
+ 0L,
+ PGTOKB(uvmexp.swpages),
+ PGTOKB(uvmexp.swpages - uvmexp.swpginuse));
+
+ if (len == 0)
+ return 0;
+
+ len -= uio->uio_offset;
+ cp = buf + uio->uio_offset;
+ len = imin(len, uio->uio_resid);
+ if (len <= 0)
+ error = 0;
+ else
+ error = uiomove(cp, len, uio);
+ return error;
+}
+
+int
+procfs_docpuinfo(struct proc *curp, struct proc *p, struct pfsnode *pfs,
+ struct uio *uio)
+{
+ char buf[512], *cp;
+ int len, error;
+
+ len = sizeof buf;
+ if (procfs_getcpuinfstr(buf, &len) < 0)
+ return EIO;
+
+ if (len == 0)
+ return 0;
+
+ len -= uio->uio_offset;
+ cp = buf + uio->uio_offset;
+ len = imin(len, uio->uio_resid);
+ if (len <= 0)
+ error = 0;
+ else
+ error = uiomove(cp, len, uio);
+ return error;
+}
+
+#ifndef __i386__
+int
+procfs_getcpuinfstr(buf, len)
+ char *buf;
+ int *len;
+{
+ *len = 0;
+
+ return 0;
+}
+#endif
diff --git a/sys/miscfs/procfs/procfs_regs.c b/sys/miscfs/procfs/procfs_regs.c
index ab86dd7b1ec..3bbbd12fc76 100644
--- a/sys/miscfs/procfs/procfs_regs.c
+++ b/sys/miscfs/procfs/procfs_regs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: procfs_regs.c,v 1.4 1997/08/29 04:24:38 millert Exp $ */
+/* $OpenBSD: procfs_regs.c,v 1.5 2001/04/09 07:14:22 tholo Exp $ */
/* $NetBSD: procfs_regs.c,v 1.9 1995/08/13 09:06:07 mycroft Exp $ */
/*
@@ -99,8 +99,9 @@ procfs_doregs(curp, p, pfs, uio)
}
int
-procfs_validregs(p)
+procfs_validregs(p, mp)
struct proc *p;
+ struct mount *mp;
{
#if defined(PT_SETREGS) || defined(PT_GETREGS)
diff --git a/sys/miscfs/procfs/procfs_subr.c b/sys/miscfs/procfs/procfs_subr.c
index 2c98efb0a8b..70fac2de646 100644
--- a/sys/miscfs/procfs/procfs_subr.c
+++ b/sys/miscfs/procfs/procfs_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: procfs_subr.c,v 1.12 2000/08/12 04:29:24 jasoni Exp $ */
+/* $OpenBSD: procfs_subr.c,v 1.13 2001/04/09 07:14:23 tholo Exp $ */
/* $NetBSD: procfs_subr.c,v 1.15 1996/02/12 15:01:42 christos Exp $ */
/*
@@ -147,6 +147,7 @@ loop:
break;
case Pcurproc: /* /proc/curproc = lr--r--r-- */
+ case Pself: /* /proc/self = lr--r--r-- */
pfs->pfs_mode = S_IRUSR|S_IRGRP|S_IROTH;
vp->v_type = VLNK;
break;
@@ -172,7 +173,9 @@ loop:
break;
case Pstatus: /* /proc/N/status = -r--r--r-- */
- case Pcmdline:
+ case Pcmdline: /* /proc/N/cmdline = -r--r--r-- */
+ case Pmeminfo: /* /proc/meminfo = -r--r--r-- */
+ case Pcpuinfo: /* /proc/cpuinfo = -r--r--r-- */
pfs->pfs_mode = S_IRUSR|S_IRGRP|S_IROTH;
vp->v_type = VREG;
break;
@@ -248,6 +251,12 @@ procfs_rw(v)
case Pcmdline:
return (procfs_docmdline(curp, p, pfs, uio));
+ case Pmeminfo:
+ return (procfs_domeminfo(curp, p, pfs, uio));
+
+ case Pcpuinfo:
+ return (procfs_docpuinfo(curp, p, pfs, uio));
+
default:
return (EOPNOTSUPP);
}
diff --git a/sys/miscfs/procfs/procfs_vfsops.c b/sys/miscfs/procfs/procfs_vfsops.c
index 287138795e0..9c1601ca502 100644
--- a/sys/miscfs/procfs/procfs_vfsops.c
+++ b/sys/miscfs/procfs/procfs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: procfs_vfsops.c,v 1.12 2001/02/20 01:50:10 assar Exp $ */
+/* $OpenBSD: procfs_vfsops.c,v 1.13 2001/04/09 07:14:23 tholo Exp $ */
/* $NetBSD: procfs_vfsops.c,v 1.25 1996/02/09 22:40:53 christos Exp $ */
/*
@@ -54,7 +54,10 @@
#include <sys/mount.h>
#include <sys/signalvar.h>
#include <sys/vnode.h>
+#include <sys/malloc.h>
+
#include <miscfs/procfs/procfs.h>
+
#include <vm/vm.h> /* for PAGE_SIZE */
#if defined(UVM)
@@ -81,6 +84,9 @@ procfs_mount(mp, path, data, ndp, p)
struct proc *p;
{
size_t size;
+ struct procfsmount *pmnt;
+ struct procfs_args args;
+ int error;
if (UIO_MX & (UIO_MX-1)) {
log(LOG_ERR, "procfs: invalid directory entry size");
@@ -90,14 +96,33 @@ procfs_mount(mp, path, data, ndp, p)
if (mp->mnt_flag & MNT_UPDATE)
return (EOPNOTSUPP);
+ if (data != NULL) {
+ error = copyin(data, &args, sizeof args);
+ if (error != 0)
+ return (error);
+
+ if (args.version != PROCFS_ARGSVERSION)
+ return (EINVAL);
+ } else
+ args.flags = 0;
+
mp->mnt_flag |= MNT_LOCAL;
- mp->mnt_data = 0;
+ pmnt = (struct procfsmount *) malloc(sizeof(struct procfsmount),
+ M_UFSMNT, M_WAITOK); /* XXX need new malloc type */
+
+ mp->mnt_data = (qaddr_t)pmnt;
vfs_getnewfsid(mp);
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
bcopy("procfs", mp->mnt_stat.f_mntfromname, sizeof("procfs"));
+
+#ifdef notyet
+ pmnt->pmnt_exechook = exechook_establish(procfs_revoke_vnodes, mp);
+#endif
+ pmnt->pmnt_flags = args.flags;
+
return (0);
}
diff --git a/sys/miscfs/procfs/procfs_vnops.c b/sys/miscfs/procfs/procfs_vnops.c
index 1b70e078403..5e24637a1df 100644
--- a/sys/miscfs/procfs/procfs_vnops.c
+++ b/sys/miscfs/procfs/procfs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: procfs_vnops.c,v 1.15 2000/08/12 04:29:24 jasoni Exp $ */
+/* $OpenBSD: procfs_vnops.c,v 1.16 2001/04/09 07:14:23 tholo Exp $ */
/* $NetBSD: procfs_vnops.c,v 1.40 1996/03/16 23:52:55 christos Exp $ */
/*
@@ -50,6 +50,7 @@
#include <sys/kernel.h>
#include <sys/file.h>
#include <sys/proc.h>
+#include <sys/mount.h>
#include <sys/vnode.h>
#include <sys/namei.h>
#include <sys/malloc.h>
@@ -68,6 +69,7 @@
* Vnode Operations.
*
*/
+static int procfs_validfile_linux __P((struct proc *, struct mount *));
/*
* This is a list of the valid names in the
@@ -79,7 +81,7 @@ struct proc_target {
u_char pt_namlen;
char *pt_name;
pfstype pt_pfstype;
- int (*pt_valid) __P((struct proc *p));
+ int (*pt_valid) __P((struct proc *p, struct mount *mp));
} proc_targets[] = {
#define N(s) sizeof(s)-1, s
/* name type validp */
@@ -94,10 +96,25 @@ struct proc_target {
{ DT_REG, N("note"), Pnote, NULL },
{ DT_REG, N("notepg"), Pnotepg, NULL },
{ DT_REG, N("cmdline"), Pcmdline, NULL },
+ { DT_REG, N("exe"), Pfile, procfs_validfile_linux },
#undef N
};
static int nproc_targets = sizeof(proc_targets) / sizeof(proc_targets[0]);
+/*
+ * List of files in the root directory. Note: the validate function
+ * will be called with p == NULL for these
+ */
+struct proc_target proc_root_targets[] = {
+#define N(s) sizeof(s)-1, s
+ /* name type validp */
+ { DT_REG, N("meminfo"), Pmeminfo, procfs_validfile_linux },
+ { DT_REG, N("cpuinfo"), Pcpuinfo, procfs_validfile_linux },
+#undef N
+};
+static int nproc_root_targets =
+ sizeof(proc_root_targets) / sizeof(proc_root_targets[0]);
+
static pid_t atopid __P((const char *, u_int));
/*
@@ -275,11 +292,14 @@ procfs_close(v)
case Pnote:
case Proot:
case Pcurproc:
+ case Pself:
case Pproc:
case Pfile:
case Pregs:
case Pfpregs:
case Pcmdline:
+ case Pmeminfo:
+ case Pcpuinfo:
break;
}
@@ -507,6 +527,8 @@ procfs_getattr(v)
switch (pfs->pfs_type) {
case Proot:
case Pcurproc:
+ case Pcpuinfo:
+ case Pmeminfo:
procp = 0;
break;
@@ -562,10 +584,16 @@ procfs_getattr(v)
vap->va_uid = procp->p_ucred->cr_uid;
vap->va_gid = procp->p_ucred->cr_gid;
break;
+ case Pmeminfo:
+ case Pcpuinfo:
+ vap->va_nlink = 1;
+ vap->va_uid = vap->va_gid = 0;
+ break;
case Pproc:
case Pfile:
case Proot:
case Pcurproc:
+ case Pself:
break;
}
@@ -600,6 +628,13 @@ procfs_getattr(v)
break;
}
+ case Pself:
+ vap->va_nlink = 1;
+ vap->va_uid = 0;
+ vap->va_gid = 0;
+ vap->va_size = vap->va_bytes = sizeof("curproc");
+ break;
+
case Pproc:
vap->va_nlink = 2;
vap->va_uid = procp->p_ucred->cr_uid;
@@ -635,6 +670,8 @@ procfs_getattr(v)
case Pnote:
case Pnotepg:
case Pcmdline:
+ case Pmeminfo:
+ case Pcpuinfo:
vap->va_bytes = vap->va_size = 0;
break;
@@ -719,7 +756,7 @@ procfs_lookup(v)
pid_t pid;
struct pfsnode *pfs;
struct proc *p;
- int i;
+ int i, error, iscurproc = 0, isself = 0;
*vpp = NULL;
@@ -739,8 +776,41 @@ procfs_lookup(v)
if (cnp->cn_flags & ISDOTDOT)
return (EIO);
- if (CNEQ(cnp, "curproc", 7))
- return (procfs_allocvp(dvp->v_mount, vpp, 0, Pcurproc));
+ iscurproc = CNEQ(cnp, "curproc", 7);
+ isself = CNEQ(cnp, "self", 4);
+
+ if (iscurproc || isself) {
+ error = procfs_allocvp(dvp->v_mount, vpp, 0,
+ iscurproc ? Pcurproc : Pself);
+#if 0
+ if ((error == 0) && (wantpunlock)) {
+ VOP_UNLOCK(dvp, 0);
+ cnp->cn_flags |= PDIRUNLOCK;
+ }
+#endif
+ return (error);
+ }
+
+ for (i = 0; i < nproc_root_targets; i++) {
+ pt = &proc_root_targets[i];
+ if (cnp->cn_namelen == pt->pt_namlen &&
+ memcmp(pt->pt_name, pname, cnp->cn_namelen) == 0 &&
+ (pt->pt_valid == NULL ||
+ (*pt->pt_valid)(p, dvp->v_mount)))
+ break;
+ }
+
+ if (i != nproc_root_targets) {
+ error = procfs_allocvp(dvp->v_mount, vpp, 0,
+ pt->pt_pfstype);
+#if 0
+ if ((error == 0) && (wantpunlock)) {
+ VOP_UNLOCK(dvp, 0);
+ cnp->cn_flags |= PDIRUNLOCK;
+ }
+#endif
+ return (error);
+ }
pid = atopid(pname, cnp->cn_namelen);
if (pid == NO_PID)
@@ -763,7 +833,8 @@ procfs_lookup(v)
for (pt = proc_targets, i = 0; i < nproc_targets; pt++, i++) {
if (cnp->cn_namelen == pt->pt_namlen &&
bcmp(pt->pt_name, pname, cnp->cn_namelen) == 0 &&
- (pt->pt_valid == NULL || (*pt->pt_valid)(p)))
+ (pt->pt_valid == NULL ||
+ (*pt->pt_valid)(p, dvp->v_mount)))
goto found;
}
break;
@@ -789,13 +860,26 @@ procfs_lookup(v)
}
int
-procfs_validfile(p)
+procfs_validfile(p, mp)
struct proc *p;
+ struct mount *mp;
{
return (procfs_findtextvp(p) != NULLVP);
}
+int
+procfs_validfile_linux(p, mp)
+ struct proc *p;
+ struct mount *mp;
+{
+ int flags;
+
+ flags = VFSTOPROC(mp)->pmnt_flags;
+ return ((flags & PROCFSMNT_LINUXCOMPAT) &&
+ (p == NULL || procfs_validfile(p, mp)));
+}
+
/*
* readdir returns directory entries from pfsnode (vp).
*
@@ -823,10 +907,12 @@ procfs_readdir(v)
struct uio *uio = ap->a_uio;
struct dirent d;
struct pfsnode *pfs;
+ struct vnode *vp;
int i;
int error;
- pfs = VTOPFS(ap->a_vp);
+ vp = ap->a_vp;
+ pfs = VTOPFS(vp);
if (uio->uio_resid < UIO_MX)
return (EINVAL);
@@ -854,7 +940,8 @@ procfs_readdir(v)
for (pt = &proc_targets[i];
uio->uio_resid >= UIO_MX && i < nproc_targets; pt++, i++) {
- if (pt->pt_valid && (*pt->pt_valid)(p) == 0)
+ if (pt->pt_valid &&
+ (*pt->pt_valid)(p, vp->v_mount) == 0)
continue;
d.d_fileno = PROCFS_FILENO(pfs->pfs_pid, pt->pt_pfstype);
@@ -908,6 +995,35 @@ procfs_readdir(v)
d.d_type = DT_LNK;
break;
+ case 3:
+ d.d_fileno = PROCFS_FILENO(0, Pself);
+ d.d_namlen = 4;
+ bcopy("self", d.d_name, 5);
+ d.d_type = DT_LNK;
+ break;
+
+ case 4:
+ if (VFSTOPROC(vp->v_mount)->pmnt_flags &
+ PROCFSMNT_LINUXCOMPAT) {
+ d.d_fileno = PROCFS_FILENO(0, Pcpuinfo);
+ d.d_namlen = 7;
+ bcopy("cpuinfo", d.d_name, 8);
+ d.d_type = DT_REG;
+ break;
+ }
+ /* fall through */
+
+ case 5:
+ if (VFSTOPROC(vp->v_mount)->pmnt_flags &
+ PROCFSMNT_LINUXCOMPAT) {
+ d.d_fileno = PROCFS_FILENO(0, Pmeminfo);
+ d.d_namlen = 7;
+ bcopy("meminfo", d.d_name, 8);
+ d.d_type = DT_REG;
+ break;
+ }
+ /* fall through */
+
default:
while (pcnt < i) {
pcnt++;
@@ -960,11 +1076,13 @@ procfs_readlink(v)
char buf[16]; /* should be enough */
int len;
- if (VTOPFS(ap->a_vp)->pfs_fileno != PROCFS_FILENO(0, Pcurproc))
+ if (VTOPFS(ap->a_vp)->pfs_fileno == PROCFS_FILENO(0, Pcurproc))
+ len = sprintf(buf, "%ld", (long)curproc->p_pid);
+ else if (VTOPFS(ap->a_vp)->pfs_fileno == PROCFS_FILENO(0, Pself))
+ len = sprintf(buf, "%s", "curproc");
+ else
return (EINVAL);
- len = sprintf(buf, "%ld", (long)curproc->p_pid);
-
return (uiomove((caddr_t)buf, len, ap->a_uio));
}