diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/i386/conf/files.i386 | 3 | ||||
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 5 | ||||
-rw-r--r-- | sys/arch/i386/i386/procfs_machdep.c | 147 | ||||
-rw-r--r-- | sys/arch/i386/isa/npx.c | 12 | ||||
-rw-r--r-- | sys/conf/files | 3 | ||||
-rw-r--r-- | sys/kern/sys_process.c | 6 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs.h | 38 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_fpregs.c | 5 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_linux.c | 140 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_regs.c | 5 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_subr.c | 13 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_vfsops.c | 29 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_vnops.c | 142 |
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)); } |