xref: /freebsd/sys/dev/xen/evtchn/evtchn_dev.c (revision d0b2dbfa0ecf2bbc9709efc5e20baf8e4b44bbbf)
1 /******************************************************************************
2  * evtchn.c
3  *
4  * Driver for receiving and demuxing event-channel signals.
5  *
6  * Copyright (c) 2004-2005, K A Fraser
7  * Multi-process extensions Copyright (c) 2004, Steven Smith
8  * FreeBSD port Copyright (c) 2014, Roger Pau Monné
9  * Fetched from git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
10  * File: drivers/xen/evtchn.c
11  * Git commit: 0dc0064add422bc0ef5165ebe9ece3052bbd457d
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License version 2
15  * as published by the Free Software Foundation; or, when distributed
16  * separately from the Linux kernel or incorporated into other
17  * software packages, subject to the following license:
18  *
19  * Permission is hereby granted, free of charge, to any person obtaining a copy
20  * of this source file (the "Software"), to deal in the Software without
21  * restriction, including without limitation the rights to use, copy, modify,
22  * merge, publish, distribute, sublicense, and/or sell copies of the Software,
23  * and to permit persons to whom the Software is furnished to do so, subject to
24  * the following conditions:
25  *
26  * The above copyright notice and this permission notice shall be included in
27  * all copies or substantial portions of the Software.
28  *
29  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
34  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
35  * IN THE SOFTWARE.
36  */
37 
38 #include <sys/cdefs.h>
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/uio.h>
42 #include <sys/bus.h>
43 #include <sys/malloc.h>
44 #include <sys/kernel.h>
45 #include <sys/lock.h>
46 #include <sys/mutex.h>
47 #include <sys/sx.h>
48 #include <sys/selinfo.h>
49 #include <sys/poll.h>
50 #include <sys/conf.h>
51 #include <sys/fcntl.h>
52 #include <sys/ioccom.h>
53 #include <sys/rman.h>
54 #include <sys/tree.h>
55 #include <sys/module.h>
56 #include <sys/filio.h>
57 #include <sys/vnode.h>
58 
59 #include <xen/xen-os.h>
60 #include <xen/evtchn.h>
61 #include <xen/xen_intr.h>
62 
63 #include <xen/evtchn/evtchnvar.h>
64 
65 MALLOC_DEFINE(M_EVTCHN, "evtchn_dev", "Xen event channel user-space device");
66 
67 struct user_evtchn;
68 
69 static int evtchn_cmp(struct user_evtchn *u1, struct user_evtchn *u2);
70 
71 RB_HEAD(evtchn_tree, user_evtchn);
72 
73 struct per_user_data {
74 	struct mtx bind_mutex; /* serialize bind/unbind operations */
75 	struct evtchn_tree evtchns;
76 
77 	/* Notification ring, accessed via /dev/xen/evtchn. */
78 #define EVTCHN_RING_SIZE     (PAGE_SIZE / sizeof(evtchn_port_t))
79 #define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1))
80 	evtchn_port_t *ring;
81 	unsigned int ring_cons, ring_prod, ring_overflow;
82 	struct sx ring_cons_mutex; /* protect against concurrent readers */
83 	struct mtx ring_prod_mutex; /* product against concurrent interrupts */
84 	struct selinfo ev_rsel;
85 };
86 
87 struct user_evtchn {
88 	RB_ENTRY(user_evtchn) node;
89 	struct per_user_data *user;
90 	evtchn_port_t port;
91 	xen_intr_handle_t handle;
92 	bool enabled;
93 };
94 
95 RB_GENERATE_STATIC(evtchn_tree, user_evtchn, node, evtchn_cmp);
96 
97 static device_t evtchn_dev;
98 
99 static d_read_t      evtchn_read;
100 static d_write_t     evtchn_write;
101 static d_ioctl_t     evtchn_ioctl;
102 static d_poll_t      evtchn_poll;
103 static d_open_t      evtchn_open;
104 
105 static void evtchn_release(void *arg);
106 
107 static struct cdevsw evtchn_devsw = {
108 	.d_version = D_VERSION,
109 	.d_open = evtchn_open,
110 	.d_read = evtchn_read,
111 	.d_write = evtchn_write,
112 	.d_ioctl = evtchn_ioctl,
113 	.d_poll = evtchn_poll,
114 	.d_name = "evtchn",
115 };
116 
117 /*------------------------- Red-black tree helpers ---------------------------*/
118 static int
119 evtchn_cmp(struct user_evtchn *u1, struct user_evtchn *u2)
120 {
121 
122 	return (u1->port - u2->port);
123 }
124 
125 static struct user_evtchn *
126 find_evtchn(struct per_user_data *u, evtchn_port_t port)
127 {
128 	struct user_evtchn tmp = {
129 		.port = port,
130 	};
131 
132 	return (RB_FIND(evtchn_tree, &u->evtchns, &tmp));
133 }
134 
135 /*--------------------------- Interrupt handlers -----------------------------*/
136 static int
137 evtchn_filter(void *arg)
138 {
139 	struct user_evtchn *evtchn;
140 
141 	evtchn = arg;
142 
143 	if (!evtchn->enabled && bootverbose) {
144 		device_printf(evtchn_dev,
145 		    "Received upcall for disabled event channel %d\n",
146 		    evtchn->port);
147 	}
148 
149 	evtchn_mask_port(evtchn->port);
150 	evtchn->enabled = false;
151 
152 	return (FILTER_SCHEDULE_THREAD);
153 }
154 
155 static void
156 evtchn_interrupt(void *arg)
157 {
158 	struct user_evtchn *evtchn;
159 	struct per_user_data *u;
160 
161 	evtchn = arg;
162 	u = evtchn->user;
163 
164 	/*
165 	 * Protect against concurrent events using this handler
166 	 * on different CPUs.
167 	 */
168 	mtx_lock(&u->ring_prod_mutex);
169 	if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) {
170 		u->ring[EVTCHN_RING_MASK(u->ring_prod)] = evtchn->port;
171 		wmb(); /* Ensure ring contents visible */
172 		if (u->ring_cons == u->ring_prod++) {
173 			wakeup(u);
174 			selwakeup(&u->ev_rsel);
175 		}
176 	} else
177 		u->ring_overflow = 1;
178 	mtx_unlock(&u->ring_prod_mutex);
179 }
180 
181 /*------------------------- Character device methods -------------------------*/
182 static int
183 evtchn_open(struct cdev *dev, int flag, int otyp, struct thread *td)
184 {
185 	struct per_user_data *u;
186 	int error;
187 
188 	u = malloc(sizeof(*u), M_EVTCHN, M_WAITOK | M_ZERO);
189 	u->ring = malloc(PAGE_SIZE, M_EVTCHN, M_WAITOK | M_ZERO);
190 
191 	/* Initialize locks */
192 	mtx_init(&u->bind_mutex, "evtchn_bind_mutex", NULL, MTX_DEF);
193 	sx_init(&u->ring_cons_mutex, "evtchn_ringc_sx");
194 	mtx_init(&u->ring_prod_mutex, "evtchn_ringp_mutex", NULL, MTX_DEF);
195 
196 	/* Initialize red-black tree. */
197 	RB_INIT(&u->evtchns);
198 
199 	/* Assign the allocated per_user_data to this open instance. */
200 	error = devfs_set_cdevpriv(u, evtchn_release);
201 	if (error != 0) {
202 		mtx_destroy(&u->bind_mutex);
203 		mtx_destroy(&u->ring_prod_mutex);
204 		sx_destroy(&u->ring_cons_mutex);
205 		free(u->ring, M_EVTCHN);
206 		free(u, M_EVTCHN);
207 	}
208 
209 	return (error);
210 }
211 
212 static void
213 evtchn_release(void *arg)
214 {
215 	struct per_user_data *u;
216 	struct user_evtchn *evtchn, *tmp;
217 
218 	u = arg;
219 
220 	seldrain(&u->ev_rsel);
221 
222 	RB_FOREACH_SAFE(evtchn, evtchn_tree, &u->evtchns, tmp) {
223 		xen_intr_unbind(&evtchn->handle);
224 
225 		RB_REMOVE(evtchn_tree, &u->evtchns, evtchn);
226 		free(evtchn, M_EVTCHN);
227 	}
228 
229 	mtx_destroy(&u->bind_mutex);
230 	mtx_destroy(&u->ring_prod_mutex);
231 	sx_destroy(&u->ring_cons_mutex);
232 	free(u->ring, M_EVTCHN);
233 	free(u, M_EVTCHN);
234 }
235 
236 static int
237 evtchn_read(struct cdev *dev, struct uio *uio, int ioflag)
238 {
239 	int error, count;
240 	unsigned int c, p, bytes1 = 0, bytes2 = 0;
241 	struct per_user_data *u;
242 
243 	error = devfs_get_cdevpriv((void **)&u);
244 	if (error != 0)
245 		return (EINVAL);
246 
247 	/* Whole number of ports. */
248 	count = uio->uio_resid;
249 	count &= ~(sizeof(evtchn_port_t)-1);
250 
251 	if (count == 0)
252 		return (0);
253 
254 	if (count > PAGE_SIZE)
255 		count = PAGE_SIZE;
256 
257 	sx_xlock(&u->ring_cons_mutex);
258 	for (;;) {
259 		if (u->ring_overflow) {
260 			error = EFBIG;
261 			goto unlock_out;
262 		}
263 
264 		c = u->ring_cons;
265 		p = u->ring_prod;
266 		if (c != p)
267 			break;
268 
269 		if (ioflag & IO_NDELAY) {
270 			error = EWOULDBLOCK;
271 			goto unlock_out;
272 		}
273 
274 		error = sx_sleep(u, &u->ring_cons_mutex, PCATCH, "evtchw", 0);
275 		if ((error != 0) && (error != EWOULDBLOCK))
276 			goto unlock_out;
277 	}
278 
279 	/* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */
280 	if (((c ^ p) & EVTCHN_RING_SIZE) != 0) {
281 		bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) *
282 		    sizeof(evtchn_port_t);
283 		bytes2 = EVTCHN_RING_MASK(p) * sizeof(evtchn_port_t);
284 	} else {
285 		bytes1 = (p - c) * sizeof(evtchn_port_t);
286 		bytes2 = 0;
287 	}
288 
289 	/* Truncate chunks according to caller's maximum byte count. */
290 	if (bytes1 > count) {
291 		bytes1 = count;
292 		bytes2 = 0;
293 	} else if ((bytes1 + bytes2) > count) {
294 		bytes2 = count - bytes1;
295 	}
296 
297 	error = EFAULT;
298 	rmb(); /* Ensure that we see the port before we copy it. */
299 
300 	if (uiomove(&u->ring[EVTCHN_RING_MASK(c)], bytes1, uio) ||
301 	    ((bytes2 != 0) && uiomove(&u->ring[0], bytes2, uio)))
302 		goto unlock_out;
303 
304 	u->ring_cons += (bytes1 + bytes2) / sizeof(evtchn_port_t);
305 	error = 0;
306 
307 unlock_out:
308 	sx_xunlock(&u->ring_cons_mutex);
309 	return (error);
310 }
311 
312 static int
313 evtchn_write(struct cdev *dev, struct uio *uio, int ioflag)
314 {
315 	int error, i, count;
316 	evtchn_port_t *kbuf;
317 	struct per_user_data *u;
318 
319 	error = devfs_get_cdevpriv((void **)&u);
320 	if (error != 0)
321 		return (EINVAL);
322 
323 	kbuf = malloc(PAGE_SIZE, M_EVTCHN, M_WAITOK);
324 
325 	count = uio->uio_resid;
326 	/* Whole number of ports. */
327 	count &= ~(sizeof(evtchn_port_t)-1);
328 
329 	error = 0;
330 	if (count == 0)
331 		goto out;
332 
333 	if (count > PAGE_SIZE)
334 		count = PAGE_SIZE;
335 
336 	error = uiomove(kbuf, count, uio);
337 	if (error != 0)
338 		goto out;
339 
340 	mtx_lock(&u->bind_mutex);
341 
342 	for (i = 0; i < (count/sizeof(evtchn_port_t)); i++) {
343 		evtchn_port_t port = kbuf[i];
344 		struct user_evtchn *evtchn;
345 
346 		evtchn = find_evtchn(u, port);
347 		if (evtchn && !evtchn->enabled) {
348 			evtchn->enabled = true;
349 			evtchn_unmask_port(evtchn->port);
350 		}
351 	}
352 
353 	mtx_unlock(&u->bind_mutex);
354 	error = 0;
355 
356 out:
357 	free(kbuf, M_EVTCHN);
358 	return (error);
359 }
360 
361 static inline int
362 evtchn_bind_user_port(struct per_user_data *u, struct user_evtchn *evtchn)
363 {
364 	int error;
365 
366 	evtchn->port = xen_intr_port(evtchn->handle);
367 	evtchn->user = u;
368 	evtchn->enabled = true;
369 	mtx_lock(&u->bind_mutex);
370 	RB_INSERT(evtchn_tree, &u->evtchns, evtchn);
371 	mtx_unlock(&u->bind_mutex);
372 	error = xen_intr_add_handler(device_get_nameunit(evtchn_dev),
373 	    evtchn_filter, evtchn_interrupt, evtchn,
374 	    INTR_TYPE_MISC | INTR_MPSAFE, evtchn->handle);
375 	if (error != 0) {
376 		xen_intr_unbind(&evtchn->handle);
377 		mtx_lock(&u->bind_mutex);
378 		RB_REMOVE(evtchn_tree, &u->evtchns, evtchn);
379 		mtx_unlock(&u->bind_mutex);
380 		free(evtchn, M_EVTCHN);
381 	}
382 	return (error);
383 }
384 
385 static int
386 evtchn_ioctl(struct cdev *dev, unsigned long cmd, caddr_t arg,
387     int mode, struct thread *td __unused)
388 {
389 	struct per_user_data *u;
390 	int error;
391 
392 	error = devfs_get_cdevpriv((void **)&u);
393 	if (error != 0)
394 		return (EINVAL);
395 
396 	switch (cmd) {
397 	case IOCTL_EVTCHN_BIND_VIRQ: {
398 		struct ioctl_evtchn_bind_virq *bind;
399 		struct user_evtchn *evtchn;
400 
401 		evtchn = malloc(sizeof(*evtchn), M_EVTCHN, M_WAITOK | M_ZERO);
402 
403 		bind = (struct ioctl_evtchn_bind_virq *)arg;
404 
405 		error = xen_intr_bind_virq(evtchn_dev, bind->virq, 0,
406 		    NULL, NULL, NULL, 0, &evtchn->handle);
407 		if (error != 0) {
408 			free(evtchn, M_EVTCHN);
409 			break;
410 		}
411 		error = evtchn_bind_user_port(u, evtchn);
412 		if (error != 0)
413 			break;
414 		bind->port = evtchn->port;
415 		break;
416 	}
417 
418 	case IOCTL_EVTCHN_BIND_INTERDOMAIN: {
419 		struct ioctl_evtchn_bind_interdomain *bind;
420 		struct user_evtchn *evtchn;
421 
422 		evtchn = malloc(sizeof(*evtchn), M_EVTCHN, M_WAITOK | M_ZERO);
423 
424 		bind = (struct ioctl_evtchn_bind_interdomain *)arg;
425 
426 		error = xen_intr_bind_remote_port(evtchn_dev,
427 		    bind->remote_domain, bind->remote_port, NULL,
428 		    NULL, NULL, 0, &evtchn->handle);
429 		if (error != 0) {
430 			free(evtchn, M_EVTCHN);
431 			break;
432 		}
433 		error = evtchn_bind_user_port(u, evtchn);
434 		if (error != 0)
435 			break;
436 		bind->port = evtchn->port;
437 		break;
438 	}
439 
440 	case IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
441 		struct ioctl_evtchn_bind_unbound_port *bind;
442 		struct user_evtchn *evtchn;
443 
444 		evtchn = malloc(sizeof(*evtchn), M_EVTCHN, M_WAITOK | M_ZERO);
445 
446 		bind = (struct ioctl_evtchn_bind_unbound_port *)arg;
447 
448 		error = xen_intr_alloc_and_bind_local_port(evtchn_dev,
449 		    bind->remote_domain, NULL, NULL, NULL, 0, &evtchn->handle);
450 		if (error != 0) {
451 			free(evtchn, M_EVTCHN);
452 			break;
453 		}
454 		error = evtchn_bind_user_port(u, evtchn);
455 		if (error != 0)
456 			break;
457 		bind->port = evtchn->port;
458 		break;
459 	}
460 
461 	case IOCTL_EVTCHN_UNBIND: {
462 		struct ioctl_evtchn_unbind *unbind;
463 		struct user_evtchn *evtchn;
464 
465 		unbind = (struct ioctl_evtchn_unbind *)arg;
466 
467 		mtx_lock(&u->bind_mutex);
468 		evtchn = find_evtchn(u, unbind->port);
469 		if (evtchn == NULL) {
470 			error = ENOTCONN;
471 			break;
472 		}
473 		RB_REMOVE(evtchn_tree, &u->evtchns, evtchn);
474 		mtx_unlock(&u->bind_mutex);
475 
476 		xen_intr_unbind(&evtchn->handle);
477 		free(evtchn, M_EVTCHN);
478 		error = 0;
479 		break;
480 	}
481 
482 	case IOCTL_EVTCHN_NOTIFY: {
483 		struct ioctl_evtchn_notify *notify;
484 		struct user_evtchn *evtchn;
485 
486 		notify = (struct ioctl_evtchn_notify *)arg;
487 
488 		mtx_lock(&u->bind_mutex);
489 		evtchn = find_evtchn(u, notify->port);
490 		if (evtchn == NULL) {
491 			error = ENOTCONN;
492 			break;
493 		}
494 
495 		xen_intr_signal(evtchn->handle);
496 		mtx_unlock(&u->bind_mutex);
497 		error = 0;
498 		break;
499 	}
500 
501 	case IOCTL_EVTCHN_RESET: {
502 		/* Initialise the ring to empty. Clear errors. */
503 		sx_xlock(&u->ring_cons_mutex);
504 		mtx_lock(&u->ring_prod_mutex);
505 		u->ring_cons = u->ring_prod = u->ring_overflow = 0;
506 		mtx_unlock(&u->ring_prod_mutex);
507 		sx_xunlock(&u->ring_cons_mutex);
508 		error = 0;
509 		break;
510 	}
511 
512 	case FIONBIO:
513 	case FIOASYNC:
514 		/* Handled in an upper layer */
515 		error = 0;
516 		break;
517 
518 	default:
519 		error = ENOTTY;
520 		break;
521 	}
522 
523 	return (error);
524 }
525 
526 static int
527 evtchn_poll(struct cdev *dev, int events, struct thread *td)
528 {
529 	struct per_user_data *u;
530 	int error, mask;
531 
532 	error = devfs_get_cdevpriv((void **)&u);
533 	if (error != 0)
534 		return (POLLERR);
535 
536 	/* we can always write */
537 	mask = events & (POLLOUT | POLLWRNORM);
538 
539 	mtx_lock(&u->ring_prod_mutex);
540 	if (events & (POLLIN | POLLRDNORM)) {
541 		if (u->ring_cons != u->ring_prod) {
542 			mask |= events & (POLLIN | POLLRDNORM);
543 		} else {
544 			/* Record that someone is waiting */
545 			selrecord(td, &u->ev_rsel);
546 		}
547 	}
548 	mtx_unlock(&u->ring_prod_mutex);
549 
550 	return (mask);
551 }
552 
553 /*------------------ Private Device Attachment Functions  --------------------*/
554 static void
555 evtchn_identify(driver_t *driver, device_t parent)
556 {
557 
558 	KASSERT((xen_domain()),
559 	    ("Trying to attach evtchn device on non Xen domain"));
560 
561 	evtchn_dev = BUS_ADD_CHILD(parent, 0, "evtchn", 0);
562 	if (evtchn_dev == NULL)
563 		panic("unable to attach evtchn user-space device");
564 }
565 
566 static int
567 evtchn_probe(device_t dev)
568 {
569 
570 	device_set_desc(dev, "Xen event channel user-space device");
571 	return (BUS_PROBE_NOWILDCARD);
572 }
573 
574 static int
575 evtchn_attach(device_t dev)
576 {
577 
578 	make_dev_credf(MAKEDEV_ETERNAL, &evtchn_devsw, 0, NULL, UID_ROOT,
579 	    GID_WHEEL, 0600, "xen/evtchn");
580 	return (0);
581 }
582 
583 /*-------------------- Private Device Attachment Data  -----------------------*/
584 static device_method_t evtchn_methods[] = {
585 	DEVMETHOD(device_identify, evtchn_identify),
586 	DEVMETHOD(device_probe, evtchn_probe),
587 	DEVMETHOD(device_attach, evtchn_attach),
588 
589 	DEVMETHOD_END
590 };
591 
592 static driver_t evtchn_driver = {
593 	"evtchn",
594 	evtchn_methods,
595 	0,
596 };
597 
598 DRIVER_MODULE(evtchn, xenpv, evtchn_driver, 0, 0);
599 MODULE_DEPEND(evtchn, xenpv, 1, 1, 1);
600