| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: xenevt.c,v 1.29.4.2 2009/09/30 00:08:03 snj Exp $ */ | | 1 | /* $NetBSD: xenevt.c,v 1.29.4.2.6.1 2015/05/22 11:44:25 sborrill Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2005 Manuel Bouyer. | | 4 | * Copyright (c) 2005 Manuel Bouyer. |
5 | * | | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | | 7 | * modification, are permitted provided that the following conditions |
8 | * are met: | | 8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright | | 9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | | 10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright | | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the | | 12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. | | 13 | * documentation and/or other materials provided with the distribution. |
14 | * 3. All advertising materials mentioning features or use of this software | | 14 | * 3. All advertising materials mentioning features or use of this software |
| @@ -21,27 +21,27 @@ | | | @@ -21,27 +21,27 @@ |
21 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 21 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
23 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 23 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
24 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 24 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
25 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 25 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
29 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 29 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 | * | | 30 | * |
31 | */ | | 31 | */ |
32 | | | 32 | |
33 | #include <sys/cdefs.h> | | 33 | #include <sys/cdefs.h> |
34 | __KERNEL_RCSID(0, "$NetBSD: xenevt.c,v 1.29.4.2 2009/09/30 00:08:03 snj Exp $"); | | 34 | __KERNEL_RCSID(0, "$NetBSD: xenevt.c,v 1.29.4.2.6.1 2015/05/22 11:44:25 sborrill Exp $"); |
35 | | | 35 | |
36 | #include "opt_xen.h" | | 36 | #include "opt_xen.h" |
37 | #include <sys/param.h> | | 37 | #include <sys/param.h> |
38 | #include <sys/kernel.h> | | 38 | #include <sys/kernel.h> |
39 | #include <sys/malloc.h> | | 39 | #include <sys/malloc.h> |
40 | #include <sys/systm.h> | | 40 | #include <sys/systm.h> |
41 | #include <sys/device.h> | | 41 | #include <sys/device.h> |
42 | #include <sys/file.h> | | 42 | #include <sys/file.h> |
43 | #include <sys/filedesc.h> | | 43 | #include <sys/filedesc.h> |
44 | #include <sys/poll.h> | | 44 | #include <sys/poll.h> |
45 | #include <sys/select.h> | | 45 | #include <sys/select.h> |
46 | #include <sys/proc.h> | | 46 | #include <sys/proc.h> |
47 | #include <sys/conf.h> | | 47 | #include <sys/conf.h> |
| @@ -486,27 +486,27 @@ done: | | | @@ -486,27 +486,27 @@ done: |
486 | } | | 486 | } |
487 | | | 487 | |
488 | static int | | 488 | static int |
489 | xenevt_fwrite(struct file *fp, off_t *offp, struct uio *uio, | | 489 | xenevt_fwrite(struct file *fp, off_t *offp, struct uio *uio, |
490 | kauth_cred_t cred, int flags) | | 490 | kauth_cred_t cred, int flags) |
491 | { | | 491 | { |
492 | struct xenevt_d *d = fp->f_data; | | 492 | struct xenevt_d *d = fp->f_data; |
493 | uint16_t *chans; | | 493 | uint16_t *chans; |
494 | int i, nentries, error; | | 494 | int i, nentries, error; |
495 | | | 495 | |
496 | if (uio->uio_resid == 0) | | 496 | if (uio->uio_resid == 0) |
497 | return (0); | | 497 | return (0); |
498 | nentries = uio->uio_resid / sizeof(uint16_t); | | 498 | nentries = uio->uio_resid / sizeof(uint16_t); |
499 | if (nentries > NR_EVENT_CHANNELS) | | 499 | if (nentries >= NR_EVENT_CHANNELS) |
500 | return EMSGSIZE; | | 500 | return EMSGSIZE; |
501 | chans = kmem_alloc(nentries * sizeof(uint16_t), KM_SLEEP); | | 501 | chans = kmem_alloc(nentries * sizeof(uint16_t), KM_SLEEP); |
502 | if (chans == NULL) | | 502 | if (chans == NULL) |
503 | return ENOMEM; | | 503 | return ENOMEM; |
504 | error = uiomove(chans, uio->uio_resid, uio); | | 504 | error = uiomove(chans, uio->uio_resid, uio); |
505 | if (error) | | 505 | if (error) |
506 | goto out; | | 506 | goto out; |
507 | for (i = 0; i < nentries; i++) { | | 507 | for (i = 0; i < nentries; i++) { |
508 | if (chans[i] < NR_EVENT_CHANNELS && | | 508 | if (chans[i] < NR_EVENT_CHANNELS && |
509 | devevent[chans[i]] == d) { | | 509 | devevent[chans[i]] == d) { |
510 | hypervisor_unmask_event(chans[i]); | | 510 | hypervisor_unmask_event(chans[i]); |
511 | } | | 511 | } |
512 | } | | 512 | } |
| @@ -570,43 +570,43 @@ xenevt_fioctl(struct file *fp, u_long cm | | | @@ -570,43 +570,43 @@ xenevt_fioctl(struct file *fp, u_long cm |
570 | op.u.alloc_unbound.dom = DOMID_SELF; | | 570 | op.u.alloc_unbound.dom = DOMID_SELF; |
571 | op.u.alloc_unbound.remote_dom = bind_unbound->remote_domain; | | 571 | op.u.alloc_unbound.remote_dom = bind_unbound->remote_domain; |
572 | if ((error = HYPERVISOR_event_channel_op(&op))) | | 572 | if ((error = HYPERVISOR_event_channel_op(&op))) |
573 | return -error; | | 573 | return -error; |
574 | bind_unbound->port = op.u.alloc_unbound.port; | | 574 | bind_unbound->port = op.u.alloc_unbound.port; |
575 | devevent[bind_unbound->port] = d; | | 575 | devevent[bind_unbound->port] = d; |
576 | hypervisor_unmask_event(bind_unbound->port); | | 576 | hypervisor_unmask_event(bind_unbound->port); |
577 | break; | | 577 | break; |
578 | } | | 578 | } |
579 | case IOCTL_EVTCHN_UNBIND: | | 579 | case IOCTL_EVTCHN_UNBIND: |
580 | { | | 580 | { |
581 | struct ioctl_evtchn_unbind *unbind = addr; | | 581 | struct ioctl_evtchn_unbind *unbind = addr; |
582 | | | 582 | |
583 | if (unbind->port > NR_EVENT_CHANNELS) | | 583 | if (unbind->port >= NR_EVENT_CHANNELS) |
584 | return EINVAL; | | 584 | return EINVAL; |
585 | if (devevent[unbind->port] != d) | | 585 | if (devevent[unbind->port] != d) |
586 | return ENOTCONN; | | 586 | return ENOTCONN; |
587 | devevent[unbind->port] = NULL; | | 587 | devevent[unbind->port] = NULL; |
588 | hypervisor_mask_event(unbind->port); | | 588 | hypervisor_mask_event(unbind->port); |
589 | op.cmd = EVTCHNOP_close; | | 589 | op.cmd = EVTCHNOP_close; |
590 | op.u.close.port = unbind->port; | | 590 | op.u.close.port = unbind->port; |
591 | if ((error = HYPERVISOR_event_channel_op(&op))) | | 591 | if ((error = HYPERVISOR_event_channel_op(&op))) |
592 | return -error; | | 592 | return -error; |
593 | break; | | 593 | break; |
594 | } | | 594 | } |
595 | case IOCTL_EVTCHN_NOTIFY: | | 595 | case IOCTL_EVTCHN_NOTIFY: |
596 | { | | 596 | { |
597 | struct ioctl_evtchn_notify *notify = addr; | | 597 | struct ioctl_evtchn_notify *notify = addr; |
598 | | | 598 | |
599 | if (notify->port > NR_EVENT_CHANNELS) | | 599 | if (notify->port >= NR_EVENT_CHANNELS) |
600 | return EINVAL; | | 600 | return EINVAL; |
601 | if (devevent[notify->port] != d) | | 601 | if (devevent[notify->port] != d) |
602 | return ENOTCONN; | | 602 | return ENOTCONN; |
603 | hypervisor_notify_via_evtchn(notify->port); | | 603 | hypervisor_notify_via_evtchn(notify->port); |
604 | break; | | 604 | break; |
605 | } | | 605 | } |
606 | #else /* !XEN3 */ | | 606 | #else /* !XEN3 */ |
607 | case EVTCHN_BIND: | | 607 | case EVTCHN_BIND: |
608 | if (*arg > NR_EVENT_CHANNELS) | | 608 | if (*arg > NR_EVENT_CHANNELS) |
609 | return EINVAL; | | 609 | return EINVAL; |
610 | if (devevent[*arg] != NULL) | | 610 | if (devevent[*arg] != NULL) |
611 | return EISCONN; | | 611 | return EISCONN; |
612 | devevent[*arg] = d; | | 612 | devevent[*arg] = d; |