--- old/usr/src/man/man9e/chpoll.9e	Wed Oct 18 21:03:40 2017
+++ new/usr/src/man/man9e/chpoll.9e	Wed Oct 18 21:03:40 2017
@@ -1,10 +1,11 @@
 '\" te
 .\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved.
 .\" Copyright 1989 AT&T
+.\" Copyright 2017 Joyent, Inc
 .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License").  You may not use this file except in compliance with the License.
 .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.  See the License for the specific language governing permissions and limitations under the License.
 .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE.  If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH CHPOLL 9E "May 7, 2008"
+.TH CHPOLL 9E "Jan 18, 2017"
 .SH NAME
 chpoll \- poll entry point for a non-STREAMS character driver
 .SH SYNOPSIS
@@ -182,13 +183,26 @@
       *reventsp = satisfied_events & events;
 } else {
       *reventsp = 0;
-      if (!anyyet)
-            *phpp = &my_local_pollhead_structure;
 }
+if ((*reventsp == 0 && !anyyet) || (events & POLLET))
+      *phpp = &my_local_pollhead_structure;
 return (0);
 .fi
 .in -2
 
+Note: Prior to the integration of \fBepoll\fR(5), which included
+edge-triggering via the \fBPOLLET\fR flag, standard chpoll mechanisms would
+only provide a pollhead in \fBphpp\fR if there were no matching events.
+Edge-triggered polling requires that \fBpollwakeup()\fR always be called for a
+resource, so if \fBPOLLET\fR is set in the \fBevents\fR of interest, the chpoll
+method must yield a pollhead and prepare to issue \fBpollwakeup()\fR calls on
+it.
+
+Drivers which are not wired up to make \fBpollwakeup()\fR calls on a pollhead
+when their status changes should emit one from their \fBchpoll\fR routine.
+This will exclude the resource from caching by pollers, since it cannot alert
+them to new events without \fBpollwakeup()\fR notification.
+
 .RE
 .RS +4
 .TP
@@ -252,7 +266,7 @@
 number.
 .SH SEE ALSO
 .LP
-\fBpoll\fR(2), \fBnochpoll\fR(9F), \fBpollwakeup\fR(9F)
+\fBpoll\fR(2), \fBepoll\fR(5), \fBnochpoll\fR(9F), \fBpollwakeup\fR(9F)
 .sp
 .LP
 \fIWriting Device Drivers\fR
--- old/usr/src/uts/common/crypto/api/kcf_random.c	Wed Oct 18 21:03:40 2017
+++ new/usr/src/uts/common/crypto/api/kcf_random.c	Wed Oct 18 21:03:40 2017
@@ -21,7 +21,7 @@
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012 Nexenta Systems, Inc.  All rights reserved.
- * Copyright (c) 2015, Joyent, Inc.
+ * Copyright 2017 Joyent, Inc.
  */
 
 /*
@@ -922,7 +922,7 @@
 			*reventsp |= (events & (POLLIN | POLLRDNORM));
 	}
 
-	if (*reventsp == 0 && !anyyet)
+	if ((*reventsp == 0 && !anyyet) || (events & POLLET))
 		*phpp = &rnd_pollhead;
 }
 
--- old/usr/src/uts/common/fs/fs_subr.c	Wed Oct 18 21:03:40 2017
+++ new/usr/src/uts/common/fs/fs_subr.c	Wed Oct 18 21:03:40 2017
@@ -25,7 +25,7 @@
 /*
  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
- * Copyright 2015 Joyent, Inc.
+ * Copyright 2017 Joyent, Inc.
  */
 
 /*
@@ -416,6 +416,17 @@
 fs_poll(vnode_t *vp, short events, int anyyet, short *reventsp,
     struct pollhead **phpp, caller_context_t *ct)
 {
+	/*
+	 * Reject all attempts for edge-triggered polling.  These should only
+	 * occur when regular files are added to a /dev/poll handle which is in
+	 * epoll mode.  The Linux epoll does not allow epoll-ing on regular
+	 * files at all, so rejecting EPOLLET requests is congruent with those
+	 * expectations.
+	 */
+	if (events & POLLET) {
+		return (EPERM);
+	}
+
 	*reventsp = 0;
 	if (events & POLLIN)
 		*reventsp |= POLLIN;
@@ -427,7 +438,15 @@
 		*reventsp |= POLLOUT;
 	if (events & POLLWRBAND)
 		*reventsp |= POLLWRBAND;
-	*phpp = !anyyet && !*reventsp ? &fs_pollhd : (struct pollhead *)NULL;
+	/*
+	 * Emitting a pollhead without the intention of issuing pollwakeup()
+	 * calls against it is a recipe for trouble.  It's only acceptable in
+	 * this case since the above logic matches practically all useful
+	 * events.
+	 */
+	if (*reventsp == 0 && !anyyet) {
+		*phpp = &fs_pollhd;
+	}
 	return (0);
 }
 
--- old/usr/src/uts/common/fs/ufs/ufs_vnops.c	Wed Oct 18 21:03:40 2017
+++ new/usr/src/uts/common/fs/ufs/ufs_vnops.c	Wed Oct 18 21:03:40 2017
@@ -21,7 +21,7 @@
 
 /*
  * Copyright (c) 1984, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2015, Joyent, Inc.
+ * Copyright 2017 Joyent, Inc.
  * Copyright (c) 2016 by Delphix. All rights reserved.
  */
 
