xref: /freebsd/sys/dev/xen/evtchn/evtchn_dev.c (revision aa0a1e58)
1 /******************************************************************************
2  * evtchn.c
3  *
4  * Xenolinux driver for receiving and demuxing event-channel signals.
5  *
6  * Copyright (c) 2004, K A Fraser
7  */
8 
9 #include <sys/cdefs.h>
10 __FBSDID("$FreeBSD$");
11 
12 #include <sys/param.h>
13 #include <sys/systm.h>
14 #include <sys/uio.h>
15 #include <sys/bus.h>
16 #include <sys/malloc.h>
17 #include <sys/kernel.h>
18 #include <sys/lock.h>
19 #include <sys/mutex.h>
20 #include <sys/selinfo.h>
21 #include <sys/poll.h>
22 #include <sys/conf.h>
23 #include <sys/fcntl.h>
24 #include <sys/ioccom.h>
25 
26 #include <machine/cpufunc.h>
27 #include <machine/intr_machdep.h>
28 #include <machine/xen-os.h>
29 #include <xen/xen_intr.h>
30 #include <machine/bus.h>
31 #include <sys/rman.h>
32 #include <machine/resource.h>
33 #include <machine/synch_bitops.h>
34 
35 #include <xen/hypervisor.h>
36 
37 
38 typedef struct evtchn_sotfc {
39 
40 	struct selinfo  ev_rsel;
41 } evtchn_softc_t;
42 
43 
44 #ifdef linuxcrap
45 /* NB. This must be shared amongst drivers if more things go in /dev/xen */
46 static devfs_handle_t xen_dev_dir;
47 #endif
48 
49 /* Only one process may open /dev/xen/evtchn at any time. */
50 static unsigned long evtchn_dev_inuse;
51 
52 /* Notification ring, accessed via /dev/xen/evtchn. */
53 
54 #define EVTCHN_RING_SIZE     2048  /* 2048 16-bit entries */
55 
56 #define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1))
57 static uint16_t *ring;
58 static unsigned int ring_cons, ring_prod, ring_overflow;
59 
60 /* Which ports is user-space bound to? */
61 static uint32_t bound_ports[32];
62 
63 /* Unique address for processes to sleep on */
64 static void *evtchn_waddr = &ring;
65 
66 static struct mtx lock, upcall_lock;
67 
68 static d_read_t      evtchn_read;
69 static d_write_t     evtchn_write;
70 static d_ioctl_t     evtchn_ioctl;
71 static d_poll_t      evtchn_poll;
72 static d_open_t      evtchn_open;
73 static d_close_t     evtchn_close;
74 
75 
76 void
77 evtchn_device_upcall(int port)
78 {
79 	mtx_lock(&upcall_lock);
80 
81 	mask_evtchn(port);
82 	clear_evtchn(port);
83 
84 	if ( ring != NULL ) {
85 		if ( (ring_prod - ring_cons) < EVTCHN_RING_SIZE ) {
86 			ring[EVTCHN_RING_MASK(ring_prod)] = (uint16_t)port;
87 			if ( ring_cons == ring_prod++ ) {
88 				wakeup(evtchn_waddr);
89 			}
90 		}
91 		else {
92 			ring_overflow = 1;
93 		}
94 	}
95 
96 	mtx_unlock(&upcall_lock);
97 }
98 
99 static void
100 __evtchn_reset_buffer_ring(void)
101 {
102 	/* Initialise the ring to empty. Clear errors. */
103 	ring_cons = ring_prod = ring_overflow = 0;
104 }
105 
106 static int
107 evtchn_read(struct cdev *dev, struct uio *uio, int ioflag)
108 {
109 	int rc;
110 	unsigned int count, c, p, sst = 0, bytes1 = 0, bytes2 = 0;
111 	count = uio->uio_resid;
112 
113 	count &= ~1; /* even number of bytes */
114 
115 	if ( count == 0 )
116 	{
117 		rc = 0;
118 		goto out;
119 	}
120 
121 	if ( count > PAGE_SIZE )
122 		count = PAGE_SIZE;
123 
124 	for ( ; ; ) {
125 		if ( (c = ring_cons) != (p = ring_prod) )
126 			break;
127 
128 		if ( ring_overflow ) {
129 			rc = EFBIG;
130 			goto out;
131 		}
132 
133 		if (sst != 0) {
134 			rc = EINTR;
135 			goto out;
136 		}
137 
138 		/* PCATCH == check for signals before and after sleeping
139 		 * PWAIT == priority of waiting on resource
140 		 */
141 		sst = tsleep(evtchn_waddr, PWAIT|PCATCH, "evchwt", 10);
142 	}
143 
144 	/* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */
145 	if ( ((c ^ p) & EVTCHN_RING_SIZE) != 0 ) {
146 		bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) * sizeof(uint16_t);
147 		bytes2 = EVTCHN_RING_MASK(p) * sizeof(uint16_t);
148 	}
149 	else {
150 		bytes1 = (p - c) * sizeof(uint16_t);
151 		bytes2 = 0;
152 	}
153 
154 	/* Truncate chunks according to caller's maximum byte count. */
155 	if ( bytes1 > count ) {
156 		bytes1 = count;
157 		bytes2 = 0;
158 	}
159 	else if ( (bytes1 + bytes2) > count ) {
160 		bytes2 = count - bytes1;
161 	}
162 
163 	if ( uiomove(&ring[EVTCHN_RING_MASK(c)], bytes1, uio) ||
164 	     ((bytes2 != 0) && uiomove(&ring[0], bytes2, uio)))
165 		/* keeping this around as its replacement is not equivalent
166 		 * copyout(&ring[0], &buf[bytes1], bytes2)
167 		 */
168 	{
169 		rc = EFAULT;
170 		goto out;
171 	}
172 
173 	ring_cons += (bytes1 + bytes2) / sizeof(uint16_t);
174 
175 	rc = bytes1 + bytes2;
176 
177  out:
178 
179 	return rc;
180 }
181 
182 static int
183 evtchn_write(struct cdev *dev, struct uio *uio, int ioflag)
184 {
185 	int  rc, i, count;
186 
187 	count = uio->uio_resid;
188 
189 	uint16_t *kbuf = (uint16_t *)malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK);
190 
191 
192 	if ( kbuf == NULL )
193 		return ENOMEM;
194 
195 	count &= ~1; /* even number of bytes */
196 
197 	if ( count == 0 ) {
198 		rc = 0;
199 		goto out;
200 	}
201 
202 	if ( count > PAGE_SIZE )
203 		count = PAGE_SIZE;
204 
205 	if ( uiomove(kbuf, count, uio) != 0 ) {
206 		rc = EFAULT;
207 		goto out;
208 	}
209 
210 	mtx_lock_spin(&lock);
211 	for ( i = 0; i < (count/2); i++ )
212 		if ( test_bit(kbuf[i], &bound_ports[0]) )
213 			unmask_evtchn(kbuf[i]);
214 	mtx_unlock_spin(&lock);
215 
216 	rc = count;
217 
218  out:
219 	free(kbuf, M_DEVBUF);
220 	return rc;
221 }
222 
223 static int
224 evtchn_ioctl(struct cdev *dev, unsigned long cmd, caddr_t arg,
225 	     int mode, struct thread *td __unused)
226 {
227 	int rc = 0;
228 
229 	mtx_lock_spin(&lock);
230 
231 	switch ( cmd )
232 	{
233 	case EVTCHN_RESET:
234 		__evtchn_reset_buffer_ring();
235 		break;
236 	case EVTCHN_BIND:
237 		if ( !synch_test_and_set_bit((int)arg, &bound_ports[0]) )
238 			unmask_evtchn((int)arg);
239 		else
240 			rc = EINVAL;
241 		break;
242 	case EVTCHN_UNBIND:
243 		if ( synch_test_and_clear_bit((int)arg, &bound_ports[0]) )
244 			mask_evtchn((int)arg);
245 		else
246 			rc = EINVAL;
247 		break;
248 	default:
249 		rc = ENOSYS;
250 		break;
251 	}
252 
253 	mtx_unlock_spin(&lock);
254 
255 	return rc;
256 }
257 
258 static int
259 evtchn_poll(struct cdev *dev, int poll_events, struct thread *td)
260 {
261 
262 	evtchn_softc_t *sc;
263 	unsigned int mask = POLLOUT | POLLWRNORM;
264 
265 	sc = dev->si_drv1;
266 
267 	if ( ring_cons != ring_prod )
268 		mask |= POLLIN | POLLRDNORM;
269 	else if ( ring_overflow )
270 		mask = POLLERR;
271 	else
272 		selrecord(td, &sc->ev_rsel);
273 
274 
275 	return mask;
276 }
277 
278 
279 static int
280 evtchn_open(struct cdev *dev, int flag, int otyp, struct thread *td)
281 {
282 	uint16_t *_ring;
283 
284 	if (flag & O_NONBLOCK)
285 		return EBUSY;
286 
287 	if ( synch_test_and_set_bit(0, &evtchn_dev_inuse) )
288 		return EBUSY;
289 
290 	if ( (_ring = (uint16_t *)malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK)) == NULL )
291 		return ENOMEM;
292 
293 	mtx_lock_spin(&lock);
294 	ring = _ring;
295 	__evtchn_reset_buffer_ring();
296 	mtx_unlock_spin(&lock);
297 
298 
299 	return 0;
300 }
301 
302 static int
303 evtchn_close(struct cdev *dev, int flag, int otyp, struct thread *td __unused)
304 {
305 	int i;
306 
307 	mtx_lock_spin(&lock);
308 	if (ring != NULL) {
309 		free(ring, M_DEVBUF);
310 		ring = NULL;
311 	}
312 	for ( i = 0; i < NR_EVENT_CHANNELS; i++ )
313 		if ( synch_test_and_clear_bit(i, &bound_ports[0]) )
314 			mask_evtchn(i);
315 	mtx_unlock_spin(&lock);
316 
317 	evtchn_dev_inuse = 0;
318 
319 	return 0;
320 }
321 
322 static struct cdevsw evtchn_devsw = {
323 	d_version:   D_VERSION,
324 	d_open:      evtchn_open,
325 	d_close:     evtchn_close,
326 	d_read:      evtchn_read,
327 	d_write:     evtchn_write,
328 	d_ioctl:     evtchn_ioctl,
329 	d_poll:      evtchn_poll,
330 	d_name:      "evtchn",
331 	d_flags:     0,
332 };
333 
334 
335 /* XXX  - if this device is ever supposed to support use by more than one process
336  * this global static will have to go away
337  */
338 static struct cdev *evtchn_dev;
339 
340 
341 
342 static int
343 evtchn_init(void *dummy __unused)
344 {
345 	/* XXX I believe we don't need these leaving them here for now until we
346 	 * have some semblance of it working
347 	 */
348 	mtx_init(&upcall_lock, "evtchup", NULL, MTX_DEF);
349 
350 	/* (DEVFS) create '/dev/misc/evtchn'. */
351 	evtchn_dev = make_dev(&evtchn_devsw, 0, UID_ROOT, GID_WHEEL, 0600, "xen/evtchn");
352 
353 	mtx_init(&lock, "evch", NULL, MTX_SPIN | MTX_NOWITNESS);
354 
355 	evtchn_dev->si_drv1 = malloc(sizeof(evtchn_softc_t), M_DEVBUF, M_WAITOK);
356 	bzero(evtchn_dev->si_drv1, sizeof(evtchn_softc_t));
357 
358 	/* XXX I don't think we need any of this rubbish */
359 #if 0
360 	if ( err != 0 )
361 	{
362 		printk(KERN_ALERT "Could not register /dev/misc/evtchn\n");
363 		return err;
364 	}
365 
366 	/* (DEVFS) create directory '/dev/xen'. */
367 	xen_dev_dir = devfs_mk_dir(NULL, "xen", NULL);
368 
369 	/* (DEVFS) &link_dest[pos] == '../misc/evtchn'. */
370 	pos = devfs_generate_path(evtchn_miscdev.devfs_handle,
371 				  &link_dest[3],
372 				  sizeof(link_dest) - 3);
373 	if ( pos >= 0 )
374 		strncpy(&link_dest[pos], "../", 3);
375 	/* (DEVFS) symlink '/dev/xen/evtchn' -> '../misc/evtchn'. */
376 	(void)devfs_mk_symlink(xen_dev_dir,
377 			       "evtchn",
378 			       DEVFS_FL_DEFAULT,
379 			       &link_dest[pos],
380 			       &symlink_handle,
381 			       NULL);
382 
383 	/* (DEVFS) automatically destroy the symlink with its destination. */
384 	devfs_auto_unregister(evtchn_miscdev.devfs_handle, symlink_handle);
385 #endif
386 	printk("Event-channel device installed.\n");
387 
388 	return 0;
389 }
390 
391 
392 SYSINIT(evtchn_init, SI_SUB_DRIVERS, SI_ORDER_FIRST, evtchn_init, NULL);
393 
394 
395