Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Applied security patches:

FreeBSD-SA-06:07
FreeBSD-SA-06:08
FreeBSD-SA-06:10
FreeBSD-SA-06:14
FreeBSD-SA-06:16
  • Loading branch information...
commit 40d4ded889a2309f2ae7adb762d8367a5b317ec1 1 parent ec03f3b
t-momose authored
View
110 freebsd5/sys/amd64/amd64/fpu.c
@@ -11,10 +11,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/fpu.c,v 1.147 2003/12/06 23:19:47 peter Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/fpu.c,v 1.154.2.1 2005/02/05 01:02:48 das Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -51,7 +47,6 @@ __FBSDID("$FreeBSD: src/sys/amd64/amd64/fpu.c,v 1.147 2003/12/06 23:19:47 peter
#include <machine/bus.h>
#include <sys/rman.h>
#include <sys/signalvar.h>
-#include <sys/user.h>
#include <machine/cputypes.h>
#include <machine/frame.h>
@@ -77,6 +72,7 @@ __FBSDID("$FreeBSD: src/sys/amd64/amd64/fpu.c,v 1.147 2003/12/06 23:19:47 peter
#define fnstsw(addr) __asm __volatile("fnstsw %0" : "=m" (*(addr)))
#define fxrstor(addr) __asm("fxrstor %0" : : "m" (*(addr)))
#define fxsave(addr) __asm __volatile("fxsave %0" : "=m" (*(addr)))
+#define ldmxcsr(r) __asm __volatile("ldmxcsr %0" : : "m" (r))
#define start_emulating() __asm("smsw %%ax; orb %0,%%al; lmsw %%ax" \
: : "n" (CR0_TS) : "ax")
#define stop_emulating() __asm("clts")
@@ -100,6 +96,8 @@ void stop_emulating(void);
typedef u_char bool_t;
+static void fpu_clean_state(void);
+
int hw_float = 1;
SYSCTL_INT(_hw,HW_FLOATINGPT, floatingpoint,
CTLFLAG_RD, &hw_float, 0,
@@ -112,28 +110,24 @@ static bool_t fpu_cleanstate_ready;
* Initialize floating point unit.
*/
void
-fpuinit()
+fpuinit(void)
{
register_t savecrit;
+ u_int mxcsr;
u_short control;
- /*
- * fpusave() initializes the fpu and sets fpcurthread = NULL
- */
savecrit = intr_disable();
- fpusave(&fpu_cleanstate); /* XXX borrow for now */
+ PCPU_SET(fpcurthread, 0);
stop_emulating();
- /* XXX fpusave() doesn't actually initialize the fpu in the SSE case. */
fninit();
control = __INITIAL_FPUCW__;
fldcw(&control);
- start_emulating();
- intr_restore(savecrit);
-
- savecrit = intr_disable();
- stop_emulating();
+ mxcsr = __INITIAL_MXCSR__;
+ ldmxcsr(mxcsr);
fxsave(&fpu_cleanstate);
start_emulating();
+ bzero(fpu_cleanstate.sv_fp, sizeof(fpu_cleanstate.sv_fp));
+ bzero(fpu_cleanstate.sv_xmm, sizeof(fpu_cleanstate.sv_xmm));
fpu_cleanstate_ready = 1;
intr_restore(savecrit);
}
@@ -147,8 +141,12 @@ fpuexit(struct thread *td)
register_t savecrit;
savecrit = intr_disable();
- if (curthread == PCPU_GET(fpcurthread))
- fpusave(&PCPU_GET(curpcb)->pcb_save);
+ if (curthread == PCPU_GET(fpcurthread)) {
+ stop_emulating();
+ fxsave(&PCPU_GET(curpcb)->pcb_save);
+ start_emulating();
+ PCPU_SET(fpcurthread, 0);
+ }
intr_restore(savecrit);
}
@@ -389,7 +387,6 @@ fpudna()
{
struct pcb *pcb;
register_t s;
- u_short control;
if (PCPU_GET(fpcurthread) == curthread) {
printf("fpudna: fpcurthread == curthread %d times\n",
@@ -412,52 +409,23 @@ fpudna()
PCPU_SET(fpcurthread, curthread);
pcb = PCPU_GET(curpcb);
+ fpu_clean_state();
+
if ((pcb->pcb_flags & PCB_FPUINITDONE) == 0) {
/*
- * This is the first time this thread has used the FPU or
- * the PCB doesn't contain a clean FPU state. Explicitly
- * initialize the FPU and load the default control word.
+ * This is the first time this thread has used the FPU,
+ * explicitly load sanitized registers.
*/
- fninit();
- control = __INITIAL_FPUCW__;
- fldcw(&control);
+ fxrstor(&fpu_cleanstate);
pcb->pcb_flags |= PCB_FPUINITDONE;
- } else {
- /*
- * The following frstor may cause a trap when the state
- * being restored has a pending error. The error will
- * appear to have been triggered by the current (fpu) user
- * instruction even when that instruction is a no-wait
- * instruction that should not trigger an error (e.g.,
- * instructions are broken the same as frstor, so our
- * treatment does not amplify the breakage.
- */
+ } else
fxrstor(&pcb->pcb_save);
- }
intr_restore(s);
return (1);
}
/*
- * Wrapper for fnsave instruction.
- *
- * fpusave() must be called with interrupts disabled, so that it clears
- * fpcurthread atomically with saving the state. We require callers to do the
- * disabling, since most callers need to disable interrupts anyway to call
- * fpusave() atomically with checking fpcurthread.
- */
-void
-fpusave(struct savefpu *addr)
-{
-
- stop_emulating();
- fxsave(addr);
- start_emulating();
- PCPU_SET(fpcurthread, NULL);
-}
-
-/*
* This should be called with interrupts disabled and only when the owning
* FPU thread is non-null.
*/
@@ -510,6 +478,7 @@ fpusetregs(struct thread *td, struct savefpu *addr)
s = intr_disable();
if (td == PCPU_GET(fpcurthread)) {
+ fpu_clean_state();
fxrstor(addr);
intr_restore(s);
} else {
@@ -520,6 +489,37 @@ fpusetregs(struct thread *td, struct savefpu *addr)
}
/*
+ * On AuthenticAMD processors, the fxrstor instruction does not restore
+ * the x87's stored last instruction pointer, last data pointer, and last
+ * opcode values, except in the rare case in which the exception summary
+ * (ES) bit in the x87 status word is set to 1.
+ *
+ * In order to avoid leaking this information across processes, we clean
+ * these values by performing a dummy load before executing fxrstor().
+ */
+static double dummy_variable = 0.0;
+static void
+fpu_clean_state(void)
+{
+ u_short status;
+
+ /*
+ * Clear the ES bit in the x87 status word if it is currently
+ * set, in order to avoid causing a fault in the upcoming load.
+ */
+ fnstsw(&status);
+ if (status & 0x80)
+ fnclex();
+
+ /*
+ * Load the dummy variable into the x87 stack. This mangles
+ * the x87 stack, but we don't care since we're about to call
+ * fxrstor() anyway.
+ */
+ __asm __volatile("ffree %%st(7); fld %0" : : "m" (dummy_variable));
+}
+
+/*
* This really sucks. We want the acpi version only, but it requires
* the isa_if.h file in order to get the definitions.
*/
View
2  freebsd5/sys/contrib/pf/net/pf_norm.c
@@ -831,7 +831,7 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
} else {
hosed++;
}
- } else {
+ } else if (frp == NULL) {
/* There is a gap between fragments */
DPFPRINTF(("fragcache[%d]: gap %d %d-%d (%d-%d)\n",
h->ip_id, -aftercut, off, max, fra->fr_off,
View
176 freebsd5/sys/fs/smbfs/smbfs_vnops.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 2000-2001 Boris Popov
* All rights reserved.
*
@@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/sys/fs/smbfs/smbfs_vnops.c,v 1.24 2002/09/26 14:07:43 phk Exp $
+ * $FreeBSD: src/sys/fs/smbfs/smbfs_vnops.c,v 1.46.2.1 2005/01/31 23:25:59 imp Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
@@ -42,10 +42,9 @@
#include <sys/mount.h>
#include <sys/unistd.h>
#include <sys/vnode.h>
+#include <sys/limits.h>
#include <sys/lockf.h>
-#include <machine/limits.h>
-
#include <vm/vm.h>
#include <vm/vm_extern.h>
@@ -83,9 +82,7 @@ static int smbfs_strategy(struct vop_strategy_args *);
static int smbfs_print(struct vop_print_args *);
static int smbfs_pathconf(struct vop_pathconf_args *ap);
static int smbfs_advlock(struct vop_advlock_args *);
-#ifndef FB_RELENG3
static int smbfs_getextattr(struct vop_getextattr_args *ap);
-#endif
vop_t **smbfs_vnodeop_p;
static struct vnodeopv_entry_desc smbfs_vnodeop_entries[] = {
@@ -99,9 +96,7 @@ static struct vnodeopv_entry_desc smbfs_vnodeop_entries[] = {
{ &vop_getpages_desc, (vop_t *) smbfs_getpages },
{ &vop_inactive_desc, (vop_t *) smbfs_inactive },
{ &vop_ioctl_desc, (vop_t *) smbfs_ioctl },
- { &vop_islocked_desc, (vop_t *) vop_stdislocked },
{ &vop_link_desc, (vop_t *) smbfs_link },
- { &vop_lock_desc, (vop_t *) vop_stdlock },
{ &vop_lookup_desc, (vop_t *) smbfs_lookup },
{ &vop_mkdir_desc, (vop_t *) smbfs_mkdir },
{ &vop_mknod_desc, (vop_t *) smbfs_mknod },
@@ -118,12 +113,9 @@ static struct vnodeopv_entry_desc smbfs_vnodeop_entries[] = {
{ &vop_setattr_desc, (vop_t *) smbfs_setattr },
{ &vop_strategy_desc, (vop_t *) smbfs_strategy },
{ &vop_symlink_desc, (vop_t *) smbfs_symlink },
- { &vop_unlock_desc, (vop_t *) vop_stdunlock },
{ &vop_write_desc, (vop_t *) smbfs_write },
-#ifndef FB_RELENG3
{ &vop_getextattr_desc, (vop_t *) smbfs_getextattr },
/* { &vop_setextattr_desc, (vop_t *) smbfs_setextattr },*/
-#endif
{ NULL, NULL }
};
@@ -142,10 +134,9 @@ smbfs_access(ap)
} */ *ap;
{
struct vnode *vp = ap->a_vp;
- struct ucred *cred = ap->a_cred;
- u_int mode = ap->a_mode;
+ mode_t mode = ap->a_mode;
+ mode_t mpmode;
struct smbmount *smp = VTOSMBFS(vp);
- int error = 0;
SMBVDEBUG("\n");
if ((mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
@@ -156,15 +147,10 @@ smbfs_access(ap)
break;
}
}
- if (cred->cr_uid == 0)
- return 0;
- if (cred->cr_uid != smp->sm_args.uid) {
- mode >>= 3;
- if (!groupmember(smp->sm_args.gid, cred))
- mode >>= 3;
- }
- error = (((vp->v_type == VREG) ? smp->sm_args.file_mode : smp->sm_args.dir_mode) & mode) == mode ? 0 : EACCES;
- return error;
+ mpmode = vp->v_type == VREG ? smp->sm_args.file_mode :
+ smp->sm_args.dir_mode;
+ return (vaccess(vp->v_type, mpmode, smp->sm_args.uid,
+ smp->sm_args.gid, ap->a_mode, ap->a_cred, NULL));
}
/* ARGSUSED */
@@ -184,13 +170,13 @@ smbfs_open(ap)
int mode = ap->a_mode;
int error, accmode;
- SMBVDEBUG("%s,%d\n", np->n_name, np->n_opencount);
+ SMBVDEBUG("%s,%d\n", np->n_name, (np->n_flag & NOPEN) != 0);
if (vp->v_type != VREG && vp->v_type != VDIR) {
SMBFSERR("open eacces vtype=%d\n", vp->v_type);
return EACCES;
}
if (vp->v_type == VDIR) {
- np->n_opencount++;
+ np->n_flag |= NOPEN;
return 0;
}
if (np->n_flag & NMODIFIED) {
@@ -212,10 +198,8 @@ smbfs_open(ap)
np->n_mtime.tv_sec = vattr.va_mtime.tv_sec;
}
}
- if (np->n_opencount) {
- np->n_opencount++;
+ if ((np->n_flag & NOPEN) != 0)
return 0;
- }
/*
* Use DENYNONE to give unixy semantics of permitting
* everything not forbidden by permissions. Ie denial
@@ -235,49 +219,8 @@ smbfs_open(ap)
error = smbfs_smb_open(np, accmode, &scred);
}
}
- if (!error) {
- np->n_opencount++;
- }
- smbfs_attr_cacheremove(vp);
- return error;
-}
-
-static int
-smbfs_closel(struct vop_close_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct smbnode *np = VTOSMB(vp);
- struct thread *td = ap->a_td;
- struct smb_cred scred;
- struct vattr vattr;
- int error;
-
- SMBVDEBUG("name=%s, pid=%d, c=%d\n",np->n_name, td->td_pid, np->n_opencount);
-
- smb_makescred(&scred, td, ap->a_cred);
-
- if (np->n_opencount == 0) {
- if (vp->v_type != VDIR)
- SMBERROR("Negative opencount\n");
- return 0;
- }
- np->n_opencount--;
- if (vp->v_type == VDIR) {
- if (np->n_opencount)
- return 0;
- if (np->n_dirseq) {
- smbfs_findclose(np->n_dirseq, &scred);
- np->n_dirseq = NULL;
- }
- error = 0;
- } else {
- error = smbfs_vinvalbuf(vp, V_SAVE, ap->a_cred, td, 1);
- if (np->n_opencount)
- return error;
- VOP_GETATTR(vp, &vattr, ap->a_cred, td);
- error = smbfs_smb_close(np->n_mount->sm_share, np->n_fid,
- &np->n_mtime, &scred);
- }
+ if (error == 0)
+ np->n_flag |= NOPEN;
smbfs_attr_cacheremove(vp);
return error;
}
@@ -298,7 +241,9 @@ smbfs_close(ap)
{
struct vnode *vp = ap->a_vp;
struct thread *td = ap->a_td;
- int error, dolock;
+ struct smbnode *np = VTOSMB(vp);
+ struct smb_cred scred;
+ int dolock;
VI_LOCK(vp);
dolock = (vp->v_iflag & VI_XLOCK) == 0;
@@ -306,10 +251,15 @@ smbfs_close(ap)
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY | LK_INTERLOCK, td);
else
VI_UNLOCK(vp);
- error = smbfs_closel(ap);
+ if (vp->v_type == VDIR && (np->n_flag & NOPEN) != 0 &&
+ np->n_dirseq != NULL) {
+ smb_makescred(&scred, td, ap->a_cred);
+ smbfs_findclose(np->n_dirseq, &scred);
+ np->n_dirseq = NULL;
+ }
if (dolock)
VOP_UNLOCK(vp, 0, td);
- return error;
+ return 0;
}
/*
@@ -329,7 +279,7 @@ smbfs_getattr(ap)
struct vattr *va=ap->a_vap;
struct smbfattr fattr;
struct smb_cred scred;
- u_int32_t oldsize;
+ u_quad_t oldsize;
int error;
SMBVDEBUG("%lx: '%s' %d\n", (long)vp, np->n_name, (vp->v_vflag & VV_ROOT) != 0);
@@ -346,7 +296,7 @@ smbfs_getattr(ap)
}
smbfs_attr_cacheenter(vp, &fattr);
smbfs_attr_cachelookup(vp, va);
- if (np->n_opencount)
+ if (np->n_flag & NOPEN)
np->n_size = oldsize;
return 0;
}
@@ -397,7 +347,7 @@ smbfs_setattr(ap)
vnode_pager_setsize(vp, (u_long)vap->va_size);
tsize = np->n_size;
np->n_size = vap->va_size;
- if (np->n_opencount == 0) {
+ if ((np->n_flag & NOPEN) == 0) {
error = smbfs_smb_open(np,
SMB_SM_DENYNONE|SMB_AM_OPENRW,
&scred);
@@ -420,6 +370,11 @@ smbfs_setattr(ap)
if (vap->va_atime.tv_sec != VNOVAL)
atime = &vap->va_atime;
if (mtime != atime) {
+ if (ap->a_cred->cr_uid != VTOSMBFS(vp)->sm_args.uid &&
+ (error = suser_cred(ap->a_cred, SUSER_ALLOWJAIL)) &&
+ ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
+ (error = VOP_ACCESS(vp, VWRITE, ap->a_cred, ap->a_td))))
+ return (error);
#if 0
if (mtime == NULL)
mtime = &np->n_mtime;
@@ -430,9 +385,9 @@ smbfs_setattr(ap)
* If file is opened, then we can use handle based calls.
* If not, use path based ones.
*/
- if (np->n_opencount == 0) {
+ if ((np->n_flag & NOPEN) == 0) {
if (vcp->vc_flags & SMBV_WIN95) {
- error = VOP_OPEN(vp, FWRITE, ap->a_cred, ap->a_td);
+ error = VOP_OPEN(vp, FWRITE, ap->a_cred, ap->a_td, -1);
if (!error) {
/* error = smbfs_smb_setfattrNT(np, 0, mtime, atime, &scred);
VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_td);*/
@@ -579,10 +534,12 @@ smbfs_remove(ap)
struct smb_cred scred;
int error;
- if (vp->v_type == VDIR || np->n_opencount || vrefcnt(vp) != 1)
+ if (vp->v_type == VDIR || (np->n_flag & NOPEN) != 0 || vrefcnt(vp) != 1)
return EPERM;
smb_makescred(&scred, cnp->cn_thread, cnp->cn_cred);
error = smbfs_smb_delete(np, &scred);
+ if (error == 0)
+ np->n_flag |= NGONE;
cache_purge(vp);
return error;
}
@@ -627,8 +584,10 @@ smbfs_rename(ap)
flags |= 2;
} else if (fvp->v_type == VREG) {
flags |= 1;
- } else
- return EINVAL;
+ } else {
+ error = EINVAL;
+ goto out;
+ }
smb_makescred(&scred, tcnp->cn_thread, tcnp->cn_cred);
/*
* It seems that Samba doesn't implement SMB_COM_MOVE call...
@@ -646,7 +605,8 @@ smbfs_rename(ap)
if (tvp && tvp != fvp) {
error = smbfs_smb_delete(VTOSMB(tvp), &scred);
if (error)
- goto out;
+ goto out_cacherem;
+ VTOSMB(fvp)->n_flag |= NGONE;
}
error = smbfs_smb_rename(VTOSMB(fvp), VTOSMB(tdvp),
tcnp->cn_nameptr, tcnp->cn_namelen, &scred);
@@ -657,6 +617,10 @@ smbfs_rename(ap)
cache_purge(tdvp);
cache_purge(fdvp);
}
+
+out_cacherem:
+ smbfs_attr_cacheremove(fdvp);
+ smbfs_attr_cacheremove(tdvp);
out:
if (tdvp == tvp)
vrele(tdvp);
@@ -666,8 +630,6 @@ smbfs_rename(ap)
vput(tvp);
vrele(fdvp);
vrele(fvp);
- smbfs_attr_cacheremove(fdvp);
- smbfs_attr_cacheremove(tdvp);
#ifdef possible_mistake
vgone(fvp);
if (tvp)
@@ -780,6 +742,8 @@ smbfs_rmdir(ap)
smb_makescred(&scred, cnp->cn_thread, cnp->cn_cred);
error = smbfs_smb_rmdir(np, &scred);
+ if (error == 0)
+ np->n_flag |= NGONE;
dnp->n_flag |= NMODIFIED;
smbfs_attr_cacheremove(dvp);
/* cache_purge(dvp);*/
@@ -845,8 +809,8 @@ int smbfs_print (ap)
printf("no smbnode data\n");
return (0);
}
- printf("name = %s, parent = %p, opencount = %d\n", np->n_name,
- np->n_parent ? SMBTOV(np->n_parent) : NULL, np->n_opencount);
+ printf("\tname = %s, parent = %p, open = %d\n", np->n_name,
+ np->n_parent ? np->n_parent : NULL, (np->n_flag & NOPEN) != 0);
return (0);
}
@@ -890,9 +854,9 @@ smbfs_strategy (ap)
struct thread *td;
int error = 0;
+ KASSERT(ap->a_vp == ap->a_bp->b_vp, ("%s(%p != %p)",
+ __func__, ap->a_vp, ap->a_bp->b_vp));
SMBVDEBUG("\n");
- if (bp->b_flags & B_PHYS)
- panic("smbfs physio");
if (bp->b_flags & B_ASYNC)
td = (struct thread *)0;
else
@@ -1074,11 +1038,18 @@ smbfs_advlock(ap)
static int
smbfs_pathcheck(struct smbmount *smp, const char *name, int nmlen, int nameiop)
{
- static const char *badchars = "*/\[]:<>=;?";
- static const char *badchars83 = " +|,";
+ static const char *badchars = "*/:<>;?";
+ static const char *badchars83 = " +|,[]=";
const char *cp;
int i, error;
+ /*
+ * Backslash characters, being a path delimiter, are prohibited
+ * within a path component even for LOOKUP operations.
+ */
+ if (index(name, '\\') != NULL)
+ return ENOENT;
+
if (nameiop == LOOKUP)
return 0;
error = ENOENT;
@@ -1137,6 +1108,7 @@ smbfs_lookup(ap)
int nameiop = cnp->cn_nameiop;
int nmlen = cnp->cn_namelen;
int lockparent, wantparent, error, islastcn, isdot;
+ int killit;
SMBVDEBUG("\n");
cnp->cn_flags &= ~PDIRUNLOCK;
@@ -1206,8 +1178,23 @@ smbfs_lookup(ap)
}
}
if (!error) {
+ killit = 0;
if (vpid == vp->v_id) {
- if (!VOP_GETATTR(vp, &vattr, cnp->cn_cred, td)
+ error = VOP_GETATTR(vp, &vattr, cnp->cn_cred, td);
+ /*
+ * If the file type on the server is inconsistent
+ * with what it was when we created the vnode,
+ * kill the bogus vnode now and fall through to
+ * the code below to create a new one with the
+ * right type.
+ */
+ if (error == 0 &&
+ ((vp->v_type == VDIR &&
+ (VTOSMB(vp)->n_dosattr & SMB_FA_DIR) == 0) ||
+ (vp->v_type == VREG &&
+ (VTOSMB(vp)->n_dosattr & SMB_FA_DIR) != 0)))
+ killit = 1;
+ else if (error == 0
/* && vattr.va_ctime.tv_sec == VTOSMB(vp)->n_ctime*/) {
if (nameiop != LOOKUP && islastcn)
cnp->cn_flags |= SAVENAME;
@@ -1217,6 +1204,8 @@ smbfs_lookup(ap)
cache_purge(vp);
}
vput(vp);
+ if (killit)
+ vgone(vp);
if (lockparent && dvp != vp && islastcn)
VOP_UNLOCK(dvp, 0, td);
}
@@ -1236,7 +1225,8 @@ smbfs_lookup(ap)
smb_makescred(&scred, td, cnp->cn_cred);
fap = &fattr;
if (flags & ISDOTDOT) {
- error = smbfs_smb_lookup(dnp->n_parent, NULL, 0, fap, &scred);
+ error = smbfs_smb_lookup(VTOSMB(dnp->n_parent), NULL, 0, fap,
+ &scred);
SMBVDEBUG("result of dotdot lookup: %d\n", error);
} else {
fap = &fattr;
View
204 freebsd5/sys/i386/isa/npx.c
@@ -11,10 +11,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -32,13 +28,14 @@
* SUCH DAMAGE.
*
* from: @(#)npx.c 7.2 (Berkeley) 5/12/91
- * $FreeBSD: src/sys/i386/isa/npx.c,v 1.136 2002/11/16 06:35:52 deischen Exp $
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/i386/isa/npx.c,v 1.152.2.3 2005/03/29 07:24:38 das Exp $");
+
#include "opt_cpu.h"
#include "opt_debug_npx.h"
#include "opt_isa.h"
-#include "opt_math_emulate.h"
#include "opt_npx.h"
#include <sys/param.h>
@@ -51,6 +48,7 @@
#include <sys/mutex.h>
#include <sys/mutex.h>
#include <sys/proc.h>
+#include <sys/smp.h>
#include <sys/sysctl.h>
#include <machine/bus.h>
#include <sys/rman.h>
@@ -58,33 +56,25 @@
#include <sys/syslog.h>
#endif
#include <sys/signalvar.h>
-#include <sys/user.h>
-#ifndef SMP
#include <machine/asmacros.h>
-#endif
#include <machine/cputypes.h>
#include <machine/frame.h>
#include <machine/md_var.h>
#include <machine/pcb.h>
#include <machine/psl.h>
-#ifndef SMP
#include <machine/clock.h>
-#endif
#include <machine/resource.h>
#include <machine/specialreg.h>
#include <machine/segments.h>
#include <machine/ucontext.h>
-#ifndef SMP
-#include <i386/isa/icu.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
#else
#include <i386/isa/isa.h>
#endif
-#endif
-#include <i386/isa/intr_machdep.h>
+#include <machine/intr_machdep.h>
#ifdef DEV_ISA
#include <isa/isavar.h>
#endif
@@ -104,9 +94,8 @@
#define NPX_DISABLE_I586_OPTIMIZED_BCOPY (1 << 0)
#define NPX_DISABLE_I586_OPTIMIZED_BZERO (1 << 1)
#define NPX_DISABLE_I586_OPTIMIZED_COPYIO (1 << 2)
-#define NPX_PREFER_EMULATOR (1 << 3)
-#if defined(__GNUC__) && !defined(lint)
+#if (defined(__GNUC__) && !defined(lint)) || defined(__INTEL_COMPILER)
#define fldcw(addr) __asm("fldcw %0" : : "m" (*(addr)))
#define fnclex() __asm("fnclex")
@@ -119,12 +108,13 @@
#ifdef CPU_ENABLE_SSE
#define fxrstor(addr) __asm("fxrstor %0" : : "m" (*(addr)))
#define fxsave(addr) __asm __volatile("fxsave %0" : "=m" (*(addr)))
+#define ldmxcsr(__csr) __asm __volatile("ldmxcsr %0" : : "m" (__csr))
#endif
#define start_emulating() __asm("smsw %%ax; orb %0,%%al; lmsw %%ax" \
: : "n" (CR0_TS) : "ax")
#define stop_emulating() __asm("clts")
-#else /* not __GNUC__ */
+#else /* !((__GNUC__ && !lint ) || __INTEL_COMPILER) */
void fldcw(caddr_t addr);
void fnclex(void);
@@ -141,7 +131,7 @@ void fxrstor(caddr_t addr);
void start_emulating(void);
void stop_emulating(void);
-#endif /* __GNUC__ */
+#endif /* (__GNUC__ && !lint ) || __INTEL_COMPILER */
#ifdef CPU_ENABLE_SSE
#define GET_FPU_CW(thread) \
@@ -161,13 +151,15 @@ void stop_emulating(void);
typedef u_char bool_t;
+#ifdef CPU_ENABLE_SSE
+static void fpu_clean_state(void);
+#endif
+
static void fpusave(union savefpu *);
static void fpurstor(union savefpu *);
static int npx_attach(device_t dev);
static void npx_identify(driver_t *driver, device_t parent);
-#ifndef SMP
static void npx_intr(void *);
-#endif
static int npx_probe(device_t dev);
#ifdef I586_CPU_XXX
static long timezero(const char *funcname,
@@ -180,10 +172,8 @@ SYSCTL_INT(_hw,HW_FLOATINGPT, floatingpoint,
CTLFLAG_RD, &hw_float, 0,
"Floatingpoint instructions executed in hardware");
-#ifndef SMP
static volatile u_int npx_intrs_while_probing;
static volatile u_int npx_traps_while_probing;
-#endif
static union savefpu npx_cleanstate;
static bool_t npx_cleanstate_ready;
@@ -191,7 +181,6 @@ static bool_t npx_ex16;
static bool_t npx_exists;
static bool_t npx_irq13;
-#ifndef SMP
alias_for_inthand_t probetrap;
__asm(" \n\
.text \n\
@@ -203,7 +192,6 @@ __asm(" \n\
fnclex \n\
iret \n\
");
-#endif /* SMP */
/*
* Identify routine. Create a connection point on our parent for probing.
@@ -220,7 +208,6 @@ npx_identify(driver, parent)
panic("npx_identify");
}
-#ifndef SMP
/*
* Do minimal handling of npx interrupts to convert them to traps.
*/
@@ -230,9 +217,7 @@ npx_intr(dummy)
{
struct thread *td;
-#ifndef SMP
npx_intrs_while_probing++;
-#endif
/*
* The BUSY# latch must be cleared in all cases so that the next
@@ -260,11 +245,10 @@ npx_intr(dummy)
if (td != NULL) {
td->td_pcb->pcb_flags |= PCB_NPXTRAP;
mtx_lock_spin(&sched_lock);
- td->td_kse->ke_flags |= KEF_ASTPENDING;
+ td->td_flags |= TDF_ASTPENDING;
mtx_unlock_spin(&sched_lock);
}
}
-#endif /* !SMP */
/*
* Probe routine. Initialize cr0 to give correct behaviour for [f]wait
@@ -276,7 +260,6 @@ static int
npx_probe(dev)
device_t dev;
{
-#ifndef SMP
struct gate_descriptor save_idt_npxtrap;
struct resource *ioport_res, *irq_res;
void *irq_cookie;
@@ -284,8 +267,9 @@ npx_probe(dev)
u_short control;
u_short status;
- save_idt_npxtrap = idt[16];
- setidt(16, probetrap, SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
+ save_idt_npxtrap = idt[IDT_MF];
+ setidt(IDT_MF, probetrap, SDT_SYS386TGT, SEL_KPL,
+ GSEL(GCODE_SEL, SEL_KPL));
ioport_rid = 0;
ioport_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &ioport_rid,
IO_NPX, IO_NPX, IO_NPXSIZE, RF_ACTIVE);
@@ -306,7 +290,6 @@ npx_probe(dev)
if (bus_setup_intr(dev, irq_res, INTR_TYPE_MISC | INTR_FAST, npx_intr,
NULL, &irq_cookie) != 0)
panic("npx: can't create intr");
-#endif /* !SMP */
/*
* Partially reset the coprocessor, if any. Some BIOS's don't reset
@@ -347,16 +330,6 @@ npx_probe(dev)
device_set_desc(dev, "math processor");
-#ifdef SMP
-
- /*
- * Exception 16 MUST work for SMP.
- */
- npx_ex16 = hw_float = npx_exists = 1;
- return (0);
-
-#else /* !SMP */
-
/*
* Don't use fwait here because it might hang.
* Don't use fnop here because it usually hangs if there is no FPU.
@@ -399,6 +372,7 @@ npx_probe(dev)
#endif
npx_traps_while_probing = npx_intrs_while_probing = 0;
fp_divide_by_0();
+ DELAY(1000); /* wait for any IRQ13 */
if (npx_traps_while_probing != 0) {
/*
* Good, exception 16 works.
@@ -411,7 +385,11 @@ npx_probe(dev)
* Bad, we are stuck with IRQ13.
*/
npx_irq13 = 1;
- idt[16] = save_idt_npxtrap;
+ idt[IDT_MF] = save_idt_npxtrap;
+#ifdef SMP
+ if (mp_ncpus > 1)
+ panic("npx0 cannot use IRQ 13 on an SMP system");
+#endif
return (0);
}
/*
@@ -424,30 +402,17 @@ npx_probe(dev)
* emulator and say that it has been installed. XXX handle devices
* that aren't really devices better.
*/
+#ifdef SMP
+ if (mp_ncpus > 1)
+ panic("npx0 cannot be emulated on an SMP system");
+#endif
/* FALLTHROUGH */
no_irq13:
- idt[16] = save_idt_npxtrap;
+ idt[IDT_MF] = save_idt_npxtrap;
bus_teardown_intr(dev, irq_res, irq_cookie);
-
- /*
- * XXX hack around brokenness of bus_teardown_intr(). If we left the
- * irq active then we would get it instead of exception 16.
- */
- {
- register_t crit;
-
- crit = intr_disable();
- mtx_lock_spin(&icu_lock);
- INTRDIS(1 << irq_num);
- mtx_unlock_spin(&icu_lock);
- intr_restore(crit);
- }
-
bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res);
bus_release_resource(dev, SYS_RES_IOPORT, ioport_rid, ioport_res);
return (0);
-
-#endif /* SMP */
}
/*
@@ -460,39 +425,15 @@ npx_attach(dev)
int flags;
register_t s;
- if (resource_int_value("npx", 0, "flags", &flags) != 0)
- flags = 0;
+ flags = device_get_flags(dev);
+
+ if (npx_irq13)
+ device_printf(dev, "IRQ 13 interface\n");
+ else if (npx_ex16)
+ device_printf(dev, "INT 16 interface\n");
+ else
+ device_printf(dev, "WARNING: no FPU!\n");
- if (flags)
- device_printf(dev, "flags 0x%x ", flags);
- if (npx_irq13) {
- device_printf(dev, "using IRQ 13 interface\n");
- } else {
-#if defined(MATH_EMULATE) || defined(GPL_MATH_EMULATE)
- if (npx_ex16) {
- if (!(flags & NPX_PREFER_EMULATOR))
- device_printf(dev, "INT 16 interface\n");
- else {
- device_printf(dev, "FPU exists, but flags request "
- "emulator\n");
- hw_float = npx_exists = 0;
- }
- } else if (npx_exists) {
- device_printf(dev, "error reporting broken; using 387 emulator\n");
- hw_float = npx_exists = 0;
- } else
- device_printf(dev, "387 emulator\n");
-#else
- if (npx_ex16) {
- device_printf(dev, "INT 16 interface\n");
- if (flags & NPX_PREFER_EMULATOR) {
- device_printf(dev, "emulator requested, but none compiled "
- "into kernel, using FPU\n");
- }
- } else
- device_printf(dev, "no 387 emulator in kernel and no FPU!\n");
-#endif
- }
npxinit(__INITIAL_NPXCW__);
if (npx_cleanstate_ready == 0) {
@@ -507,12 +448,10 @@ npx_attach(dev)
if (cpu_class == CPUCLASS_586 && npx_ex16 && npx_exists &&
timezero("i586_bzero()", i586_bzero) <
timezero("bzero()", bzero) * 4 / 5) {
- if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BCOPY)) {
+ if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BCOPY))
bcopy_vector = i586_bcopy;
- ovbcopy_vector = i586_bcopy;
- }
if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BZERO))
- bzero = i586_bzero;
+ bzero_vector = i586_bzero;
if (!(flags & NPX_DISABLE_I586_OPTIMIZED_COPYIO)) {
copyin_vector = i586_copyin;
copyout_vector = i586_copyout;
@@ -832,6 +771,9 @@ npxdna()
{
struct pcb *pcb;
register_t s;
+#ifdef CPU_ENABLE_SSE
+ int mxcsr;
+#endif
u_short control;
if (!npx_exists)
@@ -866,6 +808,12 @@ npxdna()
fninit();
control = __INITIAL_NPXCW__;
fldcw(&control);
+#ifdef CPU_ENABLE_SSE
+ if (cpu_fxsr) {
+ mxcsr = __INITIAL_MXCSR__;
+ ldmxcsr(mxcsr);
+ }
+#endif
pcb->pcb_flags |= PCB_NPXINITDONE;
} else {
/*
@@ -933,6 +881,15 @@ npxdrop()
{
struct thread *td;
+ /*
+ * Discard pending exceptions in the !cpu_fxsr case so that unmasked
+ * ones don't cause a panic on the next frstor.
+ */
+#ifdef CPU_ENABLE_SSE
+ if (!cpu_fxsr)
+#endif
+ fnclex();
+
td = PCPU_GET(fpcurthread);
PCPU_SET(fpcurthread, NULL);
td->td_pcb->pcb_flags &= ~PCB_NPXINITDONE;
@@ -960,9 +917,8 @@ npxgetregs(td, addr)
bzero(addr, sizeof(*addr));
return (_MC_FPOWNED_NONE);
}
-
s = intr_disable();
- if (curthread == PCPU_GET(fpcurthread)) {
+ if (td == PCPU_GET(fpcurthread)) {
fpusave(addr);
#ifdef CPU_ENABLE_SSE
if (!cpu_fxsr)
@@ -996,7 +952,11 @@ npxsetregs(td, addr)
return;
s = intr_disable();
- if (curthread == PCPU_GET(fpcurthread)) {
+ if (td == PCPU_GET(fpcurthread)) {
+#ifdef CPU_ENABLE_SSE
+ if (!cpu_fxsr)
+#endif
+ fnclex(); /* As in npxdrop(). */
fpurstor(addr);
intr_restore(s);
} else {
@@ -1019,15 +979,49 @@ fpusave(addr)
fnsave(addr);
}
+#ifdef CPU_ENABLE_SSE
+/*
+ * On AuthenticAMD processors, the fxrstor instruction does not restore
+ * the x87's stored last instruction pointer, last data pointer, and last
+ * opcode values, except in the rare case in which the exception summary
+ * (ES) bit in the x87 status word is set to 1.
+ *
+ * In order to avoid leaking this information across processes, we clean
+ * these values by performing a dummy load before executing fxrstor().
+ */
+static double dummy_variable = 0.0;
+static void
+fpu_clean_state(void)
+{
+ u_short status;
+
+ /*
+ * Clear the ES bit in the x87 status word if it is currently
+ * set, in order to avoid causing a fault in the upcoming load.
+ */
+ fnstsw(&status);
+ if (status & 0x80)
+ fnclex();
+
+ /*
+ * Load the dummy variable into the x87 stack. This mangles
+ * the x87 stack, but we don't care since we're about to call
+ * fxrstor() anyway.
+ */
+ __asm __volatile("ffree %%st(7); fld %0" : : "m" (dummy_variable));
+}
+#endif /* CPU_ENABLE_SSE */
+
static void
fpurstor(addr)
union savefpu *addr;
{
#ifdef CPU_ENABLE_SSE
- if (cpu_fxsr)
+ if (cpu_fxsr) {
+ fpu_clean_state();
fxrstor(addr);
- else
+ } else
#endif
frstor(addr);
}
@@ -1083,13 +1077,13 @@ static driver_t npx_driver = {
static devclass_t npx_devclass;
-#ifdef DEV_ISA
/*
* We prefer to attach to the root nexus so that the usual case (exception 16)
* doesn't describe the processor as being `on isa'.
*/
DRIVER_MODULE(npx, nexus, npx_driver, npx_devclass, 0, 0);
+#ifdef DEV_ISA
/*
* This sucks up the legacy ISA support assignments from PNPBIOS/ACPI.
*/
View
3  freebsd5/sys/netinet/tcp_sack.c
@@ -307,6 +307,7 @@ tcp_sack_option(struct tcpcb *tp, struct tcphdr *th, u_char *cp, int optlen)
tp->snd_numholes = 0;
if (tp->t_maxseg == 0)
panic("tcp_sack_option"); /* Should never happen */
+ next_block:
while (tmp_olen > 0) {
struct sackblk sack;
@@ -396,7 +397,7 @@ tcp_sack_option(struct tcpcb *tp, struct tcphdr *th, u_char *cp, int optlen)
temp = (struct sackhole *)
uma_zalloc(sack_hole_zone,M_NOWAIT);
if (temp == NULL)
- continue; /* ENOBUFS */
+ goto next_block; /* ENOBUFS */
temp->next = cur->next;
temp->start = sack.end;
temp->end = cur->end;
View
98 freebsd5/sys/nfsserver/nfs_srvsock.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 1989, 1991, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -34,11 +30,10 @@
* SUCH DAMAGE.
*
* @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95
- * $FreeBSD: src/sys/nfsserver/nfs_srvsock.c,v 1.79 2002/07/24 14:24:16 rwatson Exp $
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/nfsserver/nfs_srvsock.c,v 1.79 2002/07/24 14:24:16 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/nfsserver/nfs_srvsock.c,v 1.92.2.1 2005/01/31 23:26:47 imp Exp $");
/*
* Socket operations for use by nfs
@@ -97,12 +92,12 @@ SYSCTL_INT(_vfs_nfsrv, OID_AUTO, realign_count, CTLFLAG_RW, &nfs_realign_count,
*/
#define NFS_CWNDSCALE 256
#define NFS_MAXCWND (NFS_CWNDSCALE * 32)
-struct callout_handle nfsrv_timer_handle;
+struct callout nfsrv_callout;
static void nfs_realign(struct mbuf **pm, int hsiz); /* XXX SHARED */
static int nfsrv_getstream(struct nfssvc_sock *, int);
-int (*nfsrv3_procs[NFS_NPROCS])(struct nfsrv_descript *nd,
+int32_t (*nfsrv3_procs[NFS_NPROCS])(struct nfsrv_descript *nd,
struct nfssvc_sock *slp,
struct thread *td,
struct mbuf **mreqp) = {
@@ -145,9 +140,13 @@ nfs_rephead(int siz, struct nfsrv_descript *nd, int err,
caddr_t bpos;
struct mbuf *mb;
+ /* XXXRW: not 100% clear the lock is needed here. */
+ NFSD_LOCK_ASSERT();
+
nd->nd_repstat = err;
if (err && (nd->nd_flag & ND_NFSV3) == 0) /* XXX recheck */
siz = 0;
+ NFSD_UNLOCK();
MGETHDR(mreq, M_TRYWAIT, MT_DATA);
mb = mreq;
/*
@@ -160,6 +159,7 @@ nfs_rephead(int siz, struct nfsrv_descript *nd, int err,
MCLGET(mreq, M_TRYWAIT);
} else
mreq->m_data += min(max_hdr, M_TRAILINGSPACE(mreq));
+ NFSD_LOCK();
tl = mtod(mreq, u_int32_t *);
bpos = ((caddr_t)tl) + mreq->m_len;
*tl++ = txdr_unsigned(nd->nd_retxid);
@@ -241,13 +241,18 @@ nfs_realign(struct mbuf **pm, int hsiz) /* XXX COMMON */
struct mbuf *n = NULL;
int off = 0;
+ /* XXXRW: may not need lock? */
+ NFSD_LOCK_ASSERT();
+
++nfs_realign_test;
while ((m = *pm) != NULL) {
if ((m->m_len & 0x3) || (mtod(m, intptr_t) & 0x3)) {
+ NFSD_UNLOCK();
MGET(n, M_TRYWAIT, MT_DATA);
if (m->m_len >= MINCLSIZE) {
MCLGET(n, M_TRYWAIT);
}
+ NFSD_LOCK();
n->m_len = 0;
break;
}
@@ -286,6 +291,8 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header)
int error = 0;
struct mbuf *mrep, *md;
+ NFSD_LOCK_ASSERT();
+
mrep = nd->nd_mrep;
md = nd->nd_md;
dpos = nd->nd_dpos;
@@ -359,7 +366,7 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header)
* and related calls. Right now, this tramples on any
* extensible data in the ucred, fails to initialize the
* mutex, and worse. This must be fixed before FreeBSD
- * 5.0-RELEASE.
+ * 5.3-RELEASE.
*/
bzero((caddr_t)&nd->nd_cr, sizeof (struct ucred));
nd->nd_cr.cr_ref = 1;
@@ -415,17 +422,31 @@ nfsrv_rcv(struct socket *so, void *arg, int waitflag)
struct uio auio;
int flags, error;
+ /*
+ * XXXRW: For now, assert Giant here since the NFS server upcall
+ * will perform socket operations requiring Giant in a non-mpsafe
+ * kernel.
+ */
+ NET_ASSERT_GIANT();
+ NFSD_UNLOCK_ASSERT();
+
+ /* XXXRW: Unlocked read. */
if ((slp->ns_flag & SLP_VALID) == 0)
return;
-#ifdef notdef
+
/*
- * Define this to test for nfsds handling this under heavy load.
+ * We can't do this in the context of a socket callback
+ * because we're called with locks held.
+ * XXX: SMP
*/
if (waitflag == M_DONTWAIT) {
+ NFSD_LOCK();
slp->ns_flag |= SLP_NEEDQ;
goto dorecs;
}
-#endif
+
+
+ NFSD_LOCK();
auio.uio_td = NULL;
if (so->so_type == SOCK_STREAM) {
/*
@@ -433,7 +454,8 @@ nfsrv_rcv(struct socket *so, void *arg, int waitflag)
* to an nfsd so that there is feedback to the TCP layer that
* the nfs servers are heavily loaded.
*/
- if (STAILQ_FIRST(&slp->ns_rec) && waitflag == M_DONTWAIT) {
+ if (STAILQ_FIRST(&slp->ns_rec) != NULL &&
+ waitflag == M_DONTWAIT) {
slp->ns_flag |= SLP_NEEDQ;
goto dorecs;
}
@@ -443,8 +465,10 @@ nfsrv_rcv(struct socket *so, void *arg, int waitflag)
*/
auio.uio_resid = 1000000000;
flags = MSG_DONTWAIT;
+ NFSD_UNLOCK();
error = so->so_proto->pr_usrreqs->pru_soreceive
(so, &nam, &auio, &mp, NULL, &flags);
+ NFSD_LOCK();
if (error || mp == NULL) {
if (error == EWOULDBLOCK)
slp->ns_flag |= SLP_NEEDQ;
@@ -478,23 +502,28 @@ nfsrv_rcv(struct socket *so, void *arg, int waitflag)
do {
auio.uio_resid = 1000000000;
flags = MSG_DONTWAIT;
+ NFSD_UNLOCK();
error = so->so_proto->pr_usrreqs->pru_soreceive
(so, &nam, &auio, &mp, NULL, &flags);
if (mp) {
struct nfsrv_rec *rec;
rec = malloc(sizeof(struct nfsrv_rec),
- M_NFSRVDESC, waitflag);
+ M_NFSRVDESC,
+ waitflag == M_DONTWAIT ? M_NOWAIT : M_WAITOK);
if (!rec) {
if (nam)
FREE(nam, M_SONAME);
m_freem(mp);
+ NFSD_LOCK();
continue;
}
+ NFSD_LOCK();
nfs_realign(&mp, 10 * NFSX_UNSIGNED);
rec->nr_address = nam;
rec->nr_packet = mp;
STAILQ_INSERT_TAIL(&slp->ns_rec, rec, nr_link);
- }
+ } else
+ NFSD_LOCK();
if (error) {
if ((so->so_proto->pr_flags & PR_CONNREQUIRED)
&& error != EWOULDBLOCK) {
@@ -510,9 +539,10 @@ nfsrv_rcv(struct socket *so, void *arg, int waitflag)
*/
dorecs:
if (waitflag == M_DONTWAIT &&
- (STAILQ_FIRST(&slp->ns_rec)
- || (slp->ns_flag & (SLP_NEEDQ | SLP_DISCONN))))
+ (STAILQ_FIRST(&slp->ns_rec) != NULL ||
+ (slp->ns_flag & (SLP_NEEDQ | SLP_DISCONN))))
nfsrv_wakenfsd(slp);
+ NFSD_UNLOCK();
}
/*
@@ -529,6 +559,8 @@ nfsrv_getstream(struct nfssvc_sock *slp, int waitflag)
struct mbuf *om, *m2, *recm;
u_int32_t recmark;
+ NFSD_LOCK_ASSERT();
+
if (slp->ns_flag & SLP_GETSTREAM)
panic("nfs getstream");
slp->ns_flag |= SLP_GETSTREAM;
@@ -563,7 +595,7 @@ nfsrv_getstream(struct nfssvc_sock *slp, int waitflag)
slp->ns_flag |= SLP_LASTFRAG;
else
slp->ns_flag &= ~SLP_LASTFRAG;
- if (slp->ns_reclen > NFS_MAXPACKET) {
+ if (slp->ns_reclen > NFS_MAXPACKET || slp->ns_reclen <= 0) {
slp->ns_flag &= ~SLP_GETSTREAM;
return (EPERM);
}
@@ -587,8 +619,10 @@ nfsrv_getstream(struct nfssvc_sock *slp, int waitflag)
while (len < slp->ns_reclen) {
if ((len + m->m_len) > slp->ns_reclen) {
+ NFSD_UNLOCK();
m2 = m_copym(m, 0, slp->ns_reclen - len,
waitflag);
+ NFSD_LOCK();
if (m2) {
if (om) {
om->m_next = m2;
@@ -631,7 +665,10 @@ nfsrv_getstream(struct nfssvc_sock *slp, int waitflag)
*mpp = recm;
if (slp->ns_flag & SLP_LASTFRAG) {
struct nfsrv_rec *rec;
- rec = malloc(sizeof(struct nfsrv_rec), M_NFSRVDESC, waitflag);
+ NFSD_UNLOCK();
+ rec = malloc(sizeof(struct nfsrv_rec), M_NFSRVDESC,
+ waitflag == M_DONTWAIT ? M_NOWAIT : M_WAITOK);
+ NFSD_LOCK();
if (!rec) {
m_freem(slp->ns_frag);
} else {
@@ -658,16 +695,21 @@ nfsrv_dorec(struct nfssvc_sock *slp, struct nfsd *nfsd,
struct nfsrv_descript *nd;
int error;
+ NFSD_LOCK_ASSERT();
+
*ndp = NULL;
- if ((slp->ns_flag & SLP_VALID) == 0 || !STAILQ_FIRST(&slp->ns_rec))
+ if ((slp->ns_flag & SLP_VALID) == 0 ||
+ STAILQ_FIRST(&slp->ns_rec) == NULL)
return (ENOBUFS);
rec = STAILQ_FIRST(&slp->ns_rec);
STAILQ_REMOVE_HEAD(&slp->ns_rec, nr_link);
nam = rec->nr_address;
m = rec->nr_packet;
free(rec, M_NFSRVDESC);
+ NFSD_UNLOCK();
MALLOC(nd, struct nfsrv_descript *, sizeof (struct nfsrv_descript),
M_NFSRVDESC, M_WAITOK);
+ NFSD_LOCK();
nd->nd_md = nd->nd_mrep = m;
nd->nd_nam2 = nam;
nd->nd_dpos = mtod(m, caddr_t);
@@ -694,6 +736,8 @@ nfsrv_wakenfsd(struct nfssvc_sock *slp)
{
struct nfsd *nd;
+ NFSD_LOCK_ASSERT();
+
if ((slp->ns_flag & SLP_VALID) == 0)
return;
TAILQ_FOREACH(nd, &nfsd_head, nfsd_chain) {
@@ -703,7 +747,7 @@ nfsrv_wakenfsd(struct nfssvc_sock *slp)
panic("nfsd wakeup");
slp->ns_sref++;
nd->nfsd_slp = slp;
- wakeup((caddr_t)nd);
+ wakeup(nd);
return;
}
}
@@ -724,6 +768,9 @@ nfsrv_send(struct socket *so, struct sockaddr *nam, struct mbuf *top)
struct sockaddr *sendnam;
int error, soflags, flags;
+ NET_ASSERT_GIANT();
+ NFSD_UNLOCK_ASSERT();
+
soflags = so->so_proto->pr_flags;
if ((soflags & PR_CONNREQUIRED) || (so->so_state & SS_ISCONNECTED))
sendnam = NULL;
@@ -758,11 +805,10 @@ nfsrv_send(struct socket *so, struct sockaddr *nam, struct mbuf *top)
void
nfsrv_timer(void *arg)
{
- int s;
struct nfssvc_sock *slp;
u_quad_t cur_usec;
- s = splnet();
+ NFSD_LOCK();
/*
* Scan the write gathering queues for writes that need to be
* completed now.
@@ -773,6 +819,6 @@ nfsrv_timer(void *arg)
LIST_FIRST(&slp->ns_tq)->nd_time <= cur_usec)
nfsrv_wakenfsd(slp);
}
- splx(s);
- nfsrv_timer_handle = timeout(nfsrv_timer, NULL, nfsrv_ticks);
+ NFSD_UNLOCK();
+ callout_reset(&nfsrv_callout, nfsrv_ticks, nfsrv_timer, NULL);
}
Please sign in to comment.
Something went wrong with that request. Please try again.