From 3919ced024a76c74c494480a2ec2188cce7c06aa Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sun, 13 Dec 2009 12:19:30 -0800 Subject: [PATCH] kernel - Move MP lock inward, plus misc other stuff * Remove the MPSAFE flag from the syscalls.master file. All system calls are now called without the MP lock held and will acquire the MP lock if necessary. * Shift the MP lock inward. Try to leave most copyin/copyout operations outside the MP lock. Reorder some of the copyouts in the linux emulation code to suit. Kernel resource operations are MP safe. Process ucred access is now outside the MP lock but not quite MP safe yet (will be fixed in a followup). * Remove unnecessary KKASSERT(p) calls left over from the time before system calls where prefixed with sys_* * Fix a bunch of cases in the linux emulation code when setting groups where the ngrp range check is incorrect. --- lib/libc/i386/sys/Makefile.inc | 2 +- sys/emulation/43bsd/43bsd_exit.c | 2 + sys/emulation/43bsd/43bsd_file.c | 27 +- sys/emulation/43bsd/43bsd_hostinfo.c | 33 +- sys/emulation/43bsd/43bsd_resource.c | 6 + sys/emulation/43bsd/43bsd_signal.c | 22 +- sys/emulation/43bsd/43bsd_socket.c | 42 ++ sys/emulation/43bsd/43bsd_stats.c | 15 + sys/emulation/43bsd/43bsd_vm.c | 11 + sys/emulation/dragonfly12/dfbsd12_getdirentries.c | 15 +- sys/emulation/dragonfly12/dfbsd12_stat.c | 27 +- sys/emulation/linux/i386/linux_machdep.c | 125 ++++-- sys/emulation/linux/i386/linux_proto.h | 2 - sys/emulation/linux/i386/linux_ptrace.c | 6 + sys/emulation/linux/i386/linux_syscall.h | 2 - sys/emulation/linux/i386/linux_sysent.c | 2 - sys/emulation/linux/i386/linux_sysvec.c | 4 + sys/emulation/linux/i386/linux_union.h | 2 - sys/emulation/linux/linux_file.c | 155 ++++++- sys/emulation/linux/linux_getcwd.c | 5 +- sys/emulation/linux/linux_ioctl.c | 12 +- sys/emulation/linux/linux_ipc.c | 52 ++- sys/emulation/linux/linux_misc.c | 152 +++++-- sys/emulation/linux/linux_signal.c | 45 +- sys/emulation/linux/linux_socket.c | 6 + sys/emulation/linux/linux_stats.c | 70 ++- sys/emulation/linux/linux_sysctl.c | 32 +- sys/emulation/linux/linux_uid16.c | 60 ++- sys/kern/imgact_resident.c | 18 +- sys/kern/init_sysent.c | 82 ++-- sys/kern/kern_acct.c | 10 +- sys/kern/kern_acl.c | 36 ++ sys/kern/kern_checkpoint.c | 18 +- sys/kern/kern_descrip.c | 17 +- sys/kern/kern_event.c | 15 +- sys/kern/kern_exec.c | 7 +- sys/kern/kern_exit.c | 50 ++- sys/kern/kern_fork.c | 25 +- sys/kern/kern_jail.c | 13 +- sys/kern/kern_ktrace.c | 15 +- sys/kern/kern_linker.c | 51 ++- sys/kern/kern_module.c | 60 ++- sys/kern/kern_ntptime.c | 5 + sys/kern/kern_p1003_1b.c | 61 ++- sys/kern/kern_prot.c | 391 +++++++++++------ sys/kern/kern_resource.c | 168 ++++++-- sys/kern/kern_sched.c | 57 ++- sys/kern/kern_shutdown.c | 4 + sys/kern/kern_sig.c | 63 ++- sys/kern/kern_synch.c | 2 + sys/kern/kern_sysctl.c | 5 + sys/kern/kern_syslink.c | 5 + sys/kern/kern_systimer.c | 5 + sys/kern/kern_threads.c | 5 + sys/kern/kern_time.c | 72 +++- sys/kern/kern_umtx.c | 25 +- sys/kern/kern_upcall.c | 11 + sys/kern/kern_usched.c | 48 ++- sys/kern/kern_uuid.c | 4 + sys/kern/kern_varsym.c | 14 + sys/kern/kern_xxx.c | 61 ++- sys/kern/lwkt_caps.c | 184 +++++--- sys/kern/makesyscalls.sh | 30 +- sys/kern/subr_prof.c | 28 +- sys/kern/sys_generic.c | 29 +- sys/kern/sys_pipe.c | 6 +- sys/kern/sys_process.c | 4 + sys/kern/syscalls.c | 4 +- sys/kern/syscalls.master | 89 ++-- sys/kern/sysv_msg.c | 171 +++++--- sys/kern/sysv_sem.c | 221 ++++++---- sys/kern/sysv_shm.c | 178 +++++--- sys/kern/uipc_syscalls.c | 98 ++++- sys/kern/usched_bsd4.c | 3 + sys/kern/usched_dummy.c | 3 + sys/kern/vfs_aio.c | 261 +++++++---- sys/kern/vfs_cache.c | 5 + sys/kern/vfs_syscalls.c | 501 +++++++++++++++++----- sys/netproto/ncp/ncp_mod.c | 57 ++- sys/platform/pc32/i386/machdep.c | 4 + sys/platform/pc32/i386/sys_machdep.c | 6 +- sys/platform/pc32/i386/trap.c | 10 +- sys/platform/pc64/x86_64/machdep.c | 4 + sys/platform/pc64/x86_64/tls.c | 2 + sys/platform/pc64/x86_64/trap.c | 10 +- sys/platform/vkernel/i386/cpu_regs.c | 4 + sys/platform/vkernel/i386/trap.c | 10 +- sys/sys/syscall.h | 2 - sys/sys/syscall.mk | 2 - sys/sys/sysent.h | 1 - sys/sys/sysproto.h | 14 - sys/sys/sysunion.h | 2 - sys/vfs/nfs/nfs_syscalls.c | 33 +- sys/vm/vm_mmap.c | 147 +++++-- sys/vm/vm_swap.c | 16 +- sys/vm/vm_unix.c | 39 +- sys/vm/vm_vmspace.c | 233 +++++++--- 97 files changed, 3536 insertions(+), 1232 deletions(-) diff --git a/lib/libc/i386/sys/Makefile.inc b/lib/libc/i386/sys/Makefile.inc index 28311af383..d7f023bae3 100644 --- a/lib/libc/i386/sys/Makefile.inc +++ b/lib/libc/i386/sys/Makefile.inc @@ -13,7 +13,7 @@ NOASM= __semctl.o break.o exit.o ftruncate.o getdomainname.o getlogin.o \ lseek.o mlockall.o mmap.o msgctl.o msgget.o msgrcv.o msgsnd.o \ munlockall.o openbsd_poll.o semconfig.o semget.o \ semop.o setdomainname.o shmat.o shmctl.o shmdt.o shmget.o sstk.o \ - thr_sleep.o thr_wakeup.o truncate.o uname.o vfork.o yield.o + truncate.o uname.o vfork.o yield.o PSEUDO= _getlogin.o _exit.o diff --git a/sys/emulation/43bsd/43bsd_exit.c b/sys/emulation/43bsd/43bsd_exit.c index 838b06e051..305c798755 100644 --- a/sys/emulation/43bsd/43bsd_exit.c +++ b/sys/emulation/43bsd/43bsd_exit.c @@ -59,6 +59,8 @@ * owait() * * owait_args(int dummy) + * + * MPSAFE */ int sys_owait(struct owait_args *uap) diff --git a/sys/emulation/43bsd/43bsd_file.c b/sys/emulation/43bsd/43bsd_file.c index 3609f9bf89..d39b3ffa9b 100644 --- a/sys/emulation/43bsd/43bsd_file.c +++ b/sys/emulation/43bsd/43bsd_file.c @@ -65,51 +65,69 @@ #include +/* + * MPALMOSTSAFE + */ int sys_ocreat(struct ocreat_args *uap) { struct nlookupdata nd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) { error = kern_open(&nd, O_WRONLY | O_CREAT | O_TRUNC, uap->mode, &uap->sysmsg_iresult); } + rel_mplock(); return (error); } +/* + * MPALMOSTSAFE + */ int sys_oftruncate(struct oftruncate_args *uap) { int error; + get_mplock(); error = kern_ftruncate(uap->fd, uap->length); + rel_mplock(); return (error); } +/* + * MPSAFE + */ int sys_olseek(struct olseek_args *uap) { int error; error = kern_lseek(uap->fd, uap->offset, uap->whence, - &uap->sysmsg_offset); + &uap->sysmsg_offset); return (error); } +/* + * MPALMOSTSAFE + */ int sys_otruncate(struct otruncate_args *uap) { struct nlookupdata nd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = kern_truncate(&nd, uap->length); nlookup_done(&nd); + rel_mplock(); return (error); } @@ -125,6 +143,9 @@ struct odirent { char od_name[]; }; +/* + * MPALMOSTSAFE + */ int sys_ogetdirentries(struct ogetdirentries_args *uap) { @@ -142,8 +163,10 @@ sys_ogetdirentries(struct ogetdirentries_args *uap) buf = kmalloc(len, M_TEMP, M_WAITOK); + get_mplock(); error = kern_getdirentries(uap->fd, buf, len, - &base, &bytes_transfered, UIO_SYSSPACE); + &base, &bytes_transfered, UIO_SYSSPACE); + rel_mplock(); if (error) { kfree(buf, M_TEMP); diff --git a/sys/emulation/43bsd/43bsd_hostinfo.c b/sys/emulation/43bsd/43bsd_hostinfo.c index 4bfb08c7ea..a9e4a572d9 100644 --- a/sys/emulation/43bsd/43bsd_hostinfo.c +++ b/sys/emulation/43bsd/43bsd_hostinfo.c @@ -51,6 +51,9 @@ #include #include +/* + * MPALMOSTSAFE + */ int sys_ogethostname(struct gethostname_args *uap) { @@ -63,7 +66,9 @@ sys_ogethostname(struct gethostname_args *uap) len = MIN(uap->len, MAXHOSTNAMELEN); hostname = kmalloc(MAXHOSTNAMELEN, M_TEMP, M_WAITOK); + get_mplock(); error = kernel_sysctl(name, 2, hostname, &len, NULL, 0, NULL); + rel_mplock(); if (error == 0) error = copyout(hostname, uap->hostname, len); @@ -72,6 +77,9 @@ sys_ogethostname(struct gethostname_args *uap) return (error); } +/* + * MPALMOSTSAFE + */ int sys_osethostname(struct sethostname_args *uap) { @@ -97,12 +105,17 @@ sys_osethostname(struct sethostname_args *uap) return (error); } + get_mplock(); error = kernel_sysctl(name, 2, NULL, 0, hostname, len, NULL); + rel_mplock(); kfree(hostname, M_TEMP); return (error); } +/* + * MPSAFE + */ int sys_ogethostid(struct ogethostid_args *uap) { @@ -110,6 +123,9 @@ sys_ogethostid(struct ogethostid_args *uap) return (0); } +/* + * MPSAFE + */ int sys_osethostid(struct osethostid_args *uap) { @@ -123,6 +139,9 @@ sys_osethostid(struct osethostid_args *uap) return (0); } +/* + * MPSAFE + */ int sys_oquota(struct oquota_args *uap) { @@ -184,6 +203,9 @@ static struct { */ static char bsdi_strings[80]; /* It had better be less than this! */ +/* + * MPALMOSTSAFE + */ int sys_ogetkerninfo(struct getkerninfo_args *uap) { @@ -191,8 +213,9 @@ sys_ogetkerninfo(struct getkerninfo_args *uap) size_t size; u_int needed = 0; - switch (uap->op & 0xff00) { + get_mplock(); + switch (uap->op & 0xff00) { case KINFO_RT: name[0] = CTL_NET; name[1] = PF_ROUTE; @@ -311,15 +334,15 @@ sys_ogetkerninfo(struct getkerninfo_args *uap) } break; } - default: - return (EOPNOTSUPP); + error = EOPNOTSUPP; + break; } + rel_mplock(); if (error) return (error); uap->sysmsg_iresult = (int)size; if (uap->size) - error = copyout((caddr_t)&size, (caddr_t)uap->size, - sizeof(size)); + error = copyout(&size, uap->size, sizeof(size)); return (error); } diff --git a/sys/emulation/43bsd/43bsd_resource.c b/sys/emulation/43bsd/43bsd_resource.c index d29f777df8..af1260dbd5 100644 --- a/sys/emulation/43bsd/43bsd_resource.c +++ b/sys/emulation/43bsd/43bsd_resource.c @@ -54,6 +54,9 @@ #include #include +/* + * MPSAFE + */ int sys_ogetrlimit(struct ogetrlimit_args *uap) { @@ -76,6 +79,9 @@ sys_ogetrlimit(struct ogetrlimit_args *uap) } +/* + * MPSAFE + */ int sys_osetrlimit(struct osetrlimit_args *uap) { diff --git a/sys/emulation/43bsd/43bsd_signal.c b/sys/emulation/43bsd/43bsd_signal.c index 7743c2240e..1b41509c25 100644 --- a/sys/emulation/43bsd/43bsd_signal.c +++ b/sys/emulation/43bsd/43bsd_signal.c @@ -73,8 +73,9 @@ * This file is provided for educational purposes only. The osigvec() * syscall is probably broken because the current signal code uses * a different signal trampoline. + * + * MPALMOSTSAFE */ - int sys_osigvec(struct osigvec_args *uap) { @@ -97,7 +98,9 @@ sys_osigvec(struct osigvec_args *uap) nsap->sa_flags ^= SA_RESTART; /* opposite of SV_INTERRUPT */ } + get_mplock(); error = kern_sigaction(uap->signum, nsap, osap); + rel_mplock(); if (osap && !error) { vec.sv_handler = osap->sa_handler; @@ -110,6 +113,9 @@ sys_osigvec(struct osigvec_args *uap) return (error); } +/* + * MPSAFE + */ int sys_osigblock(struct osigblock_args *uap) { @@ -125,6 +131,9 @@ sys_osigblock(struct osigblock_args *uap) return (0); } +/* + * MPSAFE + */ int sys_osigsetmask(struct osigsetmask_args *uap) { @@ -140,6 +149,9 @@ sys_osigsetmask(struct osigsetmask_args *uap) return (0); } +/* + * MPSAFE + */ int sys_osigstack(struct osigstack_args *uap) { @@ -150,8 +162,9 @@ sys_osigstack(struct osigstack_args *uap) ss.ss_sp = lp->lwp_sigstk.ss_sp; ss.ss_onstack = lp->lwp_sigstk.ss_flags & SS_ONSTACK; if (uap->oss && (error = copyout(&ss, uap->oss, - sizeof(struct sigstack)))) + sizeof(struct sigstack)))) { return (error); + } if (uap->nss && (error = copyin(uap->nss, &ss, sizeof(ss))) == 0) { lp->lwp_sigstk.ss_sp = ss.ss_sp; lp->lwp_sigstk.ss_size = 0; @@ -161,12 +174,17 @@ sys_osigstack(struct osigstack_args *uap) return (error); } +/* + * MPALMOSTSAFE + */ int sys_okillpg(struct okillpg_args *uap) { int error; + get_mplock(); error = kern_kill(uap->signum, -uap->pgid, -1); + rel_mplock(); return (error); } diff --git a/sys/emulation/43bsd/43bsd_socket.c b/sys/emulation/43bsd/43bsd_socket.c index 282ab727f9..f33ba3bcc6 100644 --- a/sys/emulation/43bsd/43bsd_socket.c +++ b/sys/emulation/43bsd/43bsd_socket.c @@ -97,6 +97,9 @@ compat_43_copyout_sockaddr(struct sockaddr *sa, caddr_t uaddr, int sa_len) return (error); } +/* + * MPALMOSTSAFE + */ int sys_oaccept(struct accept_args *uap) { @@ -109,8 +112,10 @@ sys_oaccept(struct accept_args *uap) if (error) return (error); + get_mplock(); error = kern_accept(uap->s, 0, &sa, &sa_len, &uap->sysmsg_iresult); + rel_mplock(); if (error) { /* @@ -129,11 +134,16 @@ sys_oaccept(struct accept_args *uap) if (sa) FREE(sa, M_SONAME); } else { + get_mplock(); error = kern_accept(uap->s, 0, NULL, 0, &uap->sysmsg_iresult); + rel_mplock(); } return (error); } +/* + * MPALMOSTSAFE + */ int sys_ogetsockname(struct getsockname_args *uap) { @@ -144,7 +154,9 @@ sys_ogetsockname(struct getsockname_args *uap) if (error) return (error); + get_mplock(); error = kern_getsockname(uap->fdes, &sa, &sa_len); + rel_mplock(); if (error == 0) error = compat_43_copyout_sockaddr(sa, uap->asa, sa_len); @@ -156,6 +168,9 @@ sys_ogetsockname(struct getsockname_args *uap) return (error); } +/* + * MPALMOSTSAFE + */ int sys_ogetpeername(struct ogetpeername_args *uap) { @@ -166,7 +181,9 @@ sys_ogetpeername(struct ogetpeername_args *uap) if (error) return (error); + get_mplock(); error = kern_getpeername(uap->fdes, &sa, &sa_len); + rel_mplock(); if (error == 0) { error = compat_43_copyout_sockaddr(sa, uap->asa, sa_len); @@ -178,6 +195,9 @@ sys_ogetpeername(struct ogetpeername_args *uap) return (error); } +/* + * MPALMOSTSAFE + */ int sys_osend(struct osend_args *uap) { @@ -196,12 +216,17 @@ sys_osend(struct osend_args *uap) auio.uio_rw = UIO_WRITE; auio.uio_td = td; + get_mplock(); error = kern_sendmsg(uap->s, NULL, &auio, NULL, uap->flags, &uap->sysmsg_szresult); + rel_mplock(); return (error); } +/* + * MPALMOSTSAFE + */ int sys_osendmsg(struct osendmsg_args *uap) { @@ -281,8 +306,10 @@ sys_osendmsg(struct osendmsg_args *uap) } } + get_mplock(); error = kern_sendmsg(uap->s, sa, &auio, control, uap->flags, &uap->sysmsg_szresult); + rel_mplock(); cleanup: iovec_free(&iov, aiov); @@ -292,6 +319,9 @@ cleanup2: return (error); } +/* + * MPALMOSTSAFE + */ int sys_orecv(struct orecv_args *uap) { @@ -310,12 +340,17 @@ sys_orecv(struct orecv_args *uap) auio.uio_rw = UIO_READ; auio.uio_td = td; + get_mplock(); error = kern_recvmsg(uap->s, NULL, &auio, NULL, &uap->flags, &uap->sysmsg_szresult); + rel_mplock(); return (error); } +/* + * MPALMOSTSAFE + */ int sys_orecvfrom(struct recvfrom_args *uap) { @@ -344,8 +379,10 @@ sys_orecvfrom(struct recvfrom_args *uap) auio.uio_rw = UIO_READ; auio.uio_td = td; + get_mplock(); error = kern_recvmsg(uap->s, uap->from ? &sa : NULL, &auio, NULL, &uap->flags, &uap->sysmsg_szresult); + rel_mplock(); if (error == 0 && uap->from) { if (sa != NULL) { @@ -367,6 +404,9 @@ sys_orecvfrom(struct recvfrom_args *uap) return (error); } +/* + * MPALMOSTSAFE + */ int sys_orecvmsg(struct orecvmsg_args *uap) { @@ -415,9 +455,11 @@ sys_orecvmsg(struct orecvmsg_args *uap) flags = msg.msg_flags; + get_mplock(); error = kern_recvmsg(uap->s, (msg.msg_name ? &sa : NULL), &auio, (msg.msg_control ? &control : NULL), &flags, &uap->sysmsg_szresult); + rel_mplock(); /* * Copyout msg.msg_name and msg.msg_namelen. diff --git a/sys/emulation/43bsd/43bsd_stats.c b/sys/emulation/43bsd/43bsd_stats.c index 37480f441f..65bcfa2513 100644 --- a/sys/emulation/43bsd/43bsd_stats.c +++ b/sys/emulation/43bsd/43bsd_stats.c @@ -88,19 +88,27 @@ compat_43_copyout_stat(struct stat *st, struct ostat *uaddr) return (error); } +/* + * MPALMOSTSAFE + */ int sys_ofstat(struct ofstat_args *uap) { struct stat st; int error; + get_mplock(); error = kern_fstat(uap->fd, &st); if (error == 0) error = compat_43_copyout_stat(&st, uap->sb); + rel_mplock(); return (error); } +/* + * MPALMOSTSAFE + */ int sys_ostat(struct ostat_args *uap) { @@ -108,6 +116,7 @@ sys_ostat(struct ostat_args *uap) struct stat st; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) { error = kern_stat(&nd, &st); @@ -115,9 +124,13 @@ sys_ostat(struct ostat_args *uap) error = compat_43_copyout_stat(&st, uap->ub); nlookup_done(&nd); } + rel_mplock(); return (error); } +/* + * MPALMOSTSAFE + */ int sys_olstat(struct olstat_args *uap) { @@ -125,6 +138,7 @@ sys_olstat(struct olstat_args *uap) struct stat st; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); if (error == 0) { error = kern_stat(&nd, &st); @@ -132,5 +146,6 @@ sys_olstat(struct olstat_args *uap) error = compat_43_copyout_stat(&st, uap->ub); nlookup_done(&nd); } + rel_mplock(); return (error); } diff --git a/sys/emulation/43bsd/43bsd_vm.c b/sys/emulation/43bsd/43bsd_vm.c index d65566f855..e9409143c8 100644 --- a/sys/emulation/43bsd/43bsd_vm.c +++ b/sys/emulation/43bsd/43bsd_vm.c @@ -51,12 +51,18 @@ #include #include +/* + * MPSAFE + */ int sys_ovadvise(struct ovadvise_args *uap) { return (EINVAL); } +/* + * MPSAFE + */ int sys_ogetpagesize(struct getpagesize_args *uap) { @@ -64,6 +70,9 @@ sys_ogetpagesize(struct getpagesize_args *uap) return (0); } +/* + * MPSAFE + */ int sys_ommap(struct ommap_args *uap) { @@ -100,9 +109,11 @@ sys_ommap(struct ommap_args *uap) if (uap->flags & OMAP_INHERIT) flags |= MAP_INHERIT; + get_mplock(); error = kern_mmap(curproc->p_vmspace, uap->addr, uap->len, prot, flags, uap->fd, uap->pos, &uap->sysmsg_resultp); + rel_mplock(); return (error); } diff --git a/sys/emulation/dragonfly12/dfbsd12_getdirentries.c b/sys/emulation/dragonfly12/dfbsd12_getdirentries.c index f65dc1ebc6..4b9704eb03 100644 --- a/sys/emulation/dragonfly12/dfbsd12_getdirentries.c +++ b/sys/emulation/dragonfly12/dfbsd12_getdirentries.c @@ -56,6 +56,9 @@ struct dfbsd12_dirent { char df12_d_name[]; }; +/* + * MPALMOSTSAFE + */ static int common_getdirentries(long *base, int *result, int fd, char *usr_buf, size_t count) { @@ -72,8 +75,10 @@ common_getdirentries(long *base, int *result, int fd, char *usr_buf, size_t coun buf = kmalloc(len, M_TEMP, M_WAITOK); - error = kern_getdirentries(fd, buf, len, - base, &bytes_transfered, UIO_SYSSPACE); + get_mplock(); + error = kern_getdirentries(fd, buf, len, base, + &bytes_transfered, UIO_SYSSPACE); + rel_mplock(); if (error) { kfree(buf, M_TEMP); @@ -113,6 +118,9 @@ common_getdirentries(long *base, int *result, int fd, char *usr_buf, size_t coun return (0); } +/* + * MPSAFE + */ int sys_dfbsd12_getdirentries(struct dfbsd12_getdirentries_args *uap) { @@ -127,6 +135,9 @@ sys_dfbsd12_getdirentries(struct dfbsd12_getdirentries_args *uap) return (error); } +/* + * MPSAFE + */ int sys_dfbsd12_getdents(struct dfbsd12_getdents_args *uap) { diff --git a/sys/emulation/dragonfly12/dfbsd12_stat.c b/sys/emulation/dragonfly12/dfbsd12_stat.c index c8daa1e4af..3462fb704e 100644 --- a/sys/emulation/dragonfly12/dfbsd12_stat.c +++ b/sys/emulation/dragonfly12/dfbsd12_stat.c @@ -75,6 +75,8 @@ cvtstat(struct dfbsd12_stat *oldstat, struct stat *newstat) * stat_args(char *path, struct dfbsd12_stat *ub) * * Get file status; this version follows links. + * + * MPALMOSTSAFE */ int sys_dfbsd12_stat(struct dfbsd12_stat_args *uap) @@ -84,6 +86,7 @@ sys_dfbsd12_stat(struct dfbsd12_stat_args *uap) struct stat st; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) { error = kern_stat(&nd, &st); @@ -93,6 +96,7 @@ sys_dfbsd12_stat(struct dfbsd12_stat_args *uap) } } nlookup_done(&nd); + rel_mplock(); return (error); } @@ -100,6 +104,8 @@ sys_dfbsd12_stat(struct dfbsd12_stat_args *uap) * lstat_args(char *path, struct dfbsd12_stat *ub) * * Get file status; this version does not follow links. + * + * MPALMOSTSAFE */ int sys_dfbsd12_lstat(struct dfbsd12_lstat_args *uap) @@ -109,6 +115,7 @@ sys_dfbsd12_lstat(struct dfbsd12_lstat_args *uap) struct stat st; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); if (error == 0) { error = kern_stat(&nd, &st); @@ -118,11 +125,14 @@ sys_dfbsd12_lstat(struct dfbsd12_lstat_args *uap) } } nlookup_done(&nd); + rel_mplock(); return (error); } /* * fhstat_args(struct fhandle *u_fhp, struct dfbsd12_stat *sb) + * + * MPALMOSTSAFE */ int sys_dfbsd12_fhstat(struct dfbsd12_fhstat_args *uap) @@ -146,21 +156,28 @@ sys_dfbsd12_fhstat(struct dfbsd12_fhstat_args *uap) if (error) return (error); - if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) - return (ESTALE); + get_mplock(); + if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) { + error = ESTALE; + goto done; + } if ((error = VFS_FHTOVP(mp, NULL, &fh.fh_fid, &vp))) - return (error); + goto done; error = vn_stat(vp, &sb, td->td_proc->p_ucred); vput(vp); if (error) - return (error); + goto done; cvtstat(&osb, &sb); error = copyout(&osb, uap->sb, sizeof(osb)); +done: + rel_mplock(); return (error); } /* * dfbsd12_fstat_args(int fd, struct dfbsd12_stat *sb) + * + * MPALMOSTSAFE */ int sys_dfbsd12_fstat(struct dfbsd12_fstat_args *uap) @@ -169,7 +186,9 @@ sys_dfbsd12_fstat(struct dfbsd12_fstat_args *uap) struct stat st; int error; + get_mplock(); error = kern_fstat(uap->fd, &st); + rel_mplock(); if (error == 0) { cvtstat(&ost, &st); diff --git a/sys/emulation/linux/i386/linux_machdep.c b/sys/emulation/linux/i386/linux_machdep.c index 9cfd19a4ba..db95b3aee0 100644 --- a/sys/emulation/linux/i386/linux_machdep.c +++ b/sys/emulation/linux/i386/linux_machdep.c @@ -103,6 +103,9 @@ bsd_to_linux_sigaltstack(int bsa) return (lsa); } +/* + * MPALMOSTSAFE + */ int sys_linux_execve(struct linux_execve_args *args) { @@ -118,6 +121,7 @@ sys_linux_execve(struct linux_execve_args *args) if (ldebug(execve)) kprintf(ARGS(execve, "%s"), path); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); bzero(&exec_args, sizeof(exec_args)); if (error == 0) { @@ -144,6 +148,7 @@ sys_linux_execve(struct linux_execve_args *args) exit1(W_EXITCODE(0, SIGABRT)); /* NOTREACHED */ } + rel_mplock(); return(error); } @@ -153,11 +158,16 @@ struct l_ipc_kludge { l_long msgtyp; }; +/* + * MPALMOSTSAFE + */ int sys_linux_ipc(struct linux_ipc_args *args) { int error = 0; + get_mplock(); + switch (args->what & 0xFFFF) { case LINUX_SEMOP: { struct linux_semop_args a; @@ -191,7 +201,7 @@ sys_linux_ipc(struct linux_ipc_args *args) a.sysmsg_lresult = 0; error = copyin((caddr_t)args->ptr, &a.arg, sizeof(a.arg)); if (error) - return (error); + break; error = linux_semctl(&a); args->sysmsg_lresult = a.sysmsg_lresult; break; @@ -219,11 +229,13 @@ sys_linux_ipc(struct linux_ipc_args *args) struct l_ipc_kludge tmp; int error; - if (args->ptr == NULL) - return (EINVAL); + if (args->ptr == NULL) { + error = EINVAL; + break; + } error = copyin((caddr_t)args->ptr, &tmp, sizeof(tmp)); if (error) - return (error); + break; a.msgp = tmp.msgp; a.msgtyp = tmp.msgtyp; } else { @@ -302,9 +314,13 @@ sys_linux_ipc(struct linux_ipc_args *args) error = EINVAL; break; } + rel_mplock(); return(error); } +/* + * MPSAFE + */ int sys_linux_old_select(struct linux_old_select_args *args) { @@ -332,6 +348,9 @@ sys_linux_old_select(struct linux_old_select_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_fork(struct linux_fork_args *args) { @@ -350,6 +369,9 @@ sys_linux_fork(struct linux_fork_args *args) return (0); } +/* + * MPSAFE + */ int sys_linux_exit_group(struct linux_exit_group_args *args) { @@ -363,6 +385,9 @@ sys_linux_exit_group(struct linux_exit_group_args *args) return (error); } +/* + * MPSAFE + */ int sys_linux_vfork(struct linux_vfork_args *args) { @@ -387,6 +412,9 @@ sys_linux_vfork(struct linux_vfork_args *args) #define CLONE_SIGHAND 0x800 #define CLONE_PID 0x1000 +/* + * MPALMOSTSAFE + */ int sys_linux_clone(struct linux_clone_args *args) { @@ -430,25 +458,27 @@ sys_linux_clone(struct linux_clone_args *args) rf_args.flags = ff; rf_args.sysmsg_iresult = 0; - if ((error = sys_rfork(&rf_args)) != 0) - return (error); - args->sysmsg_iresult = rf_args.sysmsg_iresult; - - p2 = pfind(rf_args.sysmsg_iresult); - if (p2 == NULL) - return (ESRCH); + get_mplock(); + if ((error = sys_rfork(&rf_args)) == 0) { + args->sysmsg_iresult = rf_args.sysmsg_iresult; - p2->p_sigparent = exit_signal; - ONLY_LWP_IN_PROC(p2)->lwp_md.md_regs->tf_esp = - (unsigned int)args->stack; + p2 = pfind(rf_args.sysmsg_iresult); + if (p2 == NULL) + error = ESRCH; + } + rel_mplock(); + if (error == 0) { + p2->p_sigparent = exit_signal; + ONLY_LWP_IN_PROC(p2)->lwp_md.md_regs->tf_esp = + (unsigned long)args->stack; #ifdef DEBUG - if (ldebug(clone)) - kprintf(LMSG("clone: successful rfork to %ld"), - (long)p2->p_pid); + if (ldebug(clone)) + kprintf(LMSG("clone: successful rfork to %ld"), + (long)p2->p_pid); #endif - - return (0); + } + return (error); } /* XXX move */ @@ -464,9 +494,12 @@ struct l_mmap_argv { #define STACK_SIZE (2 * 1024 * 1024) #define GUARD_SIZE (4 * PAGE_SIZE) +/* + * MPALMOSTSAFE + */ static int linux_mmap_common(caddr_t linux_addr, size_t linux_len, int linux_prot, - int linux_flags, int linux_fd, off_t pos, void **res) + int linux_flags, int linux_fd, off_t pos, void **res) { struct thread *td = curthread; struct proc *p = td->td_proc; @@ -486,6 +519,9 @@ linux_mmap_common(caddr_t linux_addr, size_t linux_len, int linux_prot, } else { flags |= MAP_NOSYNC; } + + get_mplock(); + if (linux_flags & LINUX_MAP_GROWSDOWN) { flags |= MAP_STACK; /* The linux MAP_GROWSDOWN option does not limit auto @@ -564,12 +600,16 @@ linux_mmap_common(caddr_t linux_addr, size_t linux_len, int linux_prot, #endif error = kern_mmap(curproc->p_vmspace, addr, len, prot, flags, fd, pos, &new); + rel_mplock(); if (error == 0) *res = new; return (error); } +/* + * MPSAFE + */ int sys_linux_mmap(struct linux_mmap_args *args) { @@ -596,6 +636,9 @@ sys_linux_mmap(struct linux_mmap_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_mmap2(struct linux_mmap2_args *args) { @@ -617,6 +660,9 @@ sys_linux_mmap2(struct linux_mmap2_args *args) return (error); } +/* + * MPSAFE + */ int sys_linux_pipe(struct linux_pipe_args *args) { @@ -647,6 +693,9 @@ sys_linux_pipe(struct linux_pipe_args *args) return (0); } +/* + * MPSAFE + */ int sys_linux_ioperm(struct linux_ioperm_args *args) { @@ -668,6 +717,9 @@ sys_linux_ioperm(struct linux_ioperm_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_iopl(struct linux_iopl_args *args) { @@ -675,8 +727,6 @@ sys_linux_iopl(struct linux_iopl_args *args) struct lwp *lp = td->td_lwp; int error; - KKASSERT(lp); - if (args->level < 0 || args->level > 3) return (EINVAL); if ((error = priv_check(td, PRIV_ROOT)) != 0) @@ -689,6 +739,9 @@ sys_linux_iopl(struct linux_iopl_args *args) return (0); } +/* + * MPSAFE + */ int sys_linux_modify_ldt(struct linux_modify_ldt_args *uap) { @@ -756,6 +809,9 @@ sys_linux_modify_ldt(struct linux_modify_ldt_args *uap) return (error); } +/* + * MPALMOSTSAFE + */ int sys_linux_sigaction(struct linux_sigaction_args *args) { @@ -782,8 +838,10 @@ sys_linux_sigaction(struct linux_sigaction_args *args) linux_to_bsd_sigaction(&linux_act, &act); } + get_mplock(); error = kern_sigaction(args->sig, args->nsa ? &act : NULL, - args->osa ? &oact : NULL); + args->osa ? &oact : NULL); + rel_mplock(); if (args->osa != NULL && !error) { bsd_to_linux_sigaction(&oact, &linux_oact); @@ -800,6 +858,8 @@ sys_linux_sigaction(struct linux_sigaction_args *args) * Linux has two extra args, restart and oldmask. We dont use these, * but it seems that "restart" is actually a context pointer that * enables the signal to happen with a different register set. + * + * MPALMOSTSAFE */ int sys_linux_sigsuspend(struct linux_sigsuspend_args *args) @@ -817,11 +877,16 @@ sys_linux_sigsuspend(struct linux_sigsuspend_args *args) mask.__bits[0] = args->mask; linux_to_bsd_sigset(&linux_mask, &mask); + get_mplock(); error = kern_sigsuspend(&mask); + rel_mplock(); return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_rt_sigsuspend(struct linux_rt_sigsuspend_args *uap) { @@ -844,11 +909,16 @@ sys_linux_rt_sigsuspend(struct linux_rt_sigsuspend_args *uap) linux_to_bsd_sigset(&linux_mask, &mask); + get_mplock(); error = kern_sigsuspend(&mask); + rel_mplock(); return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_pause(struct linux_pause_args *args) { @@ -864,11 +934,16 @@ sys_linux_pause(struct linux_pause_args *args) mask = lp->lwp_sigmask; + get_mplock(); error = kern_sigsuspend(&mask); + rel_mplock(); return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_sigaltstack(struct linux_sigaltstack_args *uap) { @@ -891,8 +966,10 @@ sys_linux_sigaltstack(struct linux_sigaltstack_args *uap) ss.ss_flags = linux_to_bsd_sigaltstack(linux_ss.ss_flags); } + get_mplock(); error = kern_sigaltstack(uap->uss ? &ss : NULL, - uap->uoss ? &oss : NULL); + uap->uoss ? &oss : NULL); + rel_mplock(); if (error == 0 && uap->uoss) { linux_ss.ss_sp = oss.ss_sp; diff --git a/sys/emulation/linux/i386/linux_proto.h b/sys/emulation/linux/i386/linux_proto.h index de9deacbcc..6141090751 100644 --- a/sys/emulation/linux/i386/linux_proto.h +++ b/sys/emulation/linux/i386/linux_proto.h @@ -2,8 +2,6 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/emulation/linux/i386/linux_proto.h,v 1.19 2008/05/19 10:19:49 corecode Exp $ - * created from DragonFly: src/sys/emulation/linux/i386/syscalls.master,v 1.9 2006/06/05 07:26:10 dillon Exp */ #ifndef _LINUX_SYSPROTO_H_ diff --git a/sys/emulation/linux/i386/linux_ptrace.c b/sys/emulation/linux/i386/linux_ptrace.c index 9ae3b07c02..36de90846f 100644 --- a/sys/emulation/linux/i386/linux_ptrace.c +++ b/sys/emulation/linux/i386/linux_ptrace.c @@ -245,6 +245,9 @@ linux_proc_write_fpxregs(struct lwp *lp, struct linux_pt_fpxreg *fpxregs) } #endif +/* + * MPALMOSTSAFE + */ int sys_linux_ptrace(struct linux_ptrace_args *uap) { @@ -271,6 +274,8 @@ sys_linux_ptrace(struct linux_ptrace_args *uap) pid = (pid_t)uap->pid; addr = (void *)uap->addr; + get_mplock(); + switch (req) { case PTRACE_TRACEME: case PTRACE_POKETEXT: @@ -495,5 +500,6 @@ sys_linux_ptrace(struct linux_ptrace_args *uap) break; } + rel_mplock(); return (error); } diff --git a/sys/emulation/linux/i386/linux_syscall.h b/sys/emulation/linux/i386/linux_syscall.h index 885760fdb8..157ed344ca 100644 --- a/sys/emulation/linux/i386/linux_syscall.h +++ b/sys/emulation/linux/i386/linux_syscall.h @@ -2,8 +2,6 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/emulation/linux/i386/linux_syscall.h,v 1.19 2008/05/19 10:19:49 corecode Exp $ - * created from DragonFly: src/sys/emulation/linux/i386/syscalls.master,v 1.9 2006/06/05 07:26:10 dillon Exp */ #define LINUX_SYS_exit 1 diff --git a/sys/emulation/linux/i386/linux_sysent.c b/sys/emulation/linux/i386/linux_sysent.c index 5cee595d57..5e81128d9a 100644 --- a/sys/emulation/linux/i386/linux_sysent.c +++ b/sys/emulation/linux/i386/linux_sysent.c @@ -2,8 +2,6 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/emulation/linux/i386/linux_sysent.c,v 1.19 2008/05/19 10:19:49 corecode Exp $ - * created from DragonFly: src/sys/emulation/linux/i386/syscalls.master,v 1.9 2006/06/05 07:26:10 dillon Exp */ #include "opt_compat.h" diff --git a/sys/emulation/linux/i386/linux_sysvec.c b/sys/emulation/linux/i386/linux_sysvec.c index cf75f2d243..c136b4c181 100644 --- a/sys/emulation/linux/i386/linux_sysvec.c +++ b/sys/emulation/linux/i386/linux_sysvec.c @@ -538,6 +538,8 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) * make sure that the user has not modified the * psl to gain improper privileges or to cause * a machine fault. + * + * MPSAFE */ int sys_linux_sigreturn(struct linux_sigreturn_args *args) @@ -631,6 +633,8 @@ sys_linux_sigreturn(struct linux_sigreturn_args *args) * make sure that the user has not modified the * psl to gain improper privileges or to cause * a machine fault. + * + * MPSAFE */ int sys_linux_rt_sigreturn(struct linux_rt_sigreturn_args *args) diff --git a/sys/emulation/linux/i386/linux_union.h b/sys/emulation/linux/i386/linux_union.h index 5a8df8d2dc..98bebeae91 100644 --- a/sys/emulation/linux/i386/linux_union.h +++ b/sys/emulation/linux/i386/linux_union.h @@ -2,8 +2,6 @@ * Union of syscall args for messaging. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/emulation/linux/i386/linux_union.h,v 1.15 2008/05/19 10:19:49 corecode Exp $ - * created from DragonFly: src/sys/emulation/linux/i386/syscalls.master,v 1.9 2006/06/05 07:26:10 dillon Exp */ union sysunion { diff --git a/sys/emulation/linux/linux_file.c b/sys/emulation/linux/linux_file.c index b4402f70c9..dfe898b7f8 100644 --- a/sys/emulation/linux/linux_file.c +++ b/sys/emulation/linux/linux_file.c @@ -58,6 +58,9 @@ #include #include "linux_util.h" +/* + * MPALMOSTSAFE + */ int sys_linux_creat(struct linux_creat_args *args) { @@ -72,15 +75,20 @@ sys_linux_creat(struct linux_creat_args *args) if (ldebug(creat)) kprintf(ARGS(creat, "%s, %d"), path, args->mode); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); if (error == 0) { error = kern_open(&nd, O_WRONLY | O_CREAT | O_TRUNC, args->mode, &args->sysmsg_iresult); } + rel_mplock(); linux_free_path(&path); return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_open(struct linux_open_args *args) { @@ -90,8 +98,6 @@ sys_linux_open(struct linux_open_args *args) char *path; int error, flags; - KKASSERT(p); - if (args->flags & LINUX_O_CREAT) { error = linux_copyin_path(args->path, &path, LINUX_PATH_CREATE); @@ -132,6 +138,7 @@ sys_linux_open(struct linux_open_args *args) flags |= O_EXCL; if (args->flags & LINUX_O_NOCTTY) flags |= O_NOCTTY; + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); if (error == 0) { error = kern_open(&nd, flags, @@ -149,6 +156,7 @@ sys_linux_open(struct linux_open_args *args) fdrop(fp); } } + rel_mplock(); #ifdef DEBUG if (ldebug(open)) kprintf(LMSG("open returns error %d"), error); @@ -157,6 +165,9 @@ sys_linux_open(struct linux_open_args *args) return error; } +/* + * MPSAFE + */ int sys_linux_lseek(struct linux_lseek_args *args) { @@ -168,11 +179,14 @@ sys_linux_lseek(struct linux_lseek_args *args) args->fdes, (long)args->off, args->whence); #endif error = kern_lseek(args->fdes, args->off, args->whence, - &args->sysmsg_offset); + &args->sysmsg_offset); return error; } +/* + * MPSAFE + */ int sys_linux_llseek(struct linux_llseek_args *args) { @@ -193,6 +207,9 @@ sys_linux_llseek(struct linux_llseek_args *args) return (error); } +/* + * MPSAFE + */ int sys_linux_readdir(struct linux_readdir_args *args) { @@ -237,6 +254,9 @@ struct l_dirent64 { #define LINUX_DIRBLKSIZ 512 +/* + * MPALMOSTSAFE + */ static int getdents_common(struct linux_getdents64_args *args, int is64bit) { @@ -262,11 +282,10 @@ getdents_common(struct linux_getdents64_args *args, int is64bit) off_t *cookies = NULL, *cookiep; int ncookies; - KKASSERT(p); - if ((error = holdvnode(p->p_fd, args->fd, &fp)) != 0) return (error); + get_mplock(); if ((fp->f_flag & FREAD) == 0) { error = EBADF; goto done; @@ -448,10 +467,14 @@ out: kfree(buf, M_TEMP); done: + rel_mplock(); fdrop(fp); return (error); } +/* + * MPSAFE + */ int sys_linux_getdents(struct linux_getdents_args *args) { @@ -462,6 +485,9 @@ sys_linux_getdents(struct linux_getdents_args *args) return (getdents_common((struct linux_getdents64_args*)args, 0)); } +/* + * MPSAFE + */ int sys_linux_getdents64(struct linux_getdents64_args *args) { @@ -474,8 +500,9 @@ sys_linux_getdents64(struct linux_getdents64_args *args) /* * These exist mainly for hooks for doing /compat/linux translation. + * + * MPALMOSTSAFE */ - int sys_linux_access(struct linux_access_args *args) { @@ -490,14 +517,19 @@ sys_linux_access(struct linux_access_args *args) if (ldebug(access)) kprintf(ARGS(access, "%s, %d"), path, args->flags); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); if (error == 0) error = kern_access(&nd, args->flags, 0); nlookup_done(&nd); + rel_mplock(); linux_free_path(&path); return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_unlink(struct linux_unlink_args *args) { @@ -512,14 +544,19 @@ sys_linux_unlink(struct linux_unlink_args *args) if (ldebug(unlink)) kprintf(ARGS(unlink, "%s"), path); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, 0); if (error == 0) error = kern_unlink(&nd); nlookup_done(&nd); + rel_mplock(); linux_free_path(&path); return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_chdir(struct linux_chdir_args *args) { @@ -534,15 +571,20 @@ sys_linux_chdir(struct linux_chdir_args *args) if (ldebug(chdir)) kprintf(ARGS(chdir, "%s"), path); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); if (error == 0) { error = kern_chdir(&nd); nlookup_done(&nd); } + rel_mplock(); linux_free_path(&path); return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_chmod(struct linux_chmod_args *args) { @@ -557,14 +599,19 @@ sys_linux_chmod(struct linux_chmod_args *args) if (ldebug(chmod)) kprintf(ARGS(chmod, "%s, %d"), path, args->mode); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); if (error == 0) error = kern_chmod(&nd, args->mode); nlookup_done(&nd); + rel_mplock(); linux_free_path(&path); return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_mkdir(struct linux_mkdir_args *args) { @@ -579,15 +626,20 @@ sys_linux_mkdir(struct linux_mkdir_args *args) if (ldebug(mkdir)) kprintf(ARGS(mkdir, "%s, %d"), path, args->mode); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, 0); if (error == 0) error = kern_mkdir(&nd, args->mode); nlookup_done(&nd); + rel_mplock(); linux_free_path(&path); return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_rmdir(struct linux_rmdir_args *args) { @@ -602,14 +654,19 @@ sys_linux_rmdir(struct linux_rmdir_args *args) if (ldebug(rmdir)) kprintf(ARGS(rmdir, "%s"), path); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, 0); if (error == 0) error = kern_rmdir(&nd); nlookup_done(&nd); + rel_mplock(); linux_free_path(&path); return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_rename(struct linux_rename_args *args) { @@ -629,6 +686,7 @@ sys_linux_rename(struct linux_rename_args *args) if (ldebug(rename)) kprintf(ARGS(rename, "%s, %s"), from, to); #endif + get_mplock(); error = nlookup_init(&fromnd, from, UIO_SYSSPACE, 0); if (error == 0) { error = nlookup_init(&tond, to, UIO_SYSSPACE, 0); @@ -637,11 +695,15 @@ sys_linux_rename(struct linux_rename_args *args) nlookup_done(&tond); } nlookup_done(&fromnd); + rel_mplock(); linux_free_path(&from); linux_free_path(&to); return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_symlink(struct linux_symlink_args *args) { @@ -663,17 +725,22 @@ sys_linux_symlink(struct linux_symlink_args *args) if (ldebug(symlink)) kprintf(ARGS(symlink, "%s, %s"), path, link); #endif + get_mplock(); error = nlookup_init(&nd, link, UIO_SYSSPACE, 0); if (error == 0) { mode = ACCESSPERMS & ~td->td_proc->p_fd->fd_cmask; error = kern_symlink(&nd, path, mode); } nlookup_done(&nd); + rel_mplock(); linux_free_path(&path); linux_free_path(&link); return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_readlink(struct linux_readlink_args *args) { @@ -689,16 +756,21 @@ sys_linux_readlink(struct linux_readlink_args *args) kprintf(ARGS(readlink, "%s, %p, %d"), path, (void *)args->buf, args->count); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, 0); if (error == 0) { error = kern_readlink(&nd, args->buf, args->count, &args->sysmsg_iresult); } nlookup_done(&nd); + rel_mplock(); linux_free_path(&path); return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_truncate(struct linux_truncate_args *args) { @@ -714,14 +786,19 @@ sys_linux_truncate(struct linux_truncate_args *args) kprintf(ARGS(truncate, "%s, %ld"), path, (long)args->length); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); if (error == 0) error = kern_truncate(&nd, args->length); nlookup_done(&nd); + rel_mplock(); linux_free_path(&path); return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_truncate64(struct linux_truncate64_args *args) { @@ -737,14 +814,19 @@ sys_linux_truncate64(struct linux_truncate64_args *args) kprintf(ARGS(truncate64, "%s, %lld"), path, (off_t)args->length); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); if (error == 0) error = kern_truncate(&nd, args->length); nlookup_done(&nd); + rel_mplock(); linux_free_path(&path); return error; } +/* + * MPALMOSTSAFE + */ int sys_linux_ftruncate(struct linux_ftruncate_args *args) { @@ -755,11 +837,16 @@ sys_linux_ftruncate(struct linux_ftruncate_args *args) kprintf(ARGS(ftruncate, "%d, %ld"), args->fd, (long)args->length); #endif + get_mplock(); error = kern_ftruncate(args->fd, args->length); + rel_mplock(); return error; } +/* + * MPALMOSTSAFE + */ int sys_linux_ftruncate64(struct linux_ftruncate64_args *args) { @@ -770,11 +857,16 @@ sys_linux_ftruncate64(struct linux_ftruncate64_args *args) kprintf(ARGS(ftruncate64, "%d, %lld"), args->fd, (off_t)args->length); #endif + get_mplock(); error = kern_ftruncate(args->fd, args->length); + rel_mplock(); return error; } +/* + * MPALMOSTSAFE + */ int sys_linux_link(struct linux_link_args *args) { @@ -794,6 +886,7 @@ sys_linux_link(struct linux_link_args *args) if (ldebug(link)) kprintf(ARGS(link, "%s, %s"), path, link); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); if (error == 0) { error = nlookup_init(&linknd, link, UIO_SYSSPACE, 0); @@ -802,11 +895,15 @@ sys_linux_link(struct linux_link_args *args) nlookup_done(&linknd); } nlookup_done(&nd); + rel_mplock(); linux_free_path(&path); linux_free_path(&link); return(error); } +/* + * MPSAFE + */ int sys_linux_fdatasync(struct linux_fdatasync_args *uap) { @@ -821,6 +918,9 @@ sys_linux_fdatasync(struct linux_fdatasync_args *uap) return(error); } +/* + * MPSAFE + */ int sys_linux_pread(struct linux_pread_args *uap) { @@ -848,6 +948,9 @@ sys_linux_pread(struct linux_pread_args *uap) return(error); } +/* + * MPSAFE + */ int sys_linux_pwrite(struct linux_pwrite_args *uap) { @@ -875,6 +978,9 @@ sys_linux_pwrite(struct linux_pwrite_args *uap) return(error); } +/* + * MPSAFE + */ int sys_linux_oldumount(struct linux_oldumount_args *args) { @@ -889,6 +995,9 @@ sys_linux_oldumount(struct linux_oldumount_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_umount(struct linux_umount_args *args) { @@ -907,7 +1016,6 @@ sys_linux_umount(struct linux_umount_args *args) /* * fcntl family of syscalls */ - struct l_flock { l_short l_type; l_short l_whence; @@ -916,6 +1024,9 @@ struct l_flock { l_pid_t l_pid; }; +/* + * MPSAFE + */ static void linux_to_bsd_flock(struct l_flock *linux_flock, struct flock *bsd_flock) { @@ -939,6 +1050,9 @@ linux_to_bsd_flock(struct l_flock *linux_flock, struct flock *bsd_flock) bsd_flock->l_pid = (pid_t)linux_flock->l_pid; } +/* + * MPSAFE + */ static void bsd_to_linux_flock(struct flock *bsd_flock, struct l_flock *linux_flock) { @@ -968,6 +1082,9 @@ struct l_flock64 { l_pid_t l_pid; }; +/* + * MPSAFE + */ static void linux_to_bsd_flock64(struct l_flock64 *linux_flock, struct flock *bsd_flock) { @@ -991,6 +1108,9 @@ linux_to_bsd_flock64(struct l_flock64 *linux_flock, struct flock *bsd_flock) bsd_flock->l_pid = (pid_t)linux_flock->l_pid; } +/* + * MPSAFE + */ static void bsd_to_linux_flock64(struct flock *bsd_flock, struct l_flock64 *linux_flock) { @@ -1012,6 +1132,9 @@ bsd_to_linux_flock64(struct flock *bsd_flock, struct l_flock64 *linux_flock) } #endif /* __i386__ */ +/* + * MPSAFE + */ static int linux_fcntl_common(struct linux_fcntl64_args *args) { @@ -1082,6 +1205,7 @@ linux_fcntl_common(struct linux_fcntl64_args *args) return (EINVAL); } + /* MPSAFE */ error = kern_fcntl(args->fd, cmd, &dat, p->p_ucred); if (error == 0) { @@ -1130,6 +1254,9 @@ linux_fcntl_common(struct linux_fcntl64_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_fcntl(struct linux_fcntl_args *args) { @@ -1151,6 +1278,9 @@ sys_linux_fcntl(struct linux_fcntl_args *args) } #if defined(__i386__) +/* + * MPSAFE + */ int sys_linux_fcntl64(struct linux_fcntl64_args *args) { @@ -1182,6 +1312,7 @@ sys_linux_fcntl64(struct linux_fcntl64_args *args) return (error); linux_to_bsd_flock64(&linux_flock, &dat.fc_flock); + /* MPSAFE */ error = kern_fcntl(args->fd, cmd, &dat, curproc->p_ucred); if (error == 0 && args->cmd == LINUX_F_GETLK64) { @@ -1197,6 +1328,9 @@ sys_linux_fcntl64(struct linux_fcntl64_args *args) } #endif /* __i386__ */ +/* + * MPALMOSTSAFE + */ int sys_linux_chown(struct linux_chown_args *args) { @@ -1211,14 +1345,19 @@ sys_linux_chown(struct linux_chown_args *args) if (ldebug(chown)) kprintf(ARGS(chown, "%s, %d, %d"), path, args->uid, args->gid); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); if (error == 0) error = kern_chown(&nd, args->uid, args->gid); nlookup_done(&nd); + rel_mplock(); linux_free_path(&path); return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_lchown(struct linux_lchown_args *args) { @@ -1233,10 +1372,12 @@ sys_linux_lchown(struct linux_lchown_args *args) if (ldebug(lchown)) kprintf(ARGS(lchown, "%s, %d, %d"), path, args->uid, args->gid); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, 0); if (error == 0) error = kern_chown(&nd, args->uid, args->gid); nlookup_done(&nd); + rel_mplock(); linux_free_path(&path); return(error); } diff --git a/sys/emulation/linux/linux_getcwd.c b/sys/emulation/linux/linux_getcwd.c index f17a1bc710..276a45debb 100644 --- a/sys/emulation/linux/linux_getcwd.c +++ b/sys/emulation/linux/linux_getcwd.c @@ -66,8 +66,9 @@ * * Use vfs vnode-to-name reverse cache; if that fails, fall back * to reading directory contents. + * + * MPALMOSTSAFE */ - int sys_linux_getcwd(struct linux_getcwd_args *args) { @@ -88,7 +89,9 @@ sys_linux_getcwd(struct linux_getcwd_args *args) buflen = MAXPATHLEN; buf = kmalloc(buflen, M_TEMP, M_WAITOK); + get_mplock(); bp = kern_getcwd(buf, buflen, &error); + rel_mplock(); if (error == 0) { buflen = strlen(bp) + 1; error = copyout(bp, args->buf, buflen); diff --git a/sys/emulation/linux/linux_ioctl.c b/sys/emulation/linux/linux_ioctl.c index ed92064d7e..2fdca89967 100644 --- a/sys/emulation/linux/linux_ioctl.c +++ b/sys/emulation/linux/linux_ioctl.c @@ -1285,18 +1285,24 @@ static struct ioctl_map_handler linux_ioctl_base_handler = { /* * main ioctl syscall function + * + * MPALMOSTSAFE */ - int sys_linux_ioctl(struct linux_ioctl_args *args) { + int error; + #ifdef DEBUG if (ldebug(ioctl)) kprintf(ARGS(ioctl, "%d, %04x, *"), args->fd, args->cmd); #endif - return (mapped_ioctl(args->fd, args->cmd, (caddr_t)args->arg, - &linux_ioctl_map, &args->sysmsg)); + get_mplock(); + error = mapped_ioctl(args->fd, args->cmd, (caddr_t)args->arg, + &linux_ioctl_map, &args->sysmsg); + rel_mplock(); + return (error); } SYSINIT (linux_ioctl_register, SI_BOOT2_KLD, SI_ORDER_MIDDLE, diff --git a/sys/emulation/linux/linux_ipc.c b/sys/emulation/linux/linux_ipc.c index 506920712d..fe47a8b52e 100644 --- a/sys/emulation/linux/linux_ipc.c +++ b/sys/emulation/linux/linux_ipc.c @@ -81,6 +81,9 @@ struct l_ipc_perm { l_ushort seq; }; +/* + * MPSAFE + */ static void linux_to_bsd_ipc_perm(struct l_ipc_perm *lpp, struct ipc_perm *bpp) { @@ -93,7 +96,9 @@ linux_to_bsd_ipc_perm(struct l_ipc_perm *lpp, struct ipc_perm *bpp) bpp->seq = lpp->seq; } - +/* + * MPSAFE + */ static void bsd_to_linux_ipc_perm(struct ipc_perm *bpp, struct l_ipc_perm *lpp) { @@ -131,6 +136,9 @@ struct l_shmid_ds { void *private3; }; +/* + * MPSAFE + */ static void linux_to_bsd_semid_ds(struct l_semid_ds *lsp, struct semid_ds *bsp) { @@ -141,6 +149,9 @@ linux_to_bsd_semid_ds(struct l_semid_ds *lsp, struct semid_ds *bsp) bsp->sem_base = lsp->sem_base; } +/* + * MPSAFE + */ static void bsd_to_linux_semid_ds(struct semid_ds *bsp, struct l_semid_ds *lsp) { @@ -151,6 +162,9 @@ bsd_to_linux_semid_ds(struct semid_ds *bsp, struct l_semid_ds *lsp) lsp->sem_base = bsp->sem_base; } +/* + * MPSAFE + */ static void linux_to_bsd_shmid_ds(struct l_shmid_ds *lsp, struct shmid_ds *bsp) { @@ -165,6 +179,9 @@ linux_to_bsd_shmid_ds(struct l_shmid_ds *lsp, struct shmid_ds *bsp) bsp->shm_internal = lsp->private3; /* this goes (yet) SOS */ } +/* + * MPSAFE + */ static void bsd_to_linux_shmid_ds(struct shmid_ds *bsp, struct l_shmid_ds *lsp) { @@ -179,6 +196,9 @@ bsd_to_linux_shmid_ds(struct shmid_ds *bsp, struct l_shmid_ds *lsp) lsp->private3 = bsp->shm_internal; /* this goes (yet) SOS */ } +/* + * MPSAFE + */ int linux_semop(struct linux_semop_args *args) { @@ -194,6 +214,9 @@ linux_semop(struct linux_semop_args *args) return(error); } +/* + * MPSAFE + */ int linux_semget(struct linux_semget_args *args) { @@ -209,6 +232,9 @@ linux_semget(struct linux_semget_args *args) return(error); } +/* + * MPSAFE + */ int linux_semctl(struct linux_semctl_args *args) { @@ -301,6 +327,9 @@ linux_semctl(struct linux_semctl_args *args) return(error); } +/* + * MPSAFE + */ int linux_msgsnd(struct linux_msgsnd_args *args) { @@ -317,6 +346,9 @@ linux_msgsnd(struct linux_msgsnd_args *args) return(error); } +/* + * MPSAFE + */ int linux_msgrcv(struct linux_msgrcv_args *args) { @@ -334,6 +366,9 @@ linux_msgrcv(struct linux_msgrcv_args *args) return(error); } +/* + * MPSAFE + */ int linux_msgget(struct linux_msgget_args *args) { @@ -348,6 +383,9 @@ linux_msgget(struct linux_msgget_args *args) return(error); } +/* + * MPSAFE + */ int linux_msgctl(struct linux_msgctl_args *args) { @@ -363,6 +401,9 @@ linux_msgctl(struct linux_msgctl_args *args) return ((args->cmd == LINUX_IPC_RMID && error == EINVAL) ? 0 : error); } +/* + * MPSAFE + */ int linux_shmat(struct linux_shmat_args *args) { @@ -385,6 +426,9 @@ linux_shmat(struct linux_shmat_args *args) return 0; } +/* + * MPSAFE + */ int linux_shmdt(struct linux_shmdt_args *args) { @@ -398,6 +442,9 @@ linux_shmdt(struct linux_shmdt_args *args) return(error); } +/* + * MPSAFE + */ int linux_shmget(struct linux_shmget_args *args) { @@ -413,6 +460,9 @@ linux_shmget(struct linux_shmget_args *args) return(error); } +/* + * MPSAFE + */ int linux_shmctl(struct linux_shmctl_args *args) { diff --git a/sys/emulation/linux/linux_misc.c b/sys/emulation/linux/linux_misc.c index 5e1e2ab5c9..59dcf78209 100644 --- a/sys/emulation/linux/linux_misc.c +++ b/sys/emulation/linux/linux_misc.c @@ -106,13 +106,17 @@ struct l_sysinfo { char _f[22]; /* Pads structure to 64 bytes */ }; +/* + * MPALMOSTSAFE + */ int sys_linux_sysinfo(struct linux_sysinfo_args *args) { struct l_sysinfo sysinfo; vm_object_t object; - int i; struct timespec ts; + int error; + int i; /* Uptime is copied out of print_uptime() in kern_shutdown.c */ getnanouptime(&ts); @@ -138,6 +142,7 @@ sys_linux_sysinfo(struct linux_sysinfo_args *args) sysinfo.totalram = Maxmem * PAGE_SIZE; sysinfo.freeram = sysinfo.totalram - vmstats.v_wire_count * PAGE_SIZE; + get_mplock(); sysinfo.sharedram = 0; for (object = TAILQ_FIRST(&vm_object_list); object != NULL; object = TAILQ_NEXT(object, object_list)) @@ -154,12 +159,17 @@ sys_linux_sysinfo(struct linux_sysinfo_args *args) sysinfo.totalswap = swapblist->bl_blocks * 1024; sysinfo.freeswap = swapblist->bl_root->u.bmu_avail * PAGE_SIZE; } + rel_mplock(); sysinfo.procs = 20; /* Hack */ - return copyout(&sysinfo, (caddr_t)args->info, sizeof(sysinfo)); + error = copyout(&sysinfo, (caddr_t)args->info, sizeof(sysinfo)); + return (error); } +/* + * MPALMOSTSAFE + */ int sys_linux_alarm(struct linux_alarm_args *args) { @@ -168,8 +178,6 @@ sys_linux_alarm(struct linux_alarm_args *args) struct itimerval it, old_it; struct timeval tv; - KKASSERT(p); - #ifdef DEBUG if (ldebug(alarm)) kprintf(ARGS(alarm, "%u"), args->secs); @@ -182,6 +190,7 @@ sys_linux_alarm(struct linux_alarm_args *args) it.it_value.tv_usec = 0; it.it_interval.tv_sec = 0; it.it_interval.tv_usec = 0; + get_mplock(); crit_enter(); old_it = p->p_realtimer; getmicrouptime(&tv); @@ -194,6 +203,7 @@ sys_linux_alarm(struct linux_alarm_args *args) } p->p_realtimer = it; crit_exit(); + rel_mplock(); if (timevalcmp(&old_it.it_value, &tv, >)) { timevalsub(&old_it.it_value, &tv); if (old_it.it_value.tv_usec != 0) @@ -203,6 +213,9 @@ sys_linux_alarm(struct linux_alarm_args *args) return 0; } +/* + * MPALMOSTSAFE + */ int sys_linux_brk(struct linux_brk_args *args) { @@ -212,7 +225,7 @@ sys_linux_brk(struct linux_brk_args *args) vm_offset_t new, old; struct obreak_args bsd_args; - KKASSERT(p); + get_mplock(); vm = p->p_vmspace; #ifdef DEBUG if (ldebug(brk)) @@ -227,10 +240,14 @@ sys_linux_brk(struct linux_brk_args *args) args->sysmsg_result = (long)new; else args->sysmsg_result = (long)old; + rel_mplock(); return 0; } +/* + * MPALMOSTSAFE + */ int sys_linux_uselib(struct linux_uselib_args *args) { @@ -248,7 +265,6 @@ sys_linux_uselib(struct linux_uselib_args *args) int locked; char *path; - KKASSERT(td->td_proc); p = td->td_proc; error = linux_copyin_path(args->library, &path, LINUX_PATH_EXISTS); @@ -263,6 +279,7 @@ sys_linux_uselib(struct linux_uselib_args *args) locked = 0; vp = NULL; + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); nd.nl_flags |= NLC_EXEC; if (error == 0) @@ -461,10 +478,14 @@ cleanup: (vm_offset_t)a_out + PAGE_SIZE); } nlookup_done(&nd); + rel_mplock(); linux_free_path(&path); return (error); } +/* + * MPSAFE + */ int sys_linux_select(struct linux_select_args *args) { @@ -573,6 +594,9 @@ select_out: return error; } +/* + * MPSAFE + */ int sys_linux_mremap(struct linux_mremap_args *args) { @@ -610,6 +634,9 @@ sys_linux_mremap(struct linux_mremap_args *args) #define LINUX_MS_INVALIDATE 0x0002 #define LINUX_MS_SYNC 0x0004 +/* + * MPSAFE + */ int sys_linux_msync(struct linux_msync_args *args) { @@ -626,6 +653,9 @@ sys_linux_msync(struct linux_msync_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_time(struct linux_time_args *args) { @@ -657,6 +687,9 @@ struct l_times_argv { #define CONVTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK)) +/* + * MPALMOSTSAFE + */ int sys_linux_times(struct linux_times_args *args) { @@ -667,13 +700,14 @@ sys_linux_times(struct linux_times_args *args) struct rusage ru; int error; - KKASSERT(p); #ifdef DEBUG if (ldebug(times)) kprintf(ARGS(times, "*")); #endif + get_mplock(); calcru_proc(p, &ru); + rel_mplock(); tms.tms_utime = CONVTCK(ru.ru_utime); tms.tms_stime = CONVTCK(ru.ru_stime); @@ -689,6 +723,9 @@ sys_linux_times(struct linux_times_args *args) return 0; } +/* + * MPALMOSTSAFE + */ int sys_linux_newuname(struct linux_newuname_args *args) { @@ -701,6 +738,7 @@ sys_linux_newuname(struct linux_newuname_args *args) kprintf(ARGS(newuname, "*")); #endif + get_mplock(); osname = linux_get_osname(td); osrelease = linux_get_osrelease(td); @@ -711,6 +749,7 @@ sys_linux_newuname(struct linux_newuname_args *args) strncpy(utsname.version, version, LINUX_MAX_UTSNAME-1); strncpy(utsname.machine, machine, LINUX_MAX_UTSNAME-1); strncpy(utsname.domainname, domainname, LINUX_MAX_UTSNAME-1); + rel_mplock(); return (copyout(&utsname, (caddr_t)args->buf, sizeof(utsname))); } @@ -721,6 +760,9 @@ struct l_utimbuf { l_time_t l_modtime; }; +/* + * MPALMOSTSAFE + */ int sys_linux_utime(struct linux_utime_args *args) { @@ -747,10 +789,12 @@ sys_linux_utime(struct linux_utime_args *args) tv[1].tv_sec = lut.l_modtime; tv[1].tv_usec = 0; } + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); if (error == 0) error = kern_utimes(&nd, args->times ? tv : NULL); nlookup_done(&nd); + rel_mplock(); cleanup: linux_free_path(&path); return (error); @@ -759,6 +803,9 @@ cleanup: #define __WCLONE 0x80000000 +/* + * MPALMOSTSAFE + */ int sys_linux_waitpid(struct linux_waitpid_args *args) { @@ -775,7 +822,7 @@ sys_linux_waitpid(struct linux_waitpid_args *args) options |= WLINUXCLONE; error = kern_wait(args->pid, args->status ? &status : NULL, options, - NULL, &args->sysmsg_result); + NULL, &args->sysmsg_result); if (error == 0 && args->status) { status &= 0xffff; @@ -791,6 +838,9 @@ sys_linux_waitpid(struct linux_waitpid_args *args) return (error); } +/* + * MPALMOSTSAFE + */ int sys_linux_wait4(struct linux_wait4_args *args) { @@ -799,8 +849,6 @@ sys_linux_wait4(struct linux_wait4_args *args) struct rusage rusage; int error, options, status; - KKASSERT(lp); - #ifdef DEBUG if (ldebug(wait4)) kprintf(ARGS(wait4, "%d, %p, %d, %p"), @@ -813,7 +861,7 @@ sys_linux_wait4(struct linux_wait4_args *args) options |= WLINUXCLONE; error = kern_wait(args->pid, args->status ? &status : NULL, options, - args->rusage ? &rusage : NULL, &args->sysmsg_result); + args->rusage ? &rusage : NULL, &args->sysmsg_result); if (error == 0) lwp_delsig(lp, SIGCHLD); @@ -834,6 +882,9 @@ sys_linux_wait4(struct linux_wait4_args *args) return (error); } +/* + * MPALMOSTSAFE + */ int sys_linux_mknod(struct linux_mknod_args *args) { @@ -849,6 +900,7 @@ sys_linux_mknod(struct linux_mknod_args *args) kprintf(ARGS(mknod, "%s, %d, %d"), path, args->mode, args->dev); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, 0); if (error == 0) { if (args->mode & S_IFIFO) { @@ -860,6 +912,7 @@ sys_linux_mknod(struct linux_mknod_args *args) } } nlookup_done(&nd); + rel_mplock(); linux_free_path(&path); return(error); @@ -867,6 +920,8 @@ sys_linux_mknod(struct linux_mknod_args *args) /* * UGH! This is just about the dumbest idea I've ever heard!! + * + * MPSAFE */ int sys_linux_personality(struct linux_personality_args *args) @@ -885,6 +940,8 @@ sys_linux_personality(struct linux_personality_args *args) /* * Wrappers for get/setitimer for debugging.. + * + * MPSAFE */ int sys_linux_setitimer(struct linux_setitimer_args *args) @@ -919,6 +976,9 @@ sys_linux_setitimer(struct linux_setitimer_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_getitimer(struct linux_getitimer_args *args) { @@ -936,6 +996,9 @@ sys_linux_getitimer(struct linux_getitimer_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_nice(struct linux_nice_args *args) { @@ -951,6 +1014,9 @@ sys_linux_nice(struct linux_nice_args *args) return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_setgroups(struct linux_setgroups_args *args) { @@ -961,8 +1027,6 @@ sys_linux_setgroups(struct linux_setgroups_args *args) gid_t *bsd_gidset; int ngrp, error; - KKASSERT(p); - ngrp = args->gidsetsize; oldcred = p->p_ucred; @@ -975,15 +1039,17 @@ sys_linux_setgroups(struct linux_setgroups_args *args) if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, 0)) != 0) return (error); - if (ngrp >= NGROUPS) + if ((u_int)ngrp >= NGROUPS) return (EINVAL); + get_mplock(); newcred = crdup(oldcred); if (ngrp > 0) { error = copyin((caddr_t)args->grouplist, linux_gidset, ngrp * sizeof(l_gid_t)); if (error) { crfree(newcred); + rel_mplock(); return (error); } @@ -1002,9 +1068,13 @@ sys_linux_setgroups(struct linux_setgroups_args *args) setsugid(); p->p_ucred = newcred; crfree(oldcred); + rel_mplock(); return (0); } +/* + * MPSAFE + */ int sys_linux_getgroups(struct linux_getgroups_args *args) { @@ -1015,8 +1085,6 @@ sys_linux_getgroups(struct linux_getgroups_args *args) gid_t *bsd_gidset; int bsd_gidsetsz, ngrp, error; - KKASSERT(p); - cred = p->p_ucred; bsd_gidset = cred->cr_groups; bsd_gidsetsz = cred->cr_ngroups - 1; @@ -1032,7 +1100,7 @@ sys_linux_getgroups(struct linux_getgroups_args *args) return (0); } - if (ngrp < bsd_gidsetsz) + if ((u_int)ngrp < bsd_gidsetsz) return (EINVAL); ngrp = 0; @@ -1041,14 +1109,18 @@ sys_linux_getgroups(struct linux_getgroups_args *args) ngrp++; } - if ((error = copyout(linux_gidset, (caddr_t)args->grouplist, - ngrp * sizeof(l_gid_t)))) + if ((error = copyout(linux_gidset, args->grouplist, + ngrp * sizeof(l_gid_t)))) { return (error); + } args->sysmsg_result = ngrp; return (0); } +/* + * MPSAFE + */ int sys_linux_setrlimit(struct linux_setrlimit_args *args) { @@ -1079,6 +1151,9 @@ sys_linux_setrlimit(struct linux_setrlimit_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_old_getrlimit(struct linux_old_getrlimit_args *args) { @@ -1112,6 +1187,9 @@ sys_linux_old_getrlimit(struct linux_old_getrlimit_args *args) return (error); } +/* + * MPSAFE + */ int sys_linux_getrlimit(struct linux_getrlimit_args *args) { @@ -1141,6 +1219,9 @@ sys_linux_getrlimit(struct linux_getrlimit_args *args) return (error); } +/* + * MPSAFE + */ int sys_linux_sched_setscheduler(struct linux_sched_setscheduler_args *args) { @@ -1176,6 +1257,9 @@ sys_linux_sched_setscheduler(struct linux_sched_setscheduler_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_sched_getscheduler(struct linux_sched_getscheduler_args *args) { @@ -1206,6 +1290,9 @@ sys_linux_sched_getscheduler(struct linux_sched_getscheduler_args *args) return error; } +/* + * MPSAFE + */ int sys_linux_sched_get_priority_max(struct linux_sched_get_priority_max_args *args) { @@ -1237,6 +1324,9 @@ sys_linux_sched_get_priority_max(struct linux_sched_get_priority_max_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_sched_get_priority_min(struct linux_sched_get_priority_min_args *args) { @@ -1272,6 +1362,9 @@ sys_linux_sched_get_priority_min(struct linux_sched_get_priority_min_args *args) #define REBOOT_CAD_OFF 0 #define REBOOT_HALT 0xcdef0123 +/* + * MPSAFE + */ int sys_linux_reboot(struct linux_reboot_args *args) { @@ -1304,42 +1397,48 @@ sys_linux_reboot(struct linux_reboot_args *args) * linux_getuid() - MP SAFE */ +/* + * MPSAFE + */ int sys_linux_getpid(struct linux_getpid_args *args) { struct thread *td = curthread; struct proc *p = td->td_proc; - KKASSERT(p); - args->sysmsg_result = p->p_pid; return (0); } +/* + * MPSAFE + */ int sys_linux_getgid(struct linux_getgid_args *args) { struct thread *td = curthread; struct proc *p = td->td_proc; - KKASSERT(p); - args->sysmsg_result = p->p_ucred->cr_rgid; return (0); } +/* + * MPSAFE + */ int sys_linux_getuid(struct linux_getuid_args *args) { struct thread *td = curthread; struct proc *p = td->td_proc; - KKASSERT(p); - args->sysmsg_result = p->p_ucred->cr_ruid; return (0); } +/* + * MPSAFE + */ int sys_linux_getsid(struct linux_getsid_args *args) { @@ -1353,6 +1452,9 @@ sys_linux_getsid(struct linux_getsid_args *args) return(error); } +/* + * MPSAFE + */ int linux_nosys(struct nosys_args *args) { diff --git a/sys/emulation/linux/linux_signal.c b/sys/emulation/linux/linux_signal.c index ebcf6a4d45..56e656b1be 100644 --- a/sys/emulation/linux/linux_signal.c +++ b/sys/emulation/linux/linux_signal.c @@ -36,7 +36,8 @@ #include #include #include - +#include +#include #include #include #include "linux_signal.h" @@ -123,6 +124,9 @@ bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa) lsa->lsa_flags |= LINUX_SA_NOMASK; } +/* + * MPALMOSTSAFE + */ int sys_linux_signal(struct linux_signal_args *args) { @@ -145,13 +149,18 @@ sys_linux_signal(struct linux_signal_args *args) sig = args->sig; } + get_mplock(); error = kern_sigaction(sig, &nsa, &osa); + rel_mplock(); bsd_to_linux_sigaction(&osa, &linux_osa); args->sysmsg_result = (int) linux_osa.lsa_handler; return (error); } +/* + * MPALMOSTSAFE + */ int sys_linux_rt_sigaction(struct linux_rt_sigaction_args *args) { @@ -180,8 +189,10 @@ sys_linux_rt_sigaction(struct linux_rt_sigaction_args *args) sig = args->sig; } + get_mplock(); error = kern_sigaction(sig, args->act ? &nsa : NULL, - args->oact ? &osa : NULL); + args->oact ? &osa : NULL); + rel_mplock(); if (error == 0 && args->oact) { bsd_to_linux_sigaction(&osa, &linux_osa); @@ -206,6 +217,9 @@ linux_to_bsd_sigprocmask(int how) } } +/* + * MPALMOSTSAFE + */ int sys_linux_sigprocmask(struct linux_sigprocmask_args *args) { @@ -229,8 +243,10 @@ sys_linux_sigprocmask(struct linux_sigprocmask_args *args) } how = linux_to_bsd_sigprocmask(args->how); + get_mplock(); error = kern_sigprocmask(how, args->mask ? &set : NULL, - args->omask ? &oset : NULL); + args->omask ? &oset : NULL); + rel_mplock(); if (error == 0 && args->omask) { bsd_to_linux_sigset(&oset, &linux_oset); @@ -240,6 +256,9 @@ sys_linux_sigprocmask(struct linux_sigprocmask_args *args) return (error); } +/* + * MPALMOSTSAFE + */ int sys_linux_rt_sigprocmask(struct linux_rt_sigprocmask_args *args) { @@ -265,8 +284,10 @@ sys_linux_rt_sigprocmask(struct linux_rt_sigprocmask_args *args) } how = linux_to_bsd_sigprocmask(args->how); + get_mplock(); error = kern_sigprocmask(how, args->mask ? &set : NULL, - args->omask ? &oset : NULL); + args->omask ? &oset : NULL); + rel_mplock(); if (error == 0 && args->omask) { bsd_to_linux_sigset(&oset, &linux_oset); @@ -276,6 +297,9 @@ sys_linux_rt_sigprocmask(struct linux_rt_sigprocmask_args *args) return (error); } +/* + * MPSAFE + */ int sys_linux_sgetmask(struct linux_sgetmask_args *args) { @@ -292,6 +316,9 @@ sys_linux_sgetmask(struct linux_sgetmask_args *args) return (0); } +/* + * MPSAFE + */ int sys_linux_ssetmask(struct linux_ssetmask_args *args) { @@ -309,11 +336,16 @@ sys_linux_ssetmask(struct linux_ssetmask_args *args) LINUX_SIGEMPTYSET(lset); lset.__bits[0] = args->mask; linux_to_bsd_sigset(&lset, &bset); + crit_enter(); lp->lwp_sigmask = bset; SIG_CANTMASK(lp->lwp_sigmask); + crit_exit(); return (0); } +/* + * MPSAFE + */ int sys_linux_sigpending(struct linux_sigpending_args *args) { @@ -340,6 +372,9 @@ sys_linux_sigpending(struct linux_sigpending_args *args) return (error); } +/* + * MPALMOSTSAFE + */ int sys_linux_kill(struct linux_kill_args *args) { @@ -361,7 +396,9 @@ sys_linux_kill(struct linux_kill_args *args) else sig = args->signum; + get_mplock(); error = kern_kill(sig, args->pid, -1); + rel_mplock(); return(error); } diff --git a/sys/emulation/linux/linux_socket.c b/sys/emulation/linux/linux_socket.c index 6ebc142a6b..6edc1403dc 100644 --- a/sys/emulation/linux/linux_socket.c +++ b/sys/emulation/linux/linux_socket.c @@ -1190,11 +1190,16 @@ out: return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_socketcall(struct linux_socketcall_args *args) { void *arg = (void *)args->args; + get_mplock(); + switch (args->what) { case LINUX_SOCKET: return (linux_socket(arg, &args->sysmsg_result)); @@ -1231,6 +1236,7 @@ sys_linux_socketcall(struct linux_socketcall_args *args) case LINUX_RECVMSG: return (linux_recvmsg(arg, &args->sysmsg_szresult)); } + rel_mplock(); uprintf("LINUX: 'socket' typ=%d not implemented\n", args->what); return (ENOSYS); diff --git a/sys/emulation/linux/linux_stats.c b/sys/emulation/linux/linux_stats.c index 72b125abc0..b6c2afa6f7 100644 --- a/sys/emulation/linux/linux_stats.c +++ b/sys/emulation/linux/linux_stats.c @@ -92,6 +92,9 @@ newstat_copyout(struct stat *buf, void *ubuf) return (error); } +/* + * MPALMOSTSAFE + */ int sys_linux_newstat(struct linux_newstat_args *args) { @@ -107,6 +110,7 @@ sys_linux_newstat(struct linux_newstat_args *args) if (ldebug(newstat)) kprintf(ARGS(newstat, "%s, *"), path); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); if (error == 0) { error = kern_stat(&nd, &buf); @@ -114,10 +118,14 @@ sys_linux_newstat(struct linux_newstat_args *args) error = newstat_copyout(&buf, args->buf); nlookup_done(&nd); } + rel_mplock(); linux_free_path(&path); return (error); } +/* + * MPALMOSTSAFE + */ int sys_linux_newlstat(struct linux_newlstat_args *args) { @@ -133,6 +141,7 @@ sys_linux_newlstat(struct linux_newlstat_args *args) if (ldebug(newlstat)) kprintf(ARGS(newlstat, "%s, *"), path); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, 0); if (error == 0) { error = kern_stat(&nd, &sb); @@ -140,10 +149,14 @@ sys_linux_newlstat(struct linux_newlstat_args *args) error = newstat_copyout(&sb, args->buf); nlookup_done(&nd); } + rel_mplock(); linux_free_path(&path); return (error); } +/* + * MPALMOSTSAFE + */ int sys_linux_newfstat(struct linux_newfstat_args *args) { @@ -154,7 +167,9 @@ sys_linux_newfstat(struct linux_newfstat_args *args) if (ldebug(newfstat)) kprintf(ARGS(newfstat, "%d, *"), args->fd); #endif + get_mplock(); error = kern_fstat(args->fd, &buf); + rel_mplock(); if (error == 0) error = newstat_copyout(&buf, args->buf); @@ -230,6 +245,9 @@ statfs_copyout(struct statfs *statfs, struct l_statfs_buf *buf, l_int namelen) return (error); } +/* + * MPALMOSTSAFE + */ int sys_linux_statfs(struct linux_statfs_args *args) { @@ -245,6 +263,7 @@ sys_linux_statfs(struct linux_statfs_args *args) if (ldebug(statfs)) kprintf(ARGS(statfs, "%s, *"), path); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); if (error == 0) error = kern_statfs(&nd, &statfs); @@ -255,12 +274,16 @@ sys_linux_statfs(struct linux_statfs_args *args) error = EINVAL; } nlookup_done(&nd); + rel_mplock(); if (error == 0) error = statfs_copyout(&statfs, args->buf, (l_int)namelen); linux_free_path(&path); return (error); } +/* + * MPALMOSTSAFE + */ int sys_linux_fstatfs(struct linux_fstatfs_args *args) { @@ -273,11 +296,13 @@ sys_linux_fstatfs(struct linux_fstatfs_args *args) if (ldebug(fstatfs)) kprintf(ARGS(fstatfs, "%d, *"), args->fd); #endif + get_mplock(); if ((error = kern_fstatfs(args->fd, &statfs)) != 0) return (error); if ((error = holdvnode(p->p_fd, args->fd, &fp)) != 0) return (error); error = vn_get_namelen((struct vnode *)fp->f_data, &namelen); + rel_mplock(); fdrop(fp); if (error == 0) error = statfs_copyout(&statfs, args->buf, (l_int)namelen); @@ -292,6 +317,9 @@ struct l_ustat char f_fpack[6]; }; +/* + * MPALMOSTSAFE + */ int sys_linux_ustat(struct linux_ustat_args *args) { @@ -319,22 +347,29 @@ sys_linux_ustat(struct linux_ustat_args *args) * cdev_t returned from previous syscalls. Just return a bzeroed * ustat in that case. */ + get_mplock(); dev = udev2dev(makeudev(args->dev >> 8, args->dev & 0xFF), 0); if (dev != NULL && vfinddev(dev, VCHR, &vp)) { if (vp->v_mount == NULL) { vrele(vp); - return (EINVAL); + error = EINVAL; + goto done; } stat = &(vp->v_mount->mnt_stat); error = VFS_STATFS(vp->v_mount, stat, curproc->p_ucred); vrele(vp); - if (error) { - return (error); + if (error == 0) { + lu.f_tfree = stat->f_bfree; + lu.f_tinode = stat->f_ffree; } - lu.f_tfree = stat->f_bfree; - lu.f_tinode = stat->f_ffree; + } else { + error = 0; } - return (copyout(&lu, args->ubuf, sizeof(lu))); +done: + rel_mplock(); + if (error == 0) + error = copyout(&lu, args->ubuf, sizeof(lu)); + return (error); } #if defined(__i386__) @@ -372,6 +407,9 @@ stat64_copyout(struct stat *buf, void *ubuf) return (error); } +/* + * MPALMOSTSAFE + */ int sys_linux_stat64(struct linux_stat64_args *args) { @@ -387,17 +425,22 @@ sys_linux_stat64(struct linux_stat64_args *args) if (ldebug(stat64)) kprintf(ARGS(stat64, "%s, *"), path); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); if (error == 0) { error = kern_stat(&nd, &buf); - if (error == 0) - error = stat64_copyout(&buf, args->statbuf); nlookup_done(&nd); } + rel_mplock(); + if (error == 0) + error = stat64_copyout(&buf, args->statbuf); linux_free_path(&path); return (error); } +/* + * MPALMOSTSAFE + */ int sys_linux_lstat64(struct linux_lstat64_args *args) { @@ -413,17 +456,22 @@ sys_linux_lstat64(struct linux_lstat64_args *args) if (ldebug(lstat64)) kprintf(ARGS(lstat64, "%s, *"), path); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, 0); if (error == 0) { error = kern_stat(&nd, &sb); - if (error == 0) - error = stat64_copyout(&sb, args->statbuf); nlookup_done(&nd); } + rel_mplock(); + if (error == 0) + error = stat64_copyout(&sb, args->statbuf); linux_free_path(&path); return (error); } +/* + * MPALMOSTSAFE + */ int sys_linux_fstat64(struct linux_fstat64_args *args) { @@ -434,7 +482,9 @@ sys_linux_fstat64(struct linux_fstat64_args *args) if (ldebug(fstat64)) kprintf(ARGS(fstat64, "%d, *"), args->fd); #endif + get_mplock(); error = kern_fstat(args->fd, &buf); + rel_mplock(); if (error == 0) error = stat64_copyout(&buf, args->statbuf); diff --git a/sys/emulation/linux/linux_sysctl.c b/sys/emulation/linux/linux_sysctl.c index d51edccf1f..fc3cae44ef 100644 --- a/sys/emulation/linux/linux_sysctl.c +++ b/sys/emulation/linux/linux_sysctl.c @@ -75,6 +75,9 @@ handle_string(struct l___sysctl_args *la, char *value) return (0); } +/* + * MPALMOSTSAFE + */ int sys_linux_sysctl(struct linux_sysctl_args *args) { @@ -96,28 +99,37 @@ sys_linux_sysctl(struct linux_sysctl_args *args) return (error); } + get_mplock(); + switch (mib[0]) { case LINUX_CTL_KERN: - if (la.nlen < 2) + if (la.nlen < 2) { + error = ENOTDIR; break; + } switch (mib[1]) { case LINUX_KERN_VERSION: - kfree(mib, M_TEMP); - return (handle_string(&la, version)); + error = handle_string(&la, version); + break; default: + error = ENOTDIR; break; } break; default: + error = ENOTDIR; break; } + rel_mplock(); - kprintf("linux: sysctl: unhandled name="); - for (i = 0; i < la.nlen; i++) - kprintf("%c%d", (i) ? ',' : '{', mib[i]); - kprintf("}\n"); - - kfree(mib, M_TEMP); - return (ENOTDIR); + if (error == ENOTDIR && mib) { + kprintf("linux: sysctl: unhandled name="); + for (i = 0; i < la.nlen; i++) + kprintf("%c%d", (i) ? ',' : '{', mib[i]); + kprintf("}\n"); + } + if (mib) + kfree(mib, M_TEMP); + return (error); } diff --git a/sys/emulation/linux/linux_uid16.c b/sys/emulation/linux/linux_uid16.c index 35054b69ab..c01106b5c4 100644 --- a/sys/emulation/linux/linux_uid16.c +++ b/sys/emulation/linux/linux_uid16.c @@ -49,6 +49,9 @@ DUMMY(getresgid16); #define CAST_NOCHG(x) ((x == 0xFFFF) ? -1 : x) +/* + * MPALMOSTSAFE + */ int sys_linux_chown16(struct linux_chown16_args *args) { @@ -64,16 +67,21 @@ sys_linux_chown16(struct linux_chown16_args *args) kprintf(ARGS(chown16, "%s, %d, %d"), path, args->uid, args->gid); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); if (error == 0) { error = kern_chown(&nd, CAST_NOCHG(args->uid), CAST_NOCHG(args->gid)); } nlookup_done(&nd); + rel_mplock(); linux_free_path(&path); return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_lchown16(struct linux_lchown16_args *args) { @@ -89,16 +97,21 @@ sys_linux_lchown16(struct linux_lchown16_args *args) kprintf(ARGS(lchown16, "%s, %d, %d"), path, args->uid, args->gid); #endif + get_mplock(); error = nlookup_init(&nd, path, UIO_SYSSPACE, 0); if (error == 0) { error = kern_chown(&nd, CAST_NOCHG(args->uid), CAST_NOCHG(args->gid)); } nlookup_done(&nd); + rel_mplock(); linux_free_path(&path); return(error); } +/* + * MPALMOSTSAFE + */ int sys_linux_setgroups16(struct linux_setgroups16_args *args) { @@ -125,16 +138,17 @@ sys_linux_setgroups16(struct linux_setgroups16_args *args) if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, 0)) != 0) return (error); - if (ngrp >= NGROUPS) + if ((u_int)ngrp >= NGROUPS) return (EINVAL); + get_mplock(); newcred = crdup(oldcred); if (ngrp > 0) { error = copyin((caddr_t)args->gidset, linux_gidset, ngrp * sizeof(l_gid16_t)); if (error) { crfree(newcred); - return (error); + goto done; } newcred->cr_ngroups = ngrp + 1; @@ -152,9 +166,15 @@ sys_linux_setgroups16(struct linux_setgroups16_args *args) setsugid(); p->p_ucred = newcred; crfree(oldcred); - return (0); + error = 0; +done: + rel_mplock(); + return (error); } +/* + * MPSAFE + */ int sys_linux_getgroups16(struct linux_getgroups16_args *args) { @@ -184,7 +204,7 @@ sys_linux_getgroups16(struct linux_getgroups16_args *args) return (0); } - if (ngrp < bsd_gidsetsz) + if ((u_int)ngrp < (u_int)bsd_gidsetsz) return (EINVAL); ngrp = 0; @@ -194,7 +214,7 @@ sys_linux_getgroups16(struct linux_getgroups16_args *args) } error = copyout(linux_gidset, (caddr_t)args->gidset, - ngrp * sizeof(l_gid16_t)); + ngrp * sizeof(l_gid16_t)); if (error) return (error); @@ -213,6 +233,9 @@ sys_linux_getgroups16(struct linux_getgroups16_args *args) * linux_getuid16() - MP SAFE */ +/* + * MPSAFE + */ int sys_linux_getgid16(struct linux_getgid16_args *args) { @@ -222,6 +245,9 @@ sys_linux_getgid16(struct linux_getgid16_args *args) return (0); } +/* + * MPSAFE + */ int sys_linux_getuid16(struct linux_getuid16_args *args) { @@ -231,6 +257,9 @@ sys_linux_getuid16(struct linux_getuid16_args *args) return (0); } +/* + * MPSAFE + */ int sys_linux_getegid16(struct linux_getegid16_args *args) { @@ -244,6 +273,9 @@ sys_linux_getegid16(struct linux_getegid16_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_geteuid16(struct linux_geteuid16_args *args) { @@ -257,6 +289,9 @@ sys_linux_geteuid16(struct linux_geteuid16_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_setgid16(struct linux_setgid16_args *args) { @@ -271,6 +306,9 @@ sys_linux_setgid16(struct linux_setgid16_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_setuid16(struct linux_setuid16_args *args) { @@ -285,6 +323,9 @@ sys_linux_setuid16(struct linux_setuid16_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_setregid16(struct linux_setregid16_args *args) { @@ -300,6 +341,9 @@ sys_linux_setregid16(struct linux_setregid16_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_setreuid16(struct linux_setreuid16_args *args) { @@ -315,6 +359,9 @@ sys_linux_setreuid16(struct linux_setreuid16_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_setresgid16(struct linux_setresgid16_args *args) { @@ -331,6 +378,9 @@ sys_linux_setresgid16(struct linux_setresgid16_args *args) return(error); } +/* + * MPSAFE + */ int sys_linux_setresuid16(struct linux_setresuid16_args *args) { diff --git a/sys/kern/imgact_resident.c b/sys/kern/imgact_resident.c index 769f1b291b..4bdc3c6a21 100644 --- a/sys/kern/imgact_resident.c +++ b/sys/kern/imgact_resident.c @@ -189,6 +189,8 @@ exec_resident_imgact(struct image_params *imgp) * PRIV_VM_RESIDENT credentials) can do this. This * will snapshot the vmspace and cause future exec's of the specified binary * to use the snapshot directly rather then load & relocate a new copy. + * + * MPALMOSTSAFE */ int sys_exec_sys_register(struct exec_sys_register_args *uap) @@ -201,10 +203,17 @@ sys_exec_sys_register(struct exec_sys_register_args *uap) p = curproc; if ((error = priv_check_cred(p->p_ucred, PRIV_VM_RESIDENT, 0)) != 0) return(error); - if ((vp = p->p_textvp) == NULL) + + get_mplock(); + + if ((vp = p->p_textvp) == NULL) { + rel_mplock(); return(ENOENT); - if (vp->v_resident) + } + if (vp->v_resident) { + rel_mplock(); return(EEXIST); + } vhold(vp); vmres = kmalloc(sizeof(*vmres), M_EXEC_RES, M_WAITOK); vp->v_resident = vmres; @@ -219,6 +228,7 @@ sys_exec_sys_register(struct exec_sys_register_args *uap) TAILQ_INSERT_TAIL(&exec_res_list, vmres, vr_link); lockmgr(&exec_list_lock, LK_RELEASE); + rel_mplock(); return(0); } @@ -228,6 +238,8 @@ sys_exec_sys_register(struct exec_sys_register_args *uap) * Unregister the specified id. If an id of -1 is used unregister * the registration associated with the current process. An id of -2 * unregisters everything. + * + * MPALMOSTSAFE */ int sys_exec_sys_unregister(struct exec_sys_unregister_args *uap) @@ -245,6 +257,7 @@ sys_exec_sys_unregister(struct exec_sys_unregister_args *uap) /* * If id is -1, unregister ourselves */ + get_mplock(); if ((id = uap->id) == -1 && p->p_textvp && p->p_textvp->v_resident) id = p->p_textvp->v_resident->vr_id; @@ -276,6 +289,7 @@ restart: } } lockmgr(&exec_list_lock, LK_RELEASE); + rel_mplock(); if (error == 0) uap->sysmsg_result = count; return(error); diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 095bb96f92..2e562000b3 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -36,10 +36,10 @@ struct sysent sysent[] = { { 0, (sy_call_t *)sys_nosys }, /* 0 = syscall */ { AS(exit_args), (sy_call_t *)sys_exit }, /* 1 = exit */ { 0, (sy_call_t *)sys_fork }, /* 2 = fork */ - { SYF_MPSAFE | AS(read_args), (sy_call_t *)sys_read }, /* 3 = read */ - { SYF_MPSAFE | AS(write_args), (sy_call_t *)sys_write }, /* 4 = write */ + { AS(read_args), (sy_call_t *)sys_read }, /* 3 = read */ + { AS(write_args), (sy_call_t *)sys_write }, /* 4 = write */ { AS(open_args), (sy_call_t *)sys_open }, /* 5 = open */ - { SYF_MPSAFE | AS(close_args), (sy_call_t *)sys_close }, /* 6 = close */ + { AS(close_args), (sy_call_t *)sys_close }, /* 6 = close */ { AS(wait_args), (sy_call_t *)sys_wait4 }, /* 7 = wait4 */ { compat(AS(ocreat_args),creat) }, /* 8 = old creat */ { AS(link_args), (sy_call_t *)sys_link }, /* 9 = link */ @@ -57,8 +57,8 @@ struct sysent sysent[] = { { AS(mount_args), (sy_call_t *)sys_mount }, /* 21 = mount */ { AS(unmount_args), (sy_call_t *)sys_unmount }, /* 22 = unmount */ { AS(setuid_args), (sy_call_t *)sys_setuid }, /* 23 = setuid */ - { SYF_MPSAFE | 0, (sy_call_t *)sys_getuid }, /* 24 = getuid */ - { SYF_MPSAFE | 0, (sy_call_t *)sys_geteuid }, /* 25 = geteuid */ + { 0, (sy_call_t *)sys_getuid }, /* 24 = getuid */ + { 0, (sy_call_t *)sys_geteuid }, /* 25 = geteuid */ { AS(ptrace_args), (sy_call_t *)sys_ptrace }, /* 26 = ptrace */ { AS(recvmsg_args), (sy_call_t *)sys_recvmsg }, /* 27 = recvmsg */ { AS(sendmsg_args), (sy_call_t *)sys_sendmsg }, /* 28 = sendmsg */ @@ -74,13 +74,13 @@ struct sysent sysent[] = { { compat(AS(ostat_args),stat) }, /* 38 = old stat */ { 0, (sy_call_t *)sys_getppid }, /* 39 = getppid */ { compat(AS(olstat_args),lstat) }, /* 40 = old lstat */ - { SYF_MPSAFE | AS(dup_args), (sy_call_t *)sys_dup }, /* 41 = dup */ + { AS(dup_args), (sy_call_t *)sys_dup }, /* 41 = dup */ { 0, (sy_call_t *)sys_pipe }, /* 42 = pipe */ { 0, (sy_call_t *)sys_getegid }, /* 43 = getegid */ { AS(profil_args), (sy_call_t *)sys_profil }, /* 44 = profil */ { AS(ktrace_args), (sy_call_t *)sys_ktrace }, /* 45 = ktrace */ { 0, (sy_call_t *)sys_nosys }, /* 46 = obsolete freebsd3_sigaction */ - { SYF_MPSAFE | 0, (sy_call_t *)sys_getgid }, /* 47 = getgid */ + { 0, (sy_call_t *)sys_getgid }, /* 47 = getgid */ { 0, (sy_call_t *)sys_nosys }, /* 48 = obsolete freebsd3_sigprocmask */ { AS(getlogin_args), (sy_call_t *)sys_getlogin }, /* 49 = getlogin */ { AS(setlogin_args), (sy_call_t *)sys_setlogin }, /* 50 = setlogin */ @@ -93,7 +93,7 @@ struct sysent sysent[] = { { AS(symlink_args), (sy_call_t *)sys_symlink }, /* 57 = symlink */ { AS(readlink_args), (sy_call_t *)sys_readlink }, /* 58 = readlink */ { AS(execve_args), (sy_call_t *)sys_execve }, /* 59 = execve */ - { SYF_MPSAFE | AS(umask_args), (sy_call_t *)sys_umask }, /* 60 = umask */ + { AS(umask_args), (sy_call_t *)sys_umask }, /* 60 = umask */ { AS(chroot_args), (sy_call_t *)sys_chroot }, /* 61 = chroot */ { compat(AS(ofstat_args),fstat) }, /* 62 = old fstat */ { compat(AS(getkerninfo_args),getkerninfo) }, /* 63 = old getkerninfo */ @@ -114,7 +114,7 @@ struct sysent sysent[] = { { AS(mincore_args), (sy_call_t *)sys_mincore }, /* 78 = mincore */ { AS(getgroups_args), (sy_call_t *)sys_getgroups }, /* 79 = getgroups */ { AS(setgroups_args), (sy_call_t *)sys_setgroups }, /* 80 = setgroups */ - { SYF_MPSAFE | 0, (sy_call_t *)sys_getpgrp }, /* 81 = getpgrp */ + { 0, (sy_call_t *)sys_getpgrp }, /* 81 = getpgrp */ { AS(setpgid_args), (sy_call_t *)sys_setpgid }, /* 82 = setpgid */ { AS(setitimer_args), (sy_call_t *)sys_setitimer }, /* 83 = setitimer */ { compat(0,wait) }, /* 84 = old wait */ @@ -122,10 +122,10 @@ struct sysent sysent[] = { { AS(getitimer_args), (sy_call_t *)sys_getitimer }, /* 86 = getitimer */ { compat(AS(gethostname_args),gethostname) }, /* 87 = old gethostname */ { compat(AS(sethostname_args),sethostname) }, /* 88 = old sethostname */ - { SYF_MPSAFE | 0, (sy_call_t *)sys_getdtablesize }, /* 89 = getdtablesize */ - { SYF_MPSAFE | AS(dup2_args), (sy_call_t *)sys_dup2 }, /* 90 = dup2 */ + { 0, (sy_call_t *)sys_getdtablesize }, /* 89 = getdtablesize */ + { AS(dup2_args), (sy_call_t *)sys_dup2 }, /* 90 = dup2 */ { 0, (sy_call_t *)sys_nosys }, /* 91 = getdopt */ - { SYF_MPSAFE | AS(fcntl_args), (sy_call_t *)sys_fcntl }, /* 92 = fcntl */ + { AS(fcntl_args), (sy_call_t *)sys_fcntl }, /* 92 = fcntl */ { AS(select_args), (sy_call_t *)sys_select }, /* 93 = select */ { 0, (sy_call_t *)sys_nosys }, /* 94 = setdopt */ { AS(fsync_args), (sy_call_t *)sys_fsync }, /* 95 = fsync */ @@ -149,12 +149,12 @@ struct sysent sysent[] = { { compat(AS(orecvmsg_args),recvmsg) }, /* 113 = old recvmsg */ { compat(AS(osendmsg_args),sendmsg) }, /* 114 = old sendmsg */ { 0, (sy_call_t *)sys_nosys }, /* 115 = obsolete vtrace */ - { SYF_MPSAFE | AS(gettimeofday_args), (sy_call_t *)sys_gettimeofday }, /* 116 = gettimeofday */ + { AS(gettimeofday_args), (sy_call_t *)sys_gettimeofday }, /* 116 = gettimeofday */ { AS(getrusage_args), (sy_call_t *)sys_getrusage }, /* 117 = getrusage */ { AS(getsockopt_args), (sy_call_t *)sys_getsockopt }, /* 118 = getsockopt */ { 0, (sy_call_t *)sys_nosys }, /* 119 = resuba */ - { SYF_MPSAFE | AS(readv_args), (sy_call_t *)sys_readv }, /* 120 = readv */ - { SYF_MPSAFE | AS(writev_args), (sy_call_t *)sys_writev }, /* 121 = writev */ + { AS(readv_args), (sy_call_t *)sys_readv }, /* 120 = readv */ + { AS(writev_args), (sy_call_t *)sys_writev }, /* 121 = writev */ { AS(settimeofday_args), (sy_call_t *)sys_settimeofday }, /* 122 = settimeofday */ { AS(fchown_args), (sy_call_t *)sys_fchown }, /* 123 = fchown */ { AS(fchmod_args), (sy_call_t *)sys_fchmod }, /* 124 = fchmod */ @@ -177,8 +177,8 @@ struct sysent sysent[] = { { compat(AS(ogetpeername_args),getpeername) }, /* 141 = old getpeername */ { compat(0,gethostid) }, /* 142 = old gethostid */ { compat(AS(osethostid_args),sethostid) }, /* 143 = old sethostid */ - { compat(SYF_MPSAFE | AS(ogetrlimit_args),getrlimit) }, /* 144 = old getrlimit */ - { compat(SYF_MPSAFE | AS(osetrlimit_args),setrlimit) }, /* 145 = old setrlimit */ + { compat(AS(ogetrlimit_args),getrlimit) }, /* 144 = old getrlimit */ + { compat(AS(osetrlimit_args),setrlimit) }, /* 145 = old setrlimit */ { compat(AS(okillpg_args),killpg) }, /* 146 = old killpg */ { 0, (sy_call_t *)sys_setsid }, /* 147 = setsid */ { AS(quotactl_args), (sy_call_t *)sys_quotactl }, /* 148 = quotactl */ @@ -206,8 +206,8 @@ struct sysent sysent[] = { { AS(msgsys_args), (sy_call_t *)sys_msgsys }, /* 170 = msgsys */ { AS(shmsys_args), (sy_call_t *)sys_shmsys }, /* 171 = shmsys */ { 0, (sy_call_t *)sys_nosys }, /* 172 = nosys */ - { SYF_MPSAFE | AS(extpread_args), (sy_call_t *)sys_extpread }, /* 173 = extpread */ - { SYF_MPSAFE | AS(extpwrite_args), (sy_call_t *)sys_extpwrite }, /* 174 = extpwrite */ + { AS(extpread_args), (sy_call_t *)sys_extpread }, /* 173 = extpread */ + { AS(extpwrite_args), (sy_call_t *)sys_extpwrite }, /* 174 = extpwrite */ { 0, (sy_call_t *)sys_nosys }, /* 175 = nosys */ { AS(ntp_adjtime_args), (sy_call_t *)sys_ntp_adjtime }, /* 176 = ntp_adjtime */ { 0, (sy_call_t *)sys_nosys }, /* 177 = sfork */ @@ -322,8 +322,8 @@ struct sysent sysent[] = { { 0, (sy_call_t *)sys_nosys }, /* 286 = nosys */ { 0, (sy_call_t *)sys_nosys }, /* 287 = nosys */ { 0, (sy_call_t *)sys_nosys }, /* 288 = nosys */ - { SYF_MPSAFE | AS(extpreadv_args), (sy_call_t *)sys_extpreadv }, /* 289 = extpreadv */ - { SYF_MPSAFE | AS(extpwritev_args), (sy_call_t *)sys_extpwritev }, /* 290 = extpwritev */ + { AS(extpreadv_args), (sy_call_t *)sys_extpreadv }, /* 289 = extpreadv */ + { AS(extpwritev_args), (sy_call_t *)sys_extpwritev }, /* 290 = extpwritev */ { 0, (sy_call_t *)sys_nosys }, /* 291 = nosys */ { 0, (sy_call_t *)sys_nosys }, /* 292 = nosys */ { 0, (sy_call_t *)sys_nosys }, /* 293 = nosys */ @@ -355,8 +355,8 @@ struct sysent sysent[] = { { AS(aio_write_args), (sy_call_t *)sys_aio_write }, /* 319 = aio_write */ { AS(lio_listio_args), (sy_call_t *)sys_lio_listio }, /* 320 = lio_listio */ { 0, (sy_call_t *)sys_yield }, /* 321 = yield */ - { AS(thr_sleep_args), (sy_call_t *)sys_thr_sleep }, /* 322 = thr_sleep */ - { AS(thr_wakeup_args), (sy_call_t *)sys_thr_wakeup }, /* 323 = thr_wakeup */ + { 0, (sy_call_t *)sys_nosys }, /* 322 = thr_sleep */ + { 0, (sy_call_t *)sys_nosys }, /* 323 = thr_wakeup */ { AS(mlockall_args), (sy_call_t *)sys_mlockall }, /* 324 = mlockall */ { 0, (sy_call_t *)sys_munlockall }, /* 325 = munlockall */ { AS(__getcwd_args), (sy_call_t *)sys___getcwd }, /* 326 = __getcwd */ @@ -373,7 +373,7 @@ struct sysent sysent[] = { { AS(kldsym_args), (sy_call_t *)sys_kldsym }, /* 337 = kldsym */ { AS(jail_args), (sy_call_t *)sys_jail }, /* 338 = jail */ { 0, (sy_call_t *)sys_nosys }, /* 339 = pioctl */ - { SYF_MPSAFE | AS(sigprocmask_args), (sy_call_t *)sys_sigprocmask }, /* 340 = sigprocmask */ + { AS(sigprocmask_args), (sy_call_t *)sys_sigprocmask }, /* 340 = sigprocmask */ { AS(sigsuspend_args), (sy_call_t *)sys_sigsuspend }, /* 341 = sigsuspend */ { AS(sigaction_args), (sy_call_t *)sys_sigaction }, /* 342 = sigaction */ { AS(sigpending_args), (sy_call_t *)sys_sigpending }, /* 343 = sigpending */ @@ -483,9 +483,9 @@ struct sysent sysent[] = { { 0, (sy_call_t *)sys_nosys }, /* 447 = nosys */ { 0, (sy_call_t *)sys_nosys }, /* 448 = nosys */ { 0, (sy_call_t *)sys_nosys }, /* 449 = nosys */ - { SYF_MPSAFE | AS(varsym_set_args), (sy_call_t *)sys_varsym_set }, /* 450 = varsym_set */ - { SYF_MPSAFE | AS(varsym_get_args), (sy_call_t *)sys_varsym_get }, /* 451 = varsym_get */ - { SYF_MPSAFE | AS(varsym_list_args), (sy_call_t *)sys_varsym_list }, /* 452 = varsym_list */ + { AS(varsym_set_args), (sy_call_t *)sys_varsym_set }, /* 450 = varsym_set */ + { AS(varsym_get_args), (sy_call_t *)sys_varsym_get }, /* 451 = varsym_get */ + { AS(varsym_list_args), (sy_call_t *)sys_varsym_list }, /* 452 = varsym_list */ { AS(upc_register_args), (sy_call_t *)sys_upc_register }, /* 453 = upc_register */ { AS(upc_control_args), (sy_call_t *)sys_upc_control }, /* 454 = upc_control */ { AS(caps_sys_service_args), (sy_call_t *)sys_caps_sys_service }, /* 455 = caps_sys_service */ @@ -505,11 +505,11 @@ struct sysent sysent[] = { { AS(umtx_sleep_args), (sy_call_t *)sys_umtx_sleep }, /* 469 = umtx_sleep */ { AS(umtx_wakeup_args), (sy_call_t *)sys_umtx_wakeup }, /* 470 = umtx_wakeup */ { AS(jail_attach_args), (sy_call_t *)sys_jail_attach }, /* 471 = jail_attach */ - { SYF_MPSAFE | AS(set_tls_area_args), (sy_call_t *)sys_set_tls_area }, /* 472 = set_tls_area */ - { SYF_MPSAFE | AS(get_tls_area_args), (sy_call_t *)sys_get_tls_area }, /* 473 = get_tls_area */ - { SYF_MPSAFE | AS(closefrom_args), (sy_call_t *)sys_closefrom }, /* 474 = closefrom */ + { AS(set_tls_area_args), (sy_call_t *)sys_set_tls_area }, /* 472 = set_tls_area */ + { AS(get_tls_area_args), (sy_call_t *)sys_get_tls_area }, /* 473 = get_tls_area */ + { AS(closefrom_args), (sy_call_t *)sys_closefrom }, /* 474 = closefrom */ { AS(stat_args), (sy_call_t *)sys_stat }, /* 475 = stat */ - { SYF_MPSAFE | AS(fstat_args), (sy_call_t *)sys_fstat }, /* 476 = fstat */ + { AS(fstat_args), (sy_call_t *)sys_fstat }, /* 476 = fstat */ { AS(lstat_args), (sy_call_t *)sys_lstat }, /* 477 = lstat */ { AS(fhstat_args), (sy_call_t *)sys_fhstat }, /* 478 = fhstat */ { AS(getdirentries_args), (sy_call_t *)sys_getdirentries }, /* 479 = getdirentries */ @@ -543,14 +543,14 @@ struct sysent sysent[] = { { AS(fchownat_args), (sy_call_t *)sys_fchownat }, /* 507 = fchownat */ { AS(unlinkat_args), (sy_call_t *)sys_unlinkat }, /* 508 = unlinkat */ { AS(faccessat_args), (sy_call_t *)sys_faccessat }, /* 509 = faccessat */ - { SYF_MPSAFE | AS(mq_open_args), (sy_call_t *)sys_mq_open }, /* 510 = mq_open */ - { SYF_MPSAFE | AS(mq_close_args), (sy_call_t *)sys_mq_close }, /* 511 = mq_close */ - { SYF_MPSAFE | AS(mq_unlink_args), (sy_call_t *)sys_mq_unlink }, /* 512 = mq_unlink */ - { SYF_MPSAFE | AS(mq_getattr_args), (sy_call_t *)sys_mq_getattr }, /* 513 = mq_getattr */ - { SYF_MPSAFE | AS(mq_setattr_args), (sy_call_t *)sys_mq_setattr }, /* 514 = mq_setattr */ - { SYF_MPSAFE | AS(mq_notify_args), (sy_call_t *)sys_mq_notify }, /* 515 = mq_notify */ - { SYF_MPSAFE | AS(mq_send_args), (sy_call_t *)sys_mq_send }, /* 516 = mq_send */ - { SYF_MPSAFE | AS(mq_receive_args), (sy_call_t *)sys_mq_receive }, /* 517 = mq_receive */ - { SYF_MPSAFE | AS(mq_timedsend_args), (sy_call_t *)sys_mq_timedsend }, /* 518 = mq_timedsend */ - { SYF_MPSAFE | AS(mq_timedreceive_args), (sy_call_t *)sys_mq_timedreceive }, /* 519 = mq_timedreceive */ + { AS(mq_open_args), (sy_call_t *)sys_mq_open }, /* 510 = mq_open */ + { AS(mq_close_args), (sy_call_t *)sys_mq_close }, /* 511 = mq_close */ + { AS(mq_unlink_args), (sy_call_t *)sys_mq_unlink }, /* 512 = mq_unlink */ + { AS(mq_getattr_args), (sy_call_t *)sys_mq_getattr }, /* 513 = mq_getattr */ + { AS(mq_setattr_args), (sy_call_t *)sys_mq_setattr }, /* 514 = mq_setattr */ + { AS(mq_notify_args), (sy_call_t *)sys_mq_notify }, /* 515 = mq_notify */ + { AS(mq_send_args), (sy_call_t *)sys_mq_send }, /* 516 = mq_send */ + { AS(mq_receive_args), (sy_call_t *)sys_mq_receive }, /* 517 = mq_receive */ + { AS(mq_timedsend_args), (sy_call_t *)sys_mq_timedsend }, /* 518 = mq_timedsend */ + { AS(mq_timedreceive_args), (sy_call_t *)sys_mq_timedreceive }, /* 519 = mq_timedreceive */ }; diff --git a/sys/kern/kern_acct.c b/sys/kern/kern_acct.c index 14f9d362f1..8c124ecb14 100644 --- a/sys/kern/kern_acct.c +++ b/sys/kern/kern_acct.c @@ -118,6 +118,8 @@ SYSINIT(acct, SI_SUB_DRIVERS, SI_ORDER_ANY, acct_init, NULL); * previous implementation done by Mark Tinguely. * * acct(char *path) + * + * MPALMOSTSAFE */ int sys_acct(struct acct_args *uap) @@ -131,6 +133,8 @@ sys_acct(struct acct_args *uap) if (error) return (error); + get_mplock(); + /* * If accounting is to be started to a file, open that file for * appending and make sure it's a 'normal'. @@ -144,7 +148,7 @@ sys_acct(struct acct_args *uap) error = EACCES; if (error) { nlookup_done(&nd); - return (error); + goto done; } vp = nd.nl_open_vp; nd.nl_open_vp = NULL; @@ -171,7 +175,7 @@ sys_acct(struct acct_args *uap) * don't try cleaning it up. */ if (uap->path == NULL) - return (error); + goto done; /* * Save the new accounting file vnode, and schedule the new @@ -179,6 +183,8 @@ sys_acct(struct acct_args *uap) */ acctp = vp; acctwatch(NULL); +done: + rel_mplock(); return (error); } diff --git a/sys/kern/kern_acl.c b/sys/kern/kern_acl.c index 62da0776b7..af23798732 100644 --- a/sys/kern/kern_acl.c +++ b/sys/kern/kern_acl.c @@ -148,6 +148,8 @@ vacl_aclcheck(struct vnode *vp, acl_type_t type, struct acl *aclp) /* * Given a file path, get an ACL for it + * + * MPALMOSTSAFE */ int sys___acl_get_file(struct __acl_get_file_args *uap) @@ -157,6 +159,7 @@ sys___acl_get_file(struct __acl_get_file_args *uap) int error; vp = NULL; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = nlookup(&nd); @@ -167,11 +170,15 @@ sys___acl_get_file(struct __acl_get_file_args *uap) error = vacl_get_acl(vp, uap->type, uap->aclp); vrele(vp); } + rel_mplock(); + return (error); } /* * Given a file path, set an ACL for it + * + * MPALMOSTSAFE */ int sys___acl_set_file(struct __acl_set_file_args *uap) @@ -181,6 +188,7 @@ sys___acl_set_file(struct __acl_set_file_args *uap) int error; vp = NULL; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = nlookup(&nd); @@ -191,11 +199,15 @@ sys___acl_set_file(struct __acl_set_file_args *uap) error = vacl_set_acl(vp, uap->type, uap->aclp); vrele(vp); } + rel_mplock(); + return (error); } /* * Given a file descriptor, get an ACL for it + * + * MPALMOSTSAFE */ int sys___acl_get_fd(struct __acl_get_fd_args *uap) @@ -207,13 +219,18 @@ sys___acl_get_fd(struct __acl_get_fd_args *uap) KKASSERT(td->td_proc); if ((error = holdvnode(td->td_proc->p_fd, uap->filedes, &fp)) != 0) return(error); + get_mplock(); error = vacl_get_acl((struct vnode *)fp->f_data, uap->type, uap->aclp); + rel_mplock(); fdrop(fp); + return (error); } /* * Given a file descriptor, set an ACL for it + * + * MPALMOSTSAFE */ int sys___acl_set_fd(struct __acl_set_fd_args *uap) @@ -225,13 +242,17 @@ sys___acl_set_fd(struct __acl_set_fd_args *uap) KKASSERT(td->td_proc); if ((error = holdvnode(td->td_proc->p_fd, uap->filedes, &fp)) != 0) return(error); + get_mplock(); error = vacl_set_acl((struct vnode *)fp->f_data, uap->type, uap->aclp); + rel_mplock(); fdrop(fp); return (error); } /* * Given a file path, delete an ACL from it. + * + * MPALMOSTSAFE */ int sys___acl_delete_file(struct __acl_delete_file_args *uap) @@ -241,6 +262,7 @@ sys___acl_delete_file(struct __acl_delete_file_args *uap) int error; vp = NULL; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = nlookup(&nd); @@ -252,11 +274,15 @@ sys___acl_delete_file(struct __acl_delete_file_args *uap) error = vacl_delete(vp, uap->type); vrele(vp); } + rel_mplock(); + return (error); } /* * Given a file path, delete an ACL from it. + * + * MPALMOSTSAFE */ int sys___acl_delete_fd(struct __acl_delete_fd_args *uap) @@ -268,13 +294,17 @@ sys___acl_delete_fd(struct __acl_delete_fd_args *uap) KKASSERT(td->td_proc); if ((error = holdvnode(td->td_proc->p_fd, uap->filedes, &fp)) != 0) return(error); + get_mplock(); error = vacl_delete((struct vnode *)fp->f_data, uap->type); + rel_mplock(); fdrop(fp); return (error); } /* * Given a file path, check an ACL for it + * + * MPALMOSTSAFE */ int sys___acl_aclcheck_file(struct __acl_aclcheck_file_args *uap) @@ -284,6 +314,7 @@ sys___acl_aclcheck_file(struct __acl_aclcheck_file_args *uap) int error; vp = NULL; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = nlookup(&nd); @@ -295,11 +326,14 @@ sys___acl_aclcheck_file(struct __acl_aclcheck_file_args *uap) error = vacl_aclcheck(vp, uap->type, uap->aclp); vrele(vp); } + rel_mplock(); return (error); } /* * Given a file descriptor, check an ACL for it + * + * MPALMOSTSAFE */ int sys___acl_aclcheck_fd(struct __acl_aclcheck_fd_args *uap) @@ -311,7 +345,9 @@ sys___acl_aclcheck_fd(struct __acl_aclcheck_fd_args *uap) KKASSERT(td->td_proc); if ((error = holdvnode(td->td_proc->p_fd, uap->filedes, &fp)) != 0) return(error); + get_mplock(); error = vacl_aclcheck((struct vnode *)fp->f_data, uap->type, uap->aclp); + rel_mplock(); fdrop(fp); return (error); } diff --git a/sys/kern/kern_checkpoint.c b/sys/kern/kern_checkpoint.c index e2c176b620..7efcff160f 100644 --- a/sys/kern/kern_checkpoint.c +++ b/sys/kern/kern_checkpoint.c @@ -704,6 +704,9 @@ ckpt_freeze_proc(struct lwp *lp, struct file *fp) return error; } +/* + * MPALMOSTSAFE + */ int sys_sys_checkpoint(struct sys_checkpoint_args *uap) { @@ -725,6 +728,8 @@ sys_sys_checkpoint(struct sys_checkpoint_args *uap) if (uap->pid != -1 && uap->pid != p->p_pid) return (EINVAL); + get_mplock(); + switch (uap->type) { case CKPT_FREEZE: fp = NULL; @@ -738,10 +743,14 @@ sys_sys_checkpoint(struct sys_checkpoint_args *uap) fdrop(fp); break; case CKPT_THAW: - if (uap->pid != -1) - return EINVAL; - if ((fp = holdfp(p->p_fd, uap->fd, FREAD)) == NULL) - return EBADF; + if (uap->pid != -1) { + error = EINVAL; + break; + } + if ((fp = holdfp(p->p_fd, uap->fd, FREAD)) == NULL) { + error = EBADF; + break; + } uap->sysmsg_result = uap->retval; error = ckpt_thaw_proc(lp, fp); fdrop(fp); @@ -750,6 +759,7 @@ sys_sys_checkpoint(struct sys_checkpoint_args *uap) error = EOPNOTSUPP; break; } + rel_mplock(); return error; } diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index e7e0b07a63..4053a9f91a 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -870,12 +870,17 @@ kern_shutdown(int fd, int how) return (error); } +/* + * MPALMOSTSAFE + */ int sys_shutdown(struct shutdown_args *uap) { int error; + get_mplock(); error = kern_shutdown(uap->s, uap->how); + rel_mplock(); return (error); } @@ -921,8 +926,9 @@ sys_fstat(struct fstat_args *uap) /* * Return pathconf information about a file descriptor. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_fpathconf(struct fpathconf_args *uap) { @@ -932,8 +938,6 @@ sys_fpathconf(struct fpathconf_args *uap) struct vnode *vp; int error = 0; - KKASSERT(p); - if ((fp = holdfp(p->p_fd, uap->fd, -1)) == NULL) return (EBADF); @@ -950,7 +954,9 @@ sys_fpathconf(struct fpathconf_args *uap) case DTYPE_FIFO: case DTYPE_VNODE: vp = (struct vnode *)fp->f_data; + get_mplock(); error = VOP_PATHCONF(vp, uap->name, &uap->sysmsg_reg); + rel_mplock(); break; default: error = EOPNOTSUPP; @@ -2347,6 +2353,8 @@ fdrop(struct file *fp) * * Just attempt to get a record lock of the requested type on * the entire file (l_whence = SEEK_SET, l_start = 0, l_len = 0). + * + * MPALMOSTSAFE */ int sys_flock(struct flock_args *uap) @@ -2359,6 +2367,7 @@ sys_flock(struct flock_args *uap) if ((fp = holdfp(p->p_fd, uap->fd, -1)) == NULL) return (EBADF); + get_mplock(); if (fp->f_type != DTYPE_VNODE) { error = EOPNOTSUPP; goto done; @@ -2387,6 +2396,7 @@ sys_flock(struct flock_args *uap) else error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_WAIT); done: + rel_mplock(); fdrop(fp); return (error); } @@ -2399,7 +2409,6 @@ done: * consists of only the ``open()'' routine, because all subsequent * references to this file will be direct to the other driver. */ -/* ARGSUSED */ static int fdopen(struct dev_open_args *ap) { diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 5d0bdd58a1..74d4efda28 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -378,6 +378,9 @@ filt_timer(struct knote *kn, long hint) return (kn->kn_data != 0); } +/* + * MPSAFE + */ int sys_kqueue(struct kqueue_args *uap) { @@ -405,6 +408,9 @@ sys_kqueue(struct kqueue_args *uap) return (error); } +/* + * MPALMOSTSAFE + */ int sys_kevent(struct kevent_args *uap) { @@ -416,8 +422,6 @@ sys_kevent(struct kevent_args *uap) struct timespec ts; int i, n, nerrors, error; - KKASSERT(p); - fp = holdfp(p->p_fd, uap->fd, -1); if (fp == NULL) return (EBADF); @@ -436,10 +440,11 @@ sys_kevent(struct kevent_args *uap) kq = (struct kqueue *)fp->f_data; nerrors = 0; + get_mplock(); while (uap->nchanges > 0) { n = uap->nchanges > KQ_NEVENTS ? KQ_NEVENTS : uap->nchanges; error = copyin(uap->changelist, kq->kq_kev, - n * sizeof(struct kevent)); + n * sizeof(struct kevent)); if (error) goto done; for (i = 0; i < n; i++) { @@ -470,8 +475,10 @@ sys_kevent(struct kevent_args *uap) goto done; } - error = kqueue_scan(fp, uap->nevents, uap->eventlist, uap->timeout, td, &uap->sysmsg_result); + error = kqueue_scan(fp, uap->nevents, uap->eventlist, + uap->timeout, td, &uap->sysmsg_result); done: + rel_mplock(); if (fp != NULL) fdrop(fp); return (error); diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 9974137a4a..94d11a5654 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -532,6 +532,8 @@ exec_fail: /* * execve() system call. + * + * MPALMOSTSAFE */ int sys_execve(struct execve_args *uap) @@ -540,8 +542,10 @@ sys_execve(struct execve_args *uap) struct image_args args; int error; - error = nlookup_init(&nd, uap->fname, UIO_USERSPACE, NLC_FOLLOW); bzero(&args, sizeof(args)); + + get_mplock(); + error = nlookup_init(&nd, uap->fname, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) { error = exec_copyin_args(&args, uap->fname, PATH_USERSPACE, uap->argv, uap->envv); @@ -556,6 +560,7 @@ sys_execve(struct execve_args *uap) exit1(W_EXITCODE(0, SIGABRT)); /* NOTREACHED */ } + rel_mplock(); /* * The syscall result is returned in registers to the new program. diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index f940f00fcd..ce2be1c256 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -109,17 +109,23 @@ struct lwplist deadlwp_list[MAXCPU]; * Death of process. * * SYS_EXIT_ARGS(int rval) + * + * MPALMOSTSAFE */ int sys_exit(struct exit_args *uap) { + get_mplock(); exit1(W_EXITCODE(uap->rval, 0)); /* NOTREACHED */ + rel_mplock(); } /* * Extended exit -- * Death of a lwp or process with optional bells and whistles. + * + * MPALMOSTSAFE */ int sys_extexit(struct extexit_args *uap) @@ -135,7 +141,6 @@ sys_extexit(struct extexit_args *uap) case EXTEXIT_PROC: case EXTEXIT_LWP: break; - default: return (EINVAL); } @@ -143,17 +148,17 @@ sys_extexit(struct extexit_args *uap) switch (action) { case EXTEXIT_SIMPLE: break; - case EXTEXIT_SETINT: error = copyout(&uap->status, uap->addr, sizeof(uap->status)); if (error) return (error); break; - default: return (EINVAL); } + get_mplock(); + switch (who) { case EXTEXIT_LWP: /* @@ -168,7 +173,6 @@ sys_extexit(struct extexit_args *uap) } /* else last lwp in proc: do the real thing */ /* FALLTHROUGH */ - default: /* to help gcc */ case EXTEXIT_PROC: exit1(W_EXITCODE(uap->status, 0)); @@ -176,6 +180,7 @@ sys_extexit(struct extexit_args *uap) } /* NOTREACHED */ + rel_mplock(); /* safety */ } /* @@ -662,14 +667,18 @@ lwp_dispose(struct lwp *lp) kfree(lp, M_LWP); } +/* + * MPSAFE + */ int sys_wait4(struct wait_args *uap) { struct rusage rusage; int error, status; - error = kern_wait(uap->pid, uap->status ? &status : NULL, - uap->options, uap->rusage ? &rusage : NULL, &uap->sysmsg_result); + error = kern_wait(uap->pid, (uap->status ? &status : NULL), + uap->options, (uap->rusage ? &rusage : NULL), + &uap->sysmsg_result); if (error == 0 && uap->status) error = copyout(&status, uap->status, sizeof(*uap->status)); @@ -682,6 +691,8 @@ sys_wait4(struct wait_args *uap) * wait1() * * wait_args(int pid, int *status, int options, struct rusage *rusage) + * + * MPALMOSTSAFE */ int kern_wait(pid_t pid, int *status, int options, struct rusage *rusage, int *res) @@ -696,6 +707,7 @@ kern_wait(pid_t pid, int *status, int options, struct rusage *rusage, int *res) pid = -q->p_pgid; if (options &~ (WUNTRACED|WNOHANG|WCONTINUED|WLINUXCLONE)) return (EINVAL); + get_mplock(); loop: /* * Hack for backwards compatibility with badly written user code. @@ -796,7 +808,8 @@ loop: proc_reparent(p, t); ksignal(t, SIGCHLD); wakeup((caddr_t)t); - return (0); + error = 0; + goto done; } /* @@ -837,7 +850,8 @@ loop: vm_waitproc(p); kfree(p, M_PROC); nprocs--; - return (0); + error = 0; + goto done; } if (p->p_stat == SSTOP && (p->p_flag & P_WAITED) == 0 && (p->p_flag & P_TRACED || options & WUNTRACED)) { @@ -849,7 +863,8 @@ loop: /* Zero rusage so we get something consistent. */ if (rusage) bzero(rusage, sizeof(rusage)); - return (0); + error = 0; + goto done; } if (options & WCONTINUED && (p->p_flag & P_CONTINUED)) { *res = p->p_pid; @@ -857,18 +872,25 @@ loop: if (status) *status = SIGCONT; - return (0); + error = 0; + goto done; } } - if (nfound == 0) - return (ECHILD); + if (nfound == 0) { + error = ECHILD; + goto done; + } if (options & WNOHANG) { *res = 0; - return (0); + error = 0; + goto done; } error = tsleep((caddr_t)q, PCATCH, "wait", 0); - if (error) + if (error) { +done: + rel_mplock(); return (error); + } goto loop; } diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 405128cd49..a477ea0ccb 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -103,8 +103,11 @@ rb_lwp_compare(struct lwp *lp1, struct lwp *lp2) RB_GENERATE2(lwp_rb_tree, lwp, u.lwp_rbnode, rb_lwp_compare, lwpid_t, lwp_tid); - -/* ARGSUSED */ +/* + * Fork system call + * + * MPALMOSTSAFE + */ int sys_fork(struct fork_args *uap) { @@ -112,16 +115,20 @@ sys_fork(struct fork_args *uap) struct proc *p2; int error; + get_mplock(); error = fork1(lp, RFFDG | RFPROC | RFPGLOCK, &p2); if (error == 0) { start_forked_proc(lp, p2); uap->sysmsg_fds[0] = p2->p_pid; uap->sysmsg_fds[1] = 0; } + rel_mplock(); return error; } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_vfork(struct vfork_args *uap) { @@ -129,12 +136,14 @@ sys_vfork(struct vfork_args *uap) struct proc *p2; int error; + get_mplock(); error = fork1(lp, RFFDG | RFPROC | RFPPWAIT | RFMEM | RFPGLOCK, &p2); if (error == 0) { start_forked_proc(lp, p2); uap->sysmsg_fds[0] = p2->p_pid; uap->sysmsg_fds[1] = 0; } + rel_mplock(); return error; } @@ -148,6 +157,8 @@ sys_vfork(struct vfork_args *uap) * created. * * rfork { int flags } + * + * MPALMOSTSAFE */ int sys_rfork(struct rfork_args *uap) @@ -159,6 +170,7 @@ sys_rfork(struct rfork_args *uap) if ((uap->flags & RFKERNELONLY) != 0) return (EINVAL); + get_mplock(); error = fork1(lp, uap->flags | RFPGLOCK, &p2); if (error == 0) { if (p2) @@ -166,9 +178,13 @@ sys_rfork(struct rfork_args *uap) uap->sysmsg_fds[0] = p2 ? p2->p_pid : 0; uap->sysmsg_fds[1] = 0; } + rel_mplock(); return error; } +/* + * MPALMOSTSAFE + */ int sys_lwp_create(struct lwp_create_args *uap) { @@ -181,6 +197,7 @@ sys_lwp_create(struct lwp_create_args *uap) if (error) goto fail2; + get_mplock(); plimit_lwp_fork(p); /* force exclusive access */ lp = lwp_fork(curthread->td_lwp, p, RFPROC); error = cpu_prepare_lwp(lp, ¶ms); @@ -199,6 +216,7 @@ sys_lwp_create(struct lwp_create_args *uap) lp->lwp_stat = LSRUN; p->p_usched->setrunqueue(lp); crit_exit(); + rel_mplock(); return (0); @@ -210,6 +228,7 @@ fail: lp->lwp_thread->td_flags |= TDF_EXITING; PHOLD(p); lwp_dispose(lp); + rel_mplock(); fail2: return (error); } diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 243c8940eb..733e3aac3d 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -190,6 +190,8 @@ kern_jail(struct prison *pr, struct jail *j) * jail() * * jail_args(syscallarg(struct jail *) jail) + * + * MPALMOSTSAFE */ int sys_jail(struct jail_args *uap) @@ -213,6 +215,7 @@ sys_jail(struct jail_args *uap) pr = kmalloc(sizeof(*pr), M_PRISON, M_WAITOK | M_ZERO); SLIST_INIT(&pr->pr_ips); + get_mplock(); switch (jversion) { case 0: @@ -272,6 +275,7 @@ sys_jail(struct jail_args *uap) goto out; uap->sysmsg_result = pr->pr_id; + rel_mplock(); return (0); out: @@ -281,12 +285,15 @@ out: SLIST_REMOVE_HEAD(&pr->pr_ips, entries); kfree(jip, M_PRISON); } + rel_mplock(); kfree(pr, M_PRISON); return (error); } /* * int jail_attach(int jid); + * + * MPALMOSTSAFE */ int sys_jail_attach(struct jail_attach_args *uap) @@ -297,8 +304,10 @@ sys_jail_attach(struct jail_attach_args *uap) error = priv_check(td, PRIV_JAIL_ATTACH); if (error) return(error); - - return(kern_jail_attach(uap->jid)); + get_mplock(); + error = kern_jail_attach(uap->jid); + rel_mplock(); + return (error); } static void diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index f26cf46f56..5af53133e5 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -61,6 +61,9 @@ static int ktrcanset (struct proc *,struct proc *); static int ktrsetchildren (struct proc *,struct proc *,int,int, ktrace_node_t); static int ktrops (struct proc *,struct proc *,int,int, ktrace_node_t); +/* + * MPSAFE + */ static struct ktr_header * ktrgetheader(int type) { @@ -224,6 +227,9 @@ static int ktrace_clear_callback(struct proc *p, void *data); #endif +/* + * MPALMOSTSAFE + */ int sys_ktrace(struct ktrace_args *uap) { @@ -241,6 +247,7 @@ sys_ktrace(struct ktrace_args *uap) struct nlookupdata nd; ktrace_node_t tracenode = NULL; + get_mplock(); curp->p_traceflag |= KTRFAC_ACTIVE; if (ops != KTROP_CLEAR) { /* @@ -255,7 +262,7 @@ sys_ktrace(struct ktrace_args *uap) if (error) { curp->p_traceflag &= ~KTRFAC_ACTIVE; nlookup_done(&nd); - return (error); + goto done; } MALLOC(tracenode, ktrace_node_t, sizeof (struct ktrace_node), M_KTRACE, M_WAITOK | M_ZERO); @@ -322,6 +329,7 @@ done: if (tracenode) ktrdestroy(&tracenode); curp->p_traceflag &= ~KTRFAC_ACTIVE; + rel_mplock(); return (error); #else return ENOSYS; @@ -362,8 +370,9 @@ ktrace_clear_callback(struct proc *p, void *data) /* * utrace system call + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_utrace(struct utrace_args *uap) { @@ -383,7 +392,9 @@ sys_utrace(struct utrace_args *uap) if (!copyin(uap->addr, cp, uap->len)) { kth->ktr_buf = cp; kth->ktr_len = uap->len; + get_mplock(); ktrwrite(p, kth, NULL); + rel_mplock(); } FREE(kth, M_KTRACE); FREE(cp, M_KTRACE); diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index 9753aaadc5..4225e033e7 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -741,8 +741,9 @@ linker_ddb_symbol_values(c_linker_sym_t sym, linker_symval_t *symval) /* * Syscalls. + * + * MPALMOSTSAFE */ - int sys_kldload(struct kldload_args *uap) { @@ -777,7 +778,10 @@ sys_kldload(struct kldload_args *uap) modname = file; } - if ((error = linker_load_module(kldname, modname, NULL, NULL, &lf)) != 0) + get_mplock(); + error = linker_load_module(kldname, modname, NULL, NULL, &lf); + rel_mplock(); + if (error) goto out; lf->userrefs++; @@ -789,6 +793,9 @@ out: return error; } +/* + * MPALMOSTSAFE + */ int sys_kldunload(struct kldunload_args *uap) { @@ -802,6 +809,7 @@ sys_kldunload(struct kldunload_args *uap) if ((error = priv_check(td, PRIV_KLD_UNLOAD)) != 0) return error; + get_mplock(); lf = linker_find_file_by_id(uap->fileid); if (lf) { KLD_DPF(FILE, ("kldunload: lf->userrefs=%d\n", lf->userrefs)); @@ -814,19 +822,23 @@ sys_kldunload(struct kldunload_args *uap) error = linker_file_unload(lf); if (error) lf->userrefs++; - } else + } else { error = ENOENT; - + } out: + rel_mplock(); return error; } +/* + * MPALMOSTSAFE + */ int sys_kldfind(struct kldfind_args *uap) { char *filename = NULL, *modulename; linker_file_t lf; - int error = 0; + int error; uap->sysmsg_result = -1; @@ -838,11 +850,13 @@ sys_kldfind(struct kldfind_args *uap) if (modulename == NULL) modulename = filename; + get_mplock(); lf = linker_find_file_by_name(modulename); if (lf) uap->sysmsg_result = lf->id; else error = ENOENT; + rel_mplock(); out: if (filename) @@ -850,15 +864,19 @@ out: return error; } +/* + * MPALMOSTSAFE + */ int sys_kldnext(struct kldnext_args *uap) { linker_file_t lf; int error = 0; - if (uap->fileid == 0) + get_mplock(); + if (uap->fileid == 0) { lf = TAILQ_FIRST(&linker_files); - else { + } else { lf = linker_find_file_by_id(uap->fileid); if (lf == NULL) { error = ENOENT; @@ -878,9 +896,13 @@ sys_kldnext(struct kldnext_args *uap) uap->sysmsg_result = 0; out: + rel_mplock(); return error; } +/* + * MPALMOSTSAFE + */ int sys_kldstat(struct kldstat_args *uap) { @@ -890,6 +912,7 @@ sys_kldstat(struct kldstat_args *uap) struct kld_file_stat* stat; int namelen; + get_mplock(); lf = linker_find_file_by_id(uap->fileid); if (!lf) { error = ENOENT; @@ -925,27 +948,37 @@ sys_kldstat(struct kldstat_args *uap) uap->sysmsg_result = 0; out: + rel_mplock(); return error; } +/* + * MPALMOSTSAFE + */ int sys_kldfirstmod(struct kldfirstmod_args *uap) { linker_file_t lf; int error = 0; + get_mplock(); lf = linker_find_file_by_id(uap->fileid); if (lf) { if (TAILQ_FIRST(&lf->modules)) uap->sysmsg_result = module_getid(TAILQ_FIRST(&lf->modules)); else uap->sysmsg_result = 0; - } else + } else { error = ENOENT; + } + rel_mplock(); return error; } +/* + * MPALMOSTSAFE + */ int sys_kldsym(struct kldsym_args *uap) { @@ -956,6 +989,7 @@ sys_kldsym(struct kldsym_args *uap) struct kld_sym_lookup lookup; int error = 0; + get_mplock(); if ((error = copyin(uap->data, &lookup, sizeof(lookup))) != 0) goto out; if (lookup.version != sizeof(lookup) || uap->cmd != KLDSYM_LOOKUP) { @@ -994,6 +1028,7 @@ sys_kldsym(struct kldsym_args *uap) error = ENOENT; } out: + rel_mplock(); if (symstr) kfree(symstr, M_TEMP); return error; diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c index 7e4ed435ed..de2c770208 100644 --- a/sys/kern/kern_module.c +++ b/sys/kern/kern_module.c @@ -240,49 +240,71 @@ module_setspecific(module_t mod, modspecific_t *datap) /* * Syscalls. + * + * MPALMOSTSAFE */ int sys_modnext(struct modnext_args *uap) { module_t mod; + int error; + get_mplock(); uap->sysmsg_result = -1; if (uap->modid == 0) { mod = TAILQ_FIRST(&modules); if (mod) { uap->sysmsg_result = mod->id; - return 0; - } else - return ENOENT; + error = 0; + goto done; + } else { + error = ENOENT; + goto done; + } } mod = module_lookupbyid(uap->modid); - if (!mod) - return ENOENT; + if (!mod) { + error = ENOENT; + goto done; + } if (TAILQ_NEXT(mod, link)) uap->sysmsg_result = TAILQ_NEXT(mod, link)->id; else uap->sysmsg_result = 0; - return 0; + error = 0; +done: + rel_mplock(); + return error; } +/* + * MPALMOSTSAFE + */ int sys_modfnext(struct modfnext_args *uap) { module_t mod; + int error; + get_mplock(); uap->sysmsg_result = -1; mod = module_lookupbyid(uap->modid); - if (!mod) - return ENOENT; + if (!mod) { + error = ENOENT; + goto done; + } if (TAILQ_NEXT(mod, flink)) uap->sysmsg_result = TAILQ_NEXT(mod, flink)->id; else uap->sysmsg_result = 0; - return 0; + error = 0; +done: + rel_mplock(); + return error; } struct module_stat_v1 { @@ -292,18 +314,24 @@ struct module_stat_v1 { int id; }; +/* + * MPALMOSTSAFE + */ int sys_modstat(struct modstat_args *uap) { module_t mod; - int error = 0; + int error; int namelen; int version; struct module_stat* stat; + get_mplock(); mod = module_lookupbyid(uap->modid); - if (!mod) - return ENOENT; + if (!mod) { + error = ENOENT; + goto out; + } stat = uap->stat; @@ -340,16 +368,21 @@ sys_modstat(struct modstat_args *uap) uap->sysmsg_result = 0; out: + rel_mplock(); return error; } +/* + * MPALMOSTSAFE + */ int sys_modfind(struct modfind_args *uap) { - int error = 0; + int error; char name[MAXMODNAME]; module_t mod; + get_mplock(); if ((error = copyinstr(uap->name, name, sizeof name, 0)) != 0) goto out; @@ -360,5 +393,6 @@ sys_modfind(struct modfind_args *uap) uap->sysmsg_result = mod->id; out: + rel_mplock(); return error; } diff --git a/sys/kern/kern_ntptime.c b/sys/kern/kern_ntptime.c index 749fdb4113..9a8ad11084 100644 --- a/sys/kern/kern_ntptime.c +++ b/sys/kern/kern_ntptime.c @@ -265,6 +265,8 @@ SYSCTL_OPAQUE(_kern_ntp_pll, OID_AUTO, time_freq, CTLFLAG_RD, &time_freq, sizeof * See the timex.h header file for synopsis and API description. Note * that the timex.constant structure member has a dual purpose to set * the time constant and to set the TAI offset. + * + * MPALMOSTSAFE */ int sys_ntp_adjtime(struct ntp_adjtime_args *uap) @@ -293,6 +295,8 @@ sys_ntp_adjtime(struct ntp_adjtime_args *uap) error = priv_check(td, PRIV_NTP_ADJTIME); if (error) return (error); + + get_mplock(); crit_enter(); if (modes & MOD_MAXERROR) time_maxerror = ntv.maxerror; @@ -395,6 +399,7 @@ sys_ntp_adjtime(struct ntp_adjtime_args *uap) ntv.stbcnt = pps_stbcnt; #endif /* PPS_SYNC */ crit_exit(); + rel_mplock(); error = copyout((caddr_t)&ntv, (caddr_t)uap->tp, sizeof(ntv)); if (error) diff --git a/sys/kern/kern_p1003_1b.c b/sys/kern/kern_p1003_1b.c index d8b3a86e1d..bd9f191829 100644 --- a/sys/kern/kern_p1003_1b.c +++ b/sys/kern/kern_p1003_1b.c @@ -168,24 +168,32 @@ static int sched_attach(void) return ret; } +/* + * MPALMOSTSAFE + */ int sys_sched_setparam(struct sched_setparam_args *uap) { struct proc *p = curproc; struct lwp *lp; int e; - struct sched_param sched_param; + copyin(uap->param, &sched_param, sizeof(sched_param)); + get_mplock(); if ((e = p31b_proc(p, uap->pid, &p)) == 0) { lp = FIRST_LWP_IN_PROC(p); /* XXX lwp */ e = ksched_setparam(&uap->sysmsg_reg, ksched, lp, - (const struct sched_param *)&sched_param); + (const struct sched_param *)&sched_param); } + rel_mplock(); return e; } +/* + * MPALMOSTSAFE + */ int sys_sched_getparam(struct sched_getparam_args *uap) { @@ -195,41 +203,51 @@ sys_sched_getparam(struct sched_getparam_args *uap) struct sched_param sched_param; int e; + get_mplock(); if (uap->pid != 0 && uap->pid != p->p_pid) { e = p31b_proc(p, uap->pid, &targetp); if (e) - return e; + goto done; } else { targetp = p; } lp = FIRST_LWP_IN_PROC(targetp); /* XXX lwp */ e = ksched_getparam(&uap->sysmsg_reg, ksched, lp, &sched_param); - - if (!e) +done: + rel_mplock(); + if (e == 0) copyout(&sched_param, uap->param, sizeof(sched_param)); - return e; } +/* + * MPALMOSTSAFE + */ int sys_sched_setscheduler(struct sched_setscheduler_args *uap) { struct proc *p = curproc; struct lwp *lp; int e; - struct sched_param sched_param; + copyin(uap->param, &sched_param, sizeof(sched_param)); + get_mplock(); if ((e = p31b_proc(p, uap->pid, &p)) == 0) { lp = FIRST_LWP_IN_PROC(p); /* XXX lwp */ e = ksched_setscheduler(&uap->sysmsg_reg, ksched, lp, - uap->policy, (const struct sched_param *)&sched_param); + uap->policy, + (const struct sched_param *)&sched_param); } + rel_mplock(); return e; } +/* + * MPALMOSTSAFE + */ int sys_sched_getscheduler(struct sched_getscheduler_args *uap) { @@ -238,38 +256,52 @@ sys_sched_getscheduler(struct sched_getscheduler_args *uap) struct lwp *lp; int e; + get_mplock(); if (uap->pid != 0 && uap->pid != p->p_pid) { e = p31b_proc(p, uap->pid, &targetp); if (e) - return e; + goto done; } else { targetp = p; } lp = FIRST_LWP_IN_PROC(targetp); /* XXX lwp */ e = ksched_getscheduler(&uap->sysmsg_reg, ksched, lp); - +done: + rel_mplock(); return e; } +/* + * MPSAFE + */ int sys_sched_yield(struct sched_yield_args *uap) { return ksched_yield(&uap->sysmsg_reg, ksched); } +/* + * MPSAFE + */ int sys_sched_get_priority_max(struct sched_get_priority_max_args *uap) { return ksched_get_priority_max(&uap->sysmsg_reg, ksched, uap->policy); } +/* + * MPSAFE + */ int sys_sched_get_priority_min(struct sched_get_priority_min_args *uap) { return ksched_get_priority_min(&uap->sysmsg_reg, ksched, uap->policy); } +/* + * MPALMOSTSAFE + */ int sys_sched_rr_get_interval(struct sched_rr_get_interval_args *uap) { @@ -277,16 +309,19 @@ sys_sched_rr_get_interval(struct sched_rr_get_interval_args *uap) struct proc *p = curproc; struct lwp *lp = curthread->td_lwp; + get_mplock(); if ((e = p31b_proc(p, uap->pid, &p)) == 0) { - e = ksched_rr_get_interval(&uap->sysmsg_reg, ksched, - lp, uap->interval); + e = ksched_rr_get_interval(&uap->sysmsg_reg, ksched, + lp, uap->interval); } + rel_mplock(); return e; } #endif -static void p31binit(void *notused) +static void +p31binit(void *notused) { (void) sched_attach(); p31b_setcfg(CTL_P1003_1B_PAGESIZE, PAGE_SIZE); diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 70b37707e4..0abdbcf61f 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -67,9 +67,8 @@ static MALLOC_DEFINE(M_CRED, "cred", "credentials"); /* - * NOT MP SAFE due to p_pptr access + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_getpid(struct getpid_args *uap) { @@ -77,22 +76,31 @@ sys_getpid(struct getpid_args *uap) uap->sysmsg_fds[0] = p->p_pid; #if defined(COMPAT_43) || defined(COMPAT_SUNOS) + get_mplock(); uap->sysmsg_fds[1] = p->p_pptr->p_pid; + rel_mplock(); #endif return (0); } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_getppid(struct getppid_args *uap) { struct proc *p = curproc; + get_mplock(); uap->sysmsg_result = p->p_pptr->p_pid; + rel_mplock(); + return (0); } -/* ARGSUSED */ +/* + * MPSAFE + */ int sys_lwp_gettid(struct lwp_gettid_args *uap) { @@ -105,7 +113,7 @@ sys_lwp_gettid(struct lwp_gettid_args *uap) /* * Get process group ID; note that POSIX getpgrp takes no parameter * - * MP SAFE + * MPSAFE XXX pgrp */ int sys_getpgrp(struct getpgrp_args *uap) @@ -118,49 +126,66 @@ sys_getpgrp(struct getpgrp_args *uap) /* * Get an arbitrary pid's process group id + * + * MPALMOSTSAFE */ int sys_getpgid(struct getpgid_args *uap) { struct proc *p = curproc; struct proc *pt; + int error; - pt = p; - if (uap->pid == 0) - goto found; + get_mplock(); + error = 0; - if ((pt = pfind(uap->pid)) == 0) - return ESRCH; -found: - uap->sysmsg_result = pt->p_pgrp->pg_id; - return 0; + if (uap->pid == 0) { + pt = p; + } else { + pt = pfind(uap->pid); + if (pt == NULL) + error = ESRCH; + } + if (error == 0) + uap->sysmsg_result = pt->p_pgrp->pg_id; + rel_mplock(); + return (error); } /* * Get an arbitrary pid's session id. + * + * MPALMOSTSAFE */ int sys_getsid(struct getsid_args *uap) { struct proc *p = curproc; struct proc *pt; + int error; - pt = p; - if (uap->pid == 0) - goto found; + get_mplock(); + error = 0; - if ((pt = pfind(uap->pid)) == 0) - return ESRCH; -found: - uap->sysmsg_result = pt->p_session->s_sid; - return 0; + if (uap->pid == 0) { + pt = p; + } else { + pt = pfind(uap->pid); + if (pt == NULL) + error = ESRCH; + } + if (error == 0) + uap->sysmsg_result = pt->p_session->s_sid; + rel_mplock(); + return (error); } /* - * getuid() - MP SAFE + * getuid() + * + * MPSAFE XXX ucred */ -/* ARGSUSED */ int sys_getuid(struct getuid_args *uap) { @@ -174,9 +199,10 @@ sys_getuid(struct getuid_args *uap) } /* - * geteuid() - MP SAFE + * geteuid() + * + * MPSAFE XXX ucred */ -/* ARGSUSED */ int sys_geteuid(struct geteuid_args *uap) { @@ -187,9 +213,10 @@ sys_geteuid(struct geteuid_args *uap) } /* - * getgid() - MP SAFE + * getgid() + * + * MPSAFE XXX UCRED */ -/* ARGSUSED */ int sys_getgid(struct getgid_args *uap) { @@ -207,9 +234,8 @@ sys_getgid(struct getgid_args *uap) * via getgroups. This syscall exists because it is somewhat painful to do * correctly in a library function. * - * MP SAFE + * MPSAFE */ -/* ARGSUSED */ int sys_getegid(struct getegid_args *uap) { @@ -219,6 +245,9 @@ sys_getegid(struct getegid_args *uap) return (0); } +/* + * MPSAFE + */ int sys_getgroups(struct getgroups_args *uap) { @@ -227,10 +256,7 @@ sys_getgroups(struct getgroups_args *uap) u_int ngrp; int error; - if (p == NULL) /* API enforcement */ - return(EPERM); cr = p->p_ucred; - if ((ngrp = uap->gidsetsize) == 0) { uap->sysmsg_result = cr->cr_ngroups; return (0); @@ -238,26 +264,32 @@ sys_getgroups(struct getgroups_args *uap) if (ngrp < cr->cr_ngroups) return (EINVAL); ngrp = cr->cr_ngroups; - if ((error = copyout((caddr_t)cr->cr_groups, - (caddr_t)uap->gidset, ngrp * sizeof(gid_t)))) - return (error); - uap->sysmsg_result = ngrp; - return (0); + error = copyout((caddr_t)cr->cr_groups, + (caddr_t)uap->gidset, ngrp * sizeof(gid_t)); + if (error == 0) + uap->sysmsg_result = ngrp; + return (error); } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_setsid(struct setsid_args *uap) { struct proc *p = curproc; + int error; + get_mplock(); if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) { - return (EPERM); + error = EPERM; } else { - (void)enterpgrp(p, p->p_pid, 1); + enterpgrp(p, p->p_pid, 1); uap->sysmsg_result = p->p_pid; - return (0); + error = 0; } + rel_mplock(); + return (error); } /* @@ -272,35 +304,55 @@ sys_setsid(struct setsid_args *uap) * if pgid != pid * there must exist some pid in same session having pgid (EPERM) * pid must not be session leader (EPERM) + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_setpgid(struct setpgid_args *uap) { struct proc *curp = curproc; struct proc *targp; /* target process */ struct pgrp *pgrp; /* target pgrp */ + int error; if (uap->pgid < 0) return (EINVAL); + + get_mplock(); if (uap->pid != 0 && uap->pid != curp->p_pid) { - if ((targp = pfind(uap->pid)) == 0 || !inferior(targp)) - return (ESRCH); - if (targp->p_pgrp == NULL || targp->p_session != curp->p_session) - return (EPERM); - if (targp->p_flag & P_EXEC) - return (EACCES); - } else + if ((targp = pfind(uap->pid)) == 0 || !inferior(targp)) { + error = ESRCH; + goto done; + } + if (targp->p_pgrp == NULL || + targp->p_session != curp->p_session) { + error = EPERM; + goto done; + } + if (targp->p_flag & P_EXEC) { + error = EACCES; + goto done; + } + } else { targp = curp; - if (SESS_LEADER(targp)) - return (EPERM); - if (uap->pgid == 0) + } + if (SESS_LEADER(targp)) { + error = EPERM; + goto done; + } + if (uap->pgid == 0) { uap->pgid = targp->p_pid; - else if (uap->pgid != targp->p_pid) + } else if (uap->pgid != targp->p_pid) { if ((pgrp = pgfind(uap->pgid)) == 0 || - pgrp->pg_session != curp->p_session) - return (EPERM); - return (enterpgrp(targp, uap->pgid, 0)); + pgrp->pg_session != curp->p_session) { + error = EPERM; + goto done; + } + } + error = enterpgrp(targp, uap->pgid, 0); +done: + rel_mplock(); + return (error); } /* @@ -315,7 +367,9 @@ sys_setpgid(struct setpgid_args *uap) */ #define POSIX_APPENDIX_B_4_2_2 -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_setuid(struct setuid_args *uap) { @@ -324,8 +378,7 @@ sys_setuid(struct setuid_args *uap) uid_t uid; int error; - if (p == NULL) /* API enforcement */ - return(EPERM); + get_mplock(); cr = p->p_ucred; /* @@ -354,7 +407,7 @@ sys_setuid(struct setuid_args *uap) uid != cr->cr_uid && /* allow setuid(geteuid()) */ #endif (error = priv_check_cred(cr, PRIV_CRED_SETUID, 0))) - return (error); + goto done; #ifdef _POSIX_SAVED_IDS /* @@ -397,10 +450,15 @@ sys_setuid(struct setuid_args *uap) change_euid(uid); setsugid(); } - return (0); + error = 0; +done: + rel_mplock(); + return (error); } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_seteuid(struct seteuid_args *uap) { @@ -409,27 +467,30 @@ sys_seteuid(struct seteuid_args *uap) uid_t euid; int error; - if (p == NULL) /* API enforcement */ - return(EPERM); - cr = p->p_ucred; euid = uap->euid; if (euid != cr->cr_ruid && /* allow seteuid(getuid()) */ euid != cr->cr_svuid && /* allow seteuid(saved uid) */ - (error = priv_check_cred(cr, PRIV_CRED_SETEUID, 0))) + (error = priv_check_cred(cr, PRIV_CRED_SETEUID, 0))) { return (error); + } + /* * Everything's okay, do it. Copy credentials so other references do * not see our changes. */ if (cr->cr_uid != euid) { + get_mplock(); change_euid(euid); setsugid(); + rel_mplock(); } return (0); } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_setgid(struct setgid_args *uap) { @@ -438,8 +499,7 @@ sys_setgid(struct setgid_args *uap) gid_t gid; int error; - if (p == NULL) /* API enforcement */ - return(EPERM); + get_mplock(); cr = p->p_ucred; /* @@ -461,8 +521,9 @@ sys_setgid(struct setgid_args *uap) #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ gid != cr->cr_groups[0] && /* allow setgid(getegid()) */ #endif - (error = priv_check_cred(cr, PRIV_CRED_SETGID, 0))) - return (error); + (error = priv_check_cred(cr, PRIV_CRED_SETGID, 0))) { + goto done; + } #ifdef _POSIX_SAVED_IDS /* @@ -506,10 +567,15 @@ sys_setgid(struct setgid_args *uap) cr->cr_groups[0] = gid; setsugid(); } - return (0); + error = 0; +done: + rel_mplock(); + return (error); } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_setegid(struct setegid_args *uap) { @@ -518,24 +584,28 @@ sys_setegid(struct setegid_args *uap) gid_t egid; int error; - if (p == NULL) /* API enforcement */ - return(EPERM); + get_mplock(); cr = p->p_ucred; - egid = uap->egid; if (egid != cr->cr_rgid && /* allow setegid(getgid()) */ egid != cr->cr_svgid && /* allow setegid(saved gid) */ - (error = priv_check_cred(cr, PRIV_CRED_SETEGID, 0))) - return (error); + (error = priv_check_cred(cr, PRIV_CRED_SETEGID, 0))) { + goto done; + } if (cr->cr_groups[0] != egid) { cr = cratom(&p->p_ucred); cr->cr_groups[0] = egid; setsugid(); } - return (0); + error = 0; +done: + rel_mplock(); + return (error); } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_setgroups(struct setgroups_args *uap) { @@ -544,15 +614,16 @@ sys_setgroups(struct setgroups_args *uap) u_int ngrp; int error; - if (p == NULL) /* API enforcement */ - return(EPERM); + get_mplock(); cr = p->p_ucred; if ((error = priv_check_cred(cr, PRIV_CRED_SETGROUPS, 0))) - return (error); + goto done; ngrp = uap->gidsetsize; - if (ngrp > NGROUPS) - return (EINVAL); + if (ngrp > NGROUPS) { + error = EINVAL; + goto done; + } /* * XXX A little bit lazy here. We could test if anything has * changed before cratom() and setting P_SUGID. @@ -567,16 +638,22 @@ sys_setgroups(struct setgroups_args *uap) */ cr->cr_ngroups = 1; } else { - if ((error = copyin((caddr_t)uap->gidset, - (caddr_t)cr->cr_groups, ngrp * sizeof(gid_t)))) - return (error); + error = copyin(uap->gidset, cr->cr_groups, + ngrp * sizeof(gid_t)); + if (error) + goto done; cr->cr_ngroups = ngrp; } setsugid(); - return (0); + error = 0; +done: + rel_mplock(); + return (error); } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_setreuid(struct setreuid_args *uap) { @@ -585,8 +662,7 @@ sys_setreuid(struct setreuid_args *uap) uid_t ruid, euid; int error; - if (p == NULL) /* API enforcement */ - return(EPERM); + get_mplock(); cr = p->p_ucred; ruid = uap->ruid; @@ -594,8 +670,9 @@ sys_setreuid(struct setreuid_args *uap) if (((ruid != (uid_t)-1 && ruid != cr->cr_ruid && ruid != cr->cr_svuid) || (euid != (uid_t)-1 && euid != cr->cr_uid && euid != cr->cr_ruid && euid != cr->cr_svuid)) && - (error = priv_check_cred(cr, PRIV_CRED_SETREUID, 0)) != 0) - return (error); + (error = priv_check_cred(cr, PRIV_CRED_SETREUID, 0)) != 0) { + goto done; + } if (euid != (uid_t)-1 && cr->cr_uid != euid) { cr = change_euid(euid); @@ -611,10 +688,15 @@ sys_setreuid(struct setreuid_args *uap) cr->cr_svuid = cr->cr_uid; setsugid(); } - return (0); + error = 0; +done: + rel_mplock(); + return (error); } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_setregid(struct setregid_args *uap) { @@ -623,8 +705,7 @@ sys_setregid(struct setregid_args *uap) gid_t rgid, egid; int error; - if (p == NULL) /* API enforcement */ - return(EPERM); + get_mplock(); cr = p->p_ucred; rgid = uap->rgid; @@ -632,8 +713,9 @@ sys_setregid(struct setregid_args *uap) if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid && rgid != cr->cr_svgid) || (egid != (gid_t)-1 && egid != cr->cr_groups[0] && egid != cr->cr_rgid && egid != cr->cr_svgid)) && - (error = priv_check_cred(cr, PRIV_CRED_SETREGID, 0)) != 0) - return (error); + (error = priv_check_cred(cr, PRIV_CRED_SETREGID, 0)) != 0) { + goto done; + } if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) { cr = cratom(&p->p_ucred); @@ -651,15 +733,18 @@ sys_setregid(struct setregid_args *uap) cr->cr_svgid = cr->cr_groups[0]; setsugid(); } - return (0); + error = 0; +done: + rel_mplock(); + return (error); } /* * setresuid(ruid, euid, suid) is like setreuid except control over the * saved uid is explicit. + * + * MPALMOSTSAFE */ - -/* ARGSUSED */ int sys_setresuid(struct setresuid_args *uap) { @@ -668,7 +753,9 @@ sys_setresuid(struct setresuid_args *uap) uid_t ruid, euid, suid; int error; + get_mplock(); cr = p->p_ucred; + ruid = uap->ruid; euid = uap->euid; suid = uap->suid; @@ -678,8 +765,9 @@ sys_setresuid(struct setresuid_args *uap) euid != cr->cr_uid) || (suid != (uid_t)-1 && suid != cr->cr_ruid && suid != cr->cr_svuid && suid != cr->cr_uid)) && - (error = priv_check_cred(cr, PRIV_CRED_SETRESUID, 0)) != 0) - return (error); + (error = priv_check_cred(cr, PRIV_CRED_SETRESUID, 0)) != 0) { + goto done; + } if (euid != (uid_t)-1 && cr->cr_uid != euid) { cr = change_euid(euid); setsugid(); @@ -693,15 +781,18 @@ sys_setresuid(struct setresuid_args *uap) cr->cr_svuid = suid; setsugid(); } - return (0); + error = 0; +done: + rel_mplock(); + return (error); } /* * setresgid(rgid, egid, sgid) is like setregid except control over the * saved gid is explicit. + * + * MPALMOSTSAFE */ - -/* ARGSUSED */ int sys_setresgid(struct setresgid_args *uap) { @@ -710,6 +801,7 @@ sys_setresgid(struct setresgid_args *uap) gid_t rgid, egid, sgid; int error; + get_mplock(); cr = p->p_ucred; rgid = uap->rgid; egid = uap->egid; @@ -720,8 +812,9 @@ sys_setresgid(struct setresgid_args *uap) egid != cr->cr_groups[0]) || (sgid != (gid_t)-1 && sgid != cr->cr_rgid && sgid != cr->cr_svgid && sgid != cr->cr_groups[0])) && - (error = priv_check_cred(cr, PRIV_CRED_SETRESGID, 0)) != 0) - return (error); + (error = priv_check_cred(cr, PRIV_CRED_SETRESGID, 0)) != 0) { + goto done; + } if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) { cr = cratom(&p->p_ucred); @@ -738,17 +831,24 @@ sys_setresgid(struct setresgid_args *uap) cr->cr_svgid = sgid; setsugid(); } - return (0); + error = 0; +done: + rel_mplock(); + return (error); } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_getresuid(struct getresuid_args *uap) { struct proc *p = curproc; - struct ucred *cr = p->p_ucred; + struct ucred *cr; int error1 = 0, error2 = 0, error3 = 0; + get_mplock(); + cr = p->p_ucred; if (uap->ruid) error1 = copyout((caddr_t)&cr->cr_ruid, (caddr_t)uap->ruid, sizeof(cr->cr_ruid)); @@ -758,17 +858,22 @@ sys_getresuid(struct getresuid_args *uap) if (uap->suid) error3 = copyout((caddr_t)&cr->cr_svuid, (caddr_t)uap->suid, sizeof(cr->cr_svuid)); + rel_mplock(); return error1 ? error1 : (error2 ? error2 : error3); } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_getresgid(struct getresgid_args *uap) { struct proc *p = curproc; - struct ucred *cr = p->p_ucred; + struct ucred *cr; int error1 = 0, error2 = 0, error3 = 0; + get_mplock(); + cr = p->p_ucred; if (uap->rgid) error1 = copyout((caddr_t)&cr->cr_rgid, (caddr_t)uap->rgid, sizeof(cr->cr_rgid)); @@ -778,24 +883,25 @@ sys_getresgid(struct getresgid_args *uap) if (uap->sgid) error3 = copyout((caddr_t)&cr->cr_svgid, (caddr_t)uap->sgid, sizeof(cr->cr_svgid)); + rel_mplock(); return error1 ? error1 : (error2 ? error2 : error3); } -/* ARGSUSED */ +/* + * NOTE: OpenBSD sets a P_SUGIDEXEC flag set at execve() time, + * we use P_SUGID because we consider changing the owners as + * "tainting" as well. + * This is significant for procs that start as root and "become" + * a user without an exec - programs cannot know *everything* + * that libc *might* have put in their data segment. + * + * MPSAFE + */ int sys_issetugid(struct issetugid_args *uap) { - struct proc *p = curproc; - /* - * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time, - * we use P_SUGID because we consider changing the owners as - * "tainting" as well. - * This is significant for procs that start as root and "become" - * a user without an exec - programs cannot know *everything* - * that libc *might* have put in their data segment. - */ - uap->sysmsg_result = (p->p_flag & P_SUGID) ? 1 : 0; + uap->sysmsg_result = (curproc->p_flag & P_SUGID) ? 1 : 0; return (0); } @@ -1086,40 +1192,51 @@ cru2x(struct ucred *cr, struct xucred *xcr) /* * Get login name, if available. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_getlogin(struct getlogin_args *uap) { struct proc *p = curproc; + char buf[MAXLOGNAME]; + int error; - if (uap->namelen > MAXLOGNAME) + if (uap->namelen > MAXLOGNAME) /* namelen is unsigned */ uap->namelen = MAXLOGNAME; - return (copyout((caddr_t) p->p_pgrp->pg_session->s_login, - (caddr_t) uap->namebuf, uap->namelen)); + get_mplock(); + bzero(buf, sizeof(buf)); + bcopy(p->p_pgrp->pg_session->s_login, buf, uap->namelen); + rel_mplock(); + + error = copyout(buf, uap->namebuf, uap->namelen); + return (error); } /* * Set login name. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_setlogin(struct setlogin_args *uap) { struct proc *p = curproc; + char buf[MAXLOGNAME]; int error; - char logintmp[MAXLOGNAME]; KKASSERT(p != NULL); if ((error = priv_check_cred(p->p_ucred, PRIV_PROC_SETLOGIN, 0))) return (error); - error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp, - sizeof(logintmp), NULL); + bzero(buf, sizeof(buf)); + error = copyinstr(uap->namebuf, buf, sizeof(buf), NULL); if (error == ENAMETOOLONG) error = EINVAL; - else if (!error) - (void) memcpy(p->p_pgrp->pg_session->s_login, logintmp, - sizeof(logintmp)); + if (error == 0) { + get_mplock(); + memcpy(p->p_pgrp->pg_session->s_login, buf, sizeof(buf)); + rel_mplock(); + } return (error); } diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index 32b570674a..74825f4b0a 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -86,6 +86,9 @@ struct getpriority_info { static int getpriority_callback(struct proc *p, void *data); +/* + * MPALMOSTSAFE + */ int sys_getpriority(struct getpriority_args *uap) { @@ -93,6 +96,9 @@ sys_getpriority(struct getpriority_args *uap) struct proc *curp = curproc; struct proc *p; int low = PRIO_MAX + 1; + int error; + + get_mplock(); switch (uap->which) { case PRIO_PROCESS: @@ -131,12 +137,18 @@ sys_getpriority(struct getpriority_args *uap) break; default: - return (EINVAL); + error = EINVAL; + goto done; + } + if (low == PRIO_MAX + 1) { + error = ESRCH; + goto done; } - if (low == PRIO_MAX + 1) - return (ESRCH); uap->sysmsg_result = low; - return (0); + error = 0; +done: + rel_mplock(); + return (error); } /* @@ -166,6 +178,9 @@ struct setpriority_info { static int setpriority_callback(struct proc *p, void *data); +/* + * MPALMOSTSAFE + */ int sys_setpriority(struct setpriority_args *uap) { @@ -174,6 +189,8 @@ sys_setpriority(struct setpriority_args *uap) struct proc *p; int found = 0, error = 0; + get_mplock(); + switch (uap->which) { case PRIO_PROCESS: if (uap->who == 0) @@ -217,10 +234,14 @@ sys_setpriority(struct setpriority_args *uap) break; default: - return (EINVAL); + error = EINVAL; + found = 1; + break; } + + rel_mplock(); if (found == 0) - return (ESRCH); + error = ESRCH; return (error); } @@ -264,6 +285,9 @@ donice(struct proc *chgp, int n) return (0); } +/* + * MPALMOSTSAFE + */ int sys_lwp_rtprio(struct lwp_rtprio_args *uap) { @@ -276,22 +300,26 @@ sys_lwp_rtprio(struct lwp_rtprio_args *uap) error = copyin(uap->rtp, &rtp, sizeof(struct rtprio)); if (error) return error; - - if (uap->pid < 0) { + if (uap->pid < 0) return EINVAL; - } else if (uap->pid == 0) { + + get_mplock(); + if (uap->pid == 0) { /* curproc already loaded on p */ } else { p = pfind(uap->pid); } - if (p == 0) { - return ESRCH; + if (p == NULL) { + error = ESRCH; + goto done; } if (uap->tid < -1) { - return EINVAL; - } else if (uap->tid == -1) { + error = EINVAL; + goto done; + } + if (uap->tid == -1) { /* * sadly, tid can be 0 so we can't use 0 here * like sys_rtprio() @@ -299,25 +327,30 @@ sys_lwp_rtprio(struct lwp_rtprio_args *uap) lp = curthread->td_lwp; } else { lp = lwp_rb_tree_RB_LOOKUP(&p->p_lwp_tree, uap->tid); - if (lp == NULL) - return ESRCH; + if (lp == NULL) { + error = ESRCH; + goto done; + } } switch (uap->function) { case RTP_LOOKUP: - return (copyout(&lp->lwp_rtprio, uap->rtp, - sizeof(struct rtprio))); + error = copyout(&lp->lwp_rtprio, uap->rtp, + sizeof(struct rtprio)); + break; case RTP_SET: if (cr->cr_uid && cr->cr_ruid && cr->cr_uid != p->p_ucred->cr_uid && cr->cr_ruid != p->p_ucred->cr_uid) { - return EPERM; + error = EPERM; + break; } /* disallow setting rtprio in most cases if not superuser */ if (priv_check_cred(cr, PRIV_SCHED_RTPRIO, 0)) { /* can't set someone else's */ if (uap->pid) { /* XXX */ - return EPERM; + error = EPERM; + break; } /* can't set realtime priority */ /* @@ -328,7 +361,8 @@ sys_lwp_rtprio(struct lwp_rtprio_args *uap) * due to a CPU-bound normal process). Fix me! XXX */ if (RTP_PRIO_IS_REALTIME(rtp.type)) { - return EPERM; + error = EPERM; + break; } } switch (rtp.type) { @@ -341,20 +375,28 @@ sys_lwp_rtprio(struct lwp_rtprio_args *uap) if (rtp.prio > RTP_PRIO_MAX) return EINVAL; lp->lwp_rtprio = rtp; - return 0; + error = 0; + break; default: - return EINVAL; + error = EINVAL; + break; } + break; default: - return EINVAL; + error = EINVAL; + break; } - panic("can't get here"); + +done: + rel_mplock(); + return (error); } /* * Set realtime priority + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_rtprio(struct rtprio_args *uap) { @@ -369,29 +411,38 @@ sys_rtprio(struct rtprio_args *uap) if (error) return (error); + get_mplock(); if (uap->pid == 0) p = curp; else p = pfind(uap->pid); - if (p == 0) - return (ESRCH); + if (p == NULL) { + error = ESRCH; + goto done; + } /* XXX lwp */ lp = FIRST_LWP_IN_PROC(p); switch (uap->function) { case RTP_LOOKUP: - return (copyout(&lp->lwp_rtprio, uap->rtp, sizeof(struct rtprio))); + error = copyout(&lp->lwp_rtprio, uap->rtp, + sizeof(struct rtprio)); + break; case RTP_SET: if (cr->cr_uid && cr->cr_ruid && cr->cr_uid != p->p_ucred->cr_uid && - cr->cr_ruid != p->p_ucred->cr_uid) - return (EPERM); + cr->cr_ruid != p->p_ucred->cr_uid) { + error = EPERM; + break; + } /* disallow setting rtprio in most cases if not superuser */ if (priv_check_cred(cr, PRIV_SCHED_RTPRIO, 0)) { /* can't set someone else's */ - if (uap->pid) - return (EPERM); + if (uap->pid) { + error = EPERM; + break; + } /* can't set realtime priority */ /* * Realtime priority has to be restricted for reasons which should be @@ -400,8 +451,10 @@ sys_rtprio(struct rtprio_args *uap) * that other processes need (and the idleprio process can't run * due to a CPU-bound normal process). Fix me! XXX */ - if (RTP_PRIO_IS_REALTIME(rtp.type)) - return (EPERM); + if (RTP_PRIO_IS_REALTIME(rtp.type)) { + error = EPERM; + break; + } } switch (rtp.type) { #ifdef RTP_PRIO_FIFO @@ -410,19 +463,30 @@ sys_rtprio(struct rtprio_args *uap) case RTP_PRIO_REALTIME: case RTP_PRIO_NORMAL: case RTP_PRIO_IDLE: - if (rtp.prio > RTP_PRIO_MAX) - return (EINVAL); + if (rtp.prio > RTP_PRIO_MAX) { + error = EINVAL; + break; + } lp->lwp_rtprio = rtp; - return (0); + error = 0; + break; default: - return (EINVAL); + error = EINVAL; + break; } - + break; default: - return (EINVAL); + error = EINVAL; + break; } +done: + rel_mplock(); + return (error); } +/* + * MPSAFE + */ int sys_setrlimit(struct __setrlimit_args *uap) { @@ -438,6 +502,9 @@ sys_setrlimit(struct __setrlimit_args *uap) return (error); } +/* + * MPSAFE + */ int sys_getrlimit(struct __getrlimit_args *uap) { @@ -517,29 +584,36 @@ calcru_proc(struct proc *p, struct rusage *ru) } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_getrusage(struct getrusage_args *uap) { struct rusage ru; struct rusage *rup; + int error; - switch (uap->who) { + get_mplock(); + switch (uap->who) { case RUSAGE_SELF: rup = &ru; calcru_proc(curproc, rup); + error = 0; break; - case RUSAGE_CHILDREN: rup = &curproc->p_cru; + error = 0; break; - default: - return (EINVAL); + error = EINVAL; + break; } - return (copyout((caddr_t)rup, (caddr_t)uap->rusage, - sizeof (struct rusage))); + if (error == 0) + error = copyout(rup, uap->rusage, sizeof(struct rusage)); + rel_mplock(); + return (error); } void diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index cdd09e8743..98e1786d57 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -204,9 +204,13 @@ int ksched_getscheduler(register_t *ret, struct ksched *ksched, struct lwp *lp) return getscheduler(ret, ksched, lp); } -/* ksched_yield: Yield the CPU. +/* + * ksched_yield: Yield the CPU. + * + * MPSAFE */ -int ksched_yield(register_t *ret, struct ksched *ksched) +int +ksched_yield(register_t *ret, struct ksched *ksched) { struct lwp *lp; @@ -216,52 +220,59 @@ int ksched_yield(register_t *ret, struct ksched *ksched) return 0; } -int ksched_get_priority_max(register_t*ret, struct ksched *ksched, int policy) +/* + * MPSAFE + */ +int +ksched_get_priority_max(register_t*ret, struct ksched *ksched, int policy) { int e = 0; - switch (policy) - { - case SCHED_FIFO: - case SCHED_RR: + switch (policy) { + case SCHED_FIFO: + case SCHED_RR: *ret = RTP_PRIO_MAX; break; - - case SCHED_OTHER: + case SCHED_OTHER: *ret = PRIO_MAX; break; - - default: + default: e = EINVAL; + break; } return e; } -int ksched_get_priority_min(register_t *ret, struct ksched *ksched, int policy) +/* + * MPSAFE + */ +int +ksched_get_priority_min(register_t *ret, struct ksched *ksched, int policy) { int e = 0; - switch (policy) - { - case SCHED_FIFO: - case SCHED_RR: + switch (policy) { + case SCHED_FIFO: + case SCHED_RR: *ret = P1B_PRIO_MIN; break; - - case SCHED_OTHER: + case SCHED_OTHER: *ret = PRIO_MIN; break; - - default: + default: e = EINVAL; + break; } - return e; } -int ksched_rr_get_interval(register_t *ret, struct ksched *ksched, - struct lwp *lp, struct timespec *timespec) +/* + * MPSAFE + */ +int +ksched_rr_get_interval(register_t *ret, struct ksched *ksched, + struct lwp *lp, struct timespec *timespec) { *timespec = ksched->rr_interval; diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index 1ab1e48fae..6c71b62ea8 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -186,6 +186,8 @@ SYSINIT(shutdown_conf, SI_BOOT2_MACHDEP, SI_ORDER_ANY, shutdown_conf, NULL) /* * The system call that results in a reboot + * + * MPALMOSTSAFE */ int sys_reboot(struct reboot_args *uap) @@ -196,7 +198,9 @@ sys_reboot(struct reboot_args *uap) if ((error = priv_check(td, PRIV_REBOOT))) return (error); + get_mplock(); boot(uap->opt); + rel_mplock(); return (0); } diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index d5fc263920..8248bed692 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -361,6 +361,9 @@ kern_sigaction(int sig, struct sigaction *act, struct sigaction *oact) return (0); } +/* + * MPALMOSTSAFE + */ int sys_sigaction(struct sigaction_args *uap) { @@ -375,7 +378,9 @@ sys_sigaction(struct sigaction_args *uap) if (error) return (error); } + get_mplock(); error = kern_sigaction(uap->sig, actp, oactp); + rel_mplock(); if (oactp && !error) { error = copyout(oactp, uap->oact, sizeof(oact)); } @@ -478,7 +483,9 @@ kern_sigprocmask(int how, sigset_t *set, sigset_t *oset) } /* - * sigprocmask() - MP SAFE + * sigprocmask() + * + * MPSAFE */ int sys_sigprocmask(struct sigprocmask_args *uap) @@ -501,6 +508,9 @@ sys_sigprocmask(struct sigprocmask_args *uap) return (error); } +/* + * MPSAFE + */ int kern_sigpending(struct __sigset *set) { @@ -511,6 +521,9 @@ kern_sigpending(struct __sigset *set) return (0); } +/* + * MPSAFE + */ int sys_sigpending(struct sigpending_args *uap) { @@ -527,6 +540,8 @@ sys_sigpending(struct sigpending_args *uap) /* * Suspend process until signal, providing mask to be set * in the meantime. + * + * MPSAFE */ int kern_sigsuspend(struct __sigset *set) @@ -557,6 +572,8 @@ kern_sigsuspend(struct __sigset *set) /* * Note nonstandard calling convention: libc stub passes mask, not * pointer, to save a copyin. + * + * MPSAFE */ int sys_sigsuspend(struct sigsuspend_args *uap) @@ -573,6 +590,9 @@ sys_sigsuspend(struct sigsuspend_args *uap) return (error); } +/* + * MPSAFE + */ int kern_sigaltstack(struct sigaltstack *ss, struct sigaltstack *oss) { @@ -603,6 +623,9 @@ kern_sigaltstack(struct sigaltstack *ss, struct sigaltstack *oss) return (0); } +/* + * MPSAFE + */ int sys_sigaltstack(struct sigaltstack_args *uap) { @@ -745,15 +768,23 @@ kern_kill(int sig, pid_t pid, lwpid_t tid) /* NOTREACHED */ } +/* + * MPALMOSTSAFE + */ int sys_kill(struct kill_args *uap) { int error; + get_mplock(); error = kern_kill(uap->signum, uap->pid, -1); + rel_mplock(); return (error); } +/* + * MPALMOSTSAFE + */ int sys_lwp_kill(struct lwp_kill_args *uap) { @@ -774,7 +805,9 @@ sys_lwp_kill(struct lwp_kill_args *uap) if (pid == -1) pid = curproc->p_pid; + get_mplock(); error = kern_kill(uap->signum, pid, uap->tid); + rel_mplock(); return (error); } @@ -1483,6 +1516,9 @@ kern_sigtimedwait(sigset_t waitset, siginfo_t *info, struct timespec *timeout) return (error); } +/* + * MPALMOSTSAFE + */ int sys_sigtimedwait(struct sigtimedwait_args *uap) { @@ -1503,7 +1539,9 @@ sys_sigtimedwait(struct sigtimedwait_args *uap) error = copyin(uap->set, &set, sizeof(set)); if (error) return (error); + get_mplock(); error = kern_sigtimedwait(set, &info, timeout); + rel_mplock(); if (error) return (error); if (uap->info) @@ -1515,13 +1553,19 @@ sys_sigtimedwait(struct sigtimedwait_args *uap) * This could transform a thread-specific signal to another * thread / process pending signal. */ - if (error) + if (error) { + get_mplock(); ksignal(curproc, info.si_signo); - else + rel_mplock(); + } else { uap->sysmsg_result = info.si_signo; + } return (error); } +/* + * MPALMOSTSAFE + */ int sys_sigwaitinfo(struct sigwaitinfo_args *uap) { @@ -1532,7 +1576,9 @@ sys_sigwaitinfo(struct sigwaitinfo_args *uap) error = copyin(uap->set, &set, sizeof(set)); if (error) return (error); + get_mplock(); error = kern_sigtimedwait(set, &info, NULL); + rel_mplock(); if (error) return (error); if (uap->info) @@ -1544,10 +1590,13 @@ sys_sigwaitinfo(struct sigwaitinfo_args *uap) * This could transform a thread-specific signal to another * thread / process pending signal. */ - if (error) + if (error) { + get_mplock(); ksignal(curproc, info.si_signo); - else + rel_mplock(); + } else { uap->sysmsg_result = info.si_signo; + } return (error); } @@ -2100,12 +2149,16 @@ out2: /* * Nonexistent system call-- signal process (may want to handle it). * Flag error in case process won't see signal immediately (blocked or ignored). + * + * MPALMOSTSAFE */ /* ARGSUSED */ int sys_nosys(struct nosys_args *args) { + get_mplock(); lwpsignal(curproc, curthread->td_lwp, SIGSYS); + rel_mplock(); return (EINVAL); } diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index ba82d98487..f8c8395474 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -1106,6 +1106,8 @@ tstop(void) * it's call to lwkt_maybe_switch() in acquire_curproc() will likely * round-robin back to us and we will be able to re-acquire the current * process designation. + * + * MPSAFE */ void uio_yield(void) diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index efb793fc58..8a25550151 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1197,6 +1197,9 @@ sysctl_root(SYSCTL_HANDLER_ARGS) return (error); } +/* + * MPALMOSTSAFE + */ int sys___sysctl(struct sysctl_args *uap) { @@ -1210,9 +1213,11 @@ sys___sysctl(struct sysctl_args *uap) if (error) return (error); + get_mplock(); error = userland_sysctl(name, uap->namelen, uap->old, uap->oldlenp, 0, uap->new, uap->newlen, &j); + rel_mplock(); if (error && error != ENOMEM) return (error); if (uap->oldlenp) { diff --git a/sys/kern/kern_syslink.c b/sys/kern/kern_syslink.c index 81b1d6c8ea..5da8941991 100644 --- a/sys/kern/kern_syslink.c +++ b/sys/kern/kern_syslink.c @@ -249,6 +249,8 @@ static struct fileops syslinkops = { ************************************************************************ * * syslink(int cmd, struct syslink_info *info, size_t bytes) + * + * MPALMOSTSAFE */ int sys_syslink(struct syslink_args *uap) @@ -281,6 +283,7 @@ sys_syslink(struct syslink_args *uap) } if (error) return (error); + get_mplock(); /* * Process the command @@ -293,6 +296,8 @@ sys_syslink(struct syslink_args *uap) error = EINVAL; break; } + + rel_mplock(); if (error == 0 && info.head.wbflag) copyout(&info, uap->info, uap->bytes); return (error); diff --git a/sys/kern/kern_systimer.c b/sys/kern/kern_systimer.c index d4bb43b712..79a06791ec 100644 --- a/sys/kern/kern_systimer.c +++ b/sys/kern/kern_systimer.c @@ -140,6 +140,9 @@ systimer_intr_enable(void) cputimer_intr_enable(); } +/* + * MPSAFE + */ void systimer_add(systimer_t info) { @@ -191,6 +194,8 @@ systimer_add(systimer_t info) * systimer_del() * * Delete a system timer. Only the owning cpu can delete a timer. + * + * MPSAFE */ void systimer_del(systimer_t info) diff --git a/sys/kern/kern_threads.c b/sys/kern/kern_threads.c index 5cdfeecfc8..52df714162 100644 --- a/sys/kern/kern_threads.c +++ b/sys/kern/kern_threads.c @@ -58,6 +58,7 @@ #include #include /* uio_yield() fixme */ +#if 0 /* * XXX lwp @@ -152,8 +153,12 @@ sys_thr_wakeup(struct thr_wakeup_args *uap) return 0; } +#endif + /* * General purpose yield system call + * + * MPSAFE */ int sys_yield(struct yield_args *uap) diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 3c39c05ebd..386dbf1da7 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -140,6 +140,9 @@ settime(struct timeval *tv) return (0); } +/* + * MPSAFE + */ int kern_clock_gettime(clockid_t clock_id, struct timespec *ats) { @@ -159,7 +162,9 @@ kern_clock_gettime(clockid_t clock_id, struct timespec *ats) return (error); } -/* ARGSUSED */ +/* + * MPSAFE + */ int sys_clock_gettime(struct clock_gettime_args *uap) { @@ -192,7 +197,9 @@ kern_clock_settime(clockid_t clock_id, struct timespec *ats) return (error); } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_clock_settime(struct clock_settime_args *uap) { @@ -202,9 +209,15 @@ sys_clock_settime(struct clock_settime_args *uap) if ((error = copyin(uap->tp, &ats, sizeof(ats))) != 0) return (error); - return (kern_clock_settime(uap->clock_id, &ats)); + get_mplock(); + error = kern_clock_settime(uap->clock_id, &ats); + rel_mplock(); + return (error); } +/* + * MPSAFE + */ int kern_clock_getres(clockid_t clock_id, struct timespec *ts) { @@ -231,6 +244,9 @@ kern_clock_getres(clockid_t clock_id, struct timespec *ts) return(error); } +/* + * MPSAFE + */ int sys_clock_getres(struct clock_getres_args *uap) { @@ -262,6 +278,8 @@ sys_clock_getres(struct clock_getres_args *uap) * tsleep, then handle the fine-grained delay on the next * loop. This usually results in two sleeps occuring, a long one * and a short one. + * + * MPSAFE */ static void ns1_systimer(systimer_t info) @@ -334,7 +352,9 @@ nanosleep1(struct timespec *rqt, struct timespec *rmt) } } -/* ARGSUSED */ +/* + * MPSAFE + */ int sys_nanosleep(struct nanosleep_args *uap) { @@ -361,7 +381,9 @@ sys_nanosleep(struct nanosleep_args *uap) return (error); } -/* ARGSUSED */ +/* + * MPSAFE + */ int sys_gettimeofday(struct gettimeofday_args *uap) { @@ -380,7 +402,9 @@ sys_gettimeofday(struct gettimeofday_args *uap) return (error); } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_settimeofday(struct settimeofday_args *uap) { @@ -402,8 +426,13 @@ sys_settimeofday(struct settimeofday_args *uap) if (uap->tzp && (error = copyin((caddr_t)uap->tzp, (caddr_t)&atz, sizeof(atz)))) return (error); - if (uap->tv && (error = settime(&atv))) + + get_mplock(); + if (uap->tv && (error = settime(&atv))) { + rel_mplock(); return (error); + } + rel_mplock(); if (uap->tzp) tz = atz; return (0); @@ -492,7 +521,9 @@ kern_adjfreq(int64_t rate) lwkt_setcpu_self(globaldata_find(origcpu)); } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_adjtime(struct adjtime_args *uap) { @@ -503,8 +534,8 @@ sys_adjtime(struct adjtime_args *uap) if ((error = priv_check(td, PRIV_ADJTIME))) return (error); - if ((error = - copyin((caddr_t)uap->delta, (caddr_t)&atv, sizeof(struct timeval)))) + error = copyin(uap->delta, &atv, sizeof(struct timeval)); + if (error) return (error); /* @@ -515,13 +546,14 @@ sys_adjtime(struct adjtime_args *uap) * overshoot and start taking us away from the desired final time. */ ndelta = (int64_t)atv.tv_sec * 1000000000 + atv.tv_usec * 1000; + get_mplock(); kern_adjtime(ndelta, &odelta); + rel_mplock(); if (uap->olddelta) { atv.tv_sec = odelta / 1000000000; atv.tv_usec = odelta % 1000000000 / 1000; - (void) copyout((caddr_t)&atv, (caddr_t)uap->olddelta, - sizeof(struct timeval)); + copyout(&atv, uap->olddelta, sizeof(struct timeval)); } return (0); } @@ -646,8 +678,9 @@ SYSCTL_PROC(_kern_ntp, OID_AUTO, adjust, * does not suffice, therefore, to reload the real timer .it_value from the * real time timers .it_interval. Rather, we compute the next time in * absolute time the timer should go off. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_getitimer(struct getitimer_args *uap) { @@ -657,6 +690,7 @@ sys_getitimer(struct getitimer_args *uap) if (uap->which > ITIMER_PROF) return (EINVAL); + get_mplock(); crit_enter(); if (uap->which == ITIMER_REAL) { /* @@ -677,11 +711,13 @@ sys_getitimer(struct getitimer_args *uap) aitv = p->p_timer[uap->which]; } crit_exit(); - return (copyout((caddr_t)&aitv, (caddr_t)uap->itv, - sizeof (struct itimerval))); + rel_mplock(); + return (copyout(&aitv, uap->itv, sizeof (struct itimerval))); } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_setitimer(struct setitimer_args *uap) { @@ -708,6 +744,7 @@ sys_setitimer(struct setitimer_args *uap) timevalclear(&aitv.it_interval); else if (itimerfix(&aitv.it_interval)) return (EINVAL); + get_mplock(); crit_enter(); if (uap->which == ITIMER_REAL) { if (timevalisset(&p->p_realtimer.it_value)) @@ -722,6 +759,7 @@ sys_setitimer(struct setitimer_args *uap) p->p_timer[uap->which] = aitv; } crit_exit(); + rel_mplock(); return (0); } @@ -771,6 +809,8 @@ realitexpire(void *arg) * .it_interval part of an interval timer is acceptable, and * fix it to have at least minimal value (i.e. if it is less * than the resolution of the clock, round it up.) + * + * MPSAFE */ int itimerfix(struct timeval *tv) diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 3e760481b6..82b66a9d1b 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -93,6 +93,8 @@ static void umtx_sleep_page_action_cow(vm_page_t m, vm_page_action_t action); * copy-on-write. We register an event on the VM page to catch COWs. * * umtx_sleep { const int *ptr, int value, int timeout } + * + * MPALMOSTSAFE */ int sys_umtx_sleep(struct umtx_sleep_args *uap) @@ -115,9 +117,12 @@ sys_umtx_sleep(struct umtx_sleep_args *uap) * Otherwise the physical page we sleep on my not match the page * being woken up. */ + get_mplock(); m = vm_fault_page_quick((vm_offset_t)uap->ptr, VM_PROT_READ|VM_PROT_WRITE, &error); - if (m == NULL) - return (EFAULT); + if (m == NULL) { + error = EFAULT; + goto done; + } sf = sf_buf_alloc(m, SFB_CPUPRIVATE); offset = (vm_offset_t)uap->ptr & PAGE_MASK; @@ -153,6 +158,8 @@ sys_umtx_sleep(struct umtx_sleep_args *uap) sf_buf_free(sf); /*vm_page_dirty(m); we don't actually dirty the page */ vm_page_unhold(m); +done: + rel_mplock(); return(error); } @@ -175,6 +182,8 @@ umtx_sleep_page_action_cow(vm_page_t m, vm_page_action_t action) * * XXX assumes that the physical address space does not exceed the virtual * address space. + * + * MPALMOSTSAFE */ int sys_umtx_wakeup(struct umtx_wakeup_args *uap) @@ -187,9 +196,12 @@ sys_umtx_wakeup(struct umtx_wakeup_args *uap) cpu_mfence(); if ((vm_offset_t)uap->ptr & (sizeof(int) - 1)) return (EFAULT); + get_mplock(); m = vm_fault_page_quick((vm_offset_t)uap->ptr, VM_PROT_READ, &error); - if (m == NULL) - return (EFAULT); + if (m == NULL) { + error = EFAULT; + goto done; + } offset = (vm_offset_t)uap->ptr & PAGE_MASK; waddr = (void *)((intptr_t)VM_PAGE_TO_PHYS(m) + offset); @@ -200,6 +212,9 @@ sys_umtx_wakeup(struct umtx_wakeup_args *uap) wakeup_domain(waddr, PDOMAIN_UMTX); } vm_page_unhold(m); - return(0); + error = 0; +done: + rel_mplock(); + return(error); } diff --git a/sys/kern/kern_upcall.c b/sys/kern/kern_upcall.c index e77a59672e..d4714789f1 100644 --- a/sys/kern/kern_upcall.c +++ b/sys/kern/kern_upcall.c @@ -79,6 +79,8 @@ sigupcall_remote(void *arg) * upcall context is set globally for the process, not for each upcall. * * ARGS(struct upcall *upc, upcall_func_t ctx, upcall_func_t func, void *data) + * + * MPALMOSTSAFE */ int sys_upc_register(struct upc_register_args *uap) @@ -87,6 +89,9 @@ sys_upc_register(struct upc_register_args *uap) struct vmspace *vm = curproc->p_vmspace; struct vmupcall *vu; + /* + * Note: inconsequential MP race + */ if (vm->vm_upccount >= UPCALL_MAXCOUNT) return(EFBIG); @@ -97,6 +102,7 @@ sys_upc_register(struct upc_register_args *uap) vu->vu_lwp = lp; lp->lwp_upcall = uap->upc; + get_mplock(); if (vm->vm_upcalls != NULL) vu->vu_id = vm->vm_upcalls->vu_id + 1; else @@ -104,6 +110,7 @@ sys_upc_register(struct upc_register_args *uap) vu->vu_next = vm->vm_upcalls; vm->vm_upcalls = vu; ++vm->vm_upccount; + rel_mplock(); uap->sysmsg_result = vu->vu_id; return(0); } @@ -112,6 +119,8 @@ sys_upc_register(struct upc_register_args *uap) * upc_control: * * ARGS(int cmd, int upcid, void *data) + * + * MPALMOSTSAFE */ int sys_upc_control(struct upc_control_args *uap) @@ -124,6 +133,7 @@ sys_upc_control(struct upc_control_args *uap) struct vmupcall **vupp; int error; + get_mplock(); switch(uap->cmd) { case UPC_CONTROL_DISPATCH: /* @@ -252,6 +262,7 @@ sys_upc_control(struct upc_control_args *uap) error = EINVAL; break; } + rel_mplock(); return(error); } diff --git a/sys/kern/kern_usched.c b/sys/kern/kern_usched.c index b6f20dbfd9..f76ff2b3f2 100644 --- a/sys/kern/kern_usched.c +++ b/sys/kern/kern_usched.c @@ -151,6 +151,8 @@ usched_ctl(struct usched *usched, int action) * RETURN VALUES: * 0 - success * EINVAL - error + * + * MPALMOSTSAFE */ int sys_usched_set(struct usched_set_args *uap) @@ -162,17 +164,20 @@ sys_usched_set(struct usched_set_args *uap) cpumask_t mask; struct lwp *lp; int cpuid; + if (uap->pid != 0 && uap->pid != curthread->td_proc->p_pid) return (EINVAL); lp = curthread->td_lwp; + get_mplock(); + switch (uap->cmd) { case USCHED_SET_SCHEDULER: if ((error = priv_check(curthread, PRIV_SCHED_SET)) != 0) - return (error); - if ((error = copyinstr(uap->data, buffer, sizeof(buffer), - NULL)) != 0) - return (error); + break; + error = copyinstr(uap->data, buffer, sizeof(buffer), NULL); + if (error) + break; TAILQ_FOREACH(item, &usched_list, entry) { if ((strcmp(item->name, buffer) == 0)) break; @@ -187,8 +192,10 @@ sys_usched_set(struct usched_set_args *uap) * reassociation' */ /* XXX lwp have to deal with multiple lwps here */ - if (p->p_nthreads != 1) - return (EINVAL); + if (p->p_nthreads != 1) { + error = EINVAL; + break; + } if (item && item != p->p_usched) { /* XXX lwp */ p->p_usched->release_curproc(ONLY_LWP_IN_PROC(p)); @@ -199,9 +206,11 @@ sys_usched_set(struct usched_set_args *uap) break; case USCHED_SET_CPU: if ((error = priv_check(curthread, PRIV_SCHED_CPUSET)) != 0) - return (error); - if (uap->bytes != sizeof(int)) - return (EINVAL); + break; + if (uap->bytes != sizeof(int)) { + error = EINVAL; + break; + } error = copyin(uap->data, &cpuid, sizeof(int)); if (error) break; @@ -219,15 +228,19 @@ sys_usched_set(struct usched_set_args *uap) break; case USCHED_GET_CPU: /* USCHED_GET_CPU doesn't require special privileges. */ - if (uap->bytes != sizeof(int)) - return (EINVAL); + if (uap->bytes != sizeof(int)) { + error = EINVAL; + break; + } error = copyout(&(mycpu->gd_cpuid), uap->data, sizeof(int)); break; case USCHED_ADD_CPU: if ((error = priv_check(curthread, PRIV_SCHED_CPUSET)) != 0) - return (error); - if (uap->bytes != sizeof(int)) - return (EINVAL); + break; + if (uap->bytes != sizeof(int)) { + error = EINVAL; + break; + } error = copyin(uap->data, &cpuid, sizeof(int)); if (error) break; @@ -243,8 +256,10 @@ sys_usched_set(struct usched_set_args *uap) break; case USCHED_DEL_CPU: /* USCHED_DEL_CPU doesn't require special privileges. */ - if (uap->bytes != sizeof(int)) - return (EINVAL); + if (uap->bytes != sizeof(int)) { + error = EINVAL; + break; + } error = copyin(uap->data, &cpuid, sizeof(int)); if (error) break; @@ -268,6 +283,7 @@ sys_usched_set(struct usched_set_args *uap) error = EINVAL; break; } + rel_mplock(); return (error); } diff --git a/sys/kern/kern_uuid.c b/sys/kern/kern_uuid.c index e87ac8ee28..61b9d9adc2 100644 --- a/sys/kern/kern_uuid.c +++ b/sys/kern/kern_uuid.c @@ -154,6 +154,8 @@ kern_uuidgen(struct uuid *store, size_t count) * uuidgen(struct uuid *store, int count) * * Generate an array of new UUIDs + * + * MPALMOSTSAFE */ int sys_uuidgen(struct uuidgen_args *uap) @@ -173,7 +175,9 @@ sys_uuidgen(struct uuidgen_args *uap) count = uap->count; store = kmalloc(count * sizeof(struct uuid), M_TEMP, M_WAITOK); + get_mplock(); kern_uuidgen(store, count); + rel_mplock(); error = copyout(store, uap->store, count * sizeof(struct uuid)); kfree(store, M_TEMP); return (error); diff --git a/sys/kern/kern_varsym.c b/sys/kern/kern_varsym.c index 516b669a58..b4d9515ae8 100644 --- a/sys/kern/kern_varsym.c +++ b/sys/kern/kern_varsym.c @@ -128,6 +128,8 @@ varsymreplace(char *cp, int linklen, int maxlen) * varsym_set() system call * * (int level, const char *name, const char *data) + * + * MPALMOSTSAFE */ int sys_varsym_set(struct varsym_set_args *uap) @@ -147,6 +149,9 @@ sys_varsym_set(struct varsym_set_args *uap) { goto done1; } + + get_mplock(); + switch(uap->level) { case VARSYM_SYS: if (p != NULL && p->p_ucred->cr_prison != NULL) @@ -168,6 +173,7 @@ sys_varsym_set(struct varsym_set_args *uap) } break; } + rel_mplock(); done1: kfree(buf, M_TEMP); done2: @@ -178,6 +184,8 @@ done2: * varsym_get() system call * * (int mask, const char *wild, char *buf, int bufsize) + * + * MPALMOSTSAFE */ int sys_varsym_get(struct varsym_get_args *uap) @@ -187,6 +195,7 @@ sys_varsym_get(struct varsym_get_args *uap) int error; int dlen; + get_mplock(); if ((error = copyinstr(uap->wild, wild, sizeof(wild), NULL)) != 0) goto done; sym = varsymfind(uap->mask, wild, strlen(wild)); @@ -203,6 +212,7 @@ sys_varsym_get(struct varsym_get_args *uap) uap->sysmsg_result = dlen + 1; varsymdrop(sym); done: + rel_mplock(); return(error); } @@ -210,6 +220,8 @@ done: * varsym_list() system call * * (int level, char *buf, int maxsize, int *marker) + * + * MPALMOSTSAFE */ int sys_varsym_list(struct varsym_list_args *uap) @@ -226,6 +238,7 @@ sys_varsym_list(struct varsym_list_args *uap) /* * Get the marker from userspace. */ + get_mplock(); if ((error = copyin(uap->marker, &marker, sizeof(marker))) != 0) goto done; @@ -322,6 +335,7 @@ sys_varsym_list(struct varsym_list_args *uap) error = copyout(&marker, uap->marker, sizeof(marker)); uap->sysmsg_result = bytes; done: + rel_mplock(); return(error); } diff --git a/sys/kern/kern_xxx.c b/sys/kern/kern_xxx.c index 662beda909..2b28aa421f 100644 --- a/sys/kern/kern_xxx.c +++ b/sys/kern/kern_xxx.c @@ -44,8 +44,9 @@ #include #include -/* ARGSUSED */ -/* MP SAFE */ +/* + * MPALMOSTSAFE + */ int sys_uname(struct uname_args *uap) { @@ -53,26 +54,31 @@ sys_uname(struct uname_args *uap) size_t len; char *s, *us; + get_mplock(); + name[0] = CTL_KERN; name[1] = KERN_OSTYPE; len = sizeof uap->name->sysname; rtval = userland_sysctl(name, 2, uap->name->sysname, &len, 1, 0, 0, 0); - if( rtval) return rtval; + if (rtval) + goto done; subyte( uap->name->sysname + sizeof(uap->name->sysname) - 1, 0); name[1] = KERN_HOSTNAME; len = sizeof uap->name->nodename; rtval = userland_sysctl(name, 2, uap->name->nodename, &len, 1, 0, 0, 0); - if( rtval) return rtval; + if (rtval) + goto done; subyte( uap->name->nodename + sizeof(uap->name->nodename) - 1, 0); name[1] = KERN_OSRELEASE; len = sizeof uap->name->release; rtval = userland_sysctl(name, 2, uap->name->release, &len, 1, 0, 0, 0); - if( rtval) return rtval; + if (rtval) + goto done; subyte( uap->name->release + sizeof(uap->name->release) - 1, 0); /* @@ -80,7 +86,8 @@ sys_uname(struct uname_args *uap) len = sizeof uap->name->version; rtval = userland_sysctl(name, 2, uap->name->version, &len, 1, 0, 0, 0); - if( rtval) return rtval; + if (rtval) + goto done; subyte( uap->name->version + sizeof(uap->name->version) - 1, 0); */ @@ -91,35 +98,47 @@ sys_uname(struct uname_args *uap) for(us = uap->name->version; *s && *s != ':'; s++) { rtval = subyte( us++, *s); - if( rtval) - return rtval; + if (rtval) + goto done; } rtval = subyte( us++, 0); - if( rtval) - return rtval; + if (rtval) + goto done; name[0] = CTL_HW; name[1] = HW_MACHINE; len = sizeof uap->name->machine; rtval = userland_sysctl(name, 2, uap->name->machine, &len, 1, 0, 0, 0); - if( rtval) return rtval; - subyte( uap->name->machine + sizeof(uap->name->machine) - 1, 0); - - return 0; + if (rtval) + goto done; + rtval = subyte(uap->name->machine + sizeof(uap->name->machine) - 1, 0); +done: + rel_mplock(); + return rtval; } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_getdomainname(struct getdomainname_args *uap) { - int domainnamelen = strlen(domainname) + 1; + int domainnamelen; + int error; + + get_mplock(); + domainnamelen = strlen(domainname) + 1; if ((u_int)uap->len > domainnamelen + 1) uap->len = domainnamelen + 1; - return (copyout((caddr_t)domainname, (caddr_t)uap->domainname, uap->len)); + error = copyout(domainname, uap->domainname, uap->len); + rel_mplock(); + return (error); } -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_setdomainname(struct setdomainname_args *uap) { @@ -128,11 +147,13 @@ sys_setdomainname(struct setdomainname_args *uap) if ((error = priv_check(td, PRIV_SETDOMAINNAME))) return (error); - if ((u_int)uap->len > sizeof (domainname) - 1) + if ((u_int)uap->len > sizeof(domainname) - 1) return EINVAL; + get_mplock(); domainnamelen = uap->len; - error = copyin((caddr_t)uap->domainname, domainname, uap->len); + error = copyin(uap->domainname, domainname, uap->len); domainname[domainnamelen] = 0; + rel_mplock(); return (error); } diff --git a/sys/kern/lwkt_caps.c b/sys/kern/lwkt_caps.c index 514518a088..57e9c6ce56 100644 --- a/sys/kern/lwkt_caps.c +++ b/sys/kern/lwkt_caps.c @@ -566,6 +566,8 @@ caps_exit(struct thread *td) * returned. * * upcid can either be an upcall or a kqueue identifier (XXX) + * + * MPALMOSTSAFE */ int sys_caps_sys_service(struct caps_sys_service_args *uap) @@ -582,13 +584,15 @@ sys_caps_sys_service(struct caps_sys_service_args *uap) return(error); if ((ssize_t)--len <= 0) return(EINVAL); - if ((error = caps_name_check(name, len)) != 0) - return(error); + get_mplock(); - caps = kern_caps_sys_service(name, uap->uid, uap->gid, cred, - uap->flags & CAPF_UFLAGS, &error); - if (caps) - uap->sysmsg_result = caps->ci_id; + if ((error = caps_name_check(name, len)) == 0) { + caps = kern_caps_sys_service(name, uap->uid, uap->gid, cred, + uap->flags & CAPF_UFLAGS, &error); + if (caps) + uap->sysmsg_result = caps->ci_id; + } + rel_mplock(); return(error); } @@ -600,6 +604,8 @@ sys_caps_sys_service(struct caps_sys_service_args *uap) * returned. * * upcid can either be an upcall or a kqueue identifier (XXX) + * + * MPALMOSTSAFE */ int sys_caps_sys_client(struct caps_sys_client_args *uap) @@ -616,63 +622,92 @@ sys_caps_sys_client(struct caps_sys_client_args *uap) return(error); if ((ssize_t)--len <= 0) return(EINVAL); - if ((error = caps_name_check(name, len)) != 0) - return(error); + get_mplock(); - caps = kern_caps_sys_client(name, uap->uid, uap->gid, cred, - uap->flags & CAPF_UFLAGS, &error); - if (caps) - uap->sysmsg_result = caps->ci_id; + if ((error = caps_name_check(name, len)) == 0) { + caps = kern_caps_sys_client(name, uap->uid, uap->gid, cred, + uap->flags & CAPF_UFLAGS, &error); + if (caps) + uap->sysmsg_result = caps->ci_id; + } + rel_mplock(); return(error); } +/* + * MPALMOSTSAFE + */ int sys_caps_sys_close(struct caps_sys_close_args *uap) { caps_kinfo_t caps; + int error; - if ((caps = caps_find_id(curthread, uap->portid)) == NULL) - return(EINVAL); - caps_term(caps, CAPKF_TDLIST|CAPKF_HLIST|CAPKF_FLUSH|CAPKF_RCAPS, NULL); - caps_drop(caps); - return(0); + get_mplock(); + + if ((caps = caps_find_id(curthread, uap->portid)) != NULL) { + caps_term(caps, CAPKF_TDLIST|CAPKF_HLIST|CAPKF_FLUSH|CAPKF_RCAPS, + NULL); + caps_drop(caps); + error = 0; + } else { + error = EINVAL; + } + rel_mplock(); + return(error); } +/* + * MPALMOSTSAFE + */ int sys_caps_sys_setgen(struct caps_sys_setgen_args *uap) { caps_kinfo_t caps; int error; - if ((caps = caps_find_id(curthread, uap->portid)) == NULL) - return(EINVAL); - if (caps->ci_type == CAPT_FORKED) { - error = ENOTCONN; + get_mplock(); + + if ((caps = caps_find_id(curthread, uap->portid)) != NULL) { + if (caps->ci_type == CAPT_FORKED) { + error = ENOTCONN; + } else { + caps->ci_gen = uap->gen; + error = 0; + } + caps_drop(caps); } else { - caps->ci_gen = uap->gen; - error = 0; + error = EINVAL; } - caps_drop(caps); + rel_mplock(); return(error); } +/* + * MPALMOSTSAFE + */ int sys_caps_sys_getgen(struct caps_sys_getgen_args *uap) { caps_kinfo_t caps; int error; - if ((caps = caps_find_id(curthread, uap->portid)) == NULL) - return(EINVAL); - if (caps->ci_type == CAPT_FORKED) { - error = ENOTCONN; - } else if (caps->ci_rcaps == NULL) { - error = EINVAL; + get_mplock(); + + if ((caps = caps_find_id(curthread, uap->portid)) != NULL) { + if (caps->ci_type == CAPT_FORKED) { + error = ENOTCONN; + } else if (caps->ci_rcaps == NULL) { + error = EINVAL; + } else { + uap->sysmsg_result64 = caps->ci_rcaps->ci_gen; + error = 0; + } + caps_drop(caps); } else { - uap->sysmsg_result64 = caps->ci_rcaps->ci_gen; - error = 0; + error = EINVAL; } - caps_drop(caps); + rel_mplock(); return(error); } @@ -681,6 +716,8 @@ sys_caps_sys_getgen(struct caps_sys_getgen_args *uap) * * Send an opaque message of the specified size to the specified port. This * function may only be used with a client port. The message id is returned. + * + * MPALMOSTSAFE */ int sys_caps_sys_put(struct caps_sys_put_args *uap) @@ -692,8 +729,12 @@ sys_caps_sys_put(struct caps_sys_put_args *uap) if (uap->msgsize < 0) return(EINVAL); - if ((caps = caps_find_id(curthread, uap->portid)) == NULL) - return(EINVAL); + get_mplock(); + + if ((caps = caps_find_id(curthread, uap->portid)) == NULL) { + error = EINVAL; + goto done; + } if (caps->ci_type == CAPT_FORKED) { error = ENOTCONN; } else if (caps->ci_rcaps == NULL) { @@ -733,6 +774,8 @@ sys_caps_sys_put(struct caps_sys_put_args *uap) } } caps_drop(caps); +done: + rel_mplock(); return(error); } @@ -741,6 +784,8 @@ sys_caps_sys_put(struct caps_sys_put_args *uap) * * Reply to the message referenced by the specified msgid, supplying opaque * data back to the originator. + * + * MPALMOSTSAFE */ int sys_caps_sys_reply(struct caps_sys_reply_args *uap) @@ -753,8 +798,12 @@ sys_caps_sys_reply(struct caps_sys_reply_args *uap) if (uap->msgsize < 0) return(EINVAL); - if ((caps = caps_find_id(curthread, uap->portid)) == NULL) - return(EINVAL); + get_mplock(); + + if ((caps = caps_find_id(curthread, uap->portid)) == NULL) { + error = EINVAL; + goto done; + } if (caps->ci_type == CAPT_FORKED) { /* * The caps structure is just a fork placeholder, tell the caller @@ -791,6 +840,8 @@ sys_caps_sys_reply(struct caps_sys_reply_args *uap) } } caps_drop(caps); +done: + rel_mplock(); return(error); } @@ -806,6 +857,8 @@ sys_caps_sys_reply(struct caps_sys_reply_args *uap) * * EWOULDBLOCK is returned if no messages are pending. Note that 0-length * messages are perfectly acceptable so 0 can be legitimately returned. + * + * MPALMOSTSAFE */ int sys_caps_sys_get(struct caps_sys_get_args *uap) @@ -816,16 +869,21 @@ sys_caps_sys_get(struct caps_sys_get_args *uap) if (uap->maxsize < 0) return(EINVAL); - if ((caps = caps_find_id(curthread, uap->portid)) == NULL) - return(EINVAL); - if (caps->ci_type == CAPT_FORKED) { - error = ENOTCONN; - } else if ((msg = TAILQ_FIRST(&caps->ci_msgpendq)) == NULL) { - error = EWOULDBLOCK; + get_mplock(); + + if ((caps = caps_find_id(curthread, uap->portid)) != NULL) { + if (caps->ci_type == CAPT_FORKED) { + error = ENOTCONN; + } else if ((msg = TAILQ_FIRST(&caps->ci_msgpendq)) == NULL) { + error = EWOULDBLOCK; + } else { + error = caps_process_msg(caps, msg, uap); + } } else { - error = caps_process_msg(caps, msg, uap); + error = EINVAL; } caps_drop(caps); + rel_mplock(); return(error); } @@ -842,6 +900,8 @@ sys_caps_sys_get(struct caps_sys_get_args *uap) * This function blocks until interrupted or a message is received. * Note that 0-length messages are perfectly acceptable so 0 can be * legitimately returned. + * + * MPALMOSTSAFE */ int sys_caps_sys_wait(struct caps_sys_wait_args *uap) @@ -852,27 +912,33 @@ sys_caps_sys_wait(struct caps_sys_wait_args *uap) if (uap->maxsize < 0) return(EINVAL); - if ((caps = caps_find_id(curthread, uap->portid)) == NULL) - return(EINVAL); - if (caps->ci_type == CAPT_FORKED) { - error = ENOTCONN; - } else { - error = 0; - while ((msg = TAILQ_FIRST(&caps->ci_msgpendq)) == NULL) { - if ((error = tsleep(caps, PCATCH, "caps", 0)) != 0) - break; - } - if (error == 0) { - error = caps_process_msg(caps, msg, - (struct caps_sys_get_args *)uap); + get_mplock(); + + if ((caps = caps_find_id(curthread, uap->portid)) != NULL) { + if (caps->ci_type == CAPT_FORKED) { + error = ENOTCONN; + } else { + error = 0; + while ((msg = TAILQ_FIRST(&caps->ci_msgpendq)) == NULL) { + if ((error = tsleep(caps, PCATCH, "caps", 0)) != 0) + break; + } + if (error == 0) { + error = caps_process_msg(caps, msg, + (struct caps_sys_get_args *)uap); + } } + } else { + error = EINVAL; } caps_drop(caps); + rel_mplock(); return(error); } static int -caps_process_msg(caps_kinfo_t caps, caps_kmsg_t msg, struct caps_sys_get_args *uap) +caps_process_msg(caps_kinfo_t caps, caps_kmsg_t msg, + struct caps_sys_get_args *uap) { int error = 0; int msgsize; @@ -942,6 +1008,8 @@ caps_process_msg(caps_kinfo_t caps, caps_kmsg_t msg, struct caps_sys_get_args *u * to be returned after sending the abort request. This function will * return the appropriate CAPS_ABORT_* code depending on what it had * to do. + * + * MPALMOSTSAFE */ int sys_caps_sys_abort(struct caps_sys_abort_args *uap) diff --git a/sys/kern/makesyscalls.sh b/sys/kern/makesyscalls.sh index e033b74483..c5e839d03b 100644 --- a/sys/kern/makesyscalls.sh +++ b/sys/kern/makesyscalls.sh @@ -288,14 +288,6 @@ s/\$//g for (i = 5; i <= NF; i++) comment = comment " " $i } - # if the "MPSAFE" keyword is found, note it and shift the line - mpsafe = "" - $2 == "MPSAFE" { - for (i = 2; i <= NF; i++) - $i = $(i + 1); - NF -= 1; - mpsafe = "SYF_MPSAFE | " - } $2 == "STD" || $2 == "NODEF" || $2 == "NOARGS" || $2 == "NOPROTO" \ || $2 == "NOIMPL" { parseline() @@ -336,8 +328,8 @@ s/\$//g nosys = 1 if (funcname == "lkmnosys") lkmnosys = 1 - printf("\t{ %s%s, (sy_call_t *)", mpsafe, argssize) > sysent - column = 8 + 2 + length(mpsafe) + length(argssize) + 15 + printf("\t{ %s, (sy_call_t *)", argssize) > sysent + column = 8 + 2 + length(argssize) + 15 if ($2 != "NOIMPL") { printf("sys_%s },", funcname) > sysent column = column + length(funcname) + 7 @@ -387,9 +379,9 @@ s/\$//g } printf("%s\tsys_o%s (struct %s *);\n", rettype, funcname, argalias) > syscompatdcl - printf("\t{ compat(%s%s,%s) },", - mpsafe, argssize, funcname) > sysent - align_sysent_comment(8 + 9 + length(mpsafe) + \ + printf("\t{ compat(%s,%s) },", + argssize, funcname) > sysent + align_sysent_comment(8 + 9 + \ length(argssize) + 1 + length(funcname) + 4) printf("/* %d = old %s */\n", syscall, funcalias) > sysent printf("\t\"old.%s\",\t\t/* %d = old %s */\n", @@ -429,9 +421,9 @@ s/\$//g } printf("%s\tsys_dfbsd12_%s (struct %s *);\n", rettype, funcname, argalias) > syscompatdcldf12 - printf("\t{ compatdf12(%s%s,%s) },", - mpsafe, argssize, funcname) > sysent - align_sysent_comment(8 + 9 + length(mpsafe) + \ + printf("\t{ compatdf12(%s,%s) },", + argssize, funcname) > sysent + align_sysent_comment(8 + 9 + \ length(argssize) + 1 + length(funcname) + 4) printf("/* %d = old %s */\n", syscall, funcalias) > sysent printf("\t\"old.%s\",\t\t/* %d = old %s */\n", @@ -447,9 +439,9 @@ s/\$//g ncompat++ parseline() printf("%s\tsys_o%s();\n", rettype, funcname) > syscompatdcl - printf("\t{ compat(%s%s,%s) },", - mpsafe, argssize, funcname) > sysent - align_sysent_comment(8 + 9 + length(mpsafe) + \ + printf("\t{ compat(%s,%s) },", + argssize, funcname) > sysent + align_sysent_comment(8 + 9 + \ length(argssize) + 1 + length(funcname) + 4) printf("/* %d = old %s */\n", syscall, funcalias) > sysent printf("\t\"old.%s\",\t\t/* %d = old %s */\n", diff --git a/sys/kern/subr_prof.c b/sys/kern/subr_prof.c index 8dcd5aa0be..25becac1ea 100644 --- a/sys/kern/subr_prof.c +++ b/sys/kern/subr_prof.c @@ -341,8 +341,9 @@ SYSCTL_NODE(_kern, KERN_PROF, prof, CTLFLAG_RW, sysctl_kern_prof, ""); * * The scale factor is a fixed point number with 16 bits of fraction, so that * 1.0 is represented as 0x10000. A scale factor of 0 turns off profiling. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_profil(struct profil_args *uap) { @@ -351,21 +352,22 @@ sys_profil(struct profil_args *uap) if (uap->scale > (1 << 16)) return (EINVAL); + get_mplock(); if (uap->scale == 0) { stopprofclock(p); - return (0); + } else { + upp = &p->p_prof; + + /* Block profile interrupts while changing state. */ + crit_enter(); + upp->pr_off = uap->offset; + upp->pr_scale = uap->scale; + upp->pr_base = uap->samples; + upp->pr_size = uap->size; + startprofclock(p); + crit_exit(); } - upp = &p->p_prof; - - /* Block profile interrupts while changing state. */ - crit_enter(); - upp->pr_off = uap->offset; - upp->pr_scale = uap->scale; - upp->pr_base = uap->samples; - upp->pr_size = uap->size; - startprofclock(p); - crit_exit(); - + rel_mplock(); return (0); } diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index d88fd33ae4..8a978c2f77 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -513,12 +513,18 @@ dofilewrite(int fd, struct file *fp, struct uio *auio, int flags, size_t *res) /* * Ioctl system call + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_ioctl(struct ioctl_args *uap) { - return(mapped_ioctl(uap->fd, uap->com, uap->data, NULL, &uap->sysmsg)); + int error; + + get_mplock(); + error = mapped_ioctl(uap->fd, uap->com, uap->data, NULL, &uap->sysmsg); + rel_mplock(); + return (error); } struct ioctl_map_entry { @@ -751,6 +757,8 @@ SYSCTL_INT(_kern, OID_AUTO, nselcoll, CTLFLAG_RD, &nselcoll, 0, ""); /* * Select system call. + * + * MPALMOSTSAFE */ int sys_select(struct select_args *uap) @@ -777,8 +785,10 @@ sys_select(struct select_args *uap) /* * Do real work. */ + get_mplock(); error = doselect(uap->nd, uap->in, uap->ou, uap->ex, ktvp, &uap->sysmsg_result); + rel_mplock(); return (error); } @@ -786,6 +796,8 @@ sys_select(struct select_args *uap) /* * Pselect system call. + * + * MPALMOSTSAFE */ int sys_pselect(struct pselect_args *uap) @@ -823,9 +835,12 @@ sys_pselect(struct pselect_args *uap) error = copyin(uap->sigmask, &sigmask, sizeof(sigmask)); if (error) return (error); + get_mplock(); lp->lwp_oldsigmask = lp->lwp_sigmask; SIG_CANTMASK(sigmask); lp->lwp_sigmask = sigmask; + } else { + get_mplock(); } /* @@ -852,6 +867,7 @@ sys_pselect(struct pselect_args *uap) lp->lwp_sigmask = lp->lwp_oldsigmask; } } + rel_mplock(); return (error); } @@ -1027,6 +1043,8 @@ selscan(struct proc *p, fd_mask **ibits, fd_mask **obits, int nfd, int *res) /* * Poll system call. + * + * MPALMOSTSAFE */ int sys_poll(struct poll_args *uap) @@ -1075,7 +1093,9 @@ sys_poll(struct poll_args *uap) retry: ncoll = nselcoll; lp->lwp_flag |= LWP_SELECT; + get_mplock(); error = pollscan(p, bits, nfds, &uap->sysmsg_result); + rel_mplock(); if (error || uap->sysmsg_result) goto done; if (atv.tv_sec || atv.tv_usec) { @@ -1088,12 +1108,13 @@ retry: 24 * 60 * 60 * hz : tvtohz_high(&ttv); } crit_enter(); + tsleep_interlock(&selwait, PCATCH); if ((lp->lwp_flag & LWP_SELECT) == 0 || nselcoll != ncoll) { crit_exit(); goto retry; } lp->lwp_flag &= ~LWP_SELECT; - error = tsleep((caddr_t)&selwait, PCATCH, "poll", timo); + error = tsleep(&selwait, PCATCH | PINTERLOCKED, "poll", timo); crit_exit(); if (error == 0) goto retry; @@ -1153,6 +1174,8 @@ pollscan(struct proc *p, struct pollfd *fds, u_int nfd, int *res) /* * OpenBSD poll system call. * XXX this isn't quite a true representation.. OpenBSD uses select ops. + * + * MPSAFE */ int sys_openbsd_poll(struct openbsd_poll_args *uap) diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index 6ca9d87ddf..1ec3325e3d 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -253,10 +253,10 @@ pipe_rel_mplock(int *save) /* * The pipe system call for the DTYPE_PIPE type of pipes * - * pipe_ARgs(int dummy) + * pipe_args(int dummy) + * + * MPSAFE */ - -/* ARGSUSED */ int sys_pipe(struct pipe_args *uap) { diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 4c0d8257c0..8267ead558 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -198,6 +198,8 @@ pwrite (struct proc *procp, unsigned int addr, unsigned int datum) { /* * Process debugging system call. + * + * MPALMOSTSAFE */ int sys_ptrace(struct ptrace_args *uap) @@ -245,8 +247,10 @@ sys_ptrace(struct ptrace_args *uap) if (error) return (error); + get_mplock(); error = kern_ptrace(p, uap->req, uap->pid, addr, uap->data, &uap->sysmsg_result); + rel_mplock(); if (error) return (error); diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 5436705e63..098063a92d 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -329,8 +329,8 @@ const char *syscallnames[] = { "aio_write", /* 319 = aio_write */ "lio_listio", /* 320 = lio_listio */ "yield", /* 321 = yield */ - "thr_sleep", /* 322 = thr_sleep */ - "thr_wakeup", /* 323 = thr_wakeup */ + "#322", /* 322 = thr_sleep */ + "#323", /* 323 = thr_wakeup */ "mlockall", /* 324 = mlockall */ "munlockall", /* 325 = munlockall */ "__getcwd", /* 326 = __getcwd */ diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index e6fcc3fa5e..c9672219f2 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -4,10 +4,8 @@ ; System call name/number master file. ; Processed to created init_sysent.c, syscalls.c and syscall.h. -; Columns: number [MPSAFE] type nargs namespc name alt{name,tag,rtyp}/comments +; Columns: number type nargs namespc name alt{name,tag,rtyp}/comments ; number system call number, must be in order -; MPSAFE optional field, specifies that syscall does not want the -; BGL grabbed automatically (it is SMP safe). ; type one of STD, OBSOL, UNIMPL, COMPAT, CPT_NOA, LIBCOMPAT, ; NODEF, NOARGS, NOPROTO, NOIMPL ; namespc one of POSIX, BSD, NOHIDE @@ -17,6 +15,9 @@ ; alttag name of args struct tag if different from [o]`name'"_args" ; altrtyp return type if not int (bogus - syscalls always return int) ; for UNIMPL/OBSOL, name continues with comments +; +; NOTE: All system calls are now called without the MP lock. Those +; that need the MP lock will acquire it. ; types: ; STD always included @@ -47,13 +48,13 @@ 0 STD NOHIDE { int nosys(void); } syscall nosys_args int 1 STD NOHIDE { void exit(int rval); } 2 STD POSIX { int fork(void); } -3 MPSAFE STD POSIX { ssize_t read(int fd, void *buf, size_t nbyte); } -4 MPSAFE STD POSIX { ssize_t write(int fd, const void *buf, size_t nbyte); } +3 STD POSIX { ssize_t read(int fd, void *buf, size_t nbyte); } +4 STD POSIX { ssize_t write(int fd, const void *buf, size_t nbyte); } 5 STD POSIX { int open(char *path, int flags, int mode); } ; XXX should be { int open(const char *path, int flags, ...); } ; but we're not ready for `const' or varargs. ; XXX man page says `mode_t mode'. -6 MPSAFE STD POSIX { int close(int fd); } +6 STD POSIX { int close(int fd); } 7 STD BSD { int wait4(int pid, int *status, int options, \ struct rusage *rusage); } wait4 wait_args int 8 COMPAT BSD { int creat(char *path, int mode); } @@ -75,8 +76,8 @@ ; XXX `path' should have type `const char *' but we're not ready for that. 22 STD BSD { int unmount(char *path, int flags); } 23 STD POSIX { int setuid(uid_t uid); } -24 MPSAFE STD POSIX { uid_t getuid(void); } -25 MPSAFE STD POSIX { uid_t geteuid(void); } +24 STD POSIX { uid_t getuid(void); } +25 STD POSIX { uid_t geteuid(void); } 26 STD BSD { int ptrace(int req, pid_t pid, caddr_t addr, \ int data); } 27 STD BSD { int recvmsg(int s, struct msghdr *msg, int flags); } @@ -94,7 +95,7 @@ 38 COMPAT POSIX { int stat(char *path, struct ostat *ub); } 39 STD POSIX { pid_t getppid(void); } 40 COMPAT POSIX { int lstat(char *path, struct ostat *ub); } -41 MPSAFE STD POSIX { int dup(u_int fd); } +41 STD POSIX { int dup(u_int fd); } 42 STD POSIX { int pipe(void); } 43 STD POSIX { gid_t getegid(void); } 44 STD BSD { int profil(caddr_t samples, size_t size, \ @@ -102,7 +103,7 @@ 45 STD BSD { int ktrace(const char *fname, int ops, int facs, \ int pid); } 46 OBSOL NOHIDE freebsd3_sigaction -47 MPSAFE STD POSIX { gid_t getgid(void); } +47 STD POSIX { gid_t getgid(void); } 48 OBSOL NOHIDE freebsd3_sigprocmask ; XXX note nonstandard (bogus) calling convention - the libc stub passes ; us the mask, not a pointer to it, and we return the old mask as the @@ -118,7 +119,7 @@ 57 STD POSIX { int symlink(char *path, char *link); } 58 STD POSIX { int readlink(char *path, char *buf, int count); } 59 STD POSIX { int execve(char *fname, char **argv, char **envv); } -60 MPSAFE STD POSIX { int umask(int newmask); } umask umask_args int +60 STD POSIX { int umask(int newmask); } umask umask_args int 61 STD BSD { int chroot(char *path); } 62 COMPAT POSIX { int fstat(int fd, struct ostat *sb); } 63 COMPAT BSD { int getkerninfo(int op, char *where, size_t *size, \ @@ -143,7 +144,7 @@ char *vec); } 79 STD POSIX { int getgroups(u_int gidsetsize, gid_t *gidset); } 80 STD POSIX { int setgroups(u_int gidsetsize, gid_t *gidset); } -81 MPSAFE STD POSIX { int getpgrp(void); } +81 STD POSIX { int getpgrp(void); } 82 STD POSIX { int setpgid(int pid, int pgid); } 83 STD BSD { int setitimer(u_int which, struct itimerval *itv, \ struct itimerval *oitv); } @@ -154,10 +155,10 @@ gethostname gethostname_args int 88 COMPAT BSD { int sethostname(char *hostname, u_int len); } \ sethostname sethostname_args int -89 MPSAFE STD BSD { int getdtablesize(void); } -90 MPSAFE STD POSIX { int dup2(u_int from, u_int to); } +89 STD BSD { int getdtablesize(void); } +90 STD POSIX { int dup2(u_int from, u_int to); } 91 UNIMPL BSD getdopt -92 MPSAFE STD POSIX { int fcntl(int fd, int cmd, long arg); } +92 STD POSIX { int fcntl(int fd, int cmd, long arg); } ; XXX should be { int fcntl(int fd, int cmd, ...); } ; but we're not ready for varargs. ; XXX man page says `int arg' too. @@ -191,14 +192,14 @@ 113 COMPAT BSD { int recvmsg(int s, struct omsghdr *msg, int flags); } 114 COMPAT BSD { int sendmsg(int s, caddr_t msg, int flags); } 115 OBSOL NOHIDE vtrace -116 MPSAFE STD BSD { int gettimeofday(struct timeval *tp, \ +116 STD BSD { int gettimeofday(struct timeval *tp, \ struct timezone *tzp); } 117 STD BSD { int getrusage(int who, struct rusage *rusage); } 118 STD BSD { int getsockopt(int s, int level, int name, \ caddr_t val, int *avalsize); } 119 UNIMPL NOHIDE resuba (BSD/OS 2.x) -120 MPSAFE STD BSD { int readv(int fd, struct iovec *iovp, u_int iovcnt); } -121 MPSAFE STD BSD { int writev(int fd, struct iovec *iovp, \ +120 STD BSD { int readv(int fd, struct iovec *iovp, u_int iovcnt); } +121 STD BSD { int writev(int fd, struct iovec *iovp, \ u_int iovcnt); } 122 STD BSD { int settimeofday(struct timeval *tv, \ struct timezone *tzp); } @@ -228,8 +229,8 @@ 141 COMPAT BSD { int getpeername(int fdes, caddr_t asa, int *alen); } 142 COMPAT BSD { long gethostid(void); } 143 COMPAT BSD { int sethostid(long hostid); } -144 MPSAFE COMPAT BSD { int getrlimit(u_int which, struct orlimit *rlp); } -145 MPSAFE COMPAT BSD { int setrlimit(u_int which, struct orlimit *rlp); } +144 COMPAT BSD { int getrlimit(u_int which, struct orlimit *rlp); } +145 COMPAT BSD { int setrlimit(u_int which, struct orlimit *rlp); } 146 COMPAT BSD { int killpg(int pgid, int signum); } 147 STD POSIX { int setsid(void); } 148 STD BSD { int quotactl(char *path, int cmd, int uid, \ @@ -273,9 +274,9 @@ 171 STD BSD { int shmsys(int which, int a2, int a3, int a4); } ; XXX should be { int shmsys(int which, ...); } 172 UNIMPL NOHIDE nosys -173 MPSAFE STD POSIX { ssize_t extpread(int fd, void *buf, \ +173 STD POSIX { ssize_t extpread(int fd, void *buf, \ size_t nbyte, int flags, off_t offset); } -174 MPSAFE STD POSIX { ssize_t extpwrite(int fd, const void *buf, \ +174 STD POSIX { ssize_t extpwrite(int fd, const void *buf, \ size_t nbyte, int flags, off_t offset); } 175 UNIMPL NOHIDE nosys 176 STD BSD { int ntp_adjtime(struct timex *tp); } @@ -428,9 +429,9 @@ 287 UNIMPL NOHIDE nosys 288 UNIMPL NOHIDE nosys ; 289 and 290 from NetBSD (OpenBSD: 267 and 268) -289 MPSAFE STD BSD { ssize_t extpreadv(int fd, struct iovec *iovp, \ +289 STD BSD { ssize_t extpreadv(int fd, struct iovec *iovp, \ u_int iovcnt, int flags, off_t offset); } -290 MPSAFE STD BSD { ssize_t extpwritev(int fd, struct iovec *iovp,\ +290 STD BSD { ssize_t extpwritev(int fd, struct iovec *iovp,\ u_int iovcnt, int flags, off_t offset); } 291 UNIMPL NOHIDE nosys 292 UNIMPL NOHIDE nosys @@ -465,8 +466,8 @@ 319 STD BSD { int aio_write(struct aiocb *aiocbp); } 320 STD BSD { int lio_listio(int mode, struct aiocb * const *acb_list, int nent, struct sigevent *sig); } 321 STD BSD { int yield(void); } -322 STD BSD { int thr_sleep(const struct timespec *timeout); } -323 STD BSD { int thr_wakeup(pid_t pid); } +322 UNIMPL BSD thr_sleep +323 UNIMPL BSD thr_wakeup 324 STD BSD { int mlockall(int how); } 325 STD BSD { int munlockall(void); } 326 STD BSD { int __getcwd(u_char *buf, u_int buflen); } @@ -486,7 +487,7 @@ 337 STD BSD { int kldsym(int fileid, int cmd, void *data); } 338 STD BSD { int jail(struct jail *jail); } 339 UNIMPL BSD pioctl -340 MPSAFE STD POSIX { int sigprocmask(int how, const sigset_t *set, \ +340 STD POSIX { int sigprocmask(int how, const sigset_t *set, \ sigset_t *oset); } 341 STD POSIX { int sigsuspend(const sigset_t *sigmask); } 342 STD POSIX { int sigaction(int sig, const struct sigaction *act, \ @@ -621,9 +622,9 @@ 448 UNIMPL NOHIDE nosys 449 UNIMPL NOHIDE nosys ; 450 DragonFly system calls -450 MPSAFE STD BSD { int varsym_set(int level, const char *name, const char *data); } -451 MPSAFE STD BSD { int varsym_get(int mask, const char *wild, char *buf, int bufsize); } -452 MPSAFE STD BSD { int varsym_list(int level, char *buf, int maxsize, int *marker); } +450 STD BSD { int varsym_set(int level, const char *name, const char *data); } +451 STD BSD { int varsym_get(int mask, const char *wild, char *buf, int bufsize); } +452 STD BSD { int varsym_list(int level, char *buf, int maxsize, int *marker); } 453 STD BSD { int upc_register(struct upcall *upc, void *ctxfunc, void *func, void *data); } 454 STD BSD { int upc_control(int cmd, int upcid, void *data); } 455 STD BSD { int caps_sys_service(const char *name, uid_t uid, gid_t gid, int upcid, int flags); } @@ -643,11 +644,11 @@ 469 STD BSD { int umtx_sleep(volatile const int *ptr, int value, int timeout); } 470 STD BSD { int umtx_wakeup(volatile const int *ptr, int count); } 471 STD BSD { int jail_attach(int jid); } -472 MPSAFE STD BSD { int set_tls_area(int which, struct tls_info *info, size_t infosize); } -473 MPSAFE STD BSD { int get_tls_area(int which, struct tls_info *info, size_t infosize); } -474 MPSAFE STD BSD { int closefrom(int fd); } +472 STD BSD { int set_tls_area(int which, struct tls_info *info, size_t infosize); } +473 STD BSD { int get_tls_area(int which, struct tls_info *info, size_t infosize); } +474 STD BSD { int closefrom(int fd); } 475 STD POSIX { int stat(const char *path, struct stat *ub); } -476 MPSAFE STD POSIX { int fstat(int fd, struct stat *sb); } +476 STD POSIX { int fstat(int fd, struct stat *sb); } 477 STD POSIX { int lstat(const char *path, struct stat *ub); } 478 STD BSD { int fhstat(const struct fhandle *u_fhp, struct stat *sb); } 479 STD BSD { int getdirentries(int fd, char *buf, u_int count, \ @@ -703,25 +704,25 @@ int flags); } ; POSIX message queues system calls -510 MPSAFE STD POSIX { mqd_t mq_open(const char * name, int oflag, \ +510 STD POSIX { mqd_t mq_open(const char * name, int oflag, \ mode_t mode, struct mq_attr *attr); } -511 MPSAFE STD POSIX { int mq_close(mqd_t mqdes); } -512 MPSAFE STD POSIX { int mq_unlink(const char *name); } -513 MPSAFE STD POSIX { int mq_getattr(mqd_t mqdes, \ +511 STD POSIX { int mq_close(mqd_t mqdes); } +512 STD POSIX { int mq_unlink(const char *name); } +513 STD POSIX { int mq_getattr(mqd_t mqdes, \ struct mq_attr *mqstat); } -514 MPSAFE STD POSIX { int mq_setattr(mqd_t mqdes, \ +514 STD POSIX { int mq_setattr(mqd_t mqdes, \ const struct mq_attr *mqstat, \ struct mq_attr *omqstat); } -515 MPSAFE STD POSIX { int mq_notify(mqd_t mqdes, \ +515 STD POSIX { int mq_notify(mqd_t mqdes, \ const struct sigevent *notification); } -516 MPSAFE STD POSIX { int mq_send(mqd_t mqdes, const char *msg_ptr, \ +516 STD POSIX { int mq_send(mqd_t mqdes, const char *msg_ptr, \ size_t msg_len, unsigned msg_prio); } -517 MPSAFE STD POSIX { ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, \ +517 STD POSIX { ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, \ size_t msg_len, unsigned *msg_prio); } -518 MPSAFE STD POSIX { int mq_timedsend(mqd_t mqdes, \ +518 STD POSIX { int mq_timedsend(mqd_t mqdes, \ const char *msg_ptr, size_t msg_len, \ unsigned msg_prio, \ const struct timespec *abs_timeout); } -519 MPSAFE STD POSIX { ssize_t mq_timedreceive(mqd_t mqdes, \ +519 STD POSIX { ssize_t mq_timedreceive(mqd_t mqdes, \ char *msg_ptr, size_t msg_len, unsigned *msg_prio, \ const struct timespec *abs_timeout); } diff --git a/sys/kern/sysv_msg.c b/sys/kern/sysv_msg.c index 51ac36c885..4df2752656 100644 --- a/sys/kern/sysv_msg.c +++ b/sys/kern/sysv_msg.c @@ -192,12 +192,15 @@ SYSINIT(sysv_msg, SI_SUB_SYSV_MSG, SI_ORDER_FIRST, msginit, NULL) * Entry point for all MSG calls * * msgsys_args(int which, int a2, ...) (VARARGS) + * + * MPALMOSTSAFE */ int sys_msgsys(struct msgsys_args *uap) { struct proc *p = curproc; unsigned int which = (unsigned int)uap->which; + int error; if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL) return (ENOSYS); @@ -205,8 +208,11 @@ sys_msgsys(struct msgsys_args *uap) if (which >= sizeof(msgcalls)/sizeof(msgcalls[0])) return (EINVAL); bcopy(&uap->a2, &uap->which, - sizeof(struct msgsys_args) - offsetof(struct msgsys_args, a2)); - return ((*msgcalls[which])(uap)); + sizeof(struct msgsys_args) - offsetof(struct msgsys_args, a2)); + get_mplock(); + error = (*msgcalls[which])(uap); + rel_mplock(); + return (error); } static void @@ -232,6 +238,9 @@ msg_freehdr(struct msg *msghdr) free_msghdrs = msghdr; } +/* + * MPALMOSTSAFE + */ int sys_msgctl(struct msgctl_args *uap) { @@ -251,6 +260,7 @@ sys_msgctl(struct msgctl_args *uap) if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL) return (ENOSYS); + get_mplock(); msqid = IPCID_TO_IX(msqid); if (msqid < 0 || msqid >= msginfo.msgmni) { @@ -258,7 +268,8 @@ sys_msgctl(struct msgctl_args *uap) kprintf("msqid (%d) out of range (0<=msqid<%d)\n", msqid, msginfo.msgmni); #endif - return(EINVAL); + eval = EINVAL; + goto done; } msqptr = &msqids[msqid]; @@ -267,25 +278,25 @@ sys_msgctl(struct msgctl_args *uap) #ifdef MSG_DEBUG_OK kprintf("no such msqid\n"); #endif - return(EINVAL); + eval = EINVAL; + goto done; } if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { #ifdef MSG_DEBUG_OK kprintf("wrong sequence number\n"); #endif - return(EINVAL); + eval = EINVAL; + goto done; } - eval = 0; rval = 0; switch (cmd) { - case IPC_RMID: { struct msg *msghdr; - if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_M))) - return(eval); + if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_M)) != 0) + break; /* Free the message headers */ msghdr = msqptr->msg_first; while (msghdr != NULL) { @@ -312,14 +323,14 @@ sys_msgctl(struct msgctl_args *uap) break; case IPC_SET: - if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_M))) - return(eval); + if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_M)) != 0) + break; if ((eval = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0) - return(eval); + break; if (msqbuf.msg_qbytes > msqptr->msg_qbytes) { eval = priv_check(td, PRIV_ROOT); if (eval) - return(eval); + break; } if (msqbuf.msg_qbytes > msginfo.msgmnb) { #ifdef MSG_DEBUG_OK @@ -332,12 +343,13 @@ sys_msgctl(struct msgctl_args *uap) #ifdef MSG_DEBUG_OK kprintf("can't reduce msg_qbytes to 0\n"); #endif - return(EINVAL); /* non-standard errno! */ + eval = EINVAL; /* non-standard errno! */ + break; } msqptr->msg_perm.uid = msqbuf.msg_perm.uid; /* change the owner */ msqptr->msg_perm.gid = msqbuf.msg_perm.gid; /* change the owner */ msqptr->msg_perm.mode = (msqptr->msg_perm.mode & ~0777) | - (msqbuf.msg_perm.mode & 0777); + (msqbuf.msg_perm.mode & 0777); msqptr->msg_qbytes = msqbuf.msg_qbytes; msqptr->msg_ctime = time_second; break; @@ -347,24 +359,29 @@ sys_msgctl(struct msgctl_args *uap) #ifdef MSG_DEBUG_OK kprintf("requester doesn't have read access\n"); #endif - return(eval); + eval = EINVAL; + break; } - eval = copyout((caddr_t)msqptr, user_msqptr, - sizeof(struct msqid_ds)); + eval = copyout(msqptr, user_msqptr, sizeof(struct msqid_ds)); break; default: #ifdef MSG_DEBUG_OK kprintf("invalid command %d\n", cmd); #endif - return(EINVAL); + eval = EINVAL; + break; } - +done: + rel_mplock(); if (eval == 0) uap->sysmsg_result = rval; return(eval); } +/* + * MPALMOSTSAFE + */ int sys_msgget(struct msgget_args *uap) { @@ -378,10 +395,12 @@ sys_msgget(struct msgget_args *uap) #ifdef MSG_DEBUG_OK kprintf("msgget(0x%x, 0%o)\n", key, msgflg); #endif - if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL) return (ENOSYS); + eval = 0; + get_mplock(); + if (key != IPC_PRIVATE) { for (msqid = 0; msqid < msginfo.msgmni; msqid++) { msqptr = &msqids[msqid]; @@ -397,16 +416,17 @@ sys_msgget(struct msgget_args *uap) #ifdef MSG_DEBUG_OK kprintf("not exclusive\n"); #endif - return(EEXIST); + eval = EEXIST; + goto done; } if ((eval = ipcperm(p, &msqptr->msg_perm, msgflg & 0700 ))) { #ifdef MSG_DEBUG_OK kprintf("requester doesn't have 0%o access\n", msgflg & 0700); #endif - return(eval); + goto done; } - goto found; + goto done; } } @@ -430,7 +450,8 @@ sys_msgget(struct msgget_args *uap) #ifdef MSG_DEBUG_OK kprintf("no more msqid_ds's available\n"); #endif - return(ENOSPC); + eval = ENOSPC; + goto done; } #ifdef MSG_DEBUG_OK kprintf("msqid %d is available\n", msqid); @@ -457,15 +478,20 @@ sys_msgget(struct msgget_args *uap) #ifdef MSG_DEBUG_OK kprintf("didn't find it and wasn't asked to create it\n"); #endif - return(ENOENT); + eval = ENOENT; } -found: +done: + rel_mplock(); /* Construct the unique msqid */ - uap->sysmsg_result = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm); - return(0); + if (eval == 0) + uap->sysmsg_result = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm); + return(eval); } +/* + * MPALMOSTSAFE + */ int sys_msgsnd(struct msgsnd_args *uap) { @@ -487,6 +513,7 @@ sys_msgsnd(struct msgsnd_args *uap) if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL) return (ENOSYS); + get_mplock(); msqid = IPCID_TO_IX(msqid); if (msqid < 0 || msqid >= msginfo.msgmni) { @@ -494,7 +521,8 @@ sys_msgsnd(struct msgsnd_args *uap) kprintf("msqid (%d) out of range (0<=msqid<%d)\n", msqid, msginfo.msgmni); #endif - return(EINVAL); + eval = EINVAL; + goto done; } msqptr = &msqids[msqid]; @@ -502,20 +530,23 @@ sys_msgsnd(struct msgsnd_args *uap) #ifdef MSG_DEBUG_OK kprintf("no such message queue id\n"); #endif - return(EINVAL); + eval = EINVAL; + goto done; } if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { #ifdef MSG_DEBUG_OK kprintf("wrong sequence number\n"); #endif - return(EINVAL); + eval = EINVAL; + goto done; } if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_W))) { #ifdef MSG_DEBUG_OK kprintf("requester doesn't have write access\n"); #endif - return(eval); + eval = eval; + goto done; } segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz; @@ -535,7 +566,8 @@ sys_msgsnd(struct msgsnd_args *uap) #ifdef MSG_DEBUG_OK kprintf("msgsz > msqptr->msg_qbytes\n"); #endif - return(EINVAL); + eval = EINVAL; + goto done; } if (msqptr->msg_perm.mode & MSG_LOCKED) { @@ -570,7 +602,8 @@ sys_msgsnd(struct msgsnd_args *uap) #ifdef MSG_DEBUG_OK kprintf("need more resources but caller doesn't want to wait\n"); #endif - return(EAGAIN); + eval = EAGAIN; + goto done; } if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0) { @@ -600,7 +633,8 @@ sys_msgsnd(struct msgsnd_args *uap) #ifdef MSG_DEBUG_OK kprintf("msgsnd: interrupted system call\n"); #endif - return(EINTR); + eval = EINTR; + goto done; } /* @@ -611,7 +645,8 @@ sys_msgsnd(struct msgsnd_args *uap) #ifdef MSG_DEBUG_OK kprintf("msqid deleted\n"); #endif - return(EIDRM); + eval = EIDRM; + goto done; } } else { @@ -690,7 +725,7 @@ sys_msgsnd(struct msgsnd_args *uap) msg_freehdr(msghdr); msqptr->msg_perm.mode &= ~MSG_LOCKED; wakeup((caddr_t)msqptr); - return(eval); + goto done; } user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type); @@ -705,7 +740,8 @@ sys_msgsnd(struct msgsnd_args *uap) #ifdef MSG_DEBUG_OK kprintf("mtype (%d) < 1\n", msghdr->msg_type); #endif - return(EINVAL); + eval = EINVAL; + goto done; } /* @@ -731,7 +767,7 @@ sys_msgsnd(struct msgsnd_args *uap) msg_freehdr(msghdr); msqptr->msg_perm.mode &= ~MSG_LOCKED; wakeup((caddr_t)msqptr); - return(eval); + goto done; } msgsz -= tlen; user_msgp = (char *)user_msgp + tlen; @@ -753,7 +789,8 @@ sys_msgsnd(struct msgsnd_args *uap) if (msqptr->msg_qbytes == 0) { msg_freehdr(msghdr); wakeup((caddr_t)msqptr); - return(EIDRM); + eval = EIDRM; + goto done; } /* @@ -775,10 +812,17 @@ sys_msgsnd(struct msgsnd_args *uap) msqptr->msg_stime = time_second; wakeup((caddr_t)msqptr); - uap->sysmsg_result = 0; - return(0); + eval = 0; +done: + rel_mplock(); + if (eval == 0) + uap->sysmsg_result = 0; + return (eval); } +/* + * MPALMOSTSAFE + */ int sys_msgrcv(struct msgrcv_args *uap) { @@ -802,6 +846,7 @@ sys_msgrcv(struct msgrcv_args *uap) if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL) return (ENOSYS); + get_mplock(); msqid = IPCID_TO_IX(msqid); if (msqid < 0 || msqid >= msginfo.msgmni) { @@ -809,7 +854,8 @@ sys_msgrcv(struct msgrcv_args *uap) kprintf("msqid (%d) out of range (0<=msqid<%d)\n", msqid, msginfo.msgmni); #endif - return(EINVAL); + eval = EINVAL; + goto done; } msqptr = &msqids[msqid]; @@ -817,20 +863,22 @@ sys_msgrcv(struct msgrcv_args *uap) #ifdef MSG_DEBUG_OK kprintf("no such message queue id\n"); #endif - return(EINVAL); + eval = EINVAL; + goto done; } if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { #ifdef MSG_DEBUG_OK kprintf("wrong sequence number\n"); #endif - return(EINVAL); + eval = EINVAL; + goto done; } if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_R))) { #ifdef MSG_DEBUG_OK kprintf("requester doesn't have read access\n"); #endif - return(eval); + goto done; } msghdr = NULL; @@ -844,7 +892,8 @@ sys_msgrcv(struct msgrcv_args *uap) kprintf("first message on the queue is too big (want %d, got %d)\n", msgsz, msghdr->msg_ts); #endif - return(E2BIG); + eval = E2BIG; + goto done; } if (msqptr->msg_first == msqptr->msg_last) { msqptr->msg_first = NULL; @@ -883,7 +932,8 @@ sys_msgrcv(struct msgrcv_args *uap) kprintf("requested message on the queue is too big (want %d, got %d)\n", msgsz, msghdr->msg_ts); #endif - return(E2BIG); + eval = E2BIG; + goto done; } *prev = msghdr->msg_next; if (msghdr == msqptr->msg_last) { @@ -930,11 +980,12 @@ sys_msgrcv(struct msgrcv_args *uap) #endif /* The SVID says to return ENOMSG. */ #ifdef ENOMSG - return(ENOMSG); + eval = ENOMSG; #else /* Unfortunately, BSD doesn't define that code yet! */ - return(EAGAIN); + eval = EAGAIN; #endif + goto done; } /* @@ -953,7 +1004,8 @@ sys_msgrcv(struct msgrcv_args *uap) #ifdef MSG_DEBUG_OK kprintf("msgsnd: interrupted system call\n"); #endif - return(EINTR); + eval = EINTR; + goto done; } /* @@ -965,7 +1017,8 @@ sys_msgrcv(struct msgrcv_args *uap) #ifdef MSG_DEBUG_OK kprintf("msqid deleted\n"); #endif - return(EIDRM); + eval = EIDRM; + goto done; } } @@ -1005,7 +1058,7 @@ sys_msgrcv(struct msgrcv_args *uap) #endif msg_freehdr(msghdr); wakeup((caddr_t)msqptr); - return(eval); + goto done; } user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type); @@ -1034,7 +1087,7 @@ sys_msgrcv(struct msgrcv_args *uap) #endif msg_freehdr(msghdr); wakeup((caddr_t)msqptr); - return(eval); + goto done; } user_msgp = (char *)user_msgp + tlen; next = msgmaps[next].next; @@ -1046,8 +1099,12 @@ sys_msgrcv(struct msgrcv_args *uap) msg_freehdr(msghdr); wakeup((caddr_t)msqptr); - uap->sysmsg_result = msgsz; - return(0); + eval = 0; +done: + rel_mplock(); + if (eval == 0) + uap->sysmsg_result = msgsz; + return(eval); } static int diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c index caec18d2a7..3f75691262 100644 --- a/sys/kern/sysv_sem.c +++ b/sys/kern/sysv_sem.c @@ -185,12 +185,15 @@ SYSINIT(sysv_sem, SI_SUB_SYSV_SEM, SI_ORDER_FIRST, seminit, NULL) * Entry point for all SEM calls * * semsys_args(int which, a2, a3, ...) (VARARGS) + * + * MPALMOSTSAFE */ int sys_semsys(struct semsys_args *uap) { struct proc *p = curproc; unsigned int which = (unsigned int)uap->which; + int error; if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL) return (ENOSYS); @@ -198,8 +201,11 @@ sys_semsys(struct semsys_args *uap) if (which >= sizeof(semcalls)/sizeof(semcalls[0])) return (EINVAL); bcopy(&uap->a2, &uap->which, - sizeof(struct semsys_args) - offsetof(struct semsys_args, a2)); - return ((*semcalls[which])(uap)); + sizeof(struct semsys_args) - offsetof(struct semsys_args, a2)); + get_mplock(); + error = (*semcalls[which])(uap); + rel_mplock(); + return (error); } /* @@ -369,8 +375,9 @@ semundo_clear(int semid, int semnum) /* * Note that the user-mode half of this passes a union, not a pointer + * + * MPALMOSTSAFE */ - int sys___semctl(struct __semctl_args *uap) { @@ -396,18 +403,21 @@ sys___semctl(struct __semctl_args *uap) if (semid < 0 || semid >= seminfo.semmni) return(EINVAL); + get_mplock(); semaptr = &sema[semid]; if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 || - semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) + semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) { + rel_mplock(); return(EINVAL); + } eval = 0; rval = 0; switch (cmd) { case IPC_RMID: - if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_M))) - return(eval); + if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_M)) != 0) + break; semaptr->sem_perm.cuid = cred->cr_uid; semaptr->sem_perm.uid = cred->cr_uid; semtot -= semaptr->sem_nsems; @@ -424,91 +434,102 @@ sys___semctl(struct __semctl_args *uap) break; case IPC_SET: - if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_M))) - return(eval); + if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_M)) != 0) + break; if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - return(eval); + break; if ((eval = copyin(real_arg.buf, (caddr_t)&sbuf, - sizeof(sbuf))) != 0) - return(eval); + sizeof(sbuf))) != 0) { + break; + } semaptr->sem_perm.uid = sbuf.sem_perm.uid; semaptr->sem_perm.gid = sbuf.sem_perm.gid; semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) | - (sbuf.sem_perm.mode & 0777); + (sbuf.sem_perm.mode & 0777); semaptr->sem_ctime = time_second; break; case IPC_STAT: if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R))) - return(eval); + break; if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - return(eval); - eval = copyout((caddr_t)semaptr, real_arg.buf, - sizeof(struct semid_ds)); + break; + eval = copyout(semaptr, real_arg.buf, sizeof(struct semid_ds)); break; case GETNCNT: - if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R))) - return(eval); - if (semnum < 0 || semnum >= semaptr->sem_nsems) - return(EINVAL); + if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R)) != 0) + break; + if (semnum < 0 || semnum >= semaptr->sem_nsems) { + eval = EINVAL; + break; + } rval = semaptr->sem_base[semnum].semncnt; break; case GETPID: - if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R))) - return(eval); - if (semnum < 0 || semnum >= semaptr->sem_nsems) - return(EINVAL); + if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R)) != 0) + break; + if (semnum < 0 || semnum >= semaptr->sem_nsems) { + eval = EINVAL; + break; + } rval = semaptr->sem_base[semnum].sempid; break; case GETVAL: - if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R))) - return(eval); - if (semnum < 0 || semnum >= semaptr->sem_nsems) - return(EINVAL); + if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R)) != 0) + break; + if (semnum < 0 || semnum >= semaptr->sem_nsems) { + eval = EINVAL; + break; + } rval = semaptr->sem_base[semnum].semval; break; case GETALL: - if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R))) - return(eval); + if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R)) != 0) + break; if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - return(eval); + break; for (i = 0; i < semaptr->sem_nsems; i++) { - eval = copyout((caddr_t)&semaptr->sem_base[i].semval, - &real_arg.array[i], sizeof(real_arg.array[0])); - if (eval != 0) + eval = copyout(&semaptr->sem_base[i].semval, + &real_arg.array[i], + sizeof(real_arg.array[0])); + if (eval) break; } break; case GETZCNT: - if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R))) - return(eval); - if (semnum < 0 || semnum >= semaptr->sem_nsems) - return(EINVAL); + if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R)) != 0) + break; + if (semnum < 0 || semnum >= semaptr->sem_nsems) { + eval = EINVAL; + break; + } rval = semaptr->sem_base[semnum].semzcnt; break; case SETVAL: - if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_W))) - return(eval); - if (semnum < 0 || semnum >= semaptr->sem_nsems) - return(EINVAL); + if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_W)) != 0) + break; + if (semnum < 0 || semnum >= semaptr->sem_nsems) { + eval = EINVAL; + break; + } if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - return(eval); + break; semaptr->sem_base[semnum].semval = real_arg.val; semundo_clear(semid, semnum); wakeup((caddr_t)semaptr); break; case SETALL: - if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_W))) - return(eval); + if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_W)) != 0) + break; if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - return(eval); + break; for (i = 0; i < semaptr->sem_nsems; i++) { eval = copyin(&real_arg.array[i], (caddr_t)&semaptr->sem_base[i].semval, @@ -521,14 +542,19 @@ sys___semctl(struct __semctl_args *uap) break; default: - return(EINVAL); + eval = EINVAL; + break; } + rel_mplock(); if (eval == 0) uap->sysmsg_result = rval; return(eval); } +/* + * MPALMOSTSAFE + */ int sys_semget(struct semget_args *uap) { @@ -546,6 +572,9 @@ sys_semget(struct semget_args *uap) if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL) return (ENOSYS); + get_mplock(); + eval = 0; + if (key != IPC_PRIVATE) { for (semid = 0; semid < seminfo.semmni; semid++) { if ((sema[semid].sem_perm.mode & SEM_ALLOC) && @@ -557,21 +586,24 @@ sys_semget(struct semget_args *uap) kprintf("found public key\n"); #endif if ((eval = ipcperm(p, &sema[semid].sem_perm, - semflg & 0700))) - return(eval); + semflg & 0700))) { + goto done; + } if (nsems > 0 && sema[semid].sem_nsems < nsems) { #ifdef SEM_DEBUG kprintf("too small\n"); #endif - return(EINVAL); + eval = EINVAL; + goto done; } if ((semflg & IPC_CREAT) && (semflg & IPC_EXCL)) { #ifdef SEM_DEBUG kprintf("not exclusive\n"); #endif - return(EEXIST); + eval = EEXIST; + goto done; } - goto found; + goto done; } } @@ -584,14 +616,16 @@ sys_semget(struct semget_args *uap) kprintf("nsems out of range (0<%d<=%d)\n", nsems, seminfo.semmsl); #endif - return(EINVAL); + eval = EINVAL; + goto done; } if (nsems > seminfo.semmns - semtot) { #ifdef SEM_DEBUG kprintf("not enough semaphores left (need %d, got %d)\n", nsems, seminfo.semmns - semtot); #endif - return(ENOSPC); + eval = ENOSPC; + goto done; } for (semid = 0; semid < seminfo.semmni; semid++) { if ((sema[semid].sem_perm.mode & SEM_ALLOC) == 0) @@ -601,7 +635,8 @@ sys_semget(struct semget_args *uap) #ifdef SEM_DEBUG kprintf("no more semid_ds's available\n"); #endif - return(ENOSPC); + eval = ENOSPC; + goto done; } #ifdef SEM_DEBUG kprintf("semid %d is available\n", semid); @@ -629,14 +664,21 @@ sys_semget(struct semget_args *uap) #ifdef SEM_DEBUG kprintf("didn't find it and wasn't asked to create it\n"); #endif - return(ENOENT); + eval = ENOENT; } -found: - uap->sysmsg_result = IXSEQ_TO_IPCID(semid, sema[semid].sem_perm); - return(0); +done: + if (eval == 0) { + uap->sysmsg_result = IXSEQ_TO_IPCID(semid, + sema[semid].sem_perm); + } + rel_mplock(); + return(eval); } +/* + * MPALMOSTSAFE + */ int sys_semop(struct semop_args *uap) { @@ -658,29 +700,37 @@ sys_semop(struct semop_args *uap) if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL) return (ENOSYS); + get_mplock(); semid = IPCID_TO_IX(semid); /* Convert back to zero origin */ - if (semid < 0 || semid >= seminfo.semmni) - return(EINVAL); + if (semid < 0 || semid >= seminfo.semmni) { + eval = EINVAL; + goto done; + } semaptr = &sema[semid]; - if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0) - return(EINVAL); - if (semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) - return(EINVAL); + if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0) { + eval = EINVAL; + goto done; + } + if (semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) { + eval = EINVAL; + goto done; + } if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_W))) { #ifdef SEM_DEBUG kprintf("eval = %d from ipaccess\n", eval); #endif - return(eval); + goto done; } if (nsops > MAX_SOPS) { #ifdef SEM_DEBUG kprintf("too many sops (max=%d, nsops=%u)\n", MAX_SOPS, nsops); #endif - return(E2BIG); + eval = E2BIG; + goto done; } if ((eval = copyin(uap->sops, &sops, nsops * sizeof(sops[0]))) != 0) { @@ -688,7 +738,7 @@ sys_semop(struct semop_args *uap) kprintf("eval = %d from copyin(%08x, %08x, %u)\n", eval, uap->sops, &sops, nsops * sizeof(sops[0])); #endif - return(eval); + goto done; } /* @@ -708,8 +758,10 @@ sys_semop(struct semop_args *uap) for (i = 0; i < nsops; i++) { sopptr = &sops[i]; - if (sopptr->sem_num >= semaptr->sem_nsems) - return(EFBIG); + if (sopptr->sem_num >= semaptr->sem_nsems) { + eval = EFBIG; + goto done; + } semptr = &semaptr->sem_base[sopptr->sem_num]; @@ -754,7 +806,7 @@ sys_semop(struct semop_args *uap) * Did we get through the entire vector? */ if (i >= nsops) - goto done; + goto donex; /* * No ... rollback anything that we've already done @@ -770,8 +822,10 @@ sys_semop(struct semop_args *uap) * If the request that we couldn't satisfy has the * NOWAIT flag set then return with EAGAIN. */ - if (sopptr->sem_flg & IPC_NOWAIT) - return(EAGAIN); + if (sopptr->sem_flg & IPC_NOWAIT) { + eval = EAGAIN; + goto done; + } if (sopptr->sem_op == 0) semptr->semzcnt++; @@ -794,8 +848,10 @@ sys_semop(struct semop_args *uap) * Make sure that the semaphore still exists */ if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 || - semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) - return(EIDRM); + semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) { + eval = EIDRM; + goto done; + } /* * The semaphore is still alive. Readjust the count of @@ -811,14 +867,16 @@ sys_semop(struct semop_args *uap) * (Delayed check of tsleep() return code because we * need to decrement sem[nz]cnt either way.) */ - if (eval != 0) - return(EINTR); + if (eval) { + eval = EINTR; + goto done; + } #ifdef SEM_DEBUG kprintf("semop: good morning!\n"); #endif } -done: +donex: /* * Process any SEM_UNDO requests. */ @@ -867,7 +925,7 @@ done: #ifdef SEM_DEBUG kprintf("eval = %d from semundo_adjust\n", eval); #endif - return(eval); + goto done; } /* loop through the sops */ } /* if (do_undos) */ @@ -892,7 +950,10 @@ done: kprintf("semop: done\n"); #endif uap->sysmsg_result = 0; - return(0); + eval = 0; +done: + rel_mplock(); + return(eval); } /* diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c index 3d1b8a26c7..abca0b076a 100644 --- a/sys/kern/sysv_shm.c +++ b/sys/kern/sysv_shm.c @@ -210,28 +210,43 @@ shm_delete_mapping(struct vmspace *vm, struct shmmap_state *shmmap_s) return 0; } +/* + * MPALMOSTSAFE + */ int sys_shmdt(struct shmdt_args *uap) { struct proc *p = curproc; struct shmmap_state *shmmap_s; int i; + int error; if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL) return (ENOSYS); + get_mplock(); shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm; - if (shmmap_s == NULL) - return EINVAL; - for (i = 0; i < shminfo.shmseg; i++, shmmap_s++) + if (shmmap_s == NULL) { + error = EINVAL; + goto done; + } + for (i = 0; i < shminfo.shmseg; i++, shmmap_s++) { if (shmmap_s->shmid != -1 && shmmap_s->va == (vm_offset_t)uap->shmaddr) break; + } if (i == shminfo.shmseg) - return EINVAL; - return shm_delete_mapping(p->p_vmspace, shmmap_s); + error = EINVAL; + else + error = shm_delete_mapping(p->p_vmspace, shmmap_s); +done: + rel_mplock(); + return (error); } +/* + * MPALMOSTSAFE + */ int sys_shmat(struct shmat_args *uap) { @@ -248,28 +263,38 @@ sys_shmat(struct shmat_args *uap) if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL) return (ENOSYS); + get_mplock(); +again: shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm; if (shmmap_s == NULL) { size = shminfo.shmseg * sizeof(struct shmmap_state); shmmap_s = kmalloc(size, M_SHM, M_WAITOK); for (i = 0; i < shminfo.shmseg; i++) shmmap_s[i].shmid = -1; + if (p->p_vmspace->vm_shm != NULL) { + kfree(shmmap_s, M_SHM); + goto again; + } p->p_vmspace->vm_shm = (caddr_t)shmmap_s; } shmseg = shm_find_segment_by_shmid(uap->shmid); - if (shmseg == NULL) - return EINVAL; + if (shmseg == NULL) { + error = EINVAL; + goto done; + } error = ipcperm(p, &shmseg->shm_perm, - (uap->shmflg & SHM_RDONLY) ? IPC_R : IPC_R|IPC_W); + (uap->shmflg & SHM_RDONLY) ? IPC_R : IPC_R|IPC_W); if (error) - return error; + goto done; for (i = 0; i < shminfo.shmseg; i++) { if (shmmap_s->shmid == -1) break; shmmap_s++; } - if (i >= shminfo.shmseg) - return EMFILE; + if (i >= shminfo.shmseg) { + error = EMFILE; + goto done; + } size = round_page(shmseg->shm_segsz); #ifdef VM_PROT_READ_IS_EXEC prot = VM_PROT_READ | VM_PROT_EXECUTE; @@ -281,14 +306,18 @@ sys_shmat(struct shmat_args *uap) flags = MAP_ANON | MAP_SHARED; if (uap->shmaddr) { flags |= MAP_FIXED; - if (uap->shmflg & SHM_RND) + if (uap->shmflg & SHM_RND) { attach_va = (vm_offset_t)uap->shmaddr & ~(SHMLBA-1); - else if (((vm_offset_t)uap->shmaddr & (SHMLBA-1)) == 0) + } else if (((vm_offset_t)uap->shmaddr & (SHMLBA-1)) == 0) { attach_va = (vm_offset_t)uap->shmaddr; - else - return EINVAL; + } else { + error = EINVAL; + goto done; + } } else { - /* This is just a hint to vm_map_find() about where to put it. */ + /* + * This is just a hint to vm_map_find() about where to put it. + */ attach_va = round_page((vm_offset_t)p->p_vmspace->vm_taddr + maxtsiz + maxdsiz); } @@ -303,18 +332,23 @@ sys_shmat(struct shmat_args *uap) 0); if (rv != KERN_SUCCESS) { vm_object_deallocate(shm_handle->shm_object); - return ENOMEM; + error = ENOMEM; + goto done; } vm_map_inherit(&p->p_vmspace->vm_map, - attach_va, attach_va + size, VM_INHERIT_SHARE); + attach_va, attach_va + size, VM_INHERIT_SHARE); + KKASSERT(shmmap_s->shmid == -1); shmmap_s->va = attach_va; shmmap_s->shmid = uap->shmid; shmseg->shm_lpid = p->p_pid; shmseg->shm_atime = time_second; shmseg->shm_nattch++; uap->sysmsg_result = attach_va; - return 0; + error = 0; +done: + rel_mplock(); + return error; } struct oshmid_ds { @@ -336,6 +370,9 @@ struct oshmctl_args { struct oshmid_ds *ubuf; }; +/* + * MPALMOSTSAFE + */ static int sys_oshmctl(struct proc *p, struct oshmctl_args *uap) { @@ -347,14 +384,18 @@ sys_oshmctl(struct proc *p, struct oshmctl_args *uap) if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL) return (ENOSYS); + get_mplock(); shmseg = shm_find_segment_by_shmid(uap->shmid); - if (shmseg == NULL) - return EINVAL; + if (shmseg == NULL) { + error = EINVAL; + goto done; + } + switch (uap->cmd) { case IPC_STAT: error = ipcperm(p, &shmseg->shm_perm, IPC_R); if (error) - return error; + break; outbuf.shm_perm = shmseg->shm_perm; outbuf.shm_segsz = shmseg->shm_segsz; outbuf.shm_cpid = shmseg->shm_cpid; @@ -365,19 +406,22 @@ sys_oshmctl(struct proc *p, struct oshmctl_args *uap) outbuf.shm_ctime = shmseg->shm_ctime; outbuf.shm_handle = shmseg->shm_internal; error = copyout((caddr_t)&outbuf, uap->ubuf, sizeof(outbuf)); - if (error) - return error; break; default: /* XXX casting to (sy_call_t *) is bogus, as usual. */ - return (sys_shmctl((struct shmctl_args *)uap)); + error = sys_shmctl((struct shmctl_args *)uap); } - return 0; +done: + rel_mplock(); + return error; #else return EINVAL; #endif } +/* + * MPALMOSTSAFE + */ int sys_shmctl(struct shmctl_args *uap) { @@ -389,41 +433,41 @@ sys_shmctl(struct shmctl_args *uap) if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL) return (ENOSYS); + get_mplock(); shmseg = shm_find_segment_by_shmid(uap->shmid); - if (shmseg == NULL) - return EINVAL; + if (shmseg == NULL) { + error = EINVAL; + goto done; + } + switch (uap->cmd) { case IPC_STAT: error = ipcperm(p, &shmseg->shm_perm, IPC_R); - if (error) - return error; - error = copyout((caddr_t)shmseg, uap->buf, sizeof(inbuf)); - if (error) - return error; + if (error == 0) + error = copyout(shmseg, uap->buf, sizeof(inbuf)); break; case IPC_SET: error = ipcperm(p, &shmseg->shm_perm, IPC_M); - if (error) - return error; - error = copyin(uap->buf, (caddr_t)&inbuf, sizeof(inbuf)); - if (error) - return error; - shmseg->shm_perm.uid = inbuf.shm_perm.uid; - shmseg->shm_perm.gid = inbuf.shm_perm.gid; - shmseg->shm_perm.mode = - (shmseg->shm_perm.mode & ~ACCESSPERMS) | - (inbuf.shm_perm.mode & ACCESSPERMS); - shmseg->shm_ctime = time_second; + if (error == 0) + error = copyin(uap->buf, &inbuf, sizeof(inbuf)); + if (error == 0) { + shmseg->shm_perm.uid = inbuf.shm_perm.uid; + shmseg->shm_perm.gid = inbuf.shm_perm.gid; + shmseg->shm_perm.mode = + (shmseg->shm_perm.mode & ~ACCESSPERMS) | + (inbuf.shm_perm.mode & ACCESSPERMS); + shmseg->shm_ctime = time_second; + } break; case IPC_RMID: error = ipcperm(p, &shmseg->shm_perm, IPC_M); - if (error) - return error; - shmseg->shm_perm.key = IPC_PRIVATE; - shmseg->shm_perm.mode |= SHMSEG_REMOVED; - if (shmseg->shm_nattch <= 0) { - shm_deallocate_segment(shmseg); - shm_last_free = IPCID_TO_IX(uap->shmid); + if (error == 0) { + shmseg->shm_perm.key = IPC_PRIVATE; + shmseg->shm_perm.mode |= SHMSEG_REMOVED; + if (shmseg->shm_nattch <= 0) { + shm_deallocate_segment(shmseg); + shm_last_free = IPCID_TO_IX(uap->shmid); + } } break; #if 0 @@ -431,9 +475,12 @@ sys_shmctl(struct shmctl_args *uap) case SHM_UNLOCK: #endif default: - return EINVAL; + error = EINVAL; + break; } - return 0; +done: + rel_mplock(); + return error; } static int @@ -542,6 +589,9 @@ shmget_allocate_segment(struct proc *p, struct shmget_args *uap, int mode) return 0; } +/* + * MPALMOSTSAFE + */ int sys_shmget(struct shmget_args *uap) { @@ -552,6 +602,8 @@ sys_shmget(struct shmget_args *uap) return (ENOSYS); mode = uap->shmflg & ACCESSPERMS; + get_mplock(); + if (uap->key != IPC_PRIVATE) { again: segnum = shm_find_segment_by_key(uap->key); @@ -559,16 +611,23 @@ sys_shmget(struct shmget_args *uap) error = shmget_existing(p, uap, mode, segnum); if (error == EAGAIN) goto again; - return error; + goto done; + } + if ((uap->shmflg & IPC_CREAT) == 0) { + error = ENOENT; + goto done; } - if ((uap->shmflg & IPC_CREAT) == 0) - return ENOENT; } - return shmget_allocate_segment(p, uap, mode); + error = shmget_allocate_segment(p, uap, mode); +done: + rel_mplock(); + return (error); } /* - * shmsys_args(int which, int a2, ...) (VARARGS) + * shmsys_args(int which, int a2, ...) (VARARGS) + * + * MPALMOSTSAFE */ int sys_shmsys(struct shmsys_args *uap) @@ -582,9 +641,12 @@ sys_shmsys(struct shmsys_args *uap) if (which >= sizeof(shmcalls)/sizeof(shmcalls[0])) return EINVAL; + get_mplock(); bcopy(&uap->a2, &uap->which, sizeof(struct shmsys_args) - offsetof(struct shmsys_args, a2)); error = ((*shmcalls[which])(uap)); + rel_mplock(); + return(error); } diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index c53f728dd1..f1d695c0da 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -130,13 +130,18 @@ kern_socket(int domain, int type, int protocol, int *res) return (error); } +/* + * MPALMOSTSAFE + */ int sys_socket(struct socket_args *uap) { int error; + get_mplock(); error = kern_socket(uap->domain, uap->type, uap->protocol, &uap->sysmsg_iresult); + rel_mplock(); return (error); } @@ -160,6 +165,8 @@ kern_bind(int s, struct sockaddr *sa) /* * bind_args(int s, caddr_t name, int namelen) + * + * MPALMOSTSAFE */ int sys_bind(struct bind_args *uap) @@ -170,7 +177,9 @@ sys_bind(struct bind_args *uap) error = getsockaddr(&sa, uap->name, uap->namelen); if (error) return (error); + get_mplock(); error = kern_bind(uap->s, sa); + rel_mplock(); FREE(sa, M_SONAME); return (error); @@ -195,13 +204,17 @@ kern_listen(int s, int backlog) /* * listen_args(int s, int backlog) + * + * MPALMOSTSAFE */ int sys_listen(struct listen_args *uap) { int error; + get_mplock(); error = kern_listen(uap->s, uap->backlog); + rel_mplock(); return (error); } @@ -361,6 +374,8 @@ done: /* * accept(int s, caddr_t name, int *anamelen) + * + * MPALMOSTSAFE */ int sys_accept(struct accept_args *uap) @@ -374,8 +389,10 @@ sys_accept(struct accept_args *uap) if (error) return (error); + get_mplock(); error = kern_accept(uap->s, 0, &sa, &sa_len, &uap->sysmsg_iresult); + rel_mplock(); if (error == 0) error = copyout(sa, uap->name, sa_len); @@ -386,14 +403,18 @@ sys_accept(struct accept_args *uap) if (sa) FREE(sa, M_SONAME); } else { + get_mplock(); error = kern_accept(uap->s, 0, NULL, 0, &uap->sysmsg_iresult); + rel_mplock(); } return (error); } /* * extaccept(int s, int fflags, caddr_t name, int *anamelen) + * + * MPALMOSTSAFE */ int sys_extaccept(struct extaccept_args *uap) @@ -408,8 +429,10 @@ sys_extaccept(struct extaccept_args *uap) if (error) return (error); + get_mplock(); error = kern_accept(uap->s, fflags, &sa, &sa_len, &uap->sysmsg_iresult); + rel_mplock(); if (error == 0) error = copyout(sa, uap->name, sa_len); @@ -420,8 +443,10 @@ sys_extaccept(struct extaccept_args *uap) if (sa) FREE(sa, M_SONAME); } else { + get_mplock(); error = kern_accept(uap->s, fflags, NULL, 0, &uap->sysmsg_iresult); + rel_mplock(); } return (error); } @@ -508,6 +533,8 @@ done: /* * connect_args(int s, caddr_t name, int namelen) + * + * MPALMOSTSAFE */ int sys_connect(struct connect_args *uap) @@ -518,7 +545,9 @@ sys_connect(struct connect_args *uap) error = getsockaddr(&sa, uap->name, uap->namelen); if (error) return (error); + get_mplock(); error = kern_connect(uap->s, 0, sa); + rel_mplock(); FREE(sa, M_SONAME); return (error); @@ -526,6 +555,8 @@ sys_connect(struct connect_args *uap) /* * connect_args(int s, int fflags, caddr_t name, int namelen) + * + * MPALMOSTSAFE */ int sys_extconnect(struct extconnect_args *uap) @@ -537,7 +568,9 @@ sys_extconnect(struct extconnect_args *uap) error = getsockaddr(&sa, uap->name, uap->namelen); if (error) return (error); + get_mplock(); error = kern_connect(uap->s, fflags, sa); + rel_mplock(); FREE(sa, M_SONAME); return (error); @@ -603,13 +636,17 @@ free1: /* * socketpair(int domain, int type, int protocol, int *rsv) + * + * MPALMOSTSAFE */ int sys_socketpair(struct socketpair_args *uap) { int error, sockv[2]; + get_mplock(); error = kern_socketpair(uap->domain, uap->type, uap->protocol, sockv); + rel_mplock(); if (error == 0) error = copyout(sockv, uap->rsv, sizeof(sockv)); @@ -676,6 +713,8 @@ kern_sendmsg(int s, struct sockaddr *sa, struct uio *auio, /* * sendto_args(int s, caddr_t buf, size_t len, int flags, caddr_t to, int tolen) + * + * MPALMOSTSAFE */ int sys_sendto(struct sendto_args *uap) @@ -701,8 +740,10 @@ sys_sendto(struct sendto_args *uap) auio.uio_rw = UIO_WRITE; auio.uio_td = td; + get_mplock(); error = kern_sendmsg(uap->s, sa, &auio, NULL, uap->flags, &uap->sysmsg_szresult); + rel_mplock(); if (sa) FREE(sa, M_SONAME); @@ -711,6 +752,8 @@ sys_sendto(struct sendto_args *uap) /* * sendmsg_args(int s, caddr_t msg, int flags) + * + * MPALMOSTSAFE */ int sys_sendmsg(struct sendmsg_args *uap) @@ -766,15 +809,17 @@ sys_sendmsg(struct sendmsg_args *uap) } control->m_len = msg.msg_controllen; error = copyin(msg.msg_control, mtod(control, caddr_t), - msg.msg_controllen); + msg.msg_controllen); if (error) { m_free(control); goto cleanup; } } + get_mplock(); error = kern_sendmsg(uap->s, sa, &auio, control, uap->flags, &uap->sysmsg_szresult); + rel_mplock(); cleanup: iovec_free(&iov, aiov); @@ -856,6 +901,8 @@ kern_recvmsg(int s, struct sockaddr **sa, struct uio *auio, /* * recvfrom_args(int s, caddr_t buf, size_t len, int flags, * caddr_t from, int *fromlenaddr) + * + * MPALMOSTSAFE */ int sys_recvfrom(struct recvfrom_args *uap) @@ -885,8 +932,10 @@ sys_recvfrom(struct recvfrom_args *uap) auio.uio_rw = UIO_READ; auio.uio_td = td; + get_mplock(); error = kern_recvmsg(uap->s, uap->from ? &sa : NULL, &auio, NULL, &uap->flags, &uap->sysmsg_szresult); + rel_mplock(); if (error == 0 && uap->from) { /* note: sa may still be NULL */ @@ -909,6 +958,8 @@ sys_recvfrom(struct recvfrom_args *uap) /* * recvmsg_args(int s, struct msghdr *msg, int flags) + * + * MPALMOSTSAFE */ int sys_recvmsg(struct recvmsg_args *uap) @@ -936,11 +987,11 @@ sys_recvmsg(struct recvmsg_args *uap) return (EINVAL); ufromlenp = (socklen_t *)((caddr_t)uap->msg + offsetof(struct msghdr, - msg_namelen)); + msg_namelen)); ucontrollenp = (socklen_t *)((caddr_t)uap->msg + offsetof(struct msghdr, - msg_controllen)); + msg_controllen)); uflagsp = (int *)((caddr_t)uap->msg + offsetof(struct msghdr, - msg_flags)); + msg_flags)); /* * Populate auio. @@ -958,10 +1009,12 @@ sys_recvmsg(struct recvmsg_args *uap) flags = uap->flags; + get_mplock(); error = kern_recvmsg(uap->s, (msg.msg_name ? &sa : NULL), &auio, (msg.msg_control ? &control : NULL), &flags, &uap->sysmsg_szresult); + rel_mplock(); /* * Conditionally copyout the name and populate the namelen field. @@ -1051,6 +1104,8 @@ kern_setsockopt(int s, struct sockopt *sopt) /* * setsockopt_args(int s, int level, int name, caddr_t val, int valsize) + * + * MPALMOSTSAFE */ int sys_setsockopt(struct setsockopt_args *uap) @@ -1074,7 +1129,9 @@ sys_setsockopt(struct setsockopt_args *uap) goto out; } + get_mplock(); error = kern_setsockopt(uap->s, &sopt); + rel_mplock(); out: if (uap->val) kfree(sopt.sopt_val, M_TEMP); @@ -1109,7 +1166,9 @@ kern_getsockopt(int s, struct sockopt *sopt) } /* - * getsockopt_Args(int s, int level, int name, caddr_t val, int *avalsize) + * getsockopt_args(int s, int level, int name, caddr_t val, int *avalsize) + * + * MPALMOSTSAFE */ int sys_getsockopt(struct getsockopt_args *uap) @@ -1141,7 +1200,9 @@ sys_getsockopt(struct getsockopt_args *uap) goto out; } + get_mplock(); error = kern_getsockopt(uap->s, &sopt); + rel_mplock(); if (error) goto out; valsize = sopt.sopt_valsize; @@ -1198,6 +1259,8 @@ kern_getsockname(int s, struct sockaddr **name, int *namelen) * getsockname_args(int fdes, caddr_t asa, int *alen) * * Get socket name. + * + * MPALMOSTSAFE */ int sys_getsockname(struct getsockname_args *uap) @@ -1209,7 +1272,9 @@ sys_getsockname(struct getsockname_args *uap) if (error) return (error); + get_mplock(); error = kern_getsockname(uap->fdes, &sa, &sa_len); + rel_mplock(); if (error == 0) error = copyout(sa, uap->asa, sa_len); @@ -1266,6 +1331,8 @@ kern_getpeername(int s, struct sockaddr **name, int *namelen) * getpeername_args(int fdes, caddr_t asa, int *alen) * * Get name of peer for connected socket. + * + * MPALMOSTSAFE */ int sys_getpeername(struct getpeername_args *uap) @@ -1277,7 +1344,9 @@ sys_getpeername(struct getpeername_args *uap) if (error) return (error); + get_mplock(); error = kern_getpeername(uap->fdes, &sa, &sa_len); + rel_mplock(); if (error == 0) error = copyout(sa, uap->asa, sa_len); @@ -1378,6 +1447,8 @@ sf_buf_mfree(void *arg) * the headers to count against the remaining bytes to be sent from * the file descriptor. We may wish to implement a compatibility syscall * in the future. + * + * MPALMOSTSAFE */ int sys_sendfile(struct sendfile_args *uap) @@ -1410,6 +1481,7 @@ sys_sendfile(struct sendfile_args *uap) fdrop(fp); return (EINVAL); } + get_mplock(); vp = (struct vnode *)fp->f_data; vref(vp); fdrop(fp); @@ -1447,7 +1519,7 @@ sys_sendfile(struct sendfile_args *uap) } error = kern_sendfile(vp, uap->s, uap->offset, uap->nbytes, mheader, - &sbytes, uap->flags); + &sbytes, uap->flags); if (error) goto done; @@ -1475,12 +1547,13 @@ sys_sendfile(struct sendfile_args *uap) } done: + if (vp) + vrele(vp); + rel_mplock(); if (uap->sbytes != NULL) { sbytes += hdtr_size; copyout(&sbytes, uap->sbytes, sizeof(off_t)); } - if (vp) - vrele(vp); return (error); } @@ -1770,6 +1843,9 @@ done0: return (error); } +/* + * MPALMOSTSAFE + */ int sys_sctp_peeloff(struct sctp_peeloff_args *uap) { @@ -1786,9 +1862,10 @@ sys_sctp_peeloff(struct sctp_peeloff_args *uap) assoc_id = uap->name; error = holdsock(p->p_fd, uap->sd, &lfp); - if (error) { + if (error) return (error); - } + + get_mplock(); crit_enter(); head = (struct socket *)lfp->f_data; error = sctp_can_peel_off(head, assoc_id); @@ -1849,6 +1926,7 @@ noconnection: * Release explicitly held references before returning. */ done: + rel_mplock(); if (nfp != NULL) fdrop(nfp); fdrop(lfp); diff --git a/sys/kern/usched_bsd4.c b/sys/kern/usched_bsd4.c index 57bd698be9..f021acfc7a 100644 --- a/sys/kern/usched_bsd4.c +++ b/sys/kern/usched_bsd4.c @@ -774,6 +774,9 @@ bsd4_resetpriority(struct lwp *lp) crit_exit(); } +/* + * MPSAFE + */ static void bsd4_yield(struct lwp *lp) diff --git a/sys/kern/usched_dummy.c b/sys/kern/usched_dummy.c index 68cd3b3d3f..bd2d205a6e 100644 --- a/sys/kern/usched_dummy.c +++ b/sys/kern/usched_dummy.c @@ -364,6 +364,9 @@ dummy_recalculate_estcpu(struct lwp *lp) { } +/* + * MPSAFE + */ static void dummy_yield(struct lwp *lp) diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index 2b3cea4586..ecb3e0e910 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -1084,7 +1084,6 @@ static int _aio_aqueue(struct aiocb *job, struct aio_liojob *lj, int type) { struct proc *p = curproc; - struct filedesc *fdp; struct file *fp; unsigned int fd; struct socket *so; @@ -1096,6 +1095,7 @@ _aio_aqueue(struct aiocb *job, struct aio_liojob *lj, int type) struct kevent kev; struct kqueue *kq; struct file *kq_fp; + int fflags; if ((aiocbe = TAILQ_FIRST(&aio_freejobs)) != NULL) TAILQ_REMOVE(&aio_freejobs, aiocbe, list); @@ -1132,29 +1132,20 @@ _aio_aqueue(struct aiocb *job, struct aio_liojob *lj, int type) aiocbe->uaiocb.aio_lio_opcode = type; opcode = aiocbe->uaiocb.aio_lio_opcode; - /* Get the fd info for process. */ - fdp = p->p_fd; - /* * Range check file descriptor. */ + fflags = (opcode == LIO_WRITE) ? FWRITE : FREAD; fd = aiocbe->uaiocb.aio_fildes; - if (fd >= fdp->fd_nfiles) { + fp = holdfp(p->p_fd, fd, fflags); + if (fp == NULL) { TAILQ_INSERT_HEAD(&aio_freejobs, aiocbe, list); if (type == 0) suword(&job->_aiocb_private.error, EBADF); return EBADF; } - fp = aiocbe->fd_file = fdp->fd_files[fd].fp; - if ((fp == NULL) || ((opcode == LIO_WRITE) && ((fp->f_flag & FWRITE) == - 0))) { - TAILQ_INSERT_HEAD(&aio_freejobs, aiocbe, list); - if (type == 0) - suword(&job->_aiocb_private.error, EBADF); - return EBADF; - } - fhold(fp); + aiocbe->fd_file = fp; if (aiocbe->uaiocb.aio_offset == -1LL) { error = EINVAL; @@ -1208,9 +1199,12 @@ _aio_aqueue(struct aiocb *job, struct aio_liojob *lj, int type) if (error) goto aqueue_fail; } - if ((u_int)kev.ident >= fdp->fd_nfiles || - (kq_fp = fdp->fd_files[kev.ident].fp) == NULL || - (kq_fp->f_type != DTYPE_KQUEUE)) { + kq_fp = holdfp(p->p_fd, (int)kev.ident, -1); + if (kq_fp == NULL || kq_fp->f_type != DTYPE_KQUEUE) { + if (kq_fp) { + fdrop(kq_fp); + kq_fp = NULL; + } error = EBADF; goto aqueue_fail; } @@ -1221,6 +1215,7 @@ _aio_aqueue(struct aiocb *job, struct aio_liojob *lj, int type) kev.data = (intptr_t)aiocbe; /* XXX lwp kqueue_register takes a thread, but only uses its proc */ error = kqueue_register(kq, &kev, FIRST_LWP_IN_PROC(p)->lwp_thread); + fdrop(kq_fp); aqueue_fail: if (error) { fdrop(fp); @@ -1348,12 +1343,14 @@ aio_aqueue(struct aiocb *job, int type) /* * Support the aio_return system call, as a side-effect, kernel resources are * released. + * + * MPALMOSTSAFE */ int sys_aio_return(struct aio_return_args *uap) { #ifndef VFS_AIO - return ENOSYS; + return (ENOSYS); #else struct proc *p = curproc; struct lwp *lp = curthread->td_lwp; @@ -1361,6 +1358,7 @@ sys_aio_return(struct aio_return_args *uap) struct aiocblist *cb, *ncb; struct aiocb *ujob; struct kaioinfo *ki; + int error; ki = p->p_aioinfo; if (ki == NULL) @@ -1372,14 +1370,16 @@ sys_aio_return(struct aio_return_args *uap) if (jobref == -1 || jobref == 0) return EINVAL; + get_mplock(); TAILQ_FOREACH(cb, &ki->kaio_jobdone, plist) { if (((intptr_t) cb->uaiocb._aiocb_private.kernelinfo) == jobref) { if (ujob == cb->uuaiocb) { uap->sysmsg_result = cb->uaiocb._aiocb_private.status; - } else + } else { uap->sysmsg_result = EFAULT; + } if (cb->uaiocb.aio_lio_opcode == LIO_WRITE) { lp->lwp_ru.ru_oublock += cb->outputcharge; cb->outputcharge = 0; @@ -1388,7 +1388,8 @@ sys_aio_return(struct aio_return_args *uap) cb->inputcharge = 0; } aio_free_entry(cb); - return 0; + error = 0; + goto done; } } crit_enter(); @@ -1400,20 +1401,26 @@ sys_aio_return(struct aio_return_args *uap) if (ujob == cb->uuaiocb) { uap->sysmsg_result = cb->uaiocb._aiocb_private.status; - } else + } else { uap->sysmsg_result = EFAULT; + } aio_free_entry(cb); - return 0; + error = 0; + goto done; } } crit_exit(); - - return (EINVAL); + error = EINVAL; +done: + rel_mplock(); + return (error); #endif /* VFS_AIO */ } /* * Allow a process to wakeup when any of the I/O requests are completed. + * + * MPALMOSTSAFE */ int sys_aio_suspend(struct aio_suspend_args *uap) @@ -1433,7 +1440,7 @@ sys_aio_suspend(struct aio_suspend_args *uap) long *ijoblist; struct aiocb **ujoblist; - if (uap->nent > AIO_LISTIO_MAX) + if ((u_int)uap->nent > AIO_LISTIO_MAX) return EINVAL; timo = 0; @@ -1455,6 +1462,8 @@ sys_aio_suspend(struct aio_suspend_args *uap) if (ki == NULL) return EAGAIN; + get_mplock(); + njoblist = 0; ijoblist = zalloc(aiol_zone); ujoblist = zalloc(aiol_zone); @@ -1472,7 +1481,8 @@ sys_aio_suspend(struct aio_suspend_args *uap) if (njoblist == 0) { zfree(aiol_zone, ijoblist); zfree(aiol_zone, ujoblist); - return 0; + error = 0; + goto done; } error = 0; @@ -1486,7 +1496,7 @@ sys_aio_suspend(struct aio_suspend_args *uap) error = EINVAL; zfree(aiol_zone, ijoblist); zfree(aiol_zone, ujoblist); - return error; + goto done; } } } @@ -1503,7 +1513,7 @@ sys_aio_suspend(struct aio_suspend_args *uap) error = EINVAL; zfree(aiol_zone, ijoblist); zfree(aiol_zone, ujoblist); - return error; + goto done; } } } @@ -1515,22 +1525,29 @@ sys_aio_suspend(struct aio_suspend_args *uap) if (error == ERESTART || error == EINTR) { zfree(aiol_zone, ijoblist); zfree(aiol_zone, ujoblist); - return EINTR; + error = EINTR; + goto done; } else if (error == EWOULDBLOCK) { zfree(aiol_zone, ijoblist); zfree(aiol_zone, ujoblist); - return EAGAIN; + error = EAGAIN; + goto done; } } /* NOTREACHED */ - return EINVAL; + error = EINVAL; +done: + rel_mplock(); + return (error); #endif /* VFS_AIO */ } /* * aio_cancel cancels any non-physio aio operations not currently in * progress. + * + * MPALMOSTSAFE */ int sys_aio_cancel(struct aio_cancel_args *uap) @@ -1542,7 +1559,6 @@ sys_aio_cancel(struct aio_cancel_args *uap) struct kaioinfo *ki; struct aiocblist *cbe, *cbn; struct file *fp; - struct filedesc *fdp; struct socket *so; struct proc *po; int error; @@ -1550,17 +1566,19 @@ sys_aio_cancel(struct aio_cancel_args *uap) int notcancelled=0; struct vnode *vp; - fdp = p->p_fd; - if ((u_int)uap->fd >= fdp->fd_nfiles || - (fp = fdp->fd_files[uap->fd].fp) == NULL) + fp = holdfp(p->p_fd, uap->fd, -1); + if (fp == NULL) return (EBADF); + get_mplock(); + if (fp->f_type == DTYPE_VNODE) { vp = (struct vnode *)fp->f_data; if (vn_isdisk(vp,&error)) { uap->sysmsg_result = AIO_NOTCANCELED; - return 0; + error = 0; + goto done2; } } else if (fp->f_type == DTYPE_SOCKET) { so = (struct socket *)fp->f_data; @@ -1595,7 +1613,8 @@ sys_aio_cancel(struct aio_cancel_args *uap) if ((cancelled) && (uap->aiocbp)) { uap->sysmsg_result = AIO_CANCELED; - return 0; + error = 0; + goto done2; } } ki=p->p_aioinfo; @@ -1631,17 +1650,17 @@ sys_aio_cancel(struct aio_cancel_args *uap) } crit_exit(); done: - if (notcancelled) { + if (notcancelled) uap->sysmsg_result = AIO_NOTCANCELED; - return 0; - } - if (cancelled) { + else if (cancelled) uap->sysmsg_result = AIO_CANCELED; - return 0; - } - uap->sysmsg_result = AIO_ALLDONE; - - return 0; + else + uap->sysmsg_result = AIO_ALLDONE; + error = 0; +done2: + rel_mplock(); + fdrop(fp); + return error; #endif /* VFS_AIO */ } @@ -1649,6 +1668,8 @@ done: * aio_error is implemented in the kernel level for compatibility purposes only. * For a user mode async implementation, it would be best to do it in a userland * subroutine. + * + * MPALMOSTSAFE */ int sys_aio_error(struct aio_error_args *uap) @@ -1660,6 +1681,7 @@ sys_aio_error(struct aio_error_args *uap) struct aiocblist *cb; struct kaioinfo *ki; long jobref; + int error; ki = p->p_aioinfo; if (ki == NULL) @@ -1669,11 +1691,14 @@ sys_aio_error(struct aio_error_args *uap) if ((jobref == -1) || (jobref == 0)) return EINVAL; + get_mplock(); + error = 0; + TAILQ_FOREACH(cb, &ki->kaio_jobdone, plist) { if (((intptr_t)cb->uaiocb._aiocb_private.kernelinfo) == jobref) { uap->sysmsg_result = cb->uaiocb._aiocb_private.error; - return 0; + goto done; } } @@ -1685,7 +1710,7 @@ sys_aio_error(struct aio_error_args *uap) jobref) { uap->sysmsg_result = EINPROGRESS; crit_exit(); - return 0; + goto done; } } @@ -1695,7 +1720,7 @@ sys_aio_error(struct aio_error_args *uap) jobref) { uap->sysmsg_result = EINPROGRESS; crit_exit(); - return 0; + goto done; } } crit_exit(); @@ -1707,7 +1732,7 @@ sys_aio_error(struct aio_error_args *uap) jobref) { uap->sysmsg_result = cb->uaiocb._aiocb_private.error; crit_exit(); - return 0; + goto done; } } @@ -1717,46 +1742,62 @@ sys_aio_error(struct aio_error_args *uap) jobref) { uap->sysmsg_result = EINPROGRESS; crit_exit(); - return 0; + goto done; } } crit_exit(); - -#if (0) - /* - * Hack for lio. - */ - status = fuword(&uap->aiocbp->_aiocb_private.status); - if (status == -1) - return fuword(&uap->aiocbp->_aiocb_private.error); -#endif - return EINVAL; + error = EINVAL; +done: + rel_mplock(); + return (error); #endif /* VFS_AIO */ } -/* syscall - asynchronous read from a file (REALTIME) */ +/* + * syscall - asynchronous read from a file (REALTIME) + * + * MPALMOSTSAFE + */ int sys_aio_read(struct aio_read_args *uap) { #ifndef VFS_AIO return ENOSYS; #else - return aio_aqueue(uap->aiocbp, LIO_READ); + int error; + + get_mplock(); + error = aio_aqueue(uap->aiocbp, LIO_READ); + rel_mplock(); + return (error); #endif /* VFS_AIO */ } -/* syscall - asynchronous write to a file (REALTIME) */ +/* + * syscall - asynchronous write to a file (REALTIME) + * + * MPALMOSTSAFE + */ int sys_aio_write(struct aio_write_args *uap) { #ifndef VFS_AIO return ENOSYS; #else - return aio_aqueue(uap->aiocbp, LIO_WRITE); + int error; + + get_mplock(); + error = aio_aqueue(uap->aiocbp, LIO_WRITE); + rel_mplock(); + return (error); #endif /* VFS_AIO */ } -/* syscall - XXX undocumented */ +/* + * syscall - XXX undocumented + * + * MPALMOSTSAFE + */ int sys_lio_listio(struct lio_listio_args *uap) { @@ -1781,19 +1822,27 @@ sys_lio_listio(struct lio_listio_args *uap) if (nent > AIO_LISTIO_MAX) return EINVAL; + get_mplock(); + if (p->p_aioinfo == NULL) aio_init_aioinfo(p); - if ((nent + num_queue_count) > max_queue_count) - return EAGAIN; + if ((nent + num_queue_count) > max_queue_count) { + error = EAGAIN; + goto done; + } ki = p->p_aioinfo; - if ((nent + ki->kaio_queue_count) > ki->kaio_qallowed_count) - return EAGAIN; + if ((nent + ki->kaio_queue_count) > ki->kaio_qallowed_count) { + error = EAGAIN; + goto done; + } lj = zalloc(aiolio_zone); - if (!lj) - return EAGAIN; + if (lj == NULL) { + error = EAGAIN; + goto done; + } lj->lioj_flags = 0; lj->lioj_buffer_count = 0; @@ -1810,11 +1859,12 @@ sys_lio_listio(struct lio_listio_args *uap) sizeof(lj->lioj_signal)); if (error) { zfree(aiolio_zone, lj); - return error; + goto done; } if (!_SIG_VALID(lj->lioj_signal.sigev_signo)) { zfree(aiolio_zone, lj); - return EINVAL; + error = EINVAL; + goto done; } lj->lioj_flags |= LIOJ_SIGNAL; lj->lioj_flags &= ~LIOJ_SIGNAL_POSTED; @@ -1842,8 +1892,10 @@ sys_lio_listio(struct lio_listio_args *uap) /* * If we haven't queued any, then just return error. */ - if (nentqueued == 0) - return 0; + if (nentqueued == 0) { + error = 0; + goto done; + } /* * Calculate the appropriate error return. @@ -1913,20 +1965,27 @@ sys_lio_listio(struct lio_listio_args *uap) * If all I/Os have been disposed of, then we can * return. */ - if (found == nentqueued) - return runningcode; + if (found == nentqueued) { + error = runningcode; + goto done; + } ki->kaio_flags |= KAIO_WAKEUP; error = tsleep(p, PCATCH, "aiospn", 0); - if (error == EINTR) - return EINTR; - else if (error == EWOULDBLOCK) - return EAGAIN; + if (error == EINTR) { + goto done; + } else if (error == EWOULDBLOCK) { + error = EAGAIN; + goto done; + } } } - return runningcode; + error = runningcode; +done: + rel_mplock(); + return (error); #endif /* VFS_AIO */ } @@ -2024,7 +2083,11 @@ aio_physwakeup(struct bio *bio) } #endif /* VFS_AIO */ -/* syscall - wait for the next completion of an aio request */ +/* + * syscall - wait for the next completion of an aio request + * + * MPALMOSTSAFE + */ int sys_aio_waitcomplete(struct aio_waitcomplete_args *uap) { @@ -2061,6 +2124,8 @@ sys_aio_waitcomplete(struct aio_waitcomplete_args *uap) if (ki == NULL) return EAGAIN; + get_mplock(); + for (;;) { if ((cb = TAILQ_FIRST(&ki->kaio_jobdone)) != 0) { suword(uap->aiocbp, (uintptr_t)cb->uuaiocb); @@ -2074,7 +2139,8 @@ sys_aio_waitcomplete(struct aio_waitcomplete_args *uap) cb->inputcharge = 0; } aio_free_entry(cb); - return cb->uaiocb._aiocb_private.error; + error = cb->uaiocb._aiocb_private.error; + break; } crit_enter(); @@ -2083,22 +2149,29 @@ sys_aio_waitcomplete(struct aio_waitcomplete_args *uap) suword(uap->aiocbp, (uintptr_t)cb->uuaiocb); uap->sysmsg_result = cb->uaiocb._aiocb_private.status; aio_free_entry(cb); - return cb->uaiocb._aiocb_private.error; + error = cb->uaiocb._aiocb_private.error; + break; } ki->kaio_flags |= KAIO_WAKEUP; error = tsleep(p, PCATCH, "aiowc", timo); crit_exit(); - if (error == ERESTART) - return EINTR; - else if (error < 0) - return error; - else if (error == EINTR) - return EINTR; - else if (error == EWOULDBLOCK) - return EAGAIN; + if (error == ERESTART) { + error = EINTR; + break; + } + if (error < 0) + break; + if (error == EINTR) + break; + if (error == EWOULDBLOCK) { + error = EAGAIN; + break; + } } + rel_mplock(); + return (error); #endif /* VFS_AIO */ } diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index bfdd17d21a..17a051b386 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -2409,6 +2409,9 @@ static u_long numcwdfail3; STATNODE(CTLFLAG_RD, numcwdfail3, &numcwdfail3); static u_long numcwdfail4; STATNODE(CTLFLAG_RD, numcwdfail4, &numcwdfail4); static u_long numcwdfound; STATNODE(CTLFLAG_RD, numcwdfound, &numcwdfound); +/* + * MPALMOSTSAFE + */ int sys___getcwd(struct __getcwd_args *uap) { @@ -2427,7 +2430,9 @@ sys___getcwd(struct __getcwd_args *uap) buflen = MAXPATHLEN; buf = kmalloc(buflen, M_TEMP, M_WAITOK); + get_mplock(); bp = kern_getcwd(buf, buflen, &error); + rel_mplock(); if (error == 0) error = copyout(bp, uap->buf, strlen(bp) + 1); kfree(buf, M_TEMP); diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 4862ddd214..2ec09d166c 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -106,11 +106,11 @@ SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, ""); /* * Mount a file system. - */ -/* + * * mount_args(char *type, char *path, int flags, caddr_t data) + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_mount(struct mount_args *uap) { @@ -125,20 +125,25 @@ sys_mount(struct mount_args *uap) struct vattr va; struct nlookupdata nd; char fstypename[MFSNAMELEN]; - struct ucred *cred = p->p_ucred; + struct ucred *cred; KKASSERT(p); - if (jailed(cred)) - return (EPERM); + get_mplock(); + cred = p->p_ucred; + if (jailed(cred)) { + error = EPERM; + goto done; + } if (usermount == 0 && (error = priv_check(td, PRIV_ROOT))) - return (error); + goto done; + /* * Do not allow NFS export by non-root users. */ if (uap->flags & MNT_EXPORTED) { error = priv_check(td, PRIV_ROOT); if (error) - return (error); + goto done; } /* * Silently enforce MNT_NOSUID and MNT_NODEV for non-root users @@ -158,7 +163,7 @@ sys_mount(struct mount_args *uap) } if (error) { nlookup_done(&nd); - return (error); + goto done; } /* @@ -188,7 +193,7 @@ sys_mount(struct mount_args *uap) vp = nch.ncp->nc_vp; if ((error = vget(vp, LK_EXCLUSIVE)) != 0) { cache_put(&nch); - return (error); + goto done; } cache_unlock(&nch); @@ -199,7 +204,7 @@ sys_mount(struct mount_args *uap) if ((error = copyinstr(uap->type, fstypename, MFSNAMELEN, NULL)) != 0) { cache_drop(&nch); vput(vp); - return (error); + goto done; } /* @@ -209,7 +214,8 @@ sys_mount(struct mount_args *uap) if ((vp->v_flag & (VROOT|VPFSROOT)) == 0) { cache_drop(&nch); vput(vp); - return (EINVAL); + error = EINVAL; + goto done; } if (strncmp(fstypename, "null", 5) == 0) { @@ -229,7 +235,8 @@ sys_mount(struct mount_args *uap) ((mp->mnt_flag & MNT_RDONLY) == 0)) { cache_drop(&nch); vput(vp); - return (EOPNOTSUPP); /* Needs translation */ + error = EOPNOTSUPP; /* Needs translation */ + goto done; } /* * Only root, or the user that did the original mount is @@ -239,18 +246,20 @@ sys_mount(struct mount_args *uap) (error = priv_check(td, PRIV_ROOT))) { cache_drop(&nch); vput(vp); - return (error); + goto done; } if (vfs_busy(mp, LK_NOWAIT)) { cache_drop(&nch); vput(vp); - return (EBUSY); + error = EBUSY; + goto done; } if ((vp->v_flag & VMOUNT) != 0 || hasmount) { cache_drop(&nch); vfs_unbusy(mp); vput(vp); - return (EBUSY); + error = EBUSY; + goto done; } vp->v_flag |= VMOUNT; mp->mnt_flag |= @@ -266,22 +275,24 @@ sys_mount(struct mount_args *uap) (va.va_uid != cred->cr_uid && (error = priv_check(td, PRIV_ROOT)))) { cache_drop(&nch); vput(vp); - return (error); + goto done; } if ((error = vinvalbuf(vp, V_SAVE, 0, 0)) != 0) { cache_drop(&nch); vput(vp); - return (error); + goto done; } if (vp->v_type != VDIR) { cache_drop(&nch); vput(vp); - return (ENOTDIR); + error = ENOTDIR; + goto done; } if (vp->v_mount->mnt_kern_flag & MNTK_NOSTKMNT) { cache_drop(&nch); vput(vp); - return (EPERM); + error = EPERM; + goto done; } vfsp = vfsconf_find_by_name(fstypename); if (vfsp == NULL) { @@ -291,7 +302,7 @@ sys_mount(struct mount_args *uap) if ((error = priv_check(td, PRIV_ROOT)) != 0) { cache_drop(&nch); vput(vp); - return error; + goto done; } error = linker_load_file(fstypename, &lf); if (error || lf == NULL) { @@ -299,7 +310,7 @@ sys_mount(struct mount_args *uap) vput(vp); if (lf == NULL) error = ENODEV; - return error; + goto done; } lf->userrefs++; /* lookup again, see if the VFS was loaded */ @@ -309,13 +320,15 @@ sys_mount(struct mount_args *uap) linker_file_unload(lf); cache_drop(&nch); vput(vp); - return (ENODEV); + error = ENODEV; + goto done; } } if ((vp->v_flag & VMOUNT) != 0 || hasmount) { cache_drop(&nch); vput(vp); - return (EBUSY); + error = EBUSY; + goto done; } vp->v_flag |= VMOUNT; @@ -373,7 +386,7 @@ update: vp->v_flag &= ~VMOUNT; vrele(vp); cache_drop(&nch); - return (error); + goto done; } vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); /* @@ -420,6 +433,8 @@ update: cache_drop(&nch); vput(vp); } +done: + rel_mplock(); return (error); } @@ -548,25 +563,28 @@ checkdirs_callback(struct proc *p, void *data) * * Note: unmount takes a path to the vnode mounted on as argument, * not special file (as before). - */ -/* + * * umount_args(char *path, int flags) + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_unmount(struct unmount_args *uap) { struct thread *td = curthread; struct proc *p = td->td_proc; struct mount *mp = NULL; - int error; struct nlookupdata nd; + int error; KKASSERT(p); - if (p->p_ucred->cr_prison != NULL) - return (EPERM); + get_mplock(); + if (p->p_ucred->cr_prison != NULL) { + error = EPERM; + goto done; + } if (usermount == 0 && (error = priv_check(td, PRIV_ROOT))) - return (error); + goto done; error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) @@ -602,9 +620,11 @@ sys_unmount(struct unmount_args *uap) out: nlookup_done(&nd); - if (error) - return (error); - return (dounmount(mp, uap->flags)); + if (error == 0) + error = dounmount(mp, uap->flags); +done: + rel_mplock(); + return (error); } /* @@ -831,10 +851,13 @@ SYSCTL_INT(_debug, OID_AUTO, syncprt, CTLFLAG_RW, &syncprt, 0, ""); static int sync_callback(struct mount *mp, void *data); -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_sync(struct sync_args *uap) { + get_mplock(); mountlist_scan(sync_callback, NULL, MNTSCAN_FORWARD); #ifdef DEBUG /* @@ -843,6 +866,7 @@ sys_sync(struct sync_args *uap) if (syncprt) vfs_bufstats(); #endif /* DEBUG */ + rel_mplock(); return (0); } @@ -872,8 +896,9 @@ SYSCTL_INT(_kern_prison, OID_AUTO, quotas, CTLFLAG_RW, &prison_quotas, 0, ""); * quotactl_args(char *path, int fcmd, int uid, caddr_t arg) * * Change filesystem quotas. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_quotactl(struct quotactl_args *uap) { @@ -883,10 +908,13 @@ sys_quotactl(struct quotactl_args *uap) struct mount *mp; int error; + get_mplock(); td = curthread; p = td->td_proc; - if (p->p_ucred->cr_prison && !prison_quotas) - return (EPERM); + if (p->p_ucred->cr_prison && !prison_quotas) { + error = EPERM; + goto done; + } error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) @@ -897,6 +925,8 @@ sys_quotactl(struct quotactl_args *uap) uap->arg, nd.nl_cred); } nlookup_done(&nd); +done: + rel_mplock(); return (error); } @@ -909,8 +939,9 @@ sys_quotactl(struct quotactl_args *uap) * * The actual number of bytes stored in the result buffer is returned, 0 * if none, otherwise an error is returned. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_mountctl(struct mountctl_args *uap) { @@ -975,7 +1006,9 @@ sys_mountctl(struct mountctl_args *uap) /* * Execute the internal kernel function and clean up. */ + get_mplock(); error = kern_mountctl(path, uap->op, fp, ctl, uap->ctllen, buf, uap->buflen, &uap->sysmsg_result); + rel_mplock(); if (fp) fdrop(fp); if (error == 0 && uap->sysmsg_result > 0) @@ -1069,6 +1102,8 @@ kern_statfs(struct nlookupdata *nd, struct statfs *buf) * statfs_args(char *path, struct statfs *buf) * * Get filesystem statistics. + * + * MPALMOSTSAFE */ int sys_statfs(struct statfs_args *uap) @@ -1077,15 +1112,20 @@ sys_statfs(struct statfs_args *uap) struct statfs buf; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = kern_statfs(&nd, &buf); nlookup_done(&nd); if (error == 0) error = copyout(&buf, uap->buf, sizeof(*uap->buf)); + rel_mplock(); return (error); } +/* + * MPALMOSTSAFE + */ int kern_fstatfs(int fd, struct statfs *buf) { @@ -1100,6 +1140,7 @@ kern_fstatfs(int fd, struct statfs *buf) KKASSERT(p); if ((error = holdvnode(p->p_fd, fd, &fp)) != 0) return (error); + get_mplock(); mp = ((struct vnode *)fp->f_data)->v_mount; if (mp == NULL) { error = EBADF; @@ -1127,6 +1168,7 @@ kern_fstatfs(int fd, struct statfs *buf) buf->f_fsid.val[0] = buf->f_fsid.val[1] = 0; error = 0; done: + rel_mplock(); fdrop(fp); return (error); } @@ -1135,6 +1177,8 @@ done: * fstatfs_args(int fd, struct statfs *buf) * * Get filesystem statistics. + * + * MPSAFE */ int sys_fstatfs(struct fstatfs_args *uap) @@ -1176,6 +1220,8 @@ kern_statvfs(struct nlookupdata *nd, struct statvfs *buf) * statfs_args(char *path, struct statfs *buf) * * Get filesystem statistics. + * + * MPALMOSTSAFE */ int sys_statvfs(struct statvfs_args *uap) @@ -1184,12 +1230,14 @@ sys_statvfs(struct statvfs_args *uap) struct statvfs buf; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = kern_statvfs(&nd, &buf); nlookup_done(&nd); if (error == 0) error = copyout(&buf, uap->buf, sizeof(*uap->buf)); + rel_mplock(); return (error); } @@ -1236,6 +1284,8 @@ done: * fstatfs_args(int fd, struct statfs *buf) * * Get filesystem statistics. + * + * MPALMOSTSAFE */ int sys_fstatvfs(struct fstatvfs_args *uap) @@ -1243,7 +1293,9 @@ sys_fstatvfs(struct fstatvfs_args *uap) struct statvfs buf; int error; + get_mplock(); error = kern_fstatvfs(uap->fd, &buf); + rel_mplock(); if (error == 0) error = copyout(&buf, uap->buf, sizeof(*uap->buf)); @@ -1267,7 +1319,9 @@ struct getfsstat_info { static int getfsstat_callback(struct mount *, void *); -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_getfsstat(struct getfsstat_args *uap) { @@ -1283,7 +1337,9 @@ sys_getfsstat(struct getfsstat_args *uap) info.flags = uap->flags; info.p = p; + get_mplock(); mountlist_scan(getfsstat_callback, &info, MNTSCAN_FORWARD); + rel_mplock(); if (info.sfsp && info.count > info.maxcount) uap->sysmsg_result = info.maxcount; else @@ -1356,7 +1412,9 @@ struct getvfsstat_info { static int getvfsstat_callback(struct mount *, void *); -/* ARGSUSED */ +/* + * MPALMOSTSAFE + */ int sys_getvfsstat(struct getvfsstat_args *uap) { @@ -1373,11 +1431,13 @@ sys_getvfsstat(struct getvfsstat_args *uap) info.flags = uap->flags; info.p = p; + get_mplock(); mountlist_scan(getvfsstat_callback, &info, MNTSCAN_FORWARD); if (info.vsfsp && info.count > info.maxcount) uap->sysmsg_result = info.maxcount; else uap->sysmsg_result = info.count; + rel_mplock(); return (info.error); } @@ -1448,8 +1508,9 @@ getvfsstat_callback(struct mount *mp, void *data) * fchdir_args(int fd) * * Change current working directory to a given file descriptor. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_fchdir(struct fchdir_args *uap) { @@ -1464,6 +1525,7 @@ sys_fchdir(struct fchdir_args *uap) if ((error = holdvnode(fdp, uap->fd, &fp)) != 0) return (error); + get_mplock(); vp = (struct vnode *)fp->f_data; vref(vp); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); @@ -1473,8 +1535,7 @@ sys_fchdir(struct fchdir_args *uap) error = checkvp_chdir(vp, td); if (error) { vput(vp); - fdrop(fp); - return (error); + goto done; } cache_copy(&fp->f_nchandle, &nch); @@ -1510,6 +1571,8 @@ sys_fchdir(struct fchdir_args *uap) vput(vp); } fdrop(fp); +done: + rel_mplock(); return (error); } @@ -1551,6 +1614,8 @@ kern_chdir(struct nlookupdata *nd) * chdir_args(char *path) * * Change current working directory (``.''). + * + * MPALMOSTSAFE */ int sys_chdir(struct chdir_args *uap) @@ -1558,10 +1623,12 @@ sys_chdir(struct chdir_args *uap) struct nlookupdata nd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = kern_chdir(&nd); nlookup_done(&nd); + rel_mplock(); return (error); } @@ -1665,8 +1732,9 @@ kern_chroot(struct nchandle *nch) * chroot_args(char *path) * * Change notion of root (``/'') directory. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_chroot(struct chroot_args *uap) { @@ -1675,16 +1743,16 @@ sys_chroot(struct chroot_args *uap) int error; KKASSERT(td->td_proc); + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); - if (error) { - nlookup_done(&nd); - return(error); + if (error == 0) { + nd.nl_flags |= NLC_EXEC; + error = nlookup(&nd); + if (error == 0) + error = kern_chroot(&nd.nl_nch); } - nd.nl_flags |= NLC_EXEC; - error = nlookup(&nd); - if (error == 0) - error = kern_chroot(&nd.nl_nch); nlookup_done(&nd); + rel_mplock(); return(error); } @@ -1843,6 +1911,8 @@ kern_open(struct nlookupdata *nd, int oflags, int mode, int *res) * * Check permissions, allocate an open file structure, * and call the device open routine if any. + * + * MPALMOSTSAFE */ int sys_open(struct open_args *uap) @@ -1850,17 +1920,21 @@ sys_open(struct open_args *uap) struct nlookupdata nd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); if (error == 0) { error = kern_open(&nd, uap->flags, uap->mode, &uap->sysmsg_result); } nlookup_done(&nd); + rel_mplock(); return (error); } /* * openat_args(int fd, char *path, int flags, int mode) + * + * MPALMOSTSAFE */ int sys_openat(struct openat_args *uap) @@ -1869,12 +1943,14 @@ sys_openat(struct openat_args *uap) int error; struct file *fp; + get_mplock(); error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, 0); if (error == 0) { error = kern_open(&nd, uap->flags, uap->mode, &uap->sysmsg_result); } nlookup_done_at(&nd, fp); + rel_mplock(); return (error); } @@ -1950,6 +2026,8 @@ kern_mknod(struct nlookupdata *nd, int mode, int rmajor, int rminor) * mknod_args(char *path, int mode, int dev) * * Create a special file. + * + * MPALMOSTSAFE */ int sys_mknod(struct mknod_args *uap) @@ -1957,12 +2035,14 @@ sys_mknod(struct mknod_args *uap) struct nlookupdata nd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); if (error == 0) { error = kern_mknod(&nd, uap->mode, umajor(uap->dev), uminor(uap->dev)); } nlookup_done(&nd); + rel_mplock(); return (error); } @@ -1999,6 +2079,8 @@ kern_mkfifo(struct nlookupdata *nd, int mode) * mkfifo_args(char *path, int mode) * * Create a named pipe. + * + * MPALMOSTSAFE */ int sys_mkfifo(struct mkfifo_args *uap) @@ -2006,10 +2088,12 @@ sys_mkfifo(struct mkfifo_args *uap) struct nlookupdata nd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); if (error == 0) error = kern_mkfifo(&nd, uap->mode); nlookup_done(&nd); + rel_mplock(); return (error); } @@ -2132,6 +2216,8 @@ kern_link(struct nlookupdata *nd, struct nlookupdata *linknd) * link_args(char *path, char *link) * * Make a hard file link. + * + * MPALMOSTSAFE */ int sys_link(struct link_args *uap) @@ -2139,6 +2225,7 @@ sys_link(struct link_args *uap) struct nlookupdata nd, linknd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) { error = nlookup_init(&linknd, uap->link, UIO_USERSPACE, 0); @@ -2147,6 +2234,7 @@ sys_link(struct link_args *uap) nlookup_done(&linknd); } nlookup_done(&nd); + rel_mplock(); return (error); } @@ -2179,6 +2267,8 @@ kern_symlink(struct nlookupdata *nd, char *path, int mode) * symlink(char *path, char *link) * * Make a symbolic link. + * + * MPALMOSTSAFE */ int sys_symlink(struct symlink_args *uap) @@ -2192,12 +2282,14 @@ sys_symlink(struct symlink_args *uap) path = objcache_get(namei_oc, M_WAITOK); error = copyinstr(uap->path, path, MAXPATHLEN, NULL); if (error == 0) { + get_mplock(); error = nlookup_init(&nd, uap->link, UIO_USERSPACE, 0); if (error == 0) { mode = ACCESSPERMS & ~td->td_proc->p_fd->fd_cmask; error = kern_symlink(&nd, path, mode); } nlookup_done(&nd); + rel_mplock(); } objcache_put(namei_oc, path); return (error); @@ -2207,14 +2299,16 @@ sys_symlink(struct symlink_args *uap) * undelete_args(char *path) * * Delete a whiteout from the filesystem. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_undelete(struct undelete_args *uap) { struct nlookupdata nd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); bwillinode(1); nd.nl_flags |= NLC_DELETE | NLC_REFDVP; @@ -2227,6 +2321,7 @@ sys_undelete(struct undelete_args *uap) NAMEI_DELETE); } nlookup_done(&nd); + rel_mplock(); return (error); } @@ -2249,6 +2344,8 @@ kern_unlink(struct nlookupdata *nd) * unlink_args(char *path) * * Delete a name from the filesystem. + * + * MPALMOSTSAFE */ int sys_unlink(struct unlink_args *uap) @@ -2256,10 +2353,12 @@ sys_unlink(struct unlink_args *uap) struct nlookupdata nd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); if (error == 0) error = kern_unlink(&nd); nlookup_done(&nd); + rel_mplock(); return (error); } @@ -2268,6 +2367,8 @@ sys_unlink(struct unlink_args *uap) * unlinkat_args(int fd, char *path, int flags) * * Delete the file or directory entry pointed to by fd/path. + * + * MPALMOSTSAFE */ int sys_unlinkat(struct unlinkat_args *uap) @@ -2279,6 +2380,7 @@ sys_unlinkat(struct unlinkat_args *uap) if (uap->flags & ~AT_REMOVEDIR) return (EINVAL); + get_mplock(); error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, 0); if (error == 0) { if (uap->flags & AT_REMOVEDIR) @@ -2287,9 +2389,13 @@ sys_unlinkat(struct unlinkat_args *uap) error = kern_unlink(&nd); } nlookup_done_at(&nd, fp); + rel_mplock(); return (error); } +/* + * MPALMOSTSAFE + */ int kern_lseek(int fd, off_t offset, int whence, off_t *res) { @@ -2312,20 +2418,26 @@ kern_lseek(int fd, off_t offset, int whence, off_t *res) switch (whence) { case L_INCR: + spin_lock_wr(&fp->f_spin); new_offset = fp->f_offset + offset; error = 0; break; case L_XTND: + get_mplock(); error = VOP_GETATTR(vp, &vattr); + rel_mplock(); + spin_lock_wr(&fp->f_spin); new_offset = offset + vattr.va_size; break; case L_SET: new_offset = offset; error = 0; + spin_lock_wr(&fp->f_spin); break; default: new_offset = 0; error = EINVAL; + spin_lock_wr(&fp->f_spin); break; } @@ -2347,6 +2459,7 @@ kern_lseek(int fd, off_t offset, int whence, off_t *res) } } *res = fp->f_offset; + spin_unlock_wr(&fp->f_spin); done: fdrop(fp); return (error); @@ -2356,6 +2469,8 @@ done: * lseek_args(int fd, int pad, off_t offset, int whence) * * Reposition read/write file offset. + * + * MPSAFE */ int sys_lseek(struct lseek_args *uap) @@ -2423,6 +2538,8 @@ retry: * access_args(char *path, int flags) * * Check access permissions. + * + * MPALMOSTSAFE */ int sys_access(struct access_args *uap) @@ -2430,10 +2547,12 @@ sys_access(struct access_args *uap) struct nlookupdata nd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = kern_access(&nd, uap->flags, 0); nlookup_done(&nd); + rel_mplock(); return (error); } @@ -2442,6 +2561,8 @@ sys_access(struct access_args *uap) * faccessat_args(int fd, char *path, int amode, int flags) * * Check access permissions. + * + * MPALMOSTSAFE */ int sys_faccessat(struct faccessat_args *uap) @@ -2450,11 +2571,13 @@ sys_faccessat(struct faccessat_args *uap) struct file *fp; int error; + get_mplock(); error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = kern_access(&nd, uap->amode, uap->flags); nlookup_done_at(&nd, fp); + rel_mplock(); return (error); } @@ -2497,6 +2620,8 @@ again: * stat_args(char *path, struct stat *ub) * * Get file status; this version follows links. + * + * MPALMOSTSAFE */ int sys_stat(struct stat_args *uap) @@ -2505,6 +2630,7 @@ sys_stat(struct stat_args *uap) struct stat st; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) { error = kern_stat(&nd, &st); @@ -2512,6 +2638,7 @@ sys_stat(struct stat_args *uap) error = copyout(&st, uap->ub, sizeof(*uap->ub)); } nlookup_done(&nd); + rel_mplock(); return (error); } @@ -2519,6 +2646,8 @@ sys_stat(struct stat_args *uap) * lstat_args(char *path, struct stat *ub) * * Get file status; this version does not follow links. + * + * MPALMOSTSAFE */ int sys_lstat(struct lstat_args *uap) @@ -2527,6 +2656,7 @@ sys_lstat(struct lstat_args *uap) struct stat st; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); if (error == 0) { error = kern_stat(&nd, &st); @@ -2534,6 +2664,7 @@ sys_lstat(struct lstat_args *uap) error = copyout(&st, uap->ub, sizeof(*uap->ub)); } nlookup_done(&nd); + rel_mplock(); return (error); } @@ -2541,6 +2672,8 @@ sys_lstat(struct lstat_args *uap) * fstatat_args(int fd, char *path, struct stat *sb, int flags) * * Get status of file pointed to by fd/path. + * + * MPALMOSTSAFE */ int sys_fstatat(struct fstatat_args *uap) @@ -2556,6 +2689,7 @@ sys_fstatat(struct fstatat_args *uap) flags = (uap->flags & AT_SYMLINK_NOFOLLOW) ? 0 : NLC_FOLLOW; + get_mplock(); error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, flags); if (error == 0) { @@ -2564,6 +2698,7 @@ sys_fstatat(struct fstatat_args *uap) error = copyout(&st, uap->sb, sizeof(*uap->sb)); } nlookup_done_at(&nd, fp); + rel_mplock(); return (error); } @@ -2571,8 +2706,9 @@ sys_fstatat(struct fstatat_args *uap) * pathconf_Args(char *path, int name) * * Get configurable pathname variables. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_pathconf(struct pathconf_args *uap) { @@ -2581,6 +2717,7 @@ sys_pathconf(struct pathconf_args *uap) int error; vp = NULL; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = nlookup(&nd); @@ -2591,6 +2728,7 @@ sys_pathconf(struct pathconf_args *uap) error = VOP_PATHCONF(vp, uap->name, &uap->sysmsg_reg); vput(vp); } + rel_mplock(); return (error); } @@ -2637,6 +2775,8 @@ kern_readlink(struct nlookupdata *nd, char *buf, int count, int *res) * readlink_args(char *path, char *buf, int count) * * Return target name of a symbolic link. + * + * MPALMOSTSAFE */ int sys_readlink(struct readlink_args *uap) @@ -2644,12 +2784,14 @@ sys_readlink(struct readlink_args *uap) struct nlookupdata nd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); if (error == 0) { error = kern_readlink(&nd, uap->buf, uap->count, &uap->sysmsg_result); } nlookup_done(&nd); + rel_mplock(); return (error); } @@ -2688,8 +2830,9 @@ setfflags(struct vnode *vp, int flags) * chflags(char *path, int flags) * * Change flags of a file given a path name. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_chflags(struct chflags_args *uap) { @@ -2698,6 +2841,7 @@ sys_chflags(struct chflags_args *uap) int error; vp = NULL; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = nlookup(&nd); @@ -2710,6 +2854,7 @@ sys_chflags(struct chflags_args *uap) error = setfflags(vp, uap->flags); vrele(vp); } + rel_mplock(); return (error); } @@ -2717,8 +2862,9 @@ sys_chflags(struct chflags_args *uap) * lchflags(char *path, int flags) * * Change flags of a file given a path name, but don't follow symlinks. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_lchflags(struct lchflags_args *uap) { @@ -2727,6 +2873,7 @@ sys_lchflags(struct lchflags_args *uap) int error; vp = NULL; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); if (error == 0) error = nlookup(&nd); @@ -2739,6 +2886,7 @@ sys_lchflags(struct lchflags_args *uap) error = setfflags(vp, uap->flags); vrele(vp); } + rel_mplock(); return (error); } @@ -2746,8 +2894,9 @@ sys_lchflags(struct lchflags_args *uap) * fchflags_args(int fd, int flags) * * Change flags of a file given a file descriptor. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_fchflags(struct fchflags_args *uap) { @@ -2758,10 +2907,12 @@ sys_fchflags(struct fchflags_args *uap) if ((error = holdvnode(p->p_fd, uap->fd, &fp)) != 0) return (error); + get_mplock(); if (fp->f_nchandle.ncp) error = ncp_writechk(&fp->f_nchandle); if (error == 0) error = setfflags((struct vnode *) fp->f_data, uap->flags); + rel_mplock(); fdrop(fp); return (error); } @@ -2807,18 +2958,21 @@ kern_chmod(struct nlookupdata *nd, int mode) * chmod_args(char *path, int mode) * * Change mode of a file given path name. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_chmod(struct chmod_args *uap) { struct nlookupdata nd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = kern_chmod(&nd, uap->mode); nlookup_done(&nd); + rel_mplock(); return (error); } @@ -2826,18 +2980,21 @@ sys_chmod(struct chmod_args *uap) * lchmod_args(char *path, int mode) * * Change mode of a file given path name (don't follow links.) + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_lchmod(struct lchmod_args *uap) { struct nlookupdata nd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); if (error == 0) error = kern_chmod(&nd, uap->mode); nlookup_done(&nd); + rel_mplock(); return (error); } @@ -2845,8 +3002,9 @@ sys_lchmod(struct lchmod_args *uap) * fchmod_args(int fd, int mode) * * Change mode of a file given a file descriptor. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_fchmod(struct fchmod_args *uap) { @@ -2857,10 +3015,12 @@ sys_fchmod(struct fchmod_args *uap) if ((error = holdvnode(p->p_fd, uap->fd, &fp)) != 0) return (error); + get_mplock(); if (fp->f_nchandle.ncp) error = ncp_writechk(&fp->f_nchandle); if (error == 0) error = setfmode((struct vnode *)fp->f_data, uap->mode); + rel_mplock(); fdrop(fp); return (error); } @@ -2869,6 +3029,8 @@ sys_fchmod(struct fchmod_args *uap) * fchmodat_args(char *path, int mode) * * Change mode of a file pointed to by fd/path. + * + * MPALMOSTSAFE */ int sys_fchmodat(struct fchmodat_args *uap) @@ -2882,11 +3044,13 @@ sys_fchmodat(struct fchmodat_args *uap) return (EINVAL); flags = (uap->flags & AT_SYMLINK_NOFOLLOW) ? 0 : NLC_FOLLOW; + get_mplock(); error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, flags); if (error == 0) error = kern_chmod(&nd, uap->mode); nlookup_done_at(&nd, fp); + rel_mplock(); return (error); } @@ -2932,6 +3096,8 @@ kern_chown(struct nlookupdata *nd, int uid, int gid) * chown(char *path, int uid, int gid) * * Set ownership given a path name. + * + * MPALMOSTSAFE */ int sys_chown(struct chown_args *uap) @@ -2939,10 +3105,12 @@ sys_chown(struct chown_args *uap) struct nlookupdata nd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = kern_chown(&nd, uap->uid, uap->gid); nlookup_done(&nd); + rel_mplock(); return (error); } @@ -2950,6 +3118,8 @@ sys_chown(struct chown_args *uap) * lchown_args(char *path, int uid, int gid) * * Set ownership given a path name, do not cross symlinks. + * + * MPALMOSTSAFE */ int sys_lchown(struct lchown_args *uap) @@ -2957,10 +3127,12 @@ sys_lchown(struct lchown_args *uap) struct nlookupdata nd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); if (error == 0) error = kern_chown(&nd, uap->uid, uap->gid); nlookup_done(&nd); + rel_mplock(); return (error); } @@ -2968,8 +3140,9 @@ sys_lchown(struct lchown_args *uap) * fchown_args(int fd, int uid, int gid) * * Set ownership given a file descriptor. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_fchown(struct fchown_args *uap) { @@ -2980,10 +3153,12 @@ sys_fchown(struct fchown_args *uap) if ((error = holdvnode(p->p_fd, uap->fd, &fp)) != 0) return (error); + get_mplock(); if (fp->f_nchandle.ncp) error = ncp_writechk(&fp->f_nchandle); if (error == 0) error = setfown((struct vnode *)fp->f_data, uap->uid, uap->gid); + rel_mplock(); fdrop(fp); return (error); } @@ -2992,6 +3167,8 @@ sys_fchown(struct fchown_args *uap) * fchownat(int fd, char *path, int uid, int gid, int flags) * * Set ownership of file pointed to by fd/path. + * + * MPALMOSTSAFE */ int sys_fchownat(struct fchownat_args *uap) @@ -3005,11 +3182,13 @@ sys_fchownat(struct fchownat_args *uap) return (EINVAL); flags = (uap->flags & AT_SYMLINK_NOFOLLOW) ? 0 : NLC_FOLLOW; + get_mplock(); error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, flags); if (error == 0) error = kern_chown(&nd, uap->uid, uap->gid); nlookup_done_at(&nd, fp); + rel_mplock(); return (error); } @@ -3091,6 +3270,8 @@ kern_utimes(struct nlookupdata *nd, struct timeval *tptr) * utimes_args(char *path, struct timeval *tptr) * * Set the access and modification times of a file. + * + * MPALMOSTSAFE */ int sys_utimes(struct utimes_args *uap) @@ -3104,10 +3285,12 @@ sys_utimes(struct utimes_args *uap) if (error) return (error); } + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = kern_utimes(&nd, uap->tptr ? tv : NULL); nlookup_done(&nd); + rel_mplock(); return (error); } @@ -3115,6 +3298,8 @@ sys_utimes(struct utimes_args *uap) * lutimes_args(char *path, struct timeval *tptr) * * Set the access and modification times of a file. + * + * MPALMOSTSAFE */ int sys_lutimes(struct lutimes_args *uap) @@ -3128,10 +3313,12 @@ sys_lutimes(struct lutimes_args *uap) if (error) return (error); } + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); if (error == 0) error = kern_utimes(&nd, uap->tptr ? tv : NULL); nlookup_done(&nd); + rel_mplock(); return (error); } @@ -3182,6 +3369,8 @@ kern_futimes(int fd, struct timeval *tptr) * futimes_args(int fd, struct timeval *tptr) * * Set the access and modification times of a file. + * + * MPALMOSTSAFE */ int sys_futimes(struct futimes_args *uap) @@ -3194,8 +3383,9 @@ sys_futimes(struct futimes_args *uap) if (error) return (error); } - + get_mplock(); error = kern_futimes(uap->fd, uap->tptr ? tv : NULL); + rel_mplock(); return (error); } @@ -3235,6 +3425,8 @@ kern_truncate(struct nlookupdata *nd, off_t length) * truncate(char *path, int pad, off_t length) * * Truncate a file given its path name. + * + * MPALMOSTSAFE */ int sys_truncate(struct truncate_args *uap) @@ -3242,10 +3434,12 @@ sys_truncate(struct truncate_args *uap) struct nlookupdata nd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = kern_truncate(&nd, uap->length); nlookup_done(&nd); + rel_mplock(); return error; } @@ -3295,13 +3489,17 @@ done: * ftruncate_args(int fd, int pad, off_t length) * * Truncate a file given a file descriptor. + * + * MPALMOSTSAFE */ int sys_ftruncate(struct ftruncate_args *uap) { int error; + get_mplock(); error = kern_ftruncate(uap->fd, uap->length); + rel_mplock(); return (error); } @@ -3310,8 +3508,9 @@ sys_ftruncate(struct ftruncate_args *uap) * fsync(int fd) * * Sync an open file. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_fsync(struct fsync_args *uap) { @@ -3324,6 +3523,7 @@ sys_fsync(struct fsync_args *uap) if ((error = holdvnode(p->p_fd, uap->fd, &fp)) != 0) return (error); + get_mplock(); vp = (struct vnode *)fp->f_data; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); if ((obj = vp->v_object) != NULL) @@ -3332,7 +3532,9 @@ sys_fsync(struct fsync_args *uap) if (error == 0 && vp->v_mount) error = buf_fsync(vp); vn_unlock(vp); + rel_mplock(); fdrop(fp); + return (error); } @@ -3516,6 +3718,8 @@ kern_rename(struct nlookupdata *fromnd, struct nlookupdata *tond) * * Rename files. Source and destination must either both be directories, * or both not be directories. If target is a directory, it must be empty. + * + * MPALMOSTSAFE */ int sys_rename(struct rename_args *uap) @@ -3523,6 +3727,7 @@ sys_rename(struct rename_args *uap) struct nlookupdata fromnd, tond; int error; + get_mplock(); error = nlookup_init(&fromnd, uap->from, UIO_USERSPACE, 0); if (error == 0) { error = nlookup_init(&tond, uap->to, UIO_USERSPACE, 0); @@ -3531,6 +3736,7 @@ sys_rename(struct rename_args *uap) nlookup_done(&tond); } nlookup_done(&fromnd); + rel_mplock(); return (error); } @@ -3567,18 +3773,21 @@ kern_mkdir(struct nlookupdata *nd, int mode) * mkdir_args(char *path, int mode) * * Make a directory file. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_mkdir(struct mkdir_args *uap) { struct nlookupdata nd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); if (error == 0) error = kern_mkdir(&nd, uap->mode); nlookup_done(&nd); + rel_mplock(); return (error); } @@ -3609,18 +3818,21 @@ kern_rmdir(struct nlookupdata *nd) * rmdir_args(char *path) * * Remove a directory file. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_rmdir(struct rmdir_args *uap) { struct nlookupdata nd; int error; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); if (error == 0) error = kern_rmdir(&nd); nlookup_done(&nd); + rel_mplock(); return (error); } @@ -3702,6 +3914,8 @@ done: * getdirentries_args(int fd, char *buf, u_int conut, long *basep) * * Read a block of directory entries in a file system independent format. + * + * MPALMOSTSAFE */ int sys_getdirentries(struct getdirentries_args *uap) @@ -3709,8 +3923,10 @@ sys_getdirentries(struct getdirentries_args *uap) long base; int error; + get_mplock(); error = kern_getdirentries(uap->fd, uap->buf, uap->count, &base, &uap->sysmsg_result, UIO_USERSPACE); + rel_mplock(); if (error == 0 && uap->basep) error = copyout(&base, uap->basep, sizeof(*uap->basep)); @@ -3719,24 +3935,28 @@ sys_getdirentries(struct getdirentries_args *uap) /* * getdents_args(int fd, char *buf, size_t count) + * + * MPALMOSTSAFE */ int sys_getdents(struct getdents_args *uap) { int error; + get_mplock(); error = kern_getdirentries(uap->fd, uap->buf, uap->count, NULL, - &uap->sysmsg_result, UIO_USERSPACE); + &uap->sysmsg_result, UIO_USERSPACE); + rel_mplock(); return (error); } /* - * umask(int newmask) - * * Set the mode mask for creation of filesystem nodes. * - * MP SAFE + * umask(int newmask) + * + * MPSAFE */ int sys_umask(struct umask_args *uap) @@ -3756,8 +3976,9 @@ sys_umask(struct umask_args *uap) * * Void all references to file by ripping underlying filesystem * away from vnode. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_revoke(struct revoke_args *uap) { @@ -3768,6 +3989,7 @@ sys_revoke(struct revoke_args *uap) int error; vp = NULL; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = nlookup(&nd); @@ -3790,6 +4012,7 @@ sys_revoke(struct revoke_args *uap) } if (cred) crfree(cred); + rel_mplock(); return (error); } @@ -3806,6 +4029,8 @@ sys_revoke(struct revoke_args *uap) * nullfs mounts of subdirectories are not safe. That is, it will * work, but you do not really have protection against access to * the related parent directories. + * + * MPALMOSTSAFE */ int sys_getfh(struct getfh_args *uap) @@ -3824,6 +4049,7 @@ sys_getfh(struct getfh_args *uap) return (error); vp = NULL; + get_mplock(); error = nlookup_init(&nd, uap->fname, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = nlookup(&nd); @@ -3839,6 +4065,7 @@ sys_getfh(struct getfh_args *uap) if (error == 0) error = copyout(&fh, uap->fhp, sizeof(fh)); } + rel_mplock(); return (error); } @@ -3850,6 +4077,8 @@ sys_getfh(struct getfh_args *uap) * * warning: do not remove the priv_check() call or this becomes one giant * security hole. + * + * MPALMOSTSAFE */ int sys_fhopen(struct fhopen_args *uap) @@ -3875,20 +4104,29 @@ sys_fhopen(struct fhopen_args *uap) return (error); fmode = FFLAGS(uap->flags); - /* why not allow a non-read/write open for our lockd? */ + + /* + * Why not allow a non-read/write open for our lockd? + */ if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT)) return (EINVAL); error = copyin(uap->u_fhp, &fhp, sizeof(fhp)); if (error) return(error); - /* find the mount point */ + + /* + * Find the mount point + */ + get_mplock(); mp = vfs_getvfs(&fhp.fh_fsid); - if (mp == NULL) - return (ESTALE); + if (mp == NULL) { + error = ESTALE; + goto done; + } /* now give me my vnode, it gets returned to me locked */ error = VFS_FHTOVP(mp, NULL, &fhp.fh_fid, &vp); if (error) - return (error); + goto done; /* * from now on we have to make sure not * to forget about the vnode @@ -3991,7 +4229,7 @@ sys_fhopen(struct fhopen_args *uap) fsetfd(p, NULL, indx); fdrop(fp); vrele(vp); - return (error); + goto done; } vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); fp->f_flag |= FHASLOCK; @@ -4002,6 +4240,7 @@ sys_fhopen(struct fhopen_args *uap) * reserved descriptor and return it. */ vput(vp); + rel_mplock(); fsetfd(p, fp, indx); fdrop(fp); uap->sysmsg_result = indx; @@ -4012,11 +4251,15 @@ bad_drop: fdrop(fp); bad: vput(vp); +done: + rel_mplock(); return (error); } /* * fhstat_args(struct fhandle *u_fhp, struct stat *sb) + * + * MPALMOSTSAFE */ int sys_fhstat(struct fhstat_args *uap) @@ -4039,20 +4282,25 @@ sys_fhstat(struct fhstat_args *uap) if (error) return (error); + get_mplock(); if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) - return (ESTALE); - if ((error = VFS_FHTOVP(mp, NULL, &fh.fh_fid, &vp))) - return (error); - error = vn_stat(vp, &sb, td->td_proc->p_ucred); - vput(vp); - if (error) - return (error); - error = copyout(&sb, uap->sb, sizeof(sb)); + error = ESTALE; + if (error == 0) { + if ((error = VFS_FHTOVP(mp, NULL, &fh.fh_fid, &vp)) == 0) { + error = vn_stat(vp, &sb, td->td_proc->p_ucred); + vput(vp); + } + } + rel_mplock(); + if (error == 0) + error = copyout(&sb, uap->sb, sizeof(sb)); return (error); } /* * fhstatfs_args(struct fhandle *u_fhp, struct statfs *buf) + * + * MPALMOSTSAFE */ int sys_fhstatfs(struct fhstatfs_args *uap) @@ -4076,23 +4324,28 @@ sys_fhstatfs(struct fhstatfs_args *uap) if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) return (error); - if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) - return (ESTALE); + get_mplock(); - if (p != NULL && !chroot_visible_mnt(mp, p)) - return (ESTALE); + if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) { + error = ESTALE; + goto done; + } + if (p != NULL && !chroot_visible_mnt(mp, p)) { + error = ESTALE; + goto done; + } - if ((error = VFS_FHTOVP(mp, NULL, &fh.fh_fid, &vp))) - return (error); + if ((error = VFS_FHTOVP(mp, NULL, &fh.fh_fid, &vp)) != 0) + goto done; mp = vp->v_mount; sp = &mp->mnt_stat; vput(vp); if ((error = VFS_STATFS(mp, sp, p->p_ucred)) != 0) - return (error); + goto done; error = mount_path(p, mp, &fullpath, &freepath); if (error) - return(error); + goto done; bzero(sp->f_mntonname, sizeof(sp->f_mntonname)); strlcpy(sp->f_mntonname, fullpath, sizeof(sp->f_mntonname)); kfree(freepath, M_TEMP); @@ -4103,11 +4356,16 @@ sys_fhstatfs(struct fhstatfs_args *uap) sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; sp = &sb; } - return (copyout(sp, uap->buf, sizeof(*sp))); + error = copyout(sp, uap->buf, sizeof(*sp)); +done: + rel_mplock(); + return (error); } /* * fhstatvfs_args(struct fhandle *u_fhp, struct statvfs *buf) + * + * MPALMOSTSAFE */ int sys_fhstatvfs(struct fhstatvfs_args *uap) @@ -4129,27 +4387,34 @@ sys_fhstatvfs(struct fhstatvfs_args *uap) if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) return (error); - if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) - return (ESTALE); + get_mplock(); - if (p != NULL && !chroot_visible_mnt(mp, p)) - return (ESTALE); + if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) { + error = ESTALE; + goto done; + } + if (p != NULL && !chroot_visible_mnt(mp, p)) { + error = ESTALE; + goto done; + } if ((error = VFS_FHTOVP(mp, NULL, &fh.fh_fid, &vp))) - return (error); + goto done; mp = vp->v_mount; sp = &mp->mnt_vstat; vput(vp); if ((error = VFS_STATVFS(mp, sp, p->p_ucred)) != 0) - return (error); + goto done; sp->f_flag = 0; if (mp->mnt_flag & MNT_RDONLY) sp->f_flag |= ST_RDONLY; if (mp->mnt_flag & MNT_NOSUID) sp->f_flag |= ST_NOSUID; - - return (copyout(sp, uap->buf, sizeof(*sp))); + error = copyout(sp, uap->buf, sizeof(*sp)); +done: + rel_mplock(); + return (error); } @@ -4163,6 +4428,8 @@ sys_fhstatvfs(struct fhstatvfs_args *uap) * attribute code have raised their hands. * * Currently this is used only by UFS Extended Attributes. + * + * MPALMOSTSAFE */ int sys_extattrctl(struct extattrctl_args *uap) @@ -4173,6 +4440,7 @@ sys_extattrctl(struct extattrctl_args *uap) int error; vp = NULL; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = nlookup(&nd); @@ -4183,6 +4451,8 @@ sys_extattrctl(struct extattrctl_args *uap) nd.nl_cred); } nlookup_done(&nd); + rel_mplock(); + return (error); } @@ -4191,6 +4461,8 @@ sys_extattrctl(struct extattrctl_args *uap) * Accepts attribute name, and a uio structure pointing to the data to set. * The uio is consumed in the style of writev(). The real work happens * in VOP_SETEXTATTR(). + * + * MPALMOSTSAFE */ int sys_extattr_set_file(struct extattr_set_file_args *uap) @@ -4212,6 +4484,7 @@ sys_extattr_set_file(struct extattr_set_file_args *uap) return (error); vp = NULL; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = nlookup(&nd); @@ -4221,6 +4494,7 @@ sys_extattr_set_file(struct extattr_set_file_args *uap) error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); if (error) { nlookup_done(&nd); + rel_mplock(); return (error); } @@ -4260,6 +4534,7 @@ sys_extattr_set_file(struct extattr_set_file_args *uap) done: vput(vp); nlookup_done(&nd); + rel_mplock(); if (needfree) FREE(needfree, M_IOV); return (error); @@ -4270,6 +4545,8 @@ done: * Accepts attribute name, and a uio structure pointing to a buffer for the * data. The uio is consumed in the style of readv(). The real work * happens in VOP_GETEXTATTR(); + * + * MPALMOSTSAFE */ int sys_extattr_get_file(struct extattr_get_file_args *uap) @@ -4291,6 +4568,7 @@ sys_extattr_get_file(struct extattr_get_file_args *uap) return (error); vp = NULL; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = nlookup(&nd); @@ -4298,6 +4576,7 @@ sys_extattr_get_file(struct extattr_get_file_args *uap) error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); if (error) { nlookup_done(&nd); + rel_mplock(); return (error); } @@ -4337,6 +4616,7 @@ sys_extattr_get_file(struct extattr_get_file_args *uap) done: vput(vp); nlookup_done(&nd); + rel_mplock(); if (needfree) FREE(needfree, M_IOV); return(error); @@ -4345,6 +4625,8 @@ done: /* * Syscall to delete a named extended attribute from a file or directory. * Accepts attribute name. The real work happens in VOP_SETEXTATTR(). + * + * MPALMOSTSAFE */ int sys_extattr_delete_file(struct extattr_delete_file_args *uap) @@ -4358,22 +4640,21 @@ sys_extattr_delete_file(struct extattr_delete_file_args *uap) if (error) return(error); - vp = NULL; + get_mplock(); error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) error = nlookup(&nd); if (error == 0) error = ncp_writechk(&nd.nl_nch); - if (error == 0) + if (error == 0) { error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); - if (error) { - nlookup_done(&nd); - return (error); + if (error == 0) { + error = VOP_SETEXTATTR(vp, attrname, NULL, nd.nl_cred); + vput(vp); + } } - - error = VOP_SETEXTATTR(vp, attrname, NULL, nd.nl_cred); - vput(vp); nlookup_done(&nd); + rel_mplock(); return(error); } diff --git a/sys/netproto/ncp/ncp_mod.c b/sys/netproto/ncp/ncp_mod.c index 22bd5ba89f..0a68ad3585 100644 --- a/sys/netproto/ncp/ncp_mod.c +++ b/sys/netproto/ncp/ncp_mod.c @@ -71,8 +71,11 @@ struct sncp_connect_args { int *connHandle; }; +/* + * MPALMOSTSAFE + */ static int -sncp_connect(struct sncp_connect_args *uap) +sys_sncp_connect(struct sncp_connect_args *uap) { struct thread *td = curthread; int connHandle = 0, error; @@ -87,15 +90,19 @@ sncp_connect(struct sncp_connect_args *uap) checkbad(copyin(uap->li,&li,sizeof(li))); checkbad(copyout(&connHandle,uap->connHandle,sizeof(connHandle))); /* check before */ li.password = li.user = NULL; + + get_mplock(); error = ncp_conn_getattached(&li, td, cred, NCPM_WRITE | NCPM_EXECUTE, &conn); if (error) { error = ncp_connect(&li, td, cred, &conn); } if (!error) { error = ncp_conn_gethandle(conn, td, &handle); - copyout(&handle->nh_id, uap->connHandle, sizeof(uap->connHandle)); + if (error == 0) + copyout(&handle->nh_id, uap->connHandle, sizeof(uap->connHandle)); ncp_conn_unlock(conn,td); } + rel_mplock(); bad: uap->sysmsg_result = error; return error; @@ -111,8 +118,11 @@ struct sncp_request_args { static int ncp_conn_handler(struct thread *td, struct sncp_request_args *uap, struct ncp_conn *conn, struct ncp_handle *handle); +/* + * MPALMOSTSAFE + */ static int -sncp_request(struct sncp_request_args *uap) +sys_sncp_request(struct sncp_request_args *uap) { struct thread *td = curthread; int error = 0, rqsize; @@ -122,18 +132,24 @@ sncp_request(struct sncp_request_args *uap) DECLARE_RQ; - KKASSERT(td->td_proc); + get_mplock(); + cred = td->td_proc->p_ucred; error = ncp_conn_findhandle(uap->connHandle,td,&handle); - if (error) return error; + if (error) + goto done; conn = handle->nh_conn; - if (uap->fn == NCP_CONN) - return ncp_conn_handler(td, uap, conn, handle); + if (uap->fn == NCP_CONN) { + error = ncp_conn_handler(td, uap, conn, handle); + goto done; + } error = copyin(&uap->ncpbuf->rqsize, &rqsize, sizeof(int)); - if (error) return(error); + if (error) + goto done; error = ncp_conn_lock(conn,td,cred,NCPM_EXECUTE); - if (error) return(error); + if (error) + goto done; ncp_rq_head(rqp,NCP_REQUEST,uap->fn,td,cred); if (rqsize) error = ncp_rq_usermem(rqp,(caddr_t)uap->ncpbuf->packet, rqsize); @@ -148,6 +164,8 @@ sncp_request(struct sncp_request_args *uap) } ncp_rq_done(rqp); ncp_conn_unlock(conn,td); +done: + rel_mplock(); return error; } @@ -318,8 +336,11 @@ struct sncp_conn_scan_args { int *connHandle; }; +/* + * MPALMOSTSAFE + */ static int -sncp_conn_scan(struct thread *td, struct sncp_conn_scan_args *uap) +sys_sncp_conn_scan(struct thread *td, struct sncp_conn_scan_args *uap) { int connHandle = 0, error; struct ncp_conn_args li, *lip; @@ -358,6 +379,8 @@ sncp_conn_scan(struct thread *td, struct sncp_conn_scan_args *uap) lip->user = user; lip->password = password; } + + get_mplock(); error = ncp_conn_getbyli(lip,td,cred,NCPM_EXECUTE,&conn); if (!error) { /* already have this login */ ncp_conn_gethandle(conn, td, &hp); @@ -365,6 +388,7 @@ sncp_conn_scan(struct thread *td, struct sncp_conn_scan_args *uap) ncp_conn_unlock(conn,td); copyout(&connHandle,uap->connHandle,sizeof(connHandle)); } + rel_mplock(); if (user) kfree(user, M_NCPDATA); if (password) kfree(password, M_NCPDATA); uap->sysmsg_result = error; @@ -417,8 +441,11 @@ struct sncp_intfn_args { caddr_t data; }; +/* + * MPSAFE + */ static int -sncp_intfn(struct sncp_intfn_args *uap) +sys_sncp_intfn(struct sncp_intfn_args *uap) { return ENOSYS; } @@ -426,10 +453,10 @@ sncp_intfn(struct sncp_intfn_args *uap) * define our new system calls */ static struct sysent newent[] = { - {2, (sy_call_t*)sncp_conn_scan}, - {2, (sy_call_t*)sncp_connect}, - {2, (sy_call_t*)sncp_intfn}, - {3, (sy_call_t*)sncp_request} + {2, (sy_call_t*)sys_sncp_conn_scan}, + {2, (sy_call_t*)sys_sncp_connect}, + {2, (sy_call_t*)sys_sncp_intfn}, + {3, (sy_call_t*)sys_sncp_request} }; #define SC_SIZE sizeof(newent)/sizeof(struct sysent) diff --git a/sys/platform/pc32/i386/machdep.c b/sys/platform/pc32/i386/machdep.c index 5272025ae9..95815a317c 100644 --- a/sys/platform/pc32/i386/machdep.c +++ b/sys/platform/pc32/i386/machdep.c @@ -560,6 +560,8 @@ cpu_sanitize_tls(struct savetls *tls) * context left by sendsig. Check carefully to * make sure that the user has not modified the * state to gain improper privileges. + * + * MPSAFE */ #define EFL_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0) #define CS_SECURE(cs) (ISPL(cs) == SEL_UPL) @@ -661,6 +663,7 @@ sys_sigreturn(struct sigreturn_args *uap) /* * Restore the FPU state from the frame */ + crit_enter(); npxpop(&ucp->uc_mcontext); /* @@ -677,6 +680,7 @@ sys_sigreturn(struct sigreturn_args *uap) lp->lwp_sigmask = ucp->uc_sigmask; SIG_CANTMASK(lp->lwp_sigmask); + crit_exit(); return(EJUSTRETURN); } diff --git a/sys/platform/pc32/i386/sys_machdep.c b/sys/platform/pc32/i386/sys_machdep.c index 62f7ba67a3..ae463d8fc0 100644 --- a/sys/platform/pc32/i386/sys_machdep.c +++ b/sys/platform/pc32/i386/sys_machdep.c @@ -79,14 +79,17 @@ int i386_extend_pcb(struct lwp *); /* * sysarch_args(int op, char *params) + * + * MPALMOSTSAFE */ - int sys_sysarch(struct sysarch_args *uap) { struct lwp *lp = curthread->td_lwp; int error = 0; + get_mplock(); + switch(uap->op) { case I386_GET_LDT: error = ki386_get_ldt(lp, uap->parms, &uap->sysmsg_result); @@ -107,6 +110,7 @@ sys_sysarch(struct sysarch_args *uap) error = EOPNOTSUPP; break; } + rel_mplock(); return (error); } diff --git a/sys/platform/pc32/i386/trap.c b/sys/platform/pc32/i386/trap.c index 771101e671..b3d018ce14 100644 --- a/sys/platform/pc32/i386/trap.c +++ b/sys/platform/pc32/i386/trap.c @@ -1326,16 +1326,10 @@ syscall2(struct trapframe *frame) STOPEVENT(p, S_SCE, narg); /* MP aware */ -#ifdef SMP /* - * Try to run the syscall without the MP lock if the syscall - * is MP safe. We have to obtain the MP lock no matter what if - * we are ktracing + * NOTE: All system calls run MPSAFE now. The system call itself + * is responsible for getting the MP lock. */ - if ((callp->sy_narg & SYF_MPSAFE) == 0) - MAKEMPSAFE(have_mplock); -#endif - error = (*callp->sy_call)(&args); out: diff --git a/sys/platform/pc64/x86_64/machdep.c b/sys/platform/pc64/x86_64/machdep.c index 0d7cdc2856..fbad5daf4a 100644 --- a/sys/platform/pc64/x86_64/machdep.c +++ b/sys/platform/pc64/x86_64/machdep.c @@ -583,6 +583,8 @@ cpu_sanitize_tls(struct savetls *tls) * context left by sendsig. Check carefully to * make sure that the user has not modified the * state to gain improper privileges. + * + * MPSAFE */ #define EFL_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0) #define CS_SECURE(cs) (ISPL(cs) == SEL_UPL) @@ -688,6 +690,7 @@ sys_sigreturn(struct sigreturn_args *uap) /* * Restore the FPU state from the frame */ + crit_enter(); npxpop(&ucp->uc_mcontext); /* @@ -704,6 +707,7 @@ sys_sigreturn(struct sigreturn_args *uap) lp->lwp_sigmask = ucp->uc_sigmask; SIG_CANTMASK(lp->lwp_sigmask); + crit_exit(); return(EJUSTRETURN); } diff --git a/sys/platform/pc64/x86_64/tls.c b/sys/platform/pc64/x86_64/tls.c index 35bd83bf57..578920fa5d 100644 --- a/sys/platform/pc64/x86_64/tls.c +++ b/sys/platform/pc64/x86_64/tls.c @@ -63,6 +63,8 @@ * TLS descriptor or -1 on error. * * (int which, struct tls_info *info, size_t infosize) + * + * MPSAFE */ int sys_set_tls_area(struct set_tls_area_args *uap) diff --git a/sys/platform/pc64/x86_64/trap.c b/sys/platform/pc64/x86_64/trap.c index da7499b0ce..a5f32fd467 100644 --- a/sys/platform/pc64/x86_64/trap.c +++ b/sys/platform/pc64/x86_64/trap.c @@ -1155,16 +1155,10 @@ syscall2(struct trapframe *frame) STOPEVENT(p, S_SCE, narg); /* MP aware */ -#ifdef SMP /* - * Try to run the syscall without the MP lock if the syscall - * is MP safe. We have to obtain the MP lock no matter what if - * we are ktracing + * NOTE: All system calls run MPSAFE now. The system call itself + * is responsible for getting the MP lock. */ - if ((callp->sy_narg & SYF_MPSAFE) == 0) - MAKEMPSAFE(have_mplock); -#endif - error = (*callp->sy_call)(&args); out: diff --git a/sys/platform/vkernel/i386/cpu_regs.c b/sys/platform/vkernel/i386/cpu_regs.c index 1219e5ae8d..88cd36756e 100644 --- a/sys/platform/vkernel/i386/cpu_regs.c +++ b/sys/platform/vkernel/i386/cpu_regs.c @@ -398,6 +398,8 @@ cpu_sanitize_tls(struct savetls *tls) * context left by sendsig. Check carefully to * make sure that the user has not modified the * state to gain improper privileges. + * + * MPSAFE */ #define EFL_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0) #define CS_SECURE(cs) (ISPL(cs) == SEL_UPL) @@ -496,6 +498,7 @@ sys_sigreturn(struct sigreturn_args *uap) /* * Restore the FPU state from the frame */ + crit_enter(); npxpop(&ucp.uc_mcontext); /* @@ -512,6 +515,7 @@ sys_sigreturn(struct sigreturn_args *uap) lp->lwp_sigmask = ucp.uc_sigmask; SIG_CANTMASK(lp->lwp_sigmask); + crit_exit(); return(EJUSTRETURN); } diff --git a/sys/platform/vkernel/i386/trap.c b/sys/platform/vkernel/i386/trap.c index edbb75a332..ba541d63eb 100644 --- a/sys/platform/vkernel/i386/trap.c +++ b/sys/platform/vkernel/i386/trap.c @@ -1242,16 +1242,10 @@ syscall2(struct trapframe *frame) STOPEVENT(p, S_SCE, narg); /* MP aware */ -#ifdef SMP /* - * Try to run the syscall without the MP lock if the syscall - * is MP safe. We have to obtain the MP lock no matter what if - * we are ktracing + * NOTE: All system calls run MPSAFE now. The system call itself + * is responsible for getting the MP lock. */ - if ((callp->sy_narg & SYF_MPSAFE) == 0) - MAKEMPSAFE(have_mplock); -#endif - error = (*callp->sy_call)(&args); #if 0 diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index edf5f9c8ee..94ac4415b6 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -246,8 +246,6 @@ #define SYS_aio_write 319 #define SYS_lio_listio 320 #define SYS_yield 321 -#define SYS_thr_sleep 322 -#define SYS_thr_wakeup 323 #define SYS_mlockall 324 #define SYS_munlockall 325 #define SYS___getcwd 326 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index 5d19987082..f74896cbe0 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -188,8 +188,6 @@ MIASM = \ aio_write.o \ lio_listio.o \ yield.o \ - thr_sleep.o \ - thr_wakeup.o \ mlockall.o \ munlockall.o \ __getcwd.o \ diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h index 5f11e11e67..857a9dfab7 100644 --- a/sys/sys/sysent.h +++ b/sys/sys/sysent.h @@ -52,7 +52,6 @@ struct sysent { /* system call table */ }; #define SYF_ARGMASK 0x0000FFFF -#define SYF_MPSAFE 0x00010000 #define SCARG(p,k) ((p)->k) /* get arg from args pointer */ /* placeholder till we integrate rest of lite2 syscallargs changes XXX */ diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index a8bcb365e9..7ee585b426 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -1393,18 +1393,6 @@ struct yield_args { #endif register_t dummy; }; -struct thr_sleep_args { -#ifdef _KERNEL - struct sysmsg sysmsg; -#endif - const struct timespec * timeout; char timeout_[PAD_(const struct timespec *)]; -}; -struct thr_wakeup_args { -#ifdef _KERNEL - struct sysmsg sysmsg; -#endif - pid_t pid; char pid_[PAD_(pid_t)]; -}; struct mlockall_args { #ifdef _KERNEL struct sysmsg sysmsg; @@ -2782,8 +2770,6 @@ int sys_aio_read (struct aio_read_args *); int sys_aio_write (struct aio_write_args *); int sys_lio_listio (struct lio_listio_args *); int sys_yield (struct yield_args *); -int sys_thr_sleep (struct thr_sleep_args *); -int sys_thr_wakeup (struct thr_wakeup_args *); int sys_mlockall (struct mlockall_args *); int sys_munlockall (struct munlockall_args *); int sys___getcwd (struct __getcwd_args *); diff --git a/sys/sys/sysunion.h b/sys/sys/sysunion.h index 5a67be742f..66b970f7cb 100644 --- a/sys/sys/sysunion.h +++ b/sys/sys/sysunion.h @@ -292,8 +292,6 @@ union sysunion { struct aio_write_args aio_write; struct lio_listio_args lio_listio; struct yield_args yield; - struct thr_sleep_args thr_sleep; - struct thr_wakeup_args thr_wakeup; struct mlockall_args mlockall; struct munlockall_args munlockall; struct __getcwd_args __getcwd; diff --git a/sys/vfs/nfs/nfs_syscalls.c b/sys/vfs/nfs/nfs_syscalls.c index e71f6f2178..5ef86727bb 100644 --- a/sys/vfs/nfs/nfs_syscalls.c +++ b/sys/vfs/nfs/nfs_syscalls.c @@ -120,6 +120,8 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, soreserve, CTLFLAG_RW, &nfs_soreserve, 0, ""); * - adds a socket to the selection list * - remains in the kernel as an nfsd * - remains in the kernel as an nfsiod + * + * MPALMOSTSAFE */ int sys_nfssvc(struct nfssvc_args *uap) @@ -144,12 +146,13 @@ sys_nfssvc(struct nfssvc_args *uap) * Must be super user */ error = priv_check(td, PRIV_ROOT); - if(error) + if (error) return (error); - KKASSERT(td->td_proc); /* for ucred and p_fd */ + + get_mplock(); while (nfssvc_sockhead_flag & SLP_INIT) { - nfssvc_sockhead_flag |= SLP_WANTINIT; - (void) tsleep((caddr_t)&nfssvc_sockhead, 0, "nfsd init", 0); + nfssvc_sockhead_flag |= SLP_WANTINIT; + tsleep((caddr_t)&nfssvc_sockhead, 0, "nfsd init", 0); } if (uap->flag & NFSSVC_BIOD) error = ENXIO; /* no longer need nfsiod's */ @@ -160,7 +163,7 @@ sys_nfssvc(struct nfssvc_args *uap) else if (uap->flag & NFSSVC_MNTD) { error = copyin(uap->argp, (caddr_t)&ncd, sizeof (ncd)); if (error) - return (error); + goto done; vp = NULL; error = nlookup_init(&nd, ncd.ncd_dirp, UIO_USERSPACE, NLC_FOLLOW); @@ -170,27 +173,29 @@ sys_nfssvc(struct nfssvc_args *uap) error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); nlookup_done(&nd); if (error) - return (error); + goto done; if ((vp->v_flag & VROOT) == 0) error = EINVAL; nmp = VFSTONFS(vp->v_mount); vput(vp); if (error) - return (error); + goto done; if ((nmp->nm_state & NFSSTA_MNTD) && - (uap->flag & NFSSVC_GOTAUTH) == 0) - return (0); + (uap->flag & NFSSVC_GOTAUTH) == 0) { + error = 0; + goto done; + } nmp->nm_state |= NFSSTA_MNTD; error = nfs_clientd(nmp, td->td_proc->p_ucred, &ncd, uap->flag, uap->argp, td); } else if (uap->flag & NFSSVC_ADDSOCK) { error = copyin(uap->argp, (caddr_t)&nfsdarg, sizeof(nfsdarg)); if (error) - return (error); + goto done; error = holdsock(td->td_proc->p_fd, nfsdarg.sock, &fp); if (error) - return (error); + goto done; /* * Get the client address for connected sockets. */ @@ -201,7 +206,7 @@ sys_nfssvc(struct nfssvc_args *uap) nfsdarg.namelen); if (error) { fdrop(fp); - return (error); + goto done; } } error = nfssvc_addsock(fp, nam, td); @@ -209,7 +214,7 @@ sys_nfssvc(struct nfssvc_args *uap) } else { error = copyin(uap->argp, (caddr_t)nsd, sizeof (*nsd)); if (error) - return (error); + goto done; if ((uap->flag & NFSSVC_AUTHIN) && ((nfsd = nsd->nsd_nfsd)) != NULL && (nfsd->nfsd_slp->ns_flag & SLP_VALID)) { @@ -301,6 +306,8 @@ sys_nfssvc(struct nfssvc_args *uap) #endif /* NFS_NOSERVER */ if (error == EINTR || error == ERESTART) error = 0; +done: + rel_mplock(); return (error); } diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index 0f7df62b3c..3cf36ae7a0 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -105,7 +105,9 @@ vmmapentry_rsrc_init(void *dummy) max_proc_mmap /= 100; } -/* ARGSUSED */ +/* + * MPSAFE + */ int sys_sbrk(struct sbrk_args *uap) { @@ -115,8 +117,9 @@ sys_sbrk(struct sbrk_args *uap) /* * sstk_args(int incr) + * + * MPSAFE */ -/* ARGSUSED */ int sys_sstk(struct sstk_args *uap) { @@ -419,20 +422,27 @@ done: return (error); } +/* + * MPALMOSTSAFE + */ int sys_mmap(struct mmap_args *uap) { int error; + get_mplock(); error = kern_mmap(curproc->p_vmspace, uap->addr, uap->len, uap->prot, uap->flags, uap->fd, uap->pos, &uap->sysmsg_resultp); + rel_mplock(); return (error); } /* * msync_args(void *addr, size_t len, int flags) + * + * MPALMOSTSAFE */ int sys_msync(struct msync_args *uap) @@ -462,6 +472,7 @@ sys_msync(struct msync_args *uap) if ((flags & (MS_ASYNC|MS_INVALIDATE)) == (MS_ASYNC|MS_INVALIDATE)) return (EINVAL); + get_mplock(); map = &p->p_vmspace->vm_map; /* @@ -476,18 +487,23 @@ sys_msync(struct msync_args *uap) vm_map_lock_read(map); rv = vm_map_lookup_entry(map, addr, &entry); - vm_map_unlock_read(map); - if (rv == FALSE) - return (EINVAL); + if (rv == FALSE) { + vm_map_unlock_read(map); + rv = KERN_INVALID_ADDRESS; + goto done; + } addr = entry->start; size = entry->end - entry->start; + vm_map_unlock_read(map); } /* * Clean the pages and interpret the return value. */ rv = vm_map_clean(map, addr, addr + size, (flags & MS_ASYNC) == 0, - (flags & MS_INVALIDATE) != 0); + (flags & MS_INVALIDATE) != 0); +done: + rel_mplock(); switch (rv) { case KERN_SUCCESS: @@ -505,6 +521,8 @@ sys_msync(struct msync_args *uap) /* * munmap_args(void *addr, size_t len) + * + * MPALMOSTSAFE */ int sys_munmap(struct munmap_args *uap) @@ -539,19 +557,26 @@ sys_munmap(struct munmap_args *uap) return (EINVAL); if (VM_MIN_USER_ADDRESS > 0 && addr < VM_MIN_USER_ADDRESS) return (EINVAL); + + get_mplock(); map = &p->p_vmspace->vm_map; /* * Make sure entire range is allocated. */ - if (!vm_map_check_protection(map, addr, addr + size, VM_PROT_NONE)) + if (!vm_map_check_protection(map, addr, addr + size, VM_PROT_NONE)) { + rel_mplock(); return (EINVAL); + } /* returns nothing but KERN_SUCCESS anyway */ vm_map_remove(map, addr, addr + size); + rel_mplock(); return (0); } /* * mprotect_args(const void *addr, size_t len, int prot) + * + * MPALMOSTSAFE */ int sys_mprotect(struct mprotect_args *uap) @@ -561,6 +586,7 @@ sys_mprotect(struct mprotect_args *uap) vm_offset_t tmpaddr; vm_size_t size, pageoff; vm_prot_t prot; + int error; addr = (vm_offset_t) uap->addr; size = uap->len; @@ -580,18 +606,27 @@ sys_mprotect(struct mprotect_args *uap) if (tmpaddr < addr) /* wrap */ return(EINVAL); - switch (vm_map_protect(&p->p_vmspace->vm_map, addr, addr + size, prot, - FALSE)) { + get_mplock(); + switch (vm_map_protect(&p->p_vmspace->vm_map, addr, addr + size, + prot, FALSE)) { case KERN_SUCCESS: - return (0); + error = 0; + break; case KERN_PROTECTION_FAILURE: - return (EACCES); + error = EACCES; + break; + default: + error = EINVAL; + break; } - return (EINVAL); + rel_mplock(); + return (error); } /* * minherit_args(void *addr, size_t len, int inherit) + * + * MPALMOSTSAFE */ int sys_minherit(struct minherit_args *uap) @@ -601,6 +636,7 @@ sys_minherit(struct minherit_args *uap) vm_offset_t tmpaddr; vm_size_t size, pageoff; vm_inherit_t inherit; + int error; addr = (vm_offset_t)uap->addr; size = uap->len; @@ -616,26 +652,36 @@ sys_minherit(struct minherit_args *uap) if (tmpaddr < addr) /* wrap */ return(EINVAL); - switch (vm_map_inherit(&p->p_vmspace->vm_map, addr, addr+size, - inherit)) { + get_mplock(); + + switch (vm_map_inherit(&p->p_vmspace->vm_map, addr, + addr + size, inherit)) { case KERN_SUCCESS: - return (0); + error = 0; + break; case KERN_PROTECTION_FAILURE: - return (EACCES); + error = EACCES; + break; + default: + error = EINVAL; + break; } - return (EINVAL); + rel_mplock(); + return (error); } /* * madvise_args(void *addr, size_t len, int behav) + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_madvise(struct madvise_args *uap) { struct proc *p = curproc; vm_offset_t start, end; vm_offset_t tmpaddr = (vm_offset_t)uap->addr + uap->len; + int error; /* * Check for illegal behavior @@ -659,21 +705,26 @@ sys_madvise(struct madvise_args *uap) */ start = trunc_page((vm_offset_t)uap->addr); end = round_page(tmpaddr); - - return (vm_map_madvise(&p->p_vmspace->vm_map, start, end, - uap->behav, 0)); + + get_mplock(); + error = vm_map_madvise(&p->p_vmspace->vm_map, start, end, + uap->behav, 0); + rel_mplock(); + return (error); } /* * mcontrol_args(void *addr, size_t len, int behav, off_t value) + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_mcontrol(struct mcontrol_args *uap) { struct proc *p = curproc; vm_offset_t start, end; vm_offset_t tmpaddr = (vm_offset_t)uap->addr + uap->len; + int error; /* * Check for illegal behavior @@ -698,15 +749,19 @@ sys_mcontrol(struct mcontrol_args *uap) start = trunc_page((vm_offset_t)uap->addr); end = round_page(tmpaddr); - return (vm_map_madvise(&p->p_vmspace->vm_map, start, end, - uap->behav, uap->value)); + get_mplock(); + error = vm_map_madvise(&p->p_vmspace->vm_map, start, end, + uap->behav, uap->value); + rel_mplock(); + return (error); } /* * mincore_args(const void *addr, size_t len, char *vec) + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_mincore(struct mincore_args *uap) { @@ -742,6 +797,7 @@ sys_mincore(struct mincore_args *uap) map = &p->p_vmspace->vm_map; pmap = vmspace_pmap(p->p_vmspace); + get_mplock(); vm_map_lock_read(map); RestartScan: timestamp = map->timestamp; @@ -847,7 +903,8 @@ RestartScan: while((lastvecindex + 1) < vecindex) { error = subyte( vec + lastvecindex, 0); if (error) { - return (EFAULT); + error = EFAULT; + goto done; } ++lastvecindex; } @@ -857,7 +914,8 @@ RestartScan: */ error = subyte( vec + vecindex, mincoreinfo); if (error) { - return (EFAULT); + error = EFAULT; + goto done; } /* @@ -886,7 +944,8 @@ RestartScan: while((lastvecindex + 1) < vecindex) { error = subyte( vec + lastvecindex, 0); if (error) { - return (EFAULT); + error = EFAULT; + goto done; } ++lastvecindex; } @@ -900,11 +959,16 @@ RestartScan: goto RestartScan; vm_map_unlock_read(map); - return (0); + error = 0; +done: + rel_mplock(); + return (error); } /* * mlock_args(const void *addr, size_t len) + * + * MPALMOSTSAFE */ int sys_mlock(struct mlock_args *uap) @@ -912,8 +976,8 @@ sys_mlock(struct mlock_args *uap) vm_offset_t addr; vm_offset_t tmpaddr; vm_size_t size, pageoff; - int error; struct proc *p = curproc; + int error; addr = (vm_offset_t) uap->addr; size = uap->len; @@ -931,22 +995,31 @@ sys_mlock(struct mlock_args *uap) if (atop(size) + vmstats.v_wire_count > vm_page_max_wired) return (EAGAIN); + get_mplock(); #ifdef pmap_wired_count if (size + ptoa(pmap_wired_count(vm_map_pmap(&p->p_vmspace->vm_map))) > - p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur) + p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur) { + rel_mplock(); return (ENOMEM); + } #else error = priv_check_cred(p->p_ucred, PRIV_ROOT, 0); - if (error) + if (error) { + rel_mplock(); return (error); + } #endif - error = vm_map_unwire(&p->p_vmspace->vm_map, addr, addr + size, FALSE); + rel_mplock(); return (error == KERN_SUCCESS ? 0 : ENOMEM); } /* * mlockall_args(int how) + * + * Dummy routine, doesn't actually do anything. + * + * MPSAFE */ int sys_mlockall(struct mlockall_args *uap) @@ -956,6 +1029,10 @@ sys_mlockall(struct mlockall_args *uap) /* * munlockall_args(void) + * + * Dummy routine, doesn't actually do anything. + * + * MPSAFE */ int sys_munlockall(struct munlockall_args *uap) @@ -965,6 +1042,8 @@ sys_munlockall(struct munlockall_args *uap) /* * munlock_args(const void *addr, size_t len) + * + * MPALMOSTSAFE */ int sys_munlock(struct munlock_args *uap) @@ -994,7 +1073,9 @@ sys_munlock(struct munlock_args *uap) return (error); #endif + get_mplock(); error = vm_map_unwire(&p->p_vmspace->vm_map, addr, addr + size, TRUE); + rel_mplock(); return (error == KERN_SUCCESS ? 0 : ENOMEM); } diff --git a/sys/vm/vm_swap.c b/sys/vm/vm_swap.c index dd30a4d0d8..4acef177d7 100644 --- a/sys/vm/vm_swap.c +++ b/sys/vm/vm_swap.c @@ -169,8 +169,9 @@ VNODEOP_SET(swapdev_vnode_vops); * System call swapon(name) enables swapping on device name, * which must be in the swdevsw. Return EBUSY * if already swapping on this device. + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_swapon(struct swapon_args *uap) { @@ -188,6 +189,7 @@ sys_swapon(struct swapon_args *uap) if (error) return (error); + get_mplock(); vp = NULL; error = nlookup_init(&nd, uap->name, UIO_USERSPACE, NLC_FOLLOW); if (error == 0) @@ -195,22 +197,24 @@ sys_swapon(struct swapon_args *uap) if (error == 0) error = cache_vref(&nd.nl_nch, nd.nl_cred, &vp); nlookup_done(&nd); - if (error) + if (error) { + rel_mplock(); return (error); + } - if (vn_isdisk(vp, &error)) + if (vn_isdisk(vp, &error)) { error = swaponvp(td, vp, 0); - else if (vp->v_type == VREG && vp->v_tag == VT_NFS && - (error = VOP_GETATTR(vp, &attr)) == 0) { + } else if (vp->v_type == VREG && vp->v_tag == VT_NFS && + (error = VOP_GETATTR(vp, &attr)) == 0) { /* * Allow direct swapping to NFS regular files in the same * way that nfs_mountroot() sets up diskless swapping. */ error = swaponvp(td, vp, attr.va_size / DEV_BSIZE); } - if (error) vrele(vp); + rel_mplock(); return (error); } diff --git a/sys/vm/vm_unix.c b/sys/vm/vm_unix.c index 550644a8bd..a5658f66cf 100644 --- a/sys/vm/vm_unix.c +++ b/sys/vm/vm_unix.c @@ -58,8 +58,9 @@ /* * obreak_args(char *nsize) + * + * MPALMOSTSAFE */ -/* ARGSUSED */ int sys_obreak(struct obreak_args *uap) { @@ -67,35 +68,47 @@ sys_obreak(struct obreak_args *uap) struct vmspace *vm = p->p_vmspace; vm_offset_t new, old, base; int rv; + int error; + + error = 0; + get_mplock(); base = round_page((vm_offset_t) vm->vm_daddr); new = round_page((vm_offset_t)uap->nsize); old = base + ctob(vm->vm_dsize); + if (new > base) { /* * We check resource limits here, but alow processes to * reduce their usage, even if they remain over the limit. */ if (new > old && - (new - base) > (vm_offset_t) p->p_rlimit[RLIMIT_DATA].rlim_cur) - return ENOMEM; - if (new >= VM_MAX_USER_ADDRESS) - return (ENOMEM); + (new - base) > (vm_offset_t) p->p_rlimit[RLIMIT_DATA].rlim_cur) { + error = ENOMEM; + goto done; + } + if (new >= VM_MAX_USER_ADDRESS) { + error = ENOMEM; + goto done; + } } else if (new < base) { /* * This is simply an invalid value. If someone wants to * do fancy address space manipulations, mmap and munmap * can do most of what the user would want. */ - return EINVAL; + error = EINVAL; + goto done; } if (new > old) { vm_size_t diff; diff = new - old; - if (vm->vm_map.size + diff > p->p_rlimit[RLIMIT_VMEM].rlim_cur) - return(ENOMEM); + if (vm->vm_map.size + diff > p->p_rlimit[RLIMIT_VMEM].rlim_cur) { + error = ENOMEM; + goto done; + } rv = vm_map_find(&vm->vm_map, NULL, 0, &old, diff, FALSE, @@ -103,15 +116,19 @@ sys_obreak(struct obreak_args *uap) VM_PROT_ALL, VM_PROT_ALL, 0); if (rv != KERN_SUCCESS) { - return (ENOMEM); + error = ENOMEM; + goto done; } vm->vm_dsize += btoc(diff); } else if (new < old) { rv = vm_map_remove(&vm->vm_map, new, old); if (rv != KERN_SUCCESS) { - return (ENOMEM); + error = ENOMEM; + goto done; } vm->vm_dsize -= btoc(old - new); } - return (0); +done: + rel_mplock(); + return (error); } diff --git a/sys/vm/vm_vmspace.c b/sys/vm/vm_vmspace.c index 397f2f36ab..6d97b0eda4 100644 --- a/sys/vm/vm_vmspace.c +++ b/sys/vm/vm_vmspace.c @@ -71,12 +71,15 @@ static MALLOC_DEFINE(M_VKERNEL, "vkernel", "VKernel structures"); * The vmspace starts out completely empty. Memory may be mapped into the * VMSPACE with vmspace_mmap() and MAP_VPAGETABLE section(s) controlled * with vmspace_mcontrol(). + * + * MPALMOSTSAFE */ int sys_vmspace_create(struct vmspace_create_args *uap) { struct vmspace_entry *ve; struct vkernel_proc *vkp; + int error; if (vkernel_enable == 0) return (EOPNOTSUPP); @@ -85,6 +88,7 @@ sys_vmspace_create(struct vmspace_create_args *uap) * Create a virtual kernel side-structure for the process if one * does not exist. */ + get_mplock(); if ((vkp = curproc->p_vkernel) == NULL) { vkp = kmalloc(sizeof(*vkp), M_VKERNEL, M_WAITOK|M_ZERO); vkp->refs = 1; @@ -95,36 +99,56 @@ sys_vmspace_create(struct vmspace_create_args *uap) /* * Create a new VMSPACE + * + * XXX race if kmalloc blocks */ - if (vkernel_find_vmspace(vkp, uap->id)) - return (EEXIST); + if (vkernel_find_vmspace(vkp, uap->id)) { + error = EEXIST; + goto done; + } ve = kmalloc(sizeof(struct vmspace_entry), M_VKERNEL, M_WAITOK|M_ZERO); ve->vmspace = vmspace_alloc(VM_MIN_USER_ADDRESS, VM_MAX_USER_ADDRESS); ve->id = uap->id; pmap_pinit2(vmspace_pmap(ve->vmspace)); RB_INSERT(vmspace_rb_tree, &vkp->root, ve); - return (0); + error = 0; +done: + rel_mplock(); + return (error); } /* * vmspace_destroy (void *id) * * Destroy a VMSPACE. + * + * MPALMOSTSAFE */ int sys_vmspace_destroy(struct vmspace_destroy_args *uap) { struct vkernel_proc *vkp; struct vmspace_entry *ve; + int error; - if ((vkp = curproc->p_vkernel) == NULL) - return (EINVAL); - if ((ve = vkernel_find_vmspace(vkp, uap->id)) == NULL) - return (ENOENT); - if (ve->refs) - return (EBUSY); + get_mplock(); + if ((vkp = curproc->p_vkernel) == NULL) { + error = EINVAL; + goto done; + } + if ((ve = vkernel_find_vmspace(vkp, uap->id)) == NULL) { + error = ENOENT; + goto done; + } + if (ve->refs) { + error = EBUSY; + goto done; + } vmspace_entry_delete(ve, vkp); - return(0); + error = 0; +done: + rel_mplock(); + return(error); } /* @@ -134,6 +158,8 @@ sys_vmspace_destroy(struct vmspace_destroy_args *uap) * Transfer control to a VMSPACE. Control is returned after the specified * number of microseconds or if a page fault, signal, trap, or system call * occurs. The context is updated as appropriate. + * + * MPALMOSTSAFE */ int sys_vmspace_ctl(struct vmspace_ctl_args *uap) @@ -149,17 +175,23 @@ sys_vmspace_ctl(struct vmspace_ctl_args *uap) lp = curthread->td_lwp; p = lp->lwp_proc; - if ((vkp = p->p_vkernel) == NULL) - return (EINVAL); - if ((ve = vkernel_find_vmspace(vkp, uap->id)) == NULL) - return (ENOENT); + get_mplock(); + if ((vkp = p->p_vkernel) == NULL) { + error = EINVAL; + goto done; + } + if ((ve = vkernel_find_vmspace(vkp, uap->id)) == NULL) { + error = ENOENT; + goto done; + } /* * Signal mailbox interlock */ if (p->p_flag & P_MAILBOX) { p->p_flag &= ~P_MAILBOX; - return (EINTR); + error = EINTR; + goto done; } switch(uap->cmd) { @@ -206,6 +238,8 @@ sys_vmspace_ctl(struct vmspace_ctl_args *uap) error = EOPNOTSUPP; break; } +done: + rel_mplock(); return(error); } @@ -215,6 +249,8 @@ sys_vmspace_ctl(struct vmspace_ctl_args *uap) * map memory within a VMSPACE. This function is just like a normal mmap() * but operates on the vmspace's memory map. Most callers use this to create * a MAP_VPAGETABLE mapping. + * + * MPALMOSTSAFE */ int sys_vmspace_mmap(struct vmspace_mmap_args *uap) @@ -223,13 +259,20 @@ sys_vmspace_mmap(struct vmspace_mmap_args *uap) struct vmspace_entry *ve; int error; - if ((vkp = curproc->p_vkernel) == NULL) - return (EINVAL); - if ((ve = vkernel_find_vmspace(vkp, uap->id)) == NULL) - return (ENOENT); + get_mplock(); + if ((vkp = curproc->p_vkernel) == NULL) { + error = EINVAL; + goto done; + } + if ((ve = vkernel_find_vmspace(vkp, uap->id)) == NULL) { + error = ENOENT; + goto done; + } error = kern_mmap(ve->vmspace, uap->addr, uap->len, uap->prot, uap->flags, uap->fd, uap->offset, &uap->sysmsg_resultp); +done: + rel_mplock(); return (error); } @@ -237,6 +280,8 @@ sys_vmspace_mmap(struct vmspace_mmap_args *uap) * vmspace_munmap(id, addr, len) * * unmap memory within a VMSPACE. + * + * MPALMOSTSAFE */ int sys_vmspace_munmap(struct vmspace_munmap_args *uap) @@ -247,11 +292,17 @@ sys_vmspace_munmap(struct vmspace_munmap_args *uap) vm_offset_t tmpaddr; vm_size_t size, pageoff; vm_map_t map; + int error; - if ((vkp = curproc->p_vkernel) == NULL) - return (EINVAL); - if ((ve = vkernel_find_vmspace(vkp, uap->id)) == NULL) - return (ENOENT); + get_mplock(); + if ((vkp = curproc->p_vkernel) == NULL) { + error = EINVAL; + goto done; + } + if ((ve = vkernel_find_vmspace(vkp, uap->id)) == NULL) { + error = ENOENT; + goto done; + } /* * Copied from sys_munmap() @@ -263,23 +314,38 @@ sys_vmspace_munmap(struct vmspace_munmap_args *uap) addr -= pageoff; size += pageoff; size = (vm_size_t)round_page(size); - if (size < uap->len) /* wrap */ - return (EINVAL); + if (size < uap->len) { /* wrap */ + error = EINVAL; + goto done; + } tmpaddr = addr + size; /* workaround gcc4 opt */ - if (tmpaddr < addr) /* wrap */ - return (EINVAL); - if (size == 0) - return (0); - - if (VM_MAX_USER_ADDRESS > 0 && tmpaddr > VM_MAX_USER_ADDRESS) - return (EINVAL); - if (VM_MIN_USER_ADDRESS > 0 && addr < VM_MIN_USER_ADDRESS) - return (EINVAL); + if (tmpaddr < addr) { /* wrap */ + error = EINVAL; + goto done; + } + if (size == 0) { + error = 0; + goto done; + } + + if (VM_MAX_USER_ADDRESS > 0 && tmpaddr > VM_MAX_USER_ADDRESS) { + error = EINVAL; + goto done; + } + if (VM_MIN_USER_ADDRESS > 0 && addr < VM_MIN_USER_ADDRESS) { + error = EINVAL; + goto done; + } map = &ve->vmspace->vm_map; - if (!vm_map_check_protection(map, addr, tmpaddr, VM_PROT_NONE)) - return (EINVAL); + if (!vm_map_check_protection(map, addr, tmpaddr, VM_PROT_NONE)) { + error = EINVAL; + goto done; + } vm_map_remove(map, addr, addr + size); - return (0); + error = 0; +done: + rel_mplock(); + return (error); } /* @@ -289,18 +355,31 @@ sys_vmspace_munmap(struct vmspace_munmap_args *uap) * -1 if an unrecoverable error occured. If the number of bytes read is * less then the request size, a page fault occured in the VMSPACE which * the caller must resolve in order to proceed. + * + * (not implemented yet) + * + * MPALMOSTSAFE */ int sys_vmspace_pread(struct vmspace_pread_args *uap) { struct vkernel_proc *vkp; struct vmspace_entry *ve; + int error; - if ((vkp = curproc->p_vkernel) == NULL) - return (EINVAL); - if ((ve = vkernel_find_vmspace(vkp, uap->id)) == NULL) - return (ENOENT); - return (EINVAL); + get_mplock(); + if ((vkp = curproc->p_vkernel) == NULL) { + error = EINVAL; + goto done; + } + if ((ve = vkernel_find_vmspace(vkp, uap->id)) == NULL) { + error = ENOENT; + goto done; + } + error = EINVAL; +done: + rel_mplock(); + return (error); } /* @@ -310,24 +389,39 @@ sys_vmspace_pread(struct vmspace_pread_args *uap) * -1 if an unrecoverable error occured. If the number of bytes written is * less then the request size, a page fault occured in the VMSPACE which * the caller must resolve in order to proceed. + * + * (not implemented yet) + * + * MPALMOSTSAFE */ int sys_vmspace_pwrite(struct vmspace_pwrite_args *uap) { struct vkernel_proc *vkp; struct vmspace_entry *ve; + int error; - if ((vkp = curproc->p_vkernel) == NULL) - return (EINVAL); - if ((ve = vkernel_find_vmspace(vkp, uap->id)) == NULL) - return (ENOENT); - return (EINVAL); + get_mplock(); + if ((vkp = curproc->p_vkernel) == NULL) { + error = EINVAL; + goto done; + } + if ((ve = vkernel_find_vmspace(vkp, uap->id)) == NULL) { + error = ENOENT; + goto done; + } + error = EINVAL; +done: + rel_mplock(); + return (error); } /* * vmspace_mcontrol(id, addr, len, behav, value) * * madvise/mcontrol support for a vmspace. + * + * MPALMOSTSAFE */ int sys_vmspace_mcontrol(struct vmspace_mcontrol_args *uap) @@ -336,30 +430,47 @@ sys_vmspace_mcontrol(struct vmspace_mcontrol_args *uap) struct vmspace_entry *ve; vm_offset_t start, end; vm_offset_t tmpaddr = (vm_offset_t)uap->addr + uap->len; + int error; - if ((vkp = curproc->p_vkernel) == NULL) - return (EINVAL); - if ((ve = vkernel_find_vmspace(vkp, uap->id)) == NULL) - return (ENOENT); + get_mplock(); + if ((vkp = curproc->p_vkernel) == NULL) { + error = EINVAL; + goto done; + } + if ((ve = vkernel_find_vmspace(vkp, uap->id)) == NULL) { + error = ENOENT; + goto done; + } /* * This code is basically copied from sys_mcontrol() */ - if (uap->behav < 0 || uap->behav > MADV_CONTROL_END) - return (EINVAL); + if (uap->behav < 0 || uap->behav > MADV_CONTROL_END) { + error = EINVAL; + goto done; + } - if (tmpaddr < (vm_offset_t)uap->addr) - return (EINVAL); - if (VM_MAX_USER_ADDRESS > 0 && tmpaddr > VM_MAX_USER_ADDRESS) - return (EINVAL); - if (VM_MIN_USER_ADDRESS > 0 && uap->addr < VM_MIN_USER_ADDRESS) - return (EINVAL); + if (tmpaddr < (vm_offset_t)uap->addr) { + error = EINVAL; + goto done; + } + if (VM_MAX_USER_ADDRESS > 0 && tmpaddr > VM_MAX_USER_ADDRESS) { + error = EINVAL; + goto done; + } + if (VM_MIN_USER_ADDRESS > 0 && uap->addr < VM_MIN_USER_ADDRESS) { + error = EINVAL; + goto done; + } start = trunc_page((vm_offset_t) uap->addr); end = round_page(tmpaddr); - return (vm_map_madvise(&ve->vmspace->vm_map, start, end, - uap->behav, uap->value)); + error = vm_map_madvise(&ve->vmspace->vm_map, start, end, + uap->behav, uap->value); +done: + rel_mplock(); + return (error); } /* -- 2.11.4.GIT