@@ -275,7 +275,7 @@
 /*ARGSUSED*/
 static int
 ufs_close(struct vnode *vp, int flag, int count, offset_t offset,
-	struct cred *cr, caller_context_t *ct)
+    struct cred *cr, caller_context_t *ct)
 {
 	cleanlocks(vp, ttoproc(curthread)->p_pid, 0);
 	cleanshares(vp, ttoproc(curthread)->p_pid);
@@ -302,7 +302,7 @@
 /*ARGSUSED*/
 static int
 ufs_read(struct vnode *vp, struct uio *uiop, int ioflag, struct cred *cr,
-	struct caller_context *ct)
+    struct caller_context *ct)
 {
 	struct inode *ip = VTOI(vp);
 	struct ufsvfs *ufsvfsp;
@@ -432,7 +432,7 @@
 /*ARGSUSED*/
 static int
 ufs_write(struct vnode *vp, struct uio *uiop, int ioflag, cred_t *cr,
-	caller_context_t *ct)
+    caller_context_t *ct)
 {
 	struct inode *ip = VTOI(vp);
 	struct ufsvfs *ufsvfsp;
@@ -1993,7 +1993,7 @@
 /* ARGSUSED */
 static int
 ufs_getattr(struct vnode *vp, struct vattr *vap, int flags,
-	struct cred *cr, caller_context_t *ct)
+    struct cred *cr, caller_context_t *ct)
 {
 	struct inode *ip = VTOI(vp);
 	struct ufsvfs *ufsvfsp;
@@ -2101,12 +2101,8 @@
 
 /*ARGSUSED4*/
 static int
-ufs_setattr(
-	struct vnode *vp,
-	struct vattr *vap,
-	int flags,
-	struct cred *cr,
-	caller_context_t *ct)
+ufs_setattr(struct vnode *vp, struct vattr *vap, int flags, struct cred *cr,
+    caller_context_t *ct)
 {
 	struct inode *ip = VTOI(vp);
 	struct ufsvfs *ufsvfsp = ip->i_ufsvfs;
@@ -2438,7 +2434,7 @@
 /*ARGSUSED*/
 static int
 ufs_access(struct vnode *vp, int mode, int flags, struct cred *cr,
-	caller_context_t *ct)
+    caller_context_t *ct)
 {
 	struct inode *ip = VTOI(vp);
 
@@ -2462,7 +2458,7 @@
 /* ARGSUSED */
 static int
 ufs_readlink(struct vnode *vp, struct uio *uiop, struct cred *cr,
-	caller_context_t *ct)
+    caller_context_t *ct)
 {
 	struct inode *ip = VTOI(vp);
 	struct ufsvfs *ufsvfsp;
@@ -2617,8 +2613,7 @@
 
 /* ARGSUSED */
 static int
-ufs_fsync(struct vnode *vp, int syncflag, struct cred *cr,
-	caller_context_t *ct)
+ufs_fsync(struct vnode *vp, int syncflag, struct cred *cr, caller_context_t *ct)
 {
 	struct inode *ip = VTOI(vp);
 	struct ufsvfs *ufsvfsp = ip->i_ufsvfs;
@@ -2723,8 +2718,8 @@
 /* ARGSUSED */
 static int
 ufs_lookup(struct vnode *dvp, char *nm, struct vnode **vpp,
-	struct pathname *pnp, int flags, struct vnode *rdir, struct cred *cr,
-	caller_context_t *ct, int *direntflags, pathname_t *realpnp)
+    struct pathname *pnp, int flags, struct vnode *rdir, struct cred *cr,
+    caller_context_t *ct, int *direntflags, pathname_t *realpnp)
 {
 	struct inode *ip;
 	struct inode *sip;
@@ -2908,8 +2903,8 @@
 /*ARGSUSED*/
 static int
 ufs_create(struct vnode *dvp, char *name, struct vattr *vap, enum vcexcl excl,
-	int mode, struct vnode **vpp, struct cred *cr, int flag,
-	caller_context_t *ct, vsecattr_t *vsecp)
+    int mode, struct vnode **vpp, struct cred *cr, int flag,
+    caller_context_t *ct, vsecattr_t *vsecp)
 {
 	struct inode *ip;
 	struct inode *xip;
@@ -3193,8 +3188,8 @@
 extern int ufs_idle_max;
 /*ARGSUSED*/
 static int
-ufs_remove(struct vnode *vp, char *nm, struct cred *cr,
-	caller_context_t *ct, int flags)
+ufs_remove(struct vnode *vp, char *nm, struct cred *cr, caller_context_t *ct,
+    int flags)
 {
 	struct inode *ip = VTOI(vp);
 	struct ufsvfs *ufsvfsp	= ip->i_ufsvfs;
@@ -3260,7 +3255,7 @@
 /*ARGSUSED*/
 static int
 ufs_link(struct vnode *tdvp, struct vnode *svp, char *tnm, struct cred *cr,
-	caller_context_t *ct, int flags)
+    caller_context_t *ct, int flags)
 {
 	struct inode *sip;
 	struct inode *tdp = VTOI(tdvp);
@@ -3355,14 +3350,8 @@
 
 /*ARGSUSED*/
 static int
-ufs_rename(
-	struct vnode *sdvp,		/* old (source) parent vnode */
-	char *snm,			/* old (source) entry name */
-	struct vnode *tdvp,		/* new (target) parent vnode */
-	char *tnm,			/* new (target) entry name */
-	struct cred *cr,
-	caller_context_t *ct,
-	int flags)
+ufs_rename(struct vnode *sdvp, char *snm, struct vnode *tdvp, char *tnm,
+    struct cred *cr, caller_context_t *ct, int flags)
 {
 	struct inode *sip = NULL;	/* source inode */
 	struct inode *ip = NULL;	/* check inode */
@@ -3761,8 +3750,8 @@
 /*ARGSUSED*/
 static int
 ufs_mkdir(struct vnode *dvp, char *dirname, struct vattr *vap,
-	struct vnode **vpp, struct cred *cr, caller_context_t *ct, int flags,
-	vsecattr_t *vsecp)
+    struct vnode **vpp, struct cred *cr, caller_context_t *ct, int flags,
+    vsecattr_t *vsecp)
 {
 	struct inode *ip;
 	struct inode *xip;
@@ -3839,7 +3828,7 @@
 /*ARGSUSED*/
 static int
 ufs_rmdir(struct vnode *vp, char *nm, struct vnode *cdir, struct cred *cr,
-	caller_context_t *ct, int flags)
+    caller_context_t *ct, int flags)
 {
 	struct inode *ip = VTOI(vp);
 	struct ufsvfs *ufsvfsp = ip->i_ufsvfs;
@@ -3901,13 +3890,8 @@
 
 /* ARGSUSED */
 static int
-ufs_readdir(
-	struct vnode *vp,
-	struct uio *uiop,
-	struct cred *cr,
-	int *eofp,
-	caller_context_t *ct,
-	int flags)
+ufs_readdir(struct vnode *vp, struct uio *uiop, struct cred *cr, int *eofp,
+    caller_context_t *ct, int flags)
 {
 	struct iovec *iovp;
 	struct inode *ip;
@@ -4110,14 +4094,8 @@
 
 /*ARGSUSED*/
 static int
-ufs_symlink(
-	struct vnode *dvp,		/* ptr to parent dir vnode */
-	char *linkname,			/* name of symbolic link */
-	struct vattr *vap,		/* attributes */
-	char *target,			/* target path */
-	struct cred *cr,		/* user credentials */
-	caller_context_t *ct,
-	int flags)
+ufs_symlink(struct vnode *dvp, char *linkname, struct vattr *vap, char *target,
+    struct cred *cr, caller_context_t *ct, int flags)
 {
 	struct inode *ip, *dip = VTOI(dvp);
 	struct ufsvfs *ufsvfsp = dip->i_ufsvfs;
@@ -4300,8 +4278,8 @@
  */
 int
 ufs_rdwri(enum uio_rw rw, int ioflag, struct inode *ip, caddr_t base,
-	ssize_t len, offset_t offset, enum uio_seg seg, int *aresid,
-	struct cred *cr)
+    ssize_t len, offset_t offset, enum uio_seg seg, int *aresid,
+    struct cred *cr)
 {
 	struct uio auio;
 	struct iovec aiov;
@@ -4433,8 +4411,7 @@
 
 /* ARGSUSED */
 static int
-ufs_seek(struct vnode *vp, offset_t ooff, offset_t *noffp,
-	caller_context_t *ct)
+ufs_seek(struct vnode *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct)
 {
 	return ((*noffp < 0 || *noffp > MAXOFFSET_T) ? EINVAL : 0);
 }
@@ -4442,8 +4419,8 @@
 /* ARGSUSED */
 static int
 ufs_frlock(struct vnode *vp, int cmd, struct flock64 *bfp, int flag,
-	offset_t offset, struct flk_callback *flk_cbp, struct cred *cr,
-	caller_context_t *ct)
+    offset_t offset, struct flk_callback *flk_cbp, struct cred *cr,
+    caller_context_t *ct)
 {
 	struct inode *ip = VTOI(vp);
 
@@ -4465,7 +4442,7 @@
 /* ARGSUSED */
 static int
 ufs_space(struct vnode *vp, int cmd, struct flock64 *bfp, int flag,
-	offset_t offset, cred_t *cr, caller_context_t *ct)
+    offset_t offset, cred_t *cr, caller_context_t *ct)
 {
 	struct ufsvfs *ufsvfsp = VTOI(vp)->i_ufsvfs;
 	struct ulockfs *ulp;
@@ -4527,8 +4504,8 @@
 /*ARGSUSED*/
 static int
 ufs_getpage(struct vnode *vp, offset_t off, size_t len, uint_t *protp,
-	page_t *plarr[], size_t plsz, struct seg *seg, caddr_t addr,
-	enum seg_rw rw, struct cred *cr, caller_context_t *ct)
+    page_t *plarr[], size_t plsz, struct seg *seg, caddr_t addr,
+    enum seg_rw rw, struct cred *cr, caller_context_t *ct)
 {
 	u_offset_t	uoff = (u_offset_t)off; /* type conversion */
 	u_offset_t	pgoff;
@@ -4891,7 +4868,7 @@
 /* ARGSUSED */
 static int
 ufs_getpage_miss(struct vnode *vp, u_offset_t off, size_t len, struct seg *seg,
-	caddr_t addr, page_t *pl[], size_t plsz, enum seg_rw rw, int seq)
+    caddr_t addr, page_t *pl[], size_t plsz, enum seg_rw rw, int seq)
 {
 	struct inode	*ip = VTOI(vp);
 	page_t		*pp;
@@ -5109,7 +5086,7 @@
 /*ARGSUSED*/
 static int
 ufs_putpage(struct vnode *vp, offset_t off, size_t len, int flags,
-	struct cred *cr, caller_context_t *ct)
+    struct cred *cr, caller_context_t *ct)
 {
 	struct inode *ip = VTOI(vp);
 	int err = 0;
@@ -5191,12 +5168,8 @@
  */
 /*ARGSUSED*/
 static int
-ufs_putpages(
-	struct vnode *vp,
-	offset_t off,
-	size_t len,
-	int flags,
-	struct cred *cr)
+ufs_putpages(struct vnode *vp, offset_t off, size_t len, int flags,
+    struct cred *cr)
 {
 	u_offset_t io_off;
 	u_offset_t eoff;
@@ -5366,13 +5339,8 @@
  */
 /*ARGSUSED*/
 int
-ufs_putapage(
-	struct vnode *vp,
-	page_t *pp,
-	u_offset_t *offp,
-	size_t *lenp,		/* return values */
-	int flags,
-	struct cred *cr)
+ufs_putapage(struct vnode *vp, page_t *pp, u_offset_t *offp, size_t *lenp,
+    int flags, struct cred *cr)
 {
 	u_offset_t io_off;
 	u_offset_t off;
@@ -5603,16 +5571,9 @@
 
 /* ARGSUSED */
 static int
-ufs_map(struct vnode *vp,
-	offset_t off,
-	struct as *as,
-	caddr_t *addrp,
-	size_t len,
-	uchar_t prot,
-	uchar_t maxprot,
-	uint_t flags,
-	struct cred *cr,
-	caller_context_t *ct)
+ufs_map(struct vnode *vp, offset_t off, struct as *as, caddr_t *addrp,
+    size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, struct cred *cr,
+    caller_context_t *ct)
 {
 	struct segvn_crargs vn_a;
 	struct ufsvfs *ufsvfsp = VTOI(vp)->i_ufsvfs;
@@ -5728,16 +5689,9 @@
 
 /* ARGSUSED */
 static int
-ufs_addmap(struct vnode *vp,
-	offset_t off,
-	struct as *as,
-	caddr_t addr,
-	size_t	len,
-	uchar_t  prot,
-	uchar_t  maxprot,
-	uint_t    flags,
-	struct cred *cr,
-	caller_context_t *ct)
+ufs_addmap(struct vnode *vp, offset_t off, struct as *as, caddr_t addr,
+    size_t len, uchar_t  prot, uchar_t  maxprot, uint_t    flags,
+    struct cred *cr, caller_context_t *ct)
 {
 	struct inode *ip = VTOI(vp);
 
@@ -5754,8 +5708,8 @@
 /*ARGSUSED*/
 static int
 ufs_delmap(struct vnode *vp, offset_t off, struct as *as, caddr_t addr,
-	size_t len, uint_t prot,  uint_t maxprot,  uint_t flags,
-	struct cred *cr, caller_context_t *ct)
+    size_t len, uint_t prot,  uint_t maxprot,  uint_t flags, struct cred *cr,
+    caller_context_t *ct)
 {
 	struct inode *ip = VTOI(vp);
 
@@ -5777,10 +5731,18 @@
 /* ARGSUSED */
 int
 ufs_poll(vnode_t *vp, short ev, int any, short *revp, struct pollhead **phpp,
-	caller_context_t *ct)
+    caller_context_t *ct)
 {
 	struct ufsvfs	*ufsvfsp;
 
+	/*
+	 * Regular files reject edge-triggered pollers.
+	 * See the comment in fs_poll() for a more detailed explanation.
+	 */
+	if (ev & POLLET) {
+		return (EPERM);
+	}
+
 	*revp = 0;
 	ufsvfsp = VTOI(vp)->i_ufsvfs;
 
@@ -5815,7 +5777,9 @@
 	if ((ev & POLLPRI) && (*revp & (POLLERR|POLLHUP)))
 		*revp |= POLLPRI;
 out:
-	*phpp = !any && !*revp ? &ufs_pollhd : (struct pollhead *)NULL;
+	if (*revp == 0 && ! any) {
+		*phpp = &ufs_pollhd;
+	}
 
 	return (0);
 }
@@ -5823,7 +5787,7 @@
 /* ARGSUSED */
 static int
 ufs_l_pathconf(struct vnode *vp, int cmd, ulong_t *valp, struct cred *cr,
-	caller_context_t *ct)
+    caller_context_t *ct)
 {
 	struct ufsvfs	*ufsvfsp = VTOI(vp)->i_ufsvfs;
 	struct ulockfs	*ulp = NULL;
@@ -5937,7 +5901,7 @@
 /*ARGSUSED*/
 static int
 ufs_pageio(struct vnode *vp, page_t *pp, u_offset_t io_off, size_t io_len,
-	int flags, struct cred *cr, caller_context_t *ct)
+    int flags, struct cred *cr, caller_context_t *ct)
 {
 	struct inode *ip = VTOI(vp);
 	struct ufsvfs *ufsvfsp;
@@ -6418,7 +6382,7 @@
 /* ARGSUSED */
 static int
 ufs_getsecattr(struct vnode *vp, vsecattr_t *vsap, int flag,
-	struct cred *cr, caller_context_t *ct)
+    struct cred *cr, caller_context_t *ct)
 {
 	struct inode	*ip = VTOI(vp);
 	struct ulockfs	*ulp;
@@ -6450,7 +6414,7 @@
 /* ARGSUSED */
 static int
 ufs_setsecattr(struct vnode *vp, vsecattr_t *vsap, int flag, struct cred *cr,
-	caller_context_t *ct)
+    caller_context_t *ct)
 {
 	struct inode	*ip = VTOI(vp);
 	struct ulockfs	*ulp = NULL;
--- old/usr/src/uts/common/inet/sockmods/socksdp.c	Wed Oct 18 21:03:40 2017
+++ new/usr/src/uts/common/inet/sockmods/socksdp.c	Wed Oct 18 21:03:40 2017
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2017 Joyent, Inc.
  */
 
 #include <sys/types.h>
@@ -1092,26 +1093,22 @@
 	 * Check for errors
 	 */
 	if (so->so_error != 0 &&
-	    ((POLLIN|POLLRDNORM|POLLOUT) & origevents)  != 0) {
+	    ((POLLIN|POLLRDNORM|POLLOUT) & origevents) != 0) {
 		*reventsp = (POLLIN|POLLRDNORM|POLLOUT) & origevents;
-		return (0);
+		goto done;
 	}
 
 	*reventsp = 0;
+	if (so->so_type != SOCK_STREAM) {
+		goto done;
+	}
 
 	/*
-	 * Don't mark socket as writable until TX queued data is
-	 * below watermark.
+	 * Don't mark socket writable until TX queued data is below watermark.
 	 */
-	if (so->so_type == SOCK_STREAM) {
-		if (sdp_polldata(
-		    (struct sdp_conn_struct_t *)so->so_proto_handle,
-		    SDP_XMIT)) {
-			*reventsp |= POLLOUT & events;
-		}
-	} else {
-		*reventsp = 0;
-		goto done;
+	if (sdp_polldata((struct sdp_conn_struct_t *)so->so_proto_handle,
+	    SDP_XMIT)) {
+		*reventsp |= POLLOUT & events;
 	}
 
 	if (sdp_polldata((struct sdp_conn_struct_t *)so->so_proto_handle,
@@ -1124,7 +1121,7 @@
 	}
 
 done:
-	if (!*reventsp && !anyyet) {
+	if ((*reventsp == 0 && !anyyet) || (events & POLLET)) {
 		*phpp = &so->so_poll_list;
 	}
 
--- old/usr/src/uts/common/io/1394/targets/av1394/av1394_async.c	Wed Oct 18 21:03:40 2017
+++ new/usr/src/uts/common/io/1394/targets/av1394/av1394_async.c	Wed Oct 18 21:03:40 2017
@@ -25,7 +25,7 @@
  */
 
 /*
- * Copyright (c) 2014, Joyent, Inc. All rights reserved.
+ * Copyright 2017 Joyent, Inc.
  */
 
 /*
@@ -323,7 +323,7 @@
 /*ARGSUSED*/
 int
 av1394_async_ioctl(av1394_inst_t *avp, int cmd, intptr_t arg, int mode,
-		int *rvalp)
+    int *rvalp)
 {
 	int	ret = EINVAL;
 
@@ -350,10 +350,9 @@
 	return (ret);
 }
 
-/*ARGSUSED*/
 int
 av1394_async_poll(av1394_inst_t *avp, short events, int anyyet, short *reventsp,
-		struct pollhead **phpp)
+    struct pollhead **phpp)
 {
 	av1394_async_t	*ap = &avp->av_a;
 	av1394_queue_t	*rq = &ap->a_rq;
@@ -360,13 +359,16 @@
 
 	AV1394_TNF_ENTER(av1394_async_poll);
 
-	if (events & POLLIN) {
-		if (av1394_peekq(rq))
+	if (events & (POLLIN | POLLET)) {
+		if ((events & POLLIN) && av1394_peekq(rq)) {
 			*reventsp |= POLLIN;
+		}
 
 		if ((!*reventsp && !anyyet) || (events & POLLET)) {
 			mutex_enter(&ap->a_mutex);
-			ap->a_pollevents |= POLLIN;
+			if (events & POLLIN) {
+				ap->a_pollevents |= POLLIN;
+			}
 			*phpp = &ap->a_pollhead;
 			mutex_exit(&ap->a_mutex);
 		}
--- old/usr/src/uts/common/io/1394/targets/dcam1394/dcam.c	Wed Oct 18 21:03:41 2017
+++ new/usr/src/uts/common/io/1394/targets/dcam1394/dcam.c	Wed Oct 18 21:03:41 2017
@@ -21,6 +21,7 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2017 Joyent, Inc.
  */
 
 
@@ -1040,9 +1041,6 @@
 }
 
 
-/*
- * dcam_chpoll
- */
 /* ARGSUSED */
 int
 dcam_chpoll(dev_t dev, short events, int anyyet, short *reventsp,
@@ -1049,59 +1047,48 @@
     struct pollhead **phpp)
 {
 	dcam_state_t	*softc_p;
-	int		 instance, ring_buff_has_data, read_ptr_id;
-	size_t		 read_ptr_pos, write_ptr_pos;
-	short		 revent;
+	int		instance;
+	short		revent = 0;
 
-	instance = DEV_TO_INSTANCE(dev);
+	/*
+	 * Without the logic to perform wakeups (see comment below), reject
+	 * attempts at edge-triggered polling.
+	 */
+	if (events & POLLET) {
+		return (EPERM);
+	}
 
+	instance = DEV_TO_INSTANCE(dev);
 	softc_p = (dcam_state_t *)ddi_get_soft_state(dcam_state_p, instance);
 	if (softc_p == NULL) {
 		return (ENXIO);
 	}
 
-	read_ptr_id	= 0;
-	revent		= 0;
+	if (softc_p->ring_buff_p != NULL) {
+		size_t read_ptr_pos, write_ptr_pos;
 
-	if (softc_p->ring_buff_p == NULL) {
-		ring_buff_has_data = 0;
-	} else {
 		mutex_enter(&softc_p->dcam_frame_is_done_mutex);
-
 		read_ptr_pos =
-		    ring_buff_read_ptr_pos_get(softc_p->ring_buff_p,
-		    read_ptr_id);
-
+		    ring_buff_read_ptr_pos_get(softc_p->ring_buff_p, 0);
 		write_ptr_pos =
 		    ring_buff_write_ptr_pos_get(softc_p->ring_buff_p);
+		mutex_exit(&softc_p->dcam_frame_is_done_mutex);
 
-		if (read_ptr_pos != write_ptr_pos) {
-			ring_buff_has_data = 1;
-		} else {
-			ring_buff_has_data = 0;
+		if ((events & POLLRDNORM) && read_ptr_pos != write_ptr_pos) {
+			revent |= POLLRDNORM;
 		}
-
-		mutex_exit(&softc_p->dcam_frame_is_done_mutex);
 	}
 
-	/*
-	 * now check for events
-	 */
-	if ((events & POLLRDNORM) && ring_buff_has_data) {
-		revent |= POLLRDNORM;
-	}
-
 	if ((events & POLLPRI) && softc_p->param_status) {
 		revent |= POLLPRI;
 	}
 
-	/* if no events have occurred */
-	if (revent == 0) {
-		if (!anyyet) {
-			*phpp = &softc_p->dcam_pollhead;
-		}
-	}
-
+	/*
+	 * No portion of this driver was ever wired up to perform a
+	 * pollwakeup() on an associated pollhead.  The lack of an emitted
+	 * pollhead informs poll/devpoll that the event status of this resource
+	 * is not cacheable.
+	 */
 	*reventsp = revent;
 
 	return (0);
--- old/usr/src/uts/common/io/bpf/bpf.c	Wed Oct 18 21:03:41 2017
+++ new/usr/src/uts/common/io/bpf/bpf.c	Wed Oct 18 21:03:41 2017
@@ -40,6 +40,7 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2017 Joyent, Inc.
  */
 
 /*
@@ -1396,14 +1397,7 @@
 	return (0);
 }
 
-/*
- * Support for poll() system call
- *
- * Return true iff the specific operation will not block indefinitely - with
- * the assumption that it is safe to positively acknowledge a request for the
- * ability to write to the BPF device.
- * Otherwise, return false but make a note that a selnotify() must be done.
- */
+/* ARGSUSED */
 int
 bpfchpoll(dev_t dev, short events, int anyyet, short *reventsp,
     struct pollhead **phpp)
@@ -1410,6 +1404,14 @@
 {
 	struct bpf_d *d = bpf_dev_get(getminor(dev));
 
+	/*
+	 * Until this driver is modified to issue proper pollwakeup() calls on
+	 * its pollhead, edge-triggered polling is not allowed.
+	 */
+	if (events & POLLET) {
+		return (EPERM);
+	}
+
 	if (events & (POLLIN | POLLRDNORM)) {
 		/*
 		 * An imitation of the FIONREAD ioctl code.
@@ -1420,9 +1422,13 @@
 		    d->bd_slen != 0)) {
 			*reventsp |= events & (POLLIN | POLLRDNORM);
 		} else {
+			/*
+			 * Until the bpf driver has been updated to include
+			 * adequate pollwakeup() logic, no pollhead will be
+			 * emitted here, preventing the resource from being
+			 * cached by poll()/devpoll/epoll.
+			 */
 			*reventsp = 0;
-			if (!anyyet)
-				*phpp = &d->bd_poll;
 			/* Start the read timeout if necessary */
 			if (d->bd_rtout > 0 && d->bd_state == BPF_IDLE) {
 				bpf_clear_timeout(d);
--- old/usr/src/uts/common/io/bpf/net/bpfdesc.h	Wed Oct 18 21:03:41 2017
+++ new/usr/src/uts/common/io/bpf/net/bpfdesc.h	Wed Oct 18 21:03:41 2017
@@ -149,7 +149,6 @@
 	int		bd_nonblock;	/* non-zero for non-blocking read */
 	pid_t		bd_pgid;	/* process or group id for signal */
 	int		bd_timedout;
-	struct pollhead	bd_poll;
 	timeout_id_t	bd_callout;	/* for BPF timeouts with select */
 	pid_t		bd_pid;		/* corresponding PID */
 	void		*bd_sih;	/* soft interrupt handle */
--- old/usr/src/uts/common/io/devpoll.c	Wed Oct 18 21:03:41 2017
+++ new/usr/src/uts/common/io/devpoll.c	Wed Oct 18 21:03:41 2017
@@ -25,7 +25,7 @@
 
 /*
  * Copyright (c) 2012 by Delphix. All rights reserved.
- * Copyright 2016 Joyent, Inc.
+ * Copyright 2017 Joyent, Inc.
  */
 
 #include <sys/types.h>
@@ -366,21 +366,36 @@
 
 			if (fp != pdp->pd_fp) {
 				/*
-				 * user is polling on a cached fd which was
-				 * closed and then reused. Unfortunately
-				 * there is no good way to inform user.
-				 * If the file struct is also reused, we
-				 * may not be able to detect the fd reuse
-				 * at all.  As long as this does not
-				 * cause system failure and/or memory leak,
-				 * we will play along. Man page states if
-				 * user does not clean up closed fds, polling
+				 * The user is polling on a cached fd which was
+				 * closed and then reused.  Unfortunately there
+				 * is no good way to communicate this fact to
+				 * the consumer.
+				 *
+				 * If the file struct is also reused, we may
+				 * not be able to detect the fd reuse at all.
+				 * As long as this does not cause system
+				 * failure and/or memory leaks, we will play
+				 * along.  The man page states that if the user
+				 * does not clean up closed fds, polling
 				 * results will be indeterministic.
 				 *
-				 * XXX - perhaps log the detection of fd
-				 *	 reuse?
+				 * XXX: perhaps log the detection of fd reuse?
 				 */
 				pdp->pd_fp = fp;
+
+				/*
+				 * When this situation has been detected, it's
+				 * likely that any existing pollhead is
+				 * ill-suited to perform proper wake-ups.
+				 *
+				 * Clean up the old entry under the expectation
+				 * that a valid one will be provided as part of
+				 * the later VOP_POLL.
+				 */
+				if (pdp->pd_php != NULL) {
+					pollhead_delete(pdp->pd_php, pdp);
+					pdp->pd_php = NULL;
+				}
 			}
 			/*
 			 * XXX - pollrelock() logic needs to know which
@@ -396,6 +411,27 @@
 			curthread->t_pollcache = pcp;
 			error = VOP_POLL(fp->f_vnode, pdp->pd_events, 0,
 			    &revent, &php, NULL);
+
+			/*
+			 * Recheck edge-triggered descriptors which lack a
+			 * pollhead.  While this check is performed when an fd
+			 * is added to the pollcache in dpwrite(), subsequent
+			 * descriptor manipulation could cause a different
+			 * resource to be present now.
+			 */
+			if ((pdp->pd_events & POLLET) && error == 0 &&
+			    pdp->pd_php == NULL && php == NULL && revent != 0) {
+				short levent = 0;
+
+				/*
+				 * The same POLLET-only VOP_POLL is used in an
+				 * attempt to coax a pollhead from older
+				 * driver logic.
+				 */
+				error = VOP_POLL(fp->f_vnode, POLLET,
+				    0, &levent, &php, NULL);
+			}
+
 			curthread->t_pollcache = NULL;
 			releasef(fd);
 			if (error != 0) {
@@ -431,6 +467,16 @@
 					ep->data.u64 = pdp->pd_epolldata;
 
 					/*
+					 * Since POLLNVAL is a legal event for
+					 * VOP_POLL handlers to emit, it must
+					 * be translated epoll-legal.
+					 */
+					if (revent & POLLNVAL) {
+						revent &= ~POLLNVAL;
+						revent |= POLLERR;
+					}
+
+					/*
 					 * If any of the event bits are set for
 					 * which poll and epoll representations
 					 * differ, swizzle in the native epoll
@@ -488,19 +534,12 @@
 					}
 				}
 
-				/*
-				 * If POLLET is set, clear the bit in the
-				 * bitmap -- which effectively latches the
-				 * edge on a pollwakeup() from the driver.
-				 */
-				if (pdp->pd_events & POLLET)
-					BT_CLEAR(pcp->pc_bitmap, fd);
-
-				/*
-				 * If POLLONESHOT is set, perform the implicit
-				 * POLLREMOVE.
-				 */
+				/* Handle special polling modes. */
 				if (pdp->pd_events & POLLONESHOT) {
+					/*
+					 * If POLLONESHOT is set, perform the
+					 * implicit POLLREMOVE.
+					 */
 					pdp->pd_fp = NULL;
 					pdp->pd_events = 0;
 
@@ -511,6 +550,28 @@
 					}
 
 					BT_CLEAR(pcp->pc_bitmap, fd);
+				} else if (pdp->pd_events & POLLET) {
+					/*
+					 * Wire up the pollhead which should
+					 * have been provided.  Edge-triggered
+					 * polling cannot function properly
+					 * with drivers which do not emit one.
+					 */
+					if (php != NULL &&
+					    pdp->pd_php == NULL) {
+						pollhead_insert(php, pdp);
+						pdp->pd_php = php;
+					}
+
+					/*
+					 * If the driver has emitted a pollhead,
+					 * clear the bit in the bitmap which
+					 * effectively latches the edge on a
+					 * pollwakeup() from the driver.
+					 */
+					if (pdp->pd_php != NULL) {
+						BT_CLEAR(pcp->pc_bitmap, fd);
+					}
 				}
 
 				fdcnt++;
@@ -917,6 +978,32 @@
 			curthread->t_pollcache = pcp;
 			error = VOP_POLL(fp->f_vnode, pfdp->events, 0,
 			    &pfdp->revents, &php, NULL);
+
+			/*
+			 * Edge-triggered polling requires a pollhead in order
+			 * to initiate wake-ups properly.  Drivers which are
+			 * savvy to POLLET presence, which should include
+			 * everything in-gate, will always emit one, regardless
+			 * of revent status.  Older drivers which only emit a
+			 * pollhead if 'revents == 0' are given a second chance
+			 * here via a second VOP_POLL, with only POLLET set in
+			 * the events of interest.  These circumstances should
+			 * induce any cacheable drivers to emit a pollhead for
+			 * wake-ups.
+			 *
+			 * Drivers which never emit a pollhead will simply
+			 * disobey the exectation of edge-triggered behavior.
+			 * This includes recursive epoll which, even on Linux,
+			 * yields its events in a level-triggered fashion only.
+			 */
+			if ((pdp->pd_events & POLLET) && error == 0 &&
+			    php == NULL) {
+				short levent = 0;
+
+				error = VOP_POLL(fp->f_vnode, POLLET, 0,
+				    &levent, &php, NULL);
+			}
+
 			curthread->t_pollcache = NULL;
 			/*
 			 * We always set the bit when this fd is cached;
@@ -1458,10 +1545,22 @@
 		int		fdcnt = 0;
 		pollstate_t	*ps = curthread->t_pollstate;
 
-		rc = dp_pcache_poll(dpep, NULL, pcp, nfds, &fdcnt);
-		if (rc == 0) {
-			*reventsp = (fdcnt > 0) ? POLLIN : 0;
+		/*
+		 * Recursive polling will only emit certain events.  Skip a
+		 * scan of the pollcache if those events are not of interest.
+		 */
+		if (events & (POLLIN|POLLRDNORM)) {
+			rc = dp_pcache_poll(dpep, NULL, pcp, nfds, &fdcnt);
+		} else {
+			rc = 0;
+			fdcnt = 0;
 		}
+
+		if (rc == 0 && fdcnt > 0) {
+			*reventsp = POLLIN|POLLRDNORM;
+		} else {
+			*reventsp = 0;
+		}
 		pcachelink_assoc(pcp, ps->ps_pc_stack[0]);
 		pollstate_exit(pcp);
 	} else {
--- old/usr/src/uts/common/io/eventfd.c	Wed Oct 18 21:03:41 2017
+++ new/usr/src/uts/common/io/eventfd.c	Wed Oct 18 21:03:41 2017
@@ -10,7 +10,7 @@
  */
 
 /*
- * Copyright 2016 Joyent, Inc.
+ * Copyright 2017 Joyent, Inc.
  */
 
 /*
@@ -228,8 +228,10 @@
 	if (state->efd_value < EVENTFD_VALMAX)
 		revents |= POLLWRNORM | POLLOUT;
 
-	if (!(*reventsp = revents & events) && !anyyet)
+	*reventsp = revents & events;
+	if ((*reventsp == 0 && !anyyet) || (events & POLLET)) {
 		*phpp = &state->efd_pollhd;
+	}
 
 	mutex_exit(&state->efd_lock);
 
--- old/usr/src/uts/common/io/ib/clients/of/sol_ucma/sol_ucma.c	Wed Oct 18 21:03:41 2017
+++ new/usr/src/uts/common/io/ib/clients/of/sol_ucma/sol_ucma.c	Wed Oct 18 21:03:41 2017
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2017 Joyent, Inc.
  */
 
 /*
@@ -766,8 +767,8 @@
 }
 
 static int
-sol_ucma_poll(dev_t dev, short events, int anyyet,
-    short *reventsp, struct pollhead **phpp)
+sol_ucma_poll(dev_t dev, short events, int anyyet, short *reventsp,
+    struct pollhead **phpp)
 {
 	minor_t		minor = getminor(dev);
 	sol_ucma_file_t	*filep;
@@ -785,9 +786,10 @@
 		*reventsp = POLLIN | POLLRDNORM;
 	} else {
 		*reventsp = 0;
-		if (!anyyet)
-			*phpp = filep->file_pollhead;
 	}
+	if ((*reventsp == 0 && !anyyet) || (events && POLLET)) {
+		*phpp = filep->file_pollhead;
+	}
 	sol_ofs_uobj_put(&filep->file_uobj);
 
 	return (0);
--- old/usr/src/uts/common/io/ib/clients/of/sol_umad/sol_umad.c	Wed Oct 18 21:03:41 2017
+++ new/usr/src/uts/common/io/ib/clients/of/sol_umad/sol_umad.c	Wed Oct 18 21:03:41 2017
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2017 Joyent, Inc.
  */
 
 
@@ -2545,24 +2546,17 @@
  *	is true if a message has been queued for the user context receive list.
  */
 static int
-umad_poll(
-	dev_t dev,
-	short events,
-	int anyyet,
-	short *reventsp,
-	struct pollhead **phpp)
+umad_poll(dev_t dev, short events, int anyyet, short *reventsp,
+    struct pollhead **phpp)
 {
-	int			rc = 0;
-	int			minor;
-	umad_uctx_t		*uctx;
-	umad_port_info_t	*port;
-	umad_info_t		*info;
-	short			revent = 0;
+	int		minor;
+	umad_uctx_t	*uctx;
+	umad_info_t	*info;
+	short		revent = 0;
 
 	info = ddi_get_soft_state(umad_statep, UMAD_INSTANCE);
 	if (info == NULL) {
-		rc = ENXIO;
-		goto err1;
+		return (ENXIO);
 	}
 
 	/* lookup the node and port #s */
@@ -2569,8 +2563,7 @@
 	minor = getminor(dev);
 
 	if (ISSM_MINOR(minor)) {
-		rc = ENXIO;
-		goto err1;
+		return (ENXIO);
 	}
 
 	mutex_enter(&info->info_mutex);
@@ -2577,8 +2570,7 @@
 	uctx = info->info_uctx[GET_UCTX(minor)];
 	mutex_exit(&info->info_mutex);
 	ASSERT(uctx != NULL);
-	port = uctx->uctx_port;
-	ASSERT(port != NULL);
+	ASSERT(uctx->uctx_port != NULL);
 
 	/*
 	 * Always signal ready for POLLOUT / POLLWRNORM.
@@ -2595,15 +2587,11 @@
 		mutex_exit(&uctx->uctx_recv_lock);
 	}
 
-	if (revent == 0) {
-		if (! anyyet)
-			*phpp = &uctx->uctx_pollhead;
+	if ((revent == 0 && !anyyet) || (events & POLLET)) {
+		*phpp = &uctx->uctx_pollhead;
 	}
-
 	*reventsp = revent;
-err1:
-
-	return (rc);
+	return (0);
 }
 
 /*
--- old/usr/src/uts/common/io/ib/clients/of/sol_uverbs/sol_uverbs_event.c	Wed Oct 18 21:03:41 2017
+++ new/usr/src/uts/common/io/ib/clients/of/sol_uverbs/sol_uverbs_event.c	Wed Oct 18 21:03:41 2017
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2017 Joyent, Inc.
  */
 
 /*
@@ -280,9 +281,9 @@
 	}
 
 	/*
-	 * If we didn't get an event
+	 * If we didn't get an event or are edge-triggered
 	 */
-	if (revent == 0 && !anyyet) {
+	if ((revent == 0 && !anyyet) || (events & POLLET)) {
 		SOL_OFS_DPRINTF_L5(sol_uverbs_dbg_str, "event_file_poll "
 		    "Event entry NOT available");
 
@@ -569,7 +570,7 @@
 /* ARGSUSED */
 void
 uverbs_async_cq_event_handler(void *clnt_private, ibt_hca_hdl_t hca_hdl,
-	enum ib_event_type code, ibt_async_event_t *event)
+    enum ib_event_type code, ibt_async_event_t *event)
 {
 	uverbs_ucq_uobj_t	*ucq;
 
@@ -611,7 +612,7 @@
 /* ARGSUSED */
 void
 uverbs_async_srq_event_handler(void *clnt_private, ibt_hca_hdl_t hca_hdl,
-	enum ib_event_type code, ibt_async_event_t *event)
+    enum ib_event_type code, ibt_async_event_t *event)
 {
 	uverbs_usrq_uobj_t	*usrq;
 
@@ -653,7 +654,7 @@
 /* ARGSUSED */
 void
 uverbs_async_unaff_event_handler(void *clnt_private, ibt_hca_hdl_t hca_hdl,
-	enum ib_event_type code, ibt_async_event_t *event)
+    enum ib_event_type code, ibt_async_event_t *event)
 {
 	sol_ofs_uobj_table_t	*uo_tbl = &uverbs_uctxt_uo_tbl;
 	sol_ofs_uobj_blk_t	*blk;
@@ -712,7 +713,7 @@
  */
 void
 uverbs_async_event_handler(void *clnt_private, ibt_hca_hdl_t hca_hdl,
-	ibt_async_code_t code, ibt_async_event_t *event)
+    ibt_async_code_t code, ibt_async_event_t *event)
 {
 	enum ib_event_type		ofa_type;
 	sol_uverbs_ib_event_handler_t	*handler;
@@ -884,7 +885,7 @@
  */
 void
 uverbs_release_ucq_channel(uverbs_uctxt_uobj_t *uctxt,
-	uverbs_ufile_uobj_t *ufile, uverbs_ucq_uobj_t   *ucq)
+    uverbs_ufile_uobj_t *ufile, uverbs_ucq_uobj_t   *ucq)
 {
 	uverbs_event_t	*evt;
 	llist_head_t	*entry;
@@ -1043,7 +1044,7 @@
  */
 void
 uverbs_release_usrq_uevents(uverbs_ufile_uobj_t *ufile,
-						uverbs_usrq_uobj_t *usrq)
+    uverbs_usrq_uobj_t *usrq)
 {
 	uverbs_event_t	*evt;
 	llist_head_t	*entry;
--- old/usr/src/uts/common/io/mem.c	Wed Oct 18 21:03:42 2017
+++ new/usr/src/uts/common/io/mem.c	Wed Oct 18 21:03:42 2017
@@ -25,7 +25,7 @@
  */
 
 /*
- * Copyright (c) 2015, Joyent, Inc.  All rights reserved.
+ * Copyright 2017 Joyent, Inc.
  * Copyright 2017 James S Blachly, MD <james.blachly@gmail.com>
  */
 
@@ -259,10 +259,11 @@
 		    POLLWRNORM | POLLRDBAND | POLLWRBAND);
 		/*
 		 * A non NULL pollhead pointer should be returned in case
-		 * user polls for 0 events.
+		 * user polls for 0 events or is doing an edge-triggerd poll.
 		 */
-		*phpp = !anyyet && !*reventsp ?
-		    &mm_pollhd : (struct pollhead *)NULL;
+		if ((!*reventsp && !anyyet) || (events & POLLET)) {
+			*phpp = &mm_pollhd;
+		}
 		return (0);
 	default:
 		/* no other devices currently support polling */
--- old/usr/src/uts/common/io/random.c	Wed Oct 18 21:03:42 2017
+++ new/usr/src/uts/common/io/random.c	Wed Oct 18 21:03:42 2017
@@ -20,6 +20,8 @@
  *
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2017 Joyent, Inc.
  */
 
 
@@ -329,7 +331,7 @@
 		 * A non NULL pollhead pointer should be returned in case
 		 * user polls for 0 events.
 		 */
-		if (*reventsp == 0 && !anyyet)
+		if ((*reventsp == 0 && !anyyet) || (events & POLLET))
 			*phpp = &urnd_pollhd;
 
 		break;
--- old/usr/src/uts/common/io/rsm/rsm.c	Wed Oct 18 21:03:42 2017
+++ new/usr/src/uts/common/io/rsm/rsm.c	Wed Oct 18 21:03:42 2017
@@ -23,6 +23,7 @@
  * Use is subject to license terms.
  * Copyright 2012 Milan Jurik. All rights reserved.
  * Copyright (c) 2016 by Delphix. All rights reserved.
+ * Copyright 2017 Joyent, Inc.
  */
 
 
@@ -2419,9 +2420,7 @@
 
 static void
 rsm_remap_local_importers(rsm_node_id_t src_nodeid,
-    rsm_memseg_id_t ex_segid,
-    ddi_umem_cookie_t cookie)
-
+    rsm_memseg_id_t ex_segid, ddi_umem_cookie_t cookie)
 {
 	rsmresource_t	*p = NULL;
 	rsmhash_table_t *rhash = &rsm_import_segs;
@@ -3644,10 +3643,8 @@
  *
  */
 static void
-rsm_force_unload(rsm_node_id_t src_nodeid,
-    rsm_memseg_id_t ex_segid,
+rsm_force_unload(rsm_node_id_t src_nodeid, rsm_memseg_id_t ex_segid,
     boolean_t disconnect_flag)
-
 {
 	rsmresource_t	*p = NULL;
 	rsmhash_table_t *rhash = &rsm_import_segs;
@@ -6762,7 +6759,6 @@
 	return (DDI_SUCCESS);
 }
 
-/*ARGSUSED*/
 static int
 rsm_chpoll(dev_t dev, short events, int anyyet, short *reventsp,
     struct pollhead **phpp)
@@ -6784,8 +6780,6 @@
 		return (ENXIO);
 	}
 
-	*reventsp = 0;
-
 	/*
 	 * An exported segment must be in state RSM_STATE_EXPORT; an
 	 * imported segment must be in state RSM_STATE_ACTIVE.
@@ -6794,7 +6788,11 @@
 
 	if (seg->s_pollevent) {
 		*reventsp = POLLRDNORM;
-	} else if (!anyyet) {
+	} else {
+		*reventsp = 0;
+	}
+
+	if ((*reventsp == 0 && !anyyet) || (events & POLLET)) {
 		/* cannot take segment lock here */
 		*phpp = &seg->s_poll;
 		seg->s_pollflag |= RSM_SEGMENT_POLL;
@@ -8288,7 +8286,7 @@
 
 static int
 rsmmap_dup(devmap_cookie_t dhp, void *oldpvt, devmap_cookie_t new_dhp,
-	void **newpvt)
+    void **newpvt)
 {
 	rsmseg_t	*seg = (rsmseg_t *)oldpvt;
 	rsmcookie_t	*p, *old;
@@ -8339,8 +8337,8 @@
 
 static void
 rsmmap_unmap(devmap_cookie_t dhp, void *pvtp, offset_t off, size_t len,
-	devmap_cookie_t new_dhp1, void **pvtp1,
-	devmap_cookie_t new_dhp2, void **pvtp2)
+    devmap_cookie_t new_dhp1, void **pvtp1,
+    devmap_cookie_t new_dhp2, void **pvtp2)
 {
 	/*
 	 * Remove pvtp structure from segment list.
--- old/usr/src/uts/common/io/signalfd.c	Wed Oct 18 21:03:42 2017
+++ new/usr/src/uts/common/io/signalfd.c	Wed Oct 18 21:03:42 2017
@@ -10,7 +10,7 @@
  */
 
 /*
- * Copyright 2016 Joyent, Inc.
+ * Copyright 2017 Joyent, Inc.
  */
 
 /*
@@ -560,7 +560,6 @@
 	    set.__sigbits[2]) & FILLSET2));
 }
 
-_NOTE(ARGSUSED(4))
 static int
 signalfd_poll(dev_t dev, short events, int anyyet, short *reventsp,
     struct pollhead **phpp)
@@ -581,7 +580,8 @@
 
 	mutex_exit(&state->sfd_lock);
 
-	if (!(*reventsp = revents & events) && !anyyet) {
+	*reventsp = revents & events;
+	if ((*reventsp == 0 && !anyyet) || (events & POLLET)) {
 		sigfd_proc_state_t *pstate;
 		sigfd_poll_waiter_t *pw;
 
--- old/usr/src/uts/common/io/srn.c	Wed Oct 18 21:03:42 2017
+++ new/usr/src/uts/common/io/srn.c	Wed Oct 18 21:03:42 2017
@@ -22,6 +22,7 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2017 Joyent, Inc.
  */
 
 
@@ -253,7 +254,7 @@
 
 static int
 srn_chpoll(dev_t dev, short events, int anyyet, short *reventsp,
-	struct pollhead **phpp)
+    struct pollhead **phpp)
 {
 	extern struct pollhead srn_pollhead[];
 	int	clone;
@@ -263,10 +264,11 @@
 		*reventsp |= (POLLIN | POLLRDNORM);
 	} else {
 		*reventsp = 0;
-		if (!anyyet) {
-			*phpp = &srn_pollhead[clone];
-		}
 	}
+
+	if ((*reventsp == 0 && !anyyet) || (events & POLLET)) {
+		*phpp = &srn_pollhead[clone];
+	}
 	return (0);
 }
 
--- old/usr/src/uts/common/os/streamio.c	Wed Oct 18 21:03:43 2017
+++ new/usr/src/uts/common/os/streamio.c	Wed Oct 18 21:03:43 2017
@@ -24,7 +24,7 @@
 
 /*
  * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, Joyent, Inc. All rights reserved.
+ * Copyright 2017 Joyent, Inc.
  */
 
 #include <sys/types.h>
@@ -8174,12 +8174,8 @@
  * an M_PROTO/M_PCPROTO part).
  */
 int
-strpoll(
-	struct stdata *stp,
-	short events_arg,
-	int anyyet,
-	short *reventsp,
-	struct pollhead **phpp)
+strpoll(struct stdata *stp, short events_arg, int anyyet, short *reventsp,
+    struct pollhead **phpp)
 {
 	int events = (ushort_t)events_arg;
 	int retevents = 0;
@@ -8316,8 +8312,7 @@
 				retevents |= (events & (POLLIN | POLLRDBAND));
 			break;
 		}
-		if (! (retevents & normevents) &&
-		    (stp->sd_wakeq & RSLEEP)) {
+		if (!(retevents & normevents) && (stp->sd_wakeq & RSLEEP)) {
 			/*
 			 * Sync stream barrier read queue has data.
 			 */
@@ -8328,19 +8323,11 @@
 			retevents |= normevents;
 	}
 
-	*reventsp = (short)retevents;
-	if (retevents && !(events & POLLET)) {
-		if (headlocked)
-			mutex_exit(&stp->sd_lock);
-		return (0);
-	}
-
 	/*
-	 * If poll() has not found any events yet, set up event cell
-	 * to wake up the poll if a requested event occurs on this
-	 * stream.  Check for collisions with outstanding poll requests.
+	 * Pass back a pollhead if no events are pending or if edge-triggering
+	 * has been configured on this resource.
 	 */
-	if (!anyyet) {
+	if ((retevents == 0 && !anyyet) || (events & POLLET)) {
 		*phpp = &stp->sd_pollist;
 		if (headlocked == 0) {
 			if (polllock(&stp->sd_pollist, &stp->sd_lock) != 0) {
@@ -8351,6 +8338,8 @@
 		}
 		stp->sd_rput_opt |= SR_POLLIN;
 	}
+
+	*reventsp = (short)retevents;
 	if (headlocked)
 		mutex_exit(&stp->sd_lock);
 	return (0);
--- old/usr/src/uts/common/sys/1394/targets/dcam1394/dcam.h	Wed Oct 18 21:03:43 2017
+++ new/usr/src/uts/common/sys/1394/targets/dcam1394/dcam.h	Wed Oct 18 21:03:43 2017
@@ -22,13 +22,12 @@
 /*
  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2017 Joyent, Inc.
  */
 
 #ifndef _SYS_1394_TARGETS_DCAM1394_DCAM_H
 #define	_SYS_1394_TARGETS_DCAM1394_DCAM_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/modctl.h>
 #include <sys/ksynch.h>
 #include <sys/types.h>
@@ -120,7 +119,6 @@
 	int				cur_frame_rate;
 	int				cur_ring_buff_capacity;
 	int				param_status;
-	struct pollhead			dcam_pollhead;
 	int				camera_online;
 	int				pm_open_count;
 	int				pm_cable_power;
--- old/usr/src/uts/common/xen/io/evtchn_dev.c	Wed Oct 18 21:03:43 2017
+++ new/usr/src/uts/common/xen/io/evtchn_dev.c	Wed Oct 18 21:03:43 2017
@@ -22,6 +22,7 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2017 Joyent, Inc.
  */
 
 
@@ -450,7 +451,6 @@
 	short mask = 0;
 
 	ep = EVTCHNDRV_INST2SOFTS(EVTCHNDRV_MINOR2INST(minor));
-	*phpp = (struct pollhead *)NULL;
 
 	if (ev & POLLOUT)
 		mask |= POLLOUT;
@@ -458,13 +458,14 @@
 		mask |= POLLERR;
 	if (ev & (POLLIN | POLLRDNORM)) {
 		mutex_enter(&ep->evtchn_lock);
-		if (ep->ring_cons != ep->ring_prod)
+		if (ep->ring_cons != ep->ring_prod) {
 			mask |= (POLLIN | POLLRDNORM) & ev;
-		else
-			if (mask == 0 && !anyyet)
-				*phpp = &ep->evtchn_pollhead;
+		}
 		mutex_exit(&ep->evtchn_lock);
 	}
+	if ((mask == 0 && !anyyet) || (ev & POLLET)) {
+		*phpp = &ep->evtchn_pollhead;
+	}
 	*revp = mask;
 	return (0);
 }
--- old/usr/src/uts/common/xen/io/xpvtap.c	Wed Oct 18 21:03:43 2017
+++ new/usr/src/uts/common/xen/io/xpvtap.c	Wed Oct 18 21:03:43 2017
@@ -22,6 +22,7 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2017 Joyent, Inc.
  */
 
 
@@ -656,7 +657,6 @@
 	}
 
 	if (((events & (POLLIN | POLLRDNORM)) == 0) && !anyyet) {
-		*reventsp = 0;
 		return (EINVAL);
 	}
 
@@ -664,6 +664,7 @@
 	 * if we pushed requests on the user ring since the last poll, wakeup
 	 * the user app
 	 */
+	*reventsp = 0;
 	usring = &state->bt_user_ring;
 	if (usring->ur_prod_polled != usring->ur_ring.req_prod_pvt) {
 
@@ -677,13 +678,10 @@
 
 		usring->ur_prod_polled = usring->ur_ring.sring->req_prod;
 		*reventsp =  POLLIN | POLLRDNORM;
+	}
 
-	/* no new requests */
-	} else {
-		*reventsp = 0;
-		if (!anyyet) {
-			*phpp = &state->bt_pollhead;
-		}
+	if ((*reventsp == 0 && !anyyet) || (events & POLLET)) {
+		*phpp = &state->bt_pollhead;
 	}
 
 	return (0);
--- old/usr/src/uts/intel/io/ipmi/ipmi_main.c	Wed Oct 18 21:03:43 2017
+++ new/usr/src/uts/intel/io/ipmi/ipmi_main.c	Wed Oct 18 21:03:43 2017
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
+ * Copyright 2017 Joyent, Inc.
  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  */
 
@@ -460,10 +460,8 @@
 			revent |= POLLERR;
 	}
 
-	if (revent == 0) {
-		/* nothing has occurred */
-		if (!anyyet)
-			*phpp = dev->ipmi_pollhead;
+	if ((revent == 0 && !anyyet) || (events & POLLET)) {
+		*phpp = dev->ipmi_pollhead;
 	}
 
 	*reventsp = revent;
