xref: /netbsd-src/sys/arch/xen/xen/xenevt.c (revision ea1f84790aa5273f6624a94ad78ce383f09dea38)
1 /*      $NetBSD: xenevt.c,v 1.68 2022/09/22 16:21:34 bouyer Exp $      */
2 
3 /*
4  * Copyright (c) 2005 Manuel Bouyer.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  */
27 
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: xenevt.c,v 1.68 2022/09/22 16:21:34 bouyer Exp $");
30 
31 #include "opt_xen.h"
32 #include <sys/param.h>
33 #include <sys/kernel.h>
34 #include <sys/mutex.h>
35 #include <sys/systm.h>
36 #include <sys/device.h>
37 #include <sys/file.h>
38 #include <sys/filedesc.h>
39 #include <sys/poll.h>
40 #include <sys/select.h>
41 #include <sys/proc.h>
42 #include <sys/conf.h>
43 #include <sys/intr.h>
44 #include <sys/kmem.h>
45 
46 #include <uvm/uvm_extern.h>
47 
48 #include <xen/hypervisor.h>
49 #include <xen/evtchn.h>
50 #include <xen/intr.h>
51 #ifdef XENPV
52 #include <xen/xenpmap.h>
53 #endif
54 #include <xen/xenio.h>
55 #include <xen/xenio3.h>
56 #include <xen/xen.h>
57 
58 #include "ioconf.h"
59 
60 /*
61  * Interface between the event channel and userland.
62  * Each process with a xenevt device instance open can register events it
63  * wants to receive. It will get pending events by read(), eventually blocking
64  * until some event is available. Pending events are ack'd by a bitmask
65  * write()en to the device. Some special operations (such as events binding)
66  * are done though ioctl().
67  * Processes get a device instance by opening a cloning device.
68  */
69 
70 static int	xenevt_fread(struct file *, off_t *, struct uio *,
71     kauth_cred_t, int);
72 static int	xenevt_fwrite(struct file *, off_t *, struct uio *,
73     kauth_cred_t, int);
74 static int	xenevt_fioctl(struct file *, u_long, void *);
75 static int	xenevt_fpoll(struct file *, int);
76 static int	xenevt_fclose(struct file *);
77 /* static int	xenevt_fkqfilter(struct file *, struct knote *); */
78 
79 static const struct fileops xenevt_fileops = {
80 	.fo_name = "xenevt",
81 	.fo_read = xenevt_fread,
82 	.fo_write = xenevt_fwrite,
83 	.fo_ioctl = xenevt_fioctl,
84 	.fo_fcntl = fnullop_fcntl,
85 	.fo_poll = xenevt_fpoll,
86 	.fo_stat = fbadop_stat,
87 	.fo_close = xenevt_fclose,
88 	.fo_kqfilter = /* xenevt_fkqfilter */ fnullop_kqfilter,
89 	.fo_restart = fnullop_restart,
90 };
91 
92 dev_type_open(xenevtopen);
93 dev_type_read(xenevtread);
94 dev_type_mmap(xenevtmmap);
95 const struct cdevsw xenevt_cdevsw = {
96 	.d_open = xenevtopen,
97 	.d_close = nullclose,
98 	.d_read = xenevtread,
99 	.d_write = nowrite,
100 	.d_ioctl = noioctl,
101 	.d_stop = nostop,
102 	.d_tty = notty,
103 	.d_poll = nopoll,
104 	.d_mmap = xenevtmmap,
105 	.d_kqfilter = nokqfilter,
106 	.d_discard = nodiscard,
107 	.d_flag = D_OTHER
108 };
109 
110 /* minor numbers */
111 #define DEV_EVT 0
112 #define DEV_XSD 1
113 
114 /* per-instance datas */
115 #define XENEVT_RING_SIZE 2048
116 #define XENEVT_RING_MASK 2047
117 
118 #define BYTES_PER_PORT (sizeof(evtchn_port_t) / sizeof(uint8_t))
119 
120 struct xenevt_d {
121 	kmutex_t lock;
122 	kcondvar_t cv;
123 	STAILQ_ENTRY(xenevt_d) pendingq;
124 	bool pending;
125 	evtchn_port_t ring[2048];
126 	u_int ring_read; /* pointer of the reader */
127 	u_int ring_write; /* pointer of the writer */
128 	u_int flags;
129 #define XENEVT_F_OVERFLOW 0x01 /* ring overflow */
130 #define XENEVT_F_FREE 0x02 /* free entry */
131 	struct selinfo sel; /* used by poll */
132 	struct cpu_info *ci; /* preferred CPU for events for this device */
133 };
134 
135 static struct intrhand *xenevt_ih;
136 static evtchn_port_t xenevt_ev;
137 
138 /* event -> user device mapping */
139 static struct xenevt_d *devevent[NR_EVENT_CHANNELS];
140 
141 /* pending events */
142 static void *devevent_sih;
143 static kmutex_t devevent_lock;
144 static STAILQ_HEAD(, xenevt_d) devevent_pending;
145 
146 static void xenevt_record(struct xenevt_d *, evtchn_port_t);
147 static void xenevt_free(struct xenevt_d *);
148 
149 /* pending events */
150 long xenevt_ev1;
151 long xenevt_ev2[NR_EVENT_CHANNELS];
152 static int xenevt_processevt(void *);
153 
xenevt_alloc_event(void)154 static evtchn_port_t xenevt_alloc_event(void)
155 {
156 	evtchn_op_t op;
157 	op.cmd = EVTCHNOP_alloc_unbound;
158 	op.u.alloc_unbound.dom = DOMID_SELF;
159 	op.u.alloc_unbound.remote_dom = DOMID_SELF;
160 	if (HYPERVISOR_event_channel_op(&op) != 0)
161 		panic("%s: Failed to allocate loopback event\n", __func__);
162 
163 	return op.u.alloc_unbound.port;
164 }
165 
166 /* called at boot time */
167 void
xenevtattach(int n)168 xenevtattach(int n)
169 {
170 	int level = IPL_HIGH;
171 
172 	if (!xendomain_is_privileged())
173 		return;
174 #ifndef XENPV
175 	if (vm_guest != VM_GUEST_XENPVH)
176 		return;
177 #endif
178 
179 	mutex_init(&devevent_lock, MUTEX_DEFAULT, IPL_HIGH);
180 	STAILQ_INIT(&devevent_pending);
181 
182 	devevent_sih = softint_establish(SOFTINT_SERIAL,
183 	    (void (*)(void *))xenevt_notify, NULL);
184 	memset(devevent, 0, sizeof(devevent));
185 	xenevt_ev1 = 0;
186 	memset(xenevt_ev2, 0, sizeof(xenevt_ev2));
187 
188 	/*
189 	 * Allocate a loopback event port.
190 	 * It won't be used by itself, but will help registering IPL
191 	 * handlers.
192 	 */
193 	xenevt_ev = xenevt_alloc_event();
194 
195 	/*
196 	 * The real objective here is to wiggle into the ih callchain for
197 	 * IPL level on vCPU 0. (events are bound to vCPU 0 by default).
198 	 */
199 	xenevt_ih = event_set_handler(xenevt_ev, xenevt_processevt, NULL,
200 	    level, NULL, "xenevt", true, &cpu_info_primary);
201 
202 	KASSERT(xenevt_ih != NULL);
203 }
204 
205 /* register pending event - always called with interrupt disabled */
206 void
xenevt_setipending(int l1,int l2)207 xenevt_setipending(int l1, int l2)
208 {
209 	KASSERT(curcpu() == xenevt_ih->ih_cpu);
210 	KASSERT(xenevt_ih->ih_cpu->ci_ilevel >= IPL_HIGH);
211 	atomic_or_ulong(&xenevt_ev1, 1UL << l1);
212 	atomic_or_ulong(&xenevt_ev2[l1], 1UL << l2);
213 	atomic_or_64(&xenevt_ih->ih_cpu->ci_istate, (1ULL << SIR_XENIPL_HIGH));
214 	atomic_add_int(&xenevt_ih->ih_pending, 1);
215 	evtsource[xenevt_ev]->ev_evcnt.ev_count++;
216 }
217 
218 /* process pending events */
219 static int
xenevt_processevt(void * v)220 xenevt_processevt(void *v)
221 {
222 	long l1, l2;
223 	int l1i, l2i;
224 	int port;
225 
226 	l1 = xen_atomic_xchg(&xenevt_ev1, 0);
227 	while ((l1i = xen_ffs(l1)) != 0) {
228 		l1i--;
229 		l1 &= ~(1UL << l1i);
230 		l2 = xen_atomic_xchg(&xenevt_ev2[l1i], 0);
231 		while ((l2i = xen_ffs(l2)) != 0) {
232 			l2i--;
233 			l2 &= ~(1UL << l2i);
234 			port = (l1i << LONG_SHIFT) + l2i;
235 			xenevt_event(port);
236 		}
237 	}
238 
239 	return 0;
240 }
241 
242 
243 /* event callback, called at splhigh() */
244 void
xenevt_event(int port)245 xenevt_event(int port)
246 {
247 	struct xenevt_d *d;
248 
249 	mutex_enter(&devevent_lock);
250 	d = devevent[port];
251 	if (d != NULL) {
252 		xenevt_record(d, port);
253 
254 		if (d->pending == false) {
255 			STAILQ_INSERT_TAIL(&devevent_pending, d, pendingq);
256 			d->pending = true;
257 			mutex_exit(&devevent_lock);
258 			softint_schedule(devevent_sih);
259 			return;
260 		}
261 	}
262 	mutex_exit(&devevent_lock);
263 }
264 
265 void
xenevt_notify(void)266 xenevt_notify(void)
267 {
268 	struct xenevt_d *d;
269 
270 	for (;;) {
271 		mutex_enter(&devevent_lock);
272 		d = STAILQ_FIRST(&devevent_pending);
273 		if (d == NULL) {
274 			mutex_exit(&devevent_lock);
275 			break;
276 		}
277 		STAILQ_REMOVE_HEAD(&devevent_pending, pendingq);
278 		d->pending = false;
279 		mutex_enter(&d->lock);
280 		if (d->flags & XENEVT_F_FREE) {
281 			xenevt_free(d); /* releases devevent_lock */
282 		} else {
283 			mutex_exit(&devevent_lock);
284 			selnotify(&d->sel, 0, 1);
285 			cv_broadcast(&d->cv);
286 			mutex_exit(&d->lock);
287 		}
288 	}
289 }
290 
291 static void
xenevt_record(struct xenevt_d * d,evtchn_port_t port)292 xenevt_record(struct xenevt_d *d, evtchn_port_t port)
293 {
294 
295 	/*
296 	 * This algorithm overflows for one less slot than available.
297 	 * Not really an issue, and the correct algorithm would be more
298 	 * complex
299 	 */
300 
301 	mutex_enter(&d->lock);
302 	if (d->ring_read ==
303 	    ((d->ring_write + 1) & XENEVT_RING_MASK)) {
304 		d->flags |= XENEVT_F_OVERFLOW;
305 		printf("xenevt_event: ring overflow port %d\n", port);
306 	} else {
307 		d->ring[d->ring_write] = port;
308 		d->ring_write = (d->ring_write + 1) & XENEVT_RING_MASK;
309 	}
310 	mutex_exit(&d->lock);
311 }
312 
313 /* open the xenevt device; this is where we clone */
314 int
xenevtopen(dev_t dev,int flags,int mode,struct lwp * l)315 xenevtopen(dev_t dev, int flags, int mode, struct lwp *l)
316 {
317 	struct xenevt_d *d;
318 	struct file *fp;
319 	int fd, error;
320 
321 	switch(minor(dev)) {
322 	case DEV_EVT:
323 		/* falloc() will fill in the descriptor for us. */
324 		if ((error = fd_allocfile(&fp, &fd)) != 0)
325 			return error;
326 
327 		d = kmem_zalloc(sizeof(*d), KM_SLEEP);
328 		d->ci = xenevt_ih->ih_cpu;
329 		mutex_init(&d->lock, MUTEX_DEFAULT, IPL_HIGH);
330 		cv_init(&d->cv, "xenevt");
331 		selinit(&d->sel);
332 		return fd_clone(fp, fd, flags, &xenevt_fileops, d);
333 	case DEV_XSD:
334 		/* no clone for /dev/xsd_kva */
335 		return (0);
336 	default:
337 		break;
338 	}
339 	return ENODEV;
340 }
341 
342 /* read from device: only for /dev/xsd_kva, xenevt is done though fread */
343 int
xenevtread(dev_t dev,struct uio * uio,int flags)344 xenevtread(dev_t dev, struct uio *uio, int flags)
345 {
346 #define LD_STRLEN 21 /* a 64bit integer needs 20 digits in base10 */
347 	if (minor(dev) == DEV_XSD) {
348 		char strbuf[LD_STRLEN], *bf;
349 		int off, error;
350 		size_t len;
351 
352 		off = (int)uio->uio_offset;
353 		if (off < 0)
354 			return EINVAL;
355 		len  = snprintf(strbuf, sizeof(strbuf), "%ld\n",
356 		    xen_start_info.store_mfn);
357 		if (off >= len) {
358 			bf = strbuf;
359 			len = 0;
360 		} else {
361 			bf = &strbuf[off];
362 			len -= off;
363 		}
364 		error = uiomove(bf, len, uio);
365 		return error;
366 	}
367 	return ENODEV;
368 }
369 
370 /* mmap: only for xsd_kva */
371 paddr_t
xenevtmmap(dev_t dev,off_t off,int prot)372 xenevtmmap(dev_t dev, off_t off, int prot)
373 {
374 	if (minor(dev) == DEV_XSD) {
375 		/* only one page, so off is always 0 */
376 		if (off != 0)
377 			return -1;
378 #ifdef XENPV
379 		return x86_btop(
380 		   xpmap_mtop((paddr_t)xen_start_info.store_mfn << PAGE_SHIFT));
381 #else
382 		return x86_btop(
383 		   (paddr_t)xen_start_info.store_mfn << PAGE_SHIFT);
384 #endif
385 	}
386 	return -1;
387 }
388 
389 static void
xenevt_free(struct xenevt_d * d)390 xenevt_free(struct xenevt_d *d)
391 {
392 	int i;
393 	KASSERT(mutex_owned(&devevent_lock));
394 	KASSERT(mutex_owned(&d->lock));
395 
396 	for (i = 0; i < NR_EVENT_CHANNELS; i++ ) {
397 		if (devevent[i] == d) {
398 			evtchn_op_t op = { .cmd = 0 };
399 			int error;
400 
401 			hypervisor_mask_event(i);
402 			xen_atomic_clear_bit(&d->ci->ci_evtmask[0], i);
403 			devevent[i] = NULL;
404 			op.cmd = EVTCHNOP_close;
405 			op.u.close.port = i;
406 			if ((error = HYPERVISOR_event_channel_op(&op))) {
407 				printf("xenevt_fclose: error %d from "
408 				    "hypervisor\n", -error);
409 			}
410 		}
411 	}
412 	mutex_exit(&d->lock);
413 	mutex_exit(&devevent_lock);
414 	seldestroy(&d->sel);
415 	cv_destroy(&d->cv);
416 	mutex_destroy(&d->lock);
417 	kmem_free(d, sizeof(*d));
418 }
419 
420 static int
xenevt_fclose(struct file * fp)421 xenevt_fclose(struct file *fp)
422 {
423 	struct xenevt_d *d = fp->f_data;
424 
425 	mutex_enter(&devevent_lock);
426 	mutex_enter(&d->lock);
427 	if (d->pending) {
428 		d->flags |= XENEVT_F_FREE;
429 		mutex_exit(&d->lock);
430 		mutex_exit(&devevent_lock);
431 	} else {
432 		xenevt_free(d); /* releases devevent_lock */
433 	}
434 
435 	fp->f_data = NULL;
436 	return (0);
437 }
438 
439 static int
xenevt_fread(struct file * fp,off_t * offp,struct uio * uio,kauth_cred_t cred,int flags)440 xenevt_fread(struct file *fp, off_t *offp, struct uio *uio,
441     kauth_cred_t cred, int flags)
442 {
443 	struct xenevt_d *d = fp->f_data;
444 	int error, ring_read, ring_write;
445 	size_t len, uio_len;
446 
447 	error = 0;
448 	mutex_enter(&d->lock);
449 	while (error == 0) {
450 		ring_read = d->ring_read;
451 		ring_write = d->ring_write;
452 		if (ring_read != ring_write) {
453 			break;
454 		}
455 		if (d->flags & XENEVT_F_OVERFLOW) {
456 			break;
457 		}
458 
459 		/* nothing to read */
460 		if ((fp->f_flag & FNONBLOCK) == 0) {
461 			error = cv_wait_sig(&d->cv, &d->lock);
462 		} else {
463 			error = EAGAIN;
464 		}
465 	}
466 	if (error == 0 && (d->flags & XENEVT_F_OVERFLOW)) {
467 		error = EFBIG;
468 	}
469 	mutex_exit(&d->lock);
470 
471 	if (error) {
472 		return error;
473 	}
474 
475 	uio_len = uio->uio_resid / BYTES_PER_PORT;
476 	if (ring_read <= ring_write)
477 		len = ring_write - ring_read;
478 	else
479 		len = XENEVT_RING_SIZE - ring_read;
480 	if (len > uio_len)
481 		len = uio_len;
482 	error = uiomove(&d->ring[ring_read], len * BYTES_PER_PORT, uio);
483 	if (error)
484 		return error;
485 	ring_read = (ring_read + len) & XENEVT_RING_MASK;
486 	uio_len = uio->uio_resid / BYTES_PER_PORT;
487 	if (uio_len == 0)
488 		goto done;
489 	/* ring wrapped, read the second part */
490 	len = ring_write - ring_read;
491 	if (len > uio_len)
492 		len = uio_len;
493 	error = uiomove(&d->ring[ring_read], len * BYTES_PER_PORT, uio);
494 	if (error)
495 		return error;
496 	ring_read = (ring_read + len) & XENEVT_RING_MASK;
497 
498 done:
499 	mutex_enter(&d->lock);
500 	d->ring_read = ring_read;
501 	mutex_exit(&d->lock);
502 
503 	return 0;
504 }
505 
506 static int
xenevt_fwrite(struct file * fp,off_t * offp,struct uio * uio,kauth_cred_t cred,int flags)507 xenevt_fwrite(struct file *fp, off_t *offp, struct uio *uio,
508     kauth_cred_t cred, int flags)
509 {
510 	struct xenevt_d *d = fp->f_data;
511 	uint16_t *chans;
512 	int i, nentries, error;
513 
514 	if (uio->uio_resid == 0)
515 		return (0);
516 	nentries = uio->uio_resid / sizeof(uint16_t);
517 	if (nentries >= NR_EVENT_CHANNELS)
518 		return EMSGSIZE;
519 	chans = kmem_alloc(nentries * sizeof(uint16_t), KM_SLEEP);
520 	error = uiomove(chans, uio->uio_resid, uio);
521 	if (error)
522 		goto out;
523 	mutex_enter(&devevent_lock);
524 	for (i = 0; i < nentries; i++) {
525 		if (chans[i] < NR_EVENT_CHANNELS &&
526 		    devevent[chans[i]] == d) {
527 			hypervisor_unmask_event(chans[i]);
528 		}
529 	}
530 	mutex_exit(&devevent_lock);
531 out:
532 	kmem_free(chans, nentries * sizeof(uint16_t));
533 	return 0;
534 }
535 
536 static int
xenevt_fioctl(struct file * fp,u_long cmd,void * addr)537 xenevt_fioctl(struct file *fp, u_long cmd, void *addr)
538 {
539 	struct xenevt_d *d = fp->f_data;
540 	evtchn_op_t op = { .cmd = 0 };
541 	int error;
542 
543 	switch(cmd) {
544 	case EVTCHN_RESET:
545 	case IOCTL_EVTCHN_RESET:
546 		mutex_enter(&d->lock);
547 		d->ring_read = d->ring_write = 0;
548 		d->flags = 0;
549 		mutex_exit(&d->lock);
550 		break;
551 	case IOCTL_EVTCHN_BIND_VIRQ:
552 	{
553 		struct ioctl_evtchn_bind_virq *bind_virq = addr;
554 		op.cmd = EVTCHNOP_bind_virq;
555 		op.u.bind_virq.virq = bind_virq->virq;
556 		op.u.bind_virq.vcpu = 0;
557 		if ((error = HYPERVISOR_event_channel_op(&op))) {
558 			printf("IOCTL_EVTCHN_BIND_VIRQ failed: virq %d error %d\n", bind_virq->virq, error);
559 			return -error;
560 		}
561 		bind_virq->port = op.u.bind_virq.port;
562 		mutex_enter(&devevent_lock);
563 		KASSERT(devevent[bind_virq->port] == NULL);
564 		devevent[bind_virq->port] = d;
565 		mutex_exit(&devevent_lock);
566 		xen_atomic_set_bit(&d->ci->ci_evtmask[0], bind_virq->port);
567 		hypervisor_unmask_event(bind_virq->port);
568 		break;
569 	}
570 	case IOCTL_EVTCHN_BIND_INTERDOMAIN:
571 	{
572 		struct ioctl_evtchn_bind_interdomain *bind_intd = addr;
573 		op.cmd = EVTCHNOP_bind_interdomain;
574 		op.u.bind_interdomain.remote_dom = bind_intd->remote_domain;
575 		op.u.bind_interdomain.remote_port = bind_intd->remote_port;
576 		if ((error = HYPERVISOR_event_channel_op(&op)))
577 			return -error;
578 		bind_intd->port = op.u.bind_interdomain.local_port;
579 		mutex_enter(&devevent_lock);
580 		KASSERT(devevent[bind_intd->port] == NULL);
581 		devevent[bind_intd->port] = d;
582 		mutex_exit(&devevent_lock);
583 		xen_atomic_set_bit(&d->ci->ci_evtmask[0], bind_intd->port);
584 		hypervisor_unmask_event(bind_intd->port);
585 		break;
586 	}
587 	case IOCTL_EVTCHN_BIND_UNBOUND_PORT:
588 	{
589 		struct ioctl_evtchn_bind_unbound_port *bind_unbound = addr;
590 		op.cmd = EVTCHNOP_alloc_unbound;
591 		op.u.alloc_unbound.dom = DOMID_SELF;
592 		op.u.alloc_unbound.remote_dom = bind_unbound->remote_domain;
593 		if ((error = HYPERVISOR_event_channel_op(&op)))
594 			return -error;
595 		bind_unbound->port = op.u.alloc_unbound.port;
596 		mutex_enter(&devevent_lock);
597 		KASSERT(devevent[bind_unbound->port] == NULL);
598 		devevent[bind_unbound->port] = d;
599 		mutex_exit(&devevent_lock);
600 		xen_atomic_set_bit(&d->ci->ci_evtmask[0], bind_unbound->port);
601 		hypervisor_unmask_event(bind_unbound->port);
602 		break;
603 	}
604 	case IOCTL_EVTCHN_UNBIND:
605 	{
606 		struct ioctl_evtchn_unbind *unbind = addr;
607 
608 		if (unbind->port >= NR_EVENT_CHANNELS)
609 			return EINVAL;
610 		mutex_enter(&devevent_lock);
611 		if (devevent[unbind->port] != d) {
612 			mutex_exit(&devevent_lock);
613 			return ENOTCONN;
614 		}
615 		devevent[unbind->port] = NULL;
616 		mutex_exit(&devevent_lock);
617 		hypervisor_mask_event(unbind->port);
618 		xen_atomic_clear_bit(&d->ci->ci_evtmask[0], unbind->port);
619 		op.cmd = EVTCHNOP_close;
620 		op.u.close.port = unbind->port;
621 		if ((error = HYPERVISOR_event_channel_op(&op)))
622 			return -error;
623 		break;
624 	}
625 	case IOCTL_EVTCHN_NOTIFY:
626 	{
627 		struct ioctl_evtchn_notify *notify = addr;
628 
629 		if (notify->port >= NR_EVENT_CHANNELS)
630 			return EINVAL;
631 		mutex_enter(&devevent_lock);
632 		if (devevent[notify->port] != d) {
633 			mutex_exit(&devevent_lock);
634 			return ENOTCONN;
635 		}
636 		hypervisor_notify_via_evtchn(notify->port);
637 		mutex_exit(&devevent_lock);
638 		break;
639 	}
640 	case FIONBIO:
641 		break;
642 	default:
643 		return EINVAL;
644 	}
645 	return 0;
646 }
647 
648 /*
649  * Support for poll() system call
650  *
651  * Return true if the specific operation will not block indefinitely.
652  */
653 
654 static int
xenevt_fpoll(struct file * fp,int events)655 xenevt_fpoll(struct file *fp, int events)
656 {
657 	struct xenevt_d *d = fp->f_data;
658 	int revents = events & (POLLOUT | POLLWRNORM); /* we can always write */
659 
660 	mutex_enter(&d->lock);
661 	if (events & (POLLIN | POLLRDNORM)) {
662 		if (d->ring_read != d->ring_write) {
663 			revents |= events & (POLLIN | POLLRDNORM);
664 		} else {
665 			/* Record that someone is waiting */
666 			selrecord(curlwp, &d->sel);
667 		}
668 	}
669 	mutex_exit(&d->lock);
670 	return (revents);
671 }
672