1295634Sandrew/****************************************************************************** 2295634Sandrew * evtchn.c 3295634Sandrew * 4295634Sandrew * Xenolinux driver for receiving and demuxing event-channel signals. 5295634Sandrew * 6295634Sandrew * Copyright (c) 2004, K A Fraser 7295634Sandrew */ 8295634Sandrew 9295634Sandrew#include <sys/cdefs.h> 10295634Sandrew__FBSDID("$FreeBSD$"); 11295634Sandrew 12295634Sandrew#include <sys/param.h> 13295634Sandrew#include <sys/systm.h> 14295634Sandrew#include <sys/uio.h> 15295634Sandrew#include <sys/bus.h> 16295634Sandrew#include <sys/malloc.h> 17295634Sandrew#include <sys/kernel.h> 18295634Sandrew#include <sys/lock.h> 19295634Sandrew#include <sys/mutex.h> 20295634Sandrew#include <sys/selinfo.h> 21295634Sandrew#include <sys/poll.h> 22295634Sandrew#include <sys/conf.h> 23295634Sandrew#include <sys/fcntl.h> 24295634Sandrew#include <sys/ioccom.h> 25295634Sandrew 26295634Sandrew#include <machine/xen/xen-os.h> 27295634Sandrew#include <xen/xen_intr.h> 28295634Sandrew#include <machine/bus.h> 29295634Sandrew#include <sys/rman.h> 30295634Sandrew#include <machine/resource.h> 31295634Sandrew#include <machine/xen/synch_bitops.h> 32295634Sandrew#include <xen/hypervisor.h> 33295634Sandrew#include <xen/evtchn.h> 34295634Sandrew 35295634Sandrew 36295634Sandrewtypedef struct evtchn_sotfc { 37295634Sandrew 38295634Sandrew struct selinfo ev_rsel; 39295634Sandrew} evtchn_softc_t; 40295634Sandrew 41295634Sandrew 42295634Sandrew#ifdef linuxcrap 43295634Sandrew/* NB. This must be shared amongst drivers if more things go in /dev/xen */ 44295634Sandrewstatic devfs_handle_t xen_dev_dir; 45295634Sandrew#endif 46295634Sandrew 47295634Sandrew/* Only one process may open /dev/xen/evtchn at any time. */ 48295634Sandrewstatic unsigned long evtchn_dev_inuse; 49295634Sandrew 50295634Sandrew/* Notification ring, accessed via /dev/xen/evtchn. */ 51295634Sandrew 52295634Sandrew#define EVTCHN_RING_SIZE 2048 /* 2048 16-bit entries */ 53295634Sandrew 54295634Sandrew#define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1)) 55295634Sandrewstatic uint16_t *ring; 56295634Sandrewstatic unsigned int ring_cons, ring_prod, ring_overflow; 57295654Sandrew 58295634Sandrew/* Which ports is user-space bound to? */ 59295654Sandrewstatic uint32_t bound_ports[32]; 60295634Sandrew 61295634Sandrew/* Unique address for processes to sleep on */ 62295634Sandrewstatic void *evtchn_waddr = ˚ 63295634Sandrew 64295634Sandrewstatic struct mtx lock, upcall_lock; 65295634Sandrew 66295634Sandrewstatic d_read_t evtchn_read; 67295634Sandrewstatic d_write_t evtchn_write; 68295634Sandrewstatic d_ioctl_t evtchn_ioctl; 69295634Sandrewstatic d_poll_t evtchn_poll; 70295634Sandrewstatic d_open_t evtchn_open; 71295634Sandrewstatic d_close_t evtchn_close; 72295634Sandrew 73295634Sandrew 74295634Sandrewvoid 75295634Sandrewevtchn_device_upcall(int port) 76295634Sandrew{ 77295634Sandrew mtx_lock(&upcall_lock); 78295634Sandrew 79295634Sandrew mask_evtchn(port); 80295634Sandrew clear_evtchn(port); 81295634Sandrew 82295634Sandrew if ( ring != NULL ) { 83295634Sandrew if ( (ring_prod - ring_cons) < EVTCHN_RING_SIZE ) { 84295634Sandrew ring[EVTCHN_RING_MASK(ring_prod)] = (uint16_t)port; 85295634Sandrew if ( ring_cons == ring_prod++ ) { 86295634Sandrew wakeup(evtchn_waddr); 87295634Sandrew } 88295634Sandrew } 89295634Sandrew else { 90295634Sandrew ring_overflow = 1; 91295634Sandrew } 92295634Sandrew } 93295634Sandrew 94295634Sandrew mtx_unlock(&upcall_lock); 95295634Sandrew} 96295634Sandrew 97295634Sandrewstatic void 98295634Sandrew__evtchn_reset_buffer_ring(void) 99295634Sandrew{ 100295634Sandrew /* Initialise the ring to empty. Clear errors. */ 101295634Sandrew ring_cons = ring_prod = ring_overflow = 0; 102295634Sandrew} 103295634Sandrew 104295634Sandrewstatic int 105295634Sandrewevtchn_read(struct cdev *dev, struct uio *uio, int ioflag) 106295634Sandrew{ 107295634Sandrew int rc; 108295634Sandrew unsigned int count, c, p, sst = 0, bytes1 = 0, bytes2 = 0; 109295634Sandrew count = uio->uio_resid; 110295634Sandrew 111295634Sandrew count &= ~1; /* even number of bytes */ 112295634Sandrew 113295634Sandrew if ( count == 0 ) 114295634Sandrew { 115295634Sandrew rc = 0; 116295634Sandrew goto out; 117295634Sandrew } 118295634Sandrew 119295634Sandrew if ( count > PAGE_SIZE ) 120295634Sandrew count = PAGE_SIZE; 121295634Sandrew 122295634Sandrew for ( ; ; ) { 123295634Sandrew if ( (c = ring_cons) != (p = ring_prod) ) 124295634Sandrew break; 125295634Sandrew 126295634Sandrew if ( ring_overflow ) { 127295634Sandrew rc = EFBIG; 128295634Sandrew goto out; 129295634Sandrew } 130295634Sandrew 131295634Sandrew if (sst != 0) { 132295634Sandrew rc = EINTR; 133295634Sandrew goto out; 134295634Sandrew } 135295634Sandrew 136295634Sandrew /* PCATCH == check for signals before and after sleeping 137295634Sandrew * PWAIT == priority of waiting on resource 138295634Sandrew */ 139295634Sandrew sst = tsleep(evtchn_waddr, PWAIT|PCATCH, "evchwt", 10); 140295634Sandrew } 141295654Sandrew 142295634Sandrew /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */ 143295634Sandrew if ( ((c ^ p) & EVTCHN_RING_SIZE) != 0 ) { 144295634Sandrew bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) * sizeof(uint16_t); 145295634Sandrew bytes2 = EVTCHN_RING_MASK(p) * sizeof(uint16_t); 146295634Sandrew } 147295634Sandrew else { 148295634Sandrew bytes1 = (p - c) * sizeof(uint16_t); 149295654Sandrew bytes2 = 0; 150295654Sandrew } 151295654Sandrew 152295654Sandrew /* Truncate chunks according to caller's maximum byte count. */ 153295654Sandrew if ( bytes1 > count ) { 154295654Sandrew bytes1 = count; 155295654Sandrew bytes2 = 0; 156295654Sandrew } 157295654Sandrew else if ( (bytes1 + bytes2) > count ) { 158295634Sandrew bytes2 = count - bytes1; 159295634Sandrew } 160295634Sandrew 161295654Sandrew if ( uiomove(&ring[EVTCHN_RING_MASK(c)], bytes1, uio) || 162295634Sandrew ((bytes2 != 0) && uiomove(&ring[0], bytes2, uio))) 163295634Sandrew /* keeping this around as its replacement is not equivalent 164295634Sandrew * copyout(&ring[0], &buf[bytes1], bytes2) 165295634Sandrew */ 166295634Sandrew { 167295634Sandrew rc = EFAULT; 168295634Sandrew goto out; 169295634Sandrew } 170295634Sandrew 171295634Sandrew ring_cons += (bytes1 + bytes2) / sizeof(uint16_t); 172295634Sandrew 173295634Sandrew rc = bytes1 + bytes2; 174295634Sandrew 175295634Sandrew out: 176295634Sandrew 177295634Sandrew return rc; 178295634Sandrew} 179295634Sandrew 180295634Sandrewstatic int 181295634Sandrewevtchn_write(struct cdev *dev, struct uio *uio, int ioflag) 182295634Sandrew{ 183295634Sandrew int rc, i, count; 184295634Sandrew 185295634Sandrew count = uio->uio_resid; 186 187 uint16_t *kbuf = (uint16_t *)malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK); 188 189 190 if ( kbuf == NULL ) 191 return ENOMEM; 192 193 count &= ~1; /* even number of bytes */ 194 195 if ( count == 0 ) { 196 rc = 0; 197 goto out; 198 } 199 200 if ( count > PAGE_SIZE ) 201 count = PAGE_SIZE; 202 203 if ( uiomove(kbuf, count, uio) != 0 ) { 204 rc = EFAULT; 205 goto out; 206 } 207 208 mtx_lock_spin(&lock); 209 for ( i = 0; i < (count/2); i++ ) 210 if ( test_bit(kbuf[i], &bound_ports[0]) ) 211 unmask_evtchn(kbuf[i]); 212 mtx_unlock_spin(&lock); 213 214 rc = count; 215 216 out: 217 free(kbuf, M_DEVBUF); 218 return rc; 219} 220 221static int 222evtchn_ioctl(struct cdev *dev, unsigned long cmd, caddr_t arg, 223 int mode, struct thread *td __unused) 224{ 225 int rc = 0; 226 227 mtx_lock_spin(&lock); 228 229 switch ( cmd ) 230 { 231 case EVTCHN_RESET: 232 __evtchn_reset_buffer_ring(); 233 break; 234 case EVTCHN_BIND: 235 if ( !synch_test_and_set_bit((uintptr_t)arg, &bound_ports[0]) ) 236 unmask_evtchn((uintptr_t)arg); 237 else 238 rc = EINVAL; 239 break; 240 case EVTCHN_UNBIND: 241 if ( synch_test_and_clear_bit((uintptr_t)arg, &bound_ports[0]) ) 242 mask_evtchn((uintptr_t)arg); 243 else 244 rc = EINVAL; 245 break; 246 default: 247 rc = ENOSYS; 248 break; 249 } 250 251 mtx_unlock_spin(&lock); 252 253 return rc; 254} 255 256static int 257evtchn_poll(struct cdev *dev, int poll_events, struct thread *td) 258{ 259 260 evtchn_softc_t *sc; 261 unsigned int mask = POLLOUT | POLLWRNORM; 262 263 sc = dev->si_drv1; 264 265 if ( ring_cons != ring_prod ) 266 mask |= POLLIN | POLLRDNORM; 267 else if ( ring_overflow ) 268 mask = POLLERR; 269 else 270 selrecord(td, &sc->ev_rsel); 271 272 273 return mask; 274} 275 276 277static int 278evtchn_open(struct cdev *dev, int flag, int otyp, struct thread *td) 279{ 280 uint16_t *_ring; 281 282 if (flag & O_NONBLOCK) 283 return EBUSY; 284 285 if ( synch_test_and_set_bit(0, &evtchn_dev_inuse) ) 286 return EBUSY; 287 288 if ( (_ring = (uint16_t *)malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK)) == NULL ) 289 return ENOMEM; 290 291 mtx_lock_spin(&lock); 292 ring = _ring; 293 __evtchn_reset_buffer_ring(); 294 mtx_unlock_spin(&lock); 295 296 297 return 0; 298} 299 300static int 301evtchn_close(struct cdev *dev, int flag, int otyp, struct thread *td __unused) 302{ 303 int i; 304 305 if (ring != NULL) { 306 free(ring, M_DEVBUF); 307 ring = NULL; 308 } 309 mtx_lock_spin(&lock); 310 for ( i = 0; i < NR_EVENT_CHANNELS; i++ ) 311 if ( synch_test_and_clear_bit(i, &bound_ports[0]) ) 312 mask_evtchn(i); 313 mtx_unlock_spin(&lock); 314 315 evtchn_dev_inuse = 0; 316 317 return 0; 318} 319 320static struct cdevsw evtchn_devsw = { 321 .d_version = D_VERSION, 322 .d_open = evtchn_open, 323 .d_close = evtchn_close, 324 .d_read = evtchn_read, 325 .d_write = evtchn_write, 326 .d_ioctl = evtchn_ioctl, 327 .d_poll = evtchn_poll, 328 .d_name = "evtchn", 329}; 330 331 332/* XXX - if this device is ever supposed to support use by more than one process 333 * this global static will have to go away 334 */ 335static struct cdev *evtchn_dev; 336 337 338 339static int 340evtchn_dev_init(void *dummy __unused) 341{ 342 /* XXX I believe we don't need these leaving them here for now until we 343 * have some semblance of it working 344 */ 345 mtx_init(&upcall_lock, "evtchup", NULL, MTX_DEF); 346 347 /* (DEVFS) create '/dev/misc/evtchn'. */ 348 evtchn_dev = make_dev(&evtchn_devsw, 0, UID_ROOT, GID_WHEEL, 0600, "xen/evtchn"); 349 350 mtx_init(&lock, "evch", NULL, MTX_SPIN | MTX_NOWITNESS); 351 352 evtchn_dev->si_drv1 = malloc(sizeof(evtchn_softc_t), M_DEVBUF, M_WAITOK); 353 bzero(evtchn_dev->si_drv1, sizeof(evtchn_softc_t)); 354 355 /* XXX I don't think we need any of this rubbish */ 356#if 0 357 if ( err != 0 ) 358 { 359 printk(KERN_ALERT "Could not register /dev/misc/evtchn\n"); 360 return err; 361 } 362 363 /* (DEVFS) create directory '/dev/xen'. */ 364 xen_dev_dir = devfs_mk_dir(NULL, "xen", NULL); 365 366 /* (DEVFS) &link_dest[pos] == '../misc/evtchn'. */ 367 pos = devfs_generate_path(evtchn_miscdev.devfs_handle, 368 &link_dest[3], 369 sizeof(link_dest) - 3); 370 if ( pos >= 0 ) 371 strncpy(&link_dest[pos], "../", 3); 372 /* (DEVFS) symlink '/dev/xen/evtchn' -> '../misc/evtchn'. */ 373 (void)devfs_mk_symlink(xen_dev_dir, 374 "evtchn", 375 DEVFS_FL_DEFAULT, 376 &link_dest[pos], 377 &symlink_handle, 378 NULL); 379 380 /* (DEVFS) automatically destroy the symlink with its destination. */ 381 devfs_auto_unregister(evtchn_miscdev.devfs_handle, symlink_handle); 382#endif 383 if (bootverbose) 384 printf("Event-channel device installed.\n"); 385 386 return 0; 387} 388 389SYSINIT(evtchn_dev_init, SI_SUB_DRIVERS, SI_ORDER_FIRST, evtchn_dev_init, NULL); 390 391 392