linux/drivers/xen/evtchn.c
<<
>>
Prefs
   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 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License version 2
  11 * as published by the Free Software Foundation; or, when distributed
  12 * separately from the Linux kernel or incorporated into other
  13 * software packages, subject to the following license:
  14 *
  15 * Permission is hereby granted, free of charge, to any person obtaining a copy
  16 * of this source file (the "Software"), to deal in the Software without
  17 * restriction, including without limitation the rights to use, copy, modify,
  18 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
  19 * and to permit persons to whom the Software is furnished to do so, subject to
  20 * the following conditions:
  21 *
  22 * The above copyright notice and this permission notice shall be included in
  23 * all copies or substantial portions of the Software.
  24 *
  25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  28 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  29 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  30 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  31 * IN THE SOFTWARE.
  32 */
  33
  34#include <linux/module.h>
  35#include <linux/kernel.h>
  36#include <linux/sched.h>
  37#include <linux/slab.h>
  38#include <linux/string.h>
  39#include <linux/errno.h>
  40#include <linux/fs.h>
  41#include <linux/miscdevice.h>
  42#include <linux/major.h>
  43#include <linux/proc_fs.h>
  44#include <linux/stat.h>
  45#include <linux/poll.h>
  46#include <linux/irq.h>
  47#include <linux/init.h>
  48#include <linux/gfp.h>
  49#include <linux/mutex.h>
  50#include <linux/cpu.h>
  51#include <xen/events.h>
  52#include <xen/evtchn.h>
  53#include <asm/xen/hypervisor.h>
  54
  55struct per_user_data {
  56        struct mutex bind_mutex; /* serialize bind/unbind operations */
  57
  58        /* Notification ring, accessed via /dev/xen/evtchn. */
  59#define EVTCHN_RING_SIZE     (PAGE_SIZE / sizeof(evtchn_port_t))
  60#define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1))
  61        evtchn_port_t *ring;
  62        unsigned int ring_cons, ring_prod, ring_overflow;
  63        struct mutex ring_cons_mutex; /* protect against concurrent readers */
  64
  65        /* Processes wait on this queue when ring is empty. */
  66        wait_queue_head_t evtchn_wait;
  67        struct fasync_struct *evtchn_async_queue;
  68        const char *name;
  69};
  70
  71/* Who's bound to each port? */
  72static struct per_user_data *port_user[NR_EVENT_CHANNELS];
  73static DEFINE_SPINLOCK(port_user_lock); /* protects port_user[] and ring_prod */
  74
  75irqreturn_t evtchn_interrupt(int irq, void *data)
  76{
  77        unsigned int port = (unsigned long)data;
  78        struct per_user_data *u;
  79
  80        spin_lock(&port_user_lock);
  81
  82        u = port_user[port];
  83
  84        disable_irq_nosync(irq);
  85
  86        if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) {
  87                u->ring[EVTCHN_RING_MASK(u->ring_prod)] = port;
  88                wmb(); /* Ensure ring contents visible */
  89                if (u->ring_cons == u->ring_prod++) {
  90                        wake_up_interruptible(&u->evtchn_wait);
  91                        kill_fasync(&u->evtchn_async_queue,
  92                                    SIGIO, POLL_IN);
  93                }
  94        } else {
  95                u->ring_overflow = 1;
  96        }
  97
  98        spin_unlock(&port_user_lock);
  99
 100        return IRQ_HANDLED;
 101}
 102
 103static ssize_t evtchn_read(struct file *file, char __user *buf,
 104                           size_t count, loff_t *ppos)
 105{
 106        int rc;
 107        unsigned int c, p, bytes1 = 0, bytes2 = 0;
 108        struct per_user_data *u = file->private_data;
 109
 110        /* Whole number of ports. */
 111        count &= ~(sizeof(evtchn_port_t)-1);
 112
 113        if (count == 0)
 114                return 0;
 115
 116        if (count > PAGE_SIZE)
 117                count = PAGE_SIZE;
 118
 119        for (;;) {
 120                mutex_lock(&u->ring_cons_mutex);
 121
 122                rc = -EFBIG;
 123                if (u->ring_overflow)
 124                        goto unlock_out;
 125
 126                c = u->ring_cons;
 127                p = u->ring_prod;
 128                if (c != p)
 129                        break;
 130
 131                mutex_unlock(&u->ring_cons_mutex);
 132
 133                if (file->f_flags & O_NONBLOCK)
 134                        return -EAGAIN;
 135
 136                rc = wait_event_interruptible(u->evtchn_wait,
 137                                              u->ring_cons != u->ring_prod);
 138                if (rc)
 139                        return rc;
 140        }
 141
 142        /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */
 143        if (((c ^ p) & EVTCHN_RING_SIZE) != 0) {
 144                bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) *
 145                        sizeof(evtchn_port_t);
 146                bytes2 = EVTCHN_RING_MASK(p) * sizeof(evtchn_port_t);
 147        } else {
 148                bytes1 = (p - c) * sizeof(evtchn_port_t);
 149                bytes2 = 0;
 150        }
 151
 152        /* Truncate chunks according to caller's maximum byte count. */
 153        if (bytes1 > count) {
 154                bytes1 = count;
 155                bytes2 = 0;
 156        } else if ((bytes1 + bytes2) > count) {
 157                bytes2 = count - bytes1;
 158        }
 159
 160        rc = -EFAULT;
 161        rmb(); /* Ensure that we see the port before we copy it. */
 162        if (copy_to_user(buf, &u->ring[EVTCHN_RING_MASK(c)], bytes1) ||
 163            ((bytes2 != 0) &&
 164             copy_to_user(&buf[bytes1], &u->ring[0], bytes2)))
 165                goto unlock_out;
 166
 167        u->ring_cons += (bytes1 + bytes2) / sizeof(evtchn_port_t);
 168        rc = bytes1 + bytes2;
 169
 170 unlock_out:
 171        mutex_unlock(&u->ring_cons_mutex);
 172        return rc;
 173}
 174
 175static ssize_t evtchn_write(struct file *file, const char __user *buf,
 176                            size_t count, loff_t *ppos)
 177{
 178        int rc, i;
 179        evtchn_port_t *kbuf = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
 180        struct per_user_data *u = file->private_data;
 181
 182        if (kbuf == NULL)
 183                return -ENOMEM;
 184
 185        /* Whole number of ports. */
 186        count &= ~(sizeof(evtchn_port_t)-1);
 187
 188        rc = 0;
 189        if (count == 0)
 190                goto out;
 191
 192        if (count > PAGE_SIZE)
 193                count = PAGE_SIZE;
 194
 195        rc = -EFAULT;
 196        if (copy_from_user(kbuf, buf, count) != 0)
 197                goto out;
 198
 199        spin_lock_irq(&port_user_lock);
 200        for (i = 0; i < (count/sizeof(evtchn_port_t)); i++)
 201                if ((kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u))
 202                        enable_irq(irq_from_evtchn(kbuf[i]));
 203        spin_unlock_irq(&port_user_lock);
 204
 205        rc = count;
 206
 207 out:
 208        free_page((unsigned long)kbuf);
 209        return rc;
 210}
 211
 212static int evtchn_bind_to_user(struct per_user_data *u, int port)
 213{
 214        int rc = 0;
 215
 216        /*
 217         * Ports are never reused, so every caller should pass in a
 218         * unique port.
 219         *
 220         * (Locking not necessary because we haven't registered the
 221         * interrupt handler yet, and our caller has already
 222         * serialized bind operations.)
 223         */
 224        BUG_ON(port_user[port] != NULL);
 225        port_user[port] = u;
 226
 227        rc = bind_evtchn_to_irqhandler(port, evtchn_interrupt, IRQF_DISABLED,
 228                                       u->name, (void *)(unsigned long)port);
 229        if (rc >= 0)
 230                rc = 0;
 231
 232        return rc;
 233}
 234
 235static void evtchn_unbind_from_user(struct per_user_data *u, int port)
 236{
 237        int irq = irq_from_evtchn(port);
 238
 239        unbind_from_irqhandler(irq, (void *)(unsigned long)port);
 240
 241        /* make sure we unbind the irq handler before clearing the port */
 242        barrier();
 243
 244        port_user[port] = NULL;
 245}
 246
 247static long evtchn_ioctl(struct file *file,
 248                         unsigned int cmd, unsigned long arg)
 249{
 250        int rc;
 251        struct per_user_data *u = file->private_data;
 252        void __user *uarg = (void __user *) arg;
 253
 254        /* Prevent bind from racing with unbind */
 255        mutex_lock(&u->bind_mutex);
 256
 257        switch (cmd) {
 258        case IOCTL_EVTCHN_BIND_VIRQ: {
 259                struct ioctl_evtchn_bind_virq bind;
 260                struct evtchn_bind_virq bind_virq;
 261
 262                rc = -EFAULT;
 263                if (copy_from_user(&bind, uarg, sizeof(bind)))
 264                        break;
 265
 266                bind_virq.virq = bind.virq;
 267                bind_virq.vcpu = 0;
 268                rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
 269                                                 &bind_virq);
 270                if (rc != 0)
 271                        break;
 272
 273                rc = evtchn_bind_to_user(u, bind_virq.port);
 274                if (rc == 0)
 275                        rc = bind_virq.port;
 276                break;
 277        }
 278
 279        case IOCTL_EVTCHN_BIND_INTERDOMAIN: {
 280                struct ioctl_evtchn_bind_interdomain bind;
 281                struct evtchn_bind_interdomain bind_interdomain;
 282
 283                rc = -EFAULT;
 284                if (copy_from_user(&bind, uarg, sizeof(bind)))
 285                        break;
 286
 287                bind_interdomain.remote_dom  = bind.remote_domain;
 288                bind_interdomain.remote_port = bind.remote_port;
 289                rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
 290                                                 &bind_interdomain);
 291                if (rc != 0)
 292                        break;
 293
 294                rc = evtchn_bind_to_user(u, bind_interdomain.local_port);
 295                if (rc == 0)
 296                        rc = bind_interdomain.local_port;
 297                break;
 298        }
 299
 300        case IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
 301                struct ioctl_evtchn_bind_unbound_port bind;
 302                struct evtchn_alloc_unbound alloc_unbound;
 303
 304                rc = -EFAULT;
 305                if (copy_from_user(&bind, uarg, sizeof(bind)))
 306                        break;
 307
 308                alloc_unbound.dom        = DOMID_SELF;
 309                alloc_unbound.remote_dom = bind.remote_domain;
 310                rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
 311                                                 &alloc_unbound);
 312                if (rc != 0)
 313                        break;
 314
 315                rc = evtchn_bind_to_user(u, alloc_unbound.port);
 316                if (rc == 0)
 317                        rc = alloc_unbound.port;
 318                break;
 319        }
 320
 321        case IOCTL_EVTCHN_UNBIND: {
 322                struct ioctl_evtchn_unbind unbind;
 323
 324                rc = -EFAULT;
 325                if (copy_from_user(&unbind, uarg, sizeof(unbind)))
 326                        break;
 327
 328                rc = -EINVAL;
 329                if (unbind.port >= NR_EVENT_CHANNELS)
 330                        break;
 331
 332                spin_lock_irq(&port_user_lock);
 333
 334                rc = -ENOTCONN;
 335                if (port_user[unbind.port] != u) {
 336                        spin_unlock_irq(&port_user_lock);
 337                        break;
 338                }
 339
 340                evtchn_unbind_from_user(u, unbind.port);
 341
 342                spin_unlock_irq(&port_user_lock);
 343
 344                rc = 0;
 345                break;
 346        }
 347
 348        case IOCTL_EVTCHN_NOTIFY: {
 349                struct ioctl_evtchn_notify notify;
 350
 351                rc = -EFAULT;
 352                if (copy_from_user(&notify, uarg, sizeof(notify)))
 353                        break;
 354
 355                if (notify.port >= NR_EVENT_CHANNELS) {
 356                        rc = -EINVAL;
 357                } else if (port_user[notify.port] != u) {
 358                        rc = -ENOTCONN;
 359                } else {
 360                        notify_remote_via_evtchn(notify.port);
 361                        rc = 0;
 362                }
 363                break;
 364        }
 365
 366        case IOCTL_EVTCHN_RESET: {
 367                /* Initialise the ring to empty. Clear errors. */
 368                mutex_lock(&u->ring_cons_mutex);
 369                spin_lock_irq(&port_user_lock);
 370                u->ring_cons = u->ring_prod = u->ring_overflow = 0;
 371                spin_unlock_irq(&port_user_lock);
 372                mutex_unlock(&u->ring_cons_mutex);
 373                rc = 0;
 374                break;
 375        }
 376
 377        default:
 378                rc = -ENOSYS;
 379                break;
 380        }
 381        mutex_unlock(&u->bind_mutex);
 382
 383        return rc;
 384}
 385
 386static unsigned int evtchn_poll(struct file *file, poll_table *wait)
 387{
 388        unsigned int mask = POLLOUT | POLLWRNORM;
 389        struct per_user_data *u = file->private_data;
 390
 391        poll_wait(file, &u->evtchn_wait, wait);
 392        if (u->ring_cons != u->ring_prod)
 393                mask |= POLLIN | POLLRDNORM;
 394        if (u->ring_overflow)
 395                mask = POLLERR;
 396        return mask;
 397}
 398
 399static int evtchn_fasync(int fd, struct file *filp, int on)
 400{
 401        struct per_user_data *u = filp->private_data;
 402        return fasync_helper(fd, filp, on, &u->evtchn_async_queue);
 403}
 404
 405static int evtchn_open(struct inode *inode, struct file *filp)
 406{
 407        struct per_user_data *u;
 408
 409        u = kzalloc(sizeof(*u), GFP_KERNEL);
 410        if (u == NULL)
 411                return -ENOMEM;
 412
 413        u->name = kasprintf(GFP_KERNEL, "evtchn:%s", current->comm);
 414        if (u->name == NULL) {
 415                kfree(u);
 416                return -ENOMEM;
 417        }
 418
 419        init_waitqueue_head(&u->evtchn_wait);
 420
 421        u->ring = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
 422        if (u->ring == NULL) {
 423                kfree(u->name);
 424                kfree(u);
 425                return -ENOMEM;
 426        }
 427
 428        mutex_init(&u->bind_mutex);
 429        mutex_init(&u->ring_cons_mutex);
 430
 431        filp->private_data = u;
 432
 433        return 0;
 434}
 435
 436static int evtchn_release(struct inode *inode, struct file *filp)
 437{
 438        int i;
 439        struct per_user_data *u = filp->private_data;
 440
 441        spin_lock_irq(&port_user_lock);
 442
 443        free_page((unsigned long)u->ring);
 444
 445        for (i = 0; i < NR_EVENT_CHANNELS; i++) {
 446                if (port_user[i] != u)
 447                        continue;
 448
 449                evtchn_unbind_from_user(port_user[i], i);
 450        }
 451
 452        spin_unlock_irq(&port_user_lock);
 453
 454        kfree(u->name);
 455        kfree(u);
 456
 457        return 0;
 458}
 459
 460static const struct file_operations evtchn_fops = {
 461        .owner   = THIS_MODULE,
 462        .read    = evtchn_read,
 463        .write   = evtchn_write,
 464        .unlocked_ioctl = evtchn_ioctl,
 465        .poll    = evtchn_poll,
 466        .fasync  = evtchn_fasync,
 467        .open    = evtchn_open,
 468        .release = evtchn_release,
 469};
 470
 471static struct miscdevice evtchn_miscdev = {
 472        .minor        = MISC_DYNAMIC_MINOR,
 473        .name         = "evtchn",
 474        .fops         = &evtchn_fops,
 475};
 476static int __init evtchn_init(void)
 477{
 478        int err;
 479
 480        if (!xen_domain())
 481                return -ENODEV;
 482
 483        spin_lock_init(&port_user_lock);
 484        memset(port_user, 0, sizeof(port_user));
 485
 486        /* Create '/dev/misc/evtchn'. */
 487        err = misc_register(&evtchn_miscdev);
 488        if (err != 0) {
 489                printk(KERN_ALERT "Could not register /dev/misc/evtchn\n");
 490                return err;
 491        }
 492
 493        printk(KERN_INFO "Event-channel device installed.\n");
 494
 495        return 0;
 496}
 497
 498static void __exit evtchn_cleanup(void)
 499{
 500        misc_deregister(&evtchn_miscdev);
 501}
 502
 503module_init(evtchn_init);
 504module_exit(evtchn_cleanup);
 505
 506MODULE_LICENSE("GPL");
 507