4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
31 * Driver for receiving and demuxing event-channel signals.
33 * Copyright (c) 2004-2005, K A Fraser
34 * Multi-process extensions Copyright (c) 2004, Steven Smith
36 * This file may be distributed separately from the Linux kernel, or
37 * incorporated into other software packages, subject to the following license:
39 * Permission is hereby granted, free of charge, to any person obtaining a copy
40 * of this source file (the "Software"), to deal in the Software without
41 * restriction, including without limitation the rights to use, copy, modify,
42 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
43 * and to permit persons to whom the Software is furnished to do so, subject to
44 * the following conditions:
46 * The above copyright notice and this permission notice shall be included in
47 * all copies or substantial portions of the Software.
49 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
52 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
54 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
58 #include <sys/types.h>
59 #include <sys/hypervisor.h>
60 #include <sys/machsystm.h>
61 #include <sys/mutex.h>
62 #include <sys/evtchn_impl.h>
63 #include <sys/ddi_impldefs.h>
64 #include <sys/avintr.h>
65 #include <sys/cpuvar.h>
66 #include <sys/smp_impldefs.h>
67 #include <sys/archsystm.h>
68 #include <sys/sysmacros.h>
69 #include <sys/fcntl.h>
74 #include <sys/cmn_err.h>
75 #include <sys/xen_errno.h>
76 #include <sys/policy.h>
77 #include <xen/sys/evtchn.h>
79 /* Some handy macros */
80 #define EVTCHNDRV_MINOR2INST(minor) ((int)(minor))
81 #define EVTCHNDRV_DEFAULT_NCLONES 256
82 #define EVTCHNDRV_INST2SOFTS(inst) \
83 (ddi_get_soft_state(evtchndrv_statep, (inst)))
85 /* Soft state data structure for evtchn driver */
88 /* Notification ring, accessed via /dev/xen/evtchn. */
89 #define EVTCHN_RING_SIZE (PAGESIZE / sizeof (evtchn_port_t))
90 #define EVTCHN_RING_MASK(_i) ((_i) & (EVTCHN_RING_SIZE - 1))
92 unsigned int ring_cons
, ring_prod
, ring_overflow
;
94 kcondvar_t evtchn_wait
; /* Processes wait on this when ring is empty. */
96 struct pollhead evtchn_pollhead
;
98 pid_t pid
; /* last pid to bind to this event channel. */
99 processorid_t cpu
; /* cpu thread/evtchn is bound to */
102 static void *evtchndrv_statep
;
103 int evtchndrv_nclones
= EVTCHNDRV_DEFAULT_NCLONES
;
104 static int *evtchndrv_clone_tab
;
105 static dev_info_t
*evtchndrv_dip
;
106 static kmutex_t evtchndrv_clone_tab_mutex
;
108 static int evtchndrv_detach(dev_info_t
*, ddi_detach_cmd_t
);
110 /* Who's bound to each port? */
111 static struct evtsoftdata
*port_user
[NR_EVENT_CHANNELS
];
112 static kmutex_t port_user_lock
;
115 evtchn_device_upcall()
117 struct evtsoftdata
*ep
;
121 * This is quite gross, we had to leave the evtchn that led to this
122 * invocation in a per-cpu mailbox, retrieve it now.
123 * We do this because the interface doesn't offer us a way to pass
124 * a dynamic argument up through the generic interrupt service layer.
125 * The mailbox is safe since we either run with interrupts disabled or
126 * non-preemptable till we reach here.
128 port
= CPU
->cpu_m
.mcpu_ec_mbox
;
130 CPU
->cpu_m
.mcpu_ec_mbox
= 0;
131 ec_clear_evtchn(port
);
132 mutex_enter(&port_user_lock
);
134 if ((ep
= port_user
[port
]) != NULL
) {
135 mutex_enter(&ep
->evtchn_lock
);
136 if ((ep
->ring_prod
- ep
->ring_cons
) < EVTCHN_RING_SIZE
) {
137 ep
->ring
[EVTCHN_RING_MASK(ep
->ring_prod
)] = port
;
139 * Wake up reader when ring goes non-empty
141 if (ep
->ring_cons
== ep
->ring_prod
++) {
142 cv_signal(&ep
->evtchn_wait
);
143 mutex_exit(&ep
->evtchn_lock
);
144 pollwakeup(&ep
->evtchn_pollhead
,
145 POLLIN
| POLLRDNORM
);
149 ep
->ring_overflow
= 1;
151 mutex_exit(&ep
->evtchn_lock
);
155 mutex_exit(&port_user_lock
);
160 evtchndrv_read(dev_t dev
, struct uio
*uio
, cred_t
*cr
)
164 unsigned int c
, p
, bytes1
= 0, bytes2
= 0;
165 struct evtsoftdata
*ep
;
166 minor_t minor
= getminor(dev
);
168 if (secpolicy_xvm_control(cr
))
171 ep
= EVTCHNDRV_INST2SOFTS(EVTCHNDRV_MINOR2INST(minor
));
173 /* Whole number of ports. */
174 count
= uio
->uio_resid
;
175 count
&= ~(sizeof (evtchn_port_t
) - 1);
180 if (count
> PAGESIZE
)
183 mutex_enter(&ep
->evtchn_lock
);
185 if (ep
->ring_overflow
) {
190 if ((c
= ep
->ring_cons
) != (p
= ep
->ring_prod
))
193 if (uio
->uio_fmode
& O_NONBLOCK
) {
198 if (cv_wait_sig(&ep
->evtchn_wait
, &ep
->evtchn_lock
) == 0) {
204 /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */
205 if (((c
^ p
) & EVTCHN_RING_SIZE
) != 0) {
206 bytes1
= (EVTCHN_RING_SIZE
- EVTCHN_RING_MASK(c
)) *
207 sizeof (evtchn_port_t
);
208 bytes2
= EVTCHN_RING_MASK(p
) * sizeof (evtchn_port_t
);
210 bytes1
= (p
- c
) * sizeof (evtchn_port_t
);
214 /* Truncate chunks according to caller's maximum byte count. */
215 if (bytes1
> count
) {
218 } else if ((bytes1
+ bytes2
) > count
) {
219 bytes2
= count
- bytes1
;
222 if (uiomove(&ep
->ring
[EVTCHN_RING_MASK(c
)], bytes1
, UIO_READ
, uio
) ||
223 ((bytes2
!= 0) && uiomove(&ep
->ring
[0], bytes2
, UIO_READ
, uio
))) {
228 ep
->ring_cons
+= (bytes1
+ bytes2
) / sizeof (evtchn_port_t
);
230 mutex_exit(&ep
->evtchn_lock
);
236 evtchndrv_write(dev_t dev
, struct uio
*uio
, cred_t
*cr
)
241 struct evtsoftdata
*ep
;
243 minor_t minor
= getminor(dev
);
244 evtchn_port_t sbuf
[32];
246 if (secpolicy_xvm_control(cr
))
249 ep
= EVTCHNDRV_INST2SOFTS(EVTCHNDRV_MINOR2INST(minor
));
252 /* Whole number of ports. */
253 count
= uio
->uio_resid
;
254 count
&= ~(sizeof (evtchn_port_t
) - 1);
259 if (count
> PAGESIZE
)
262 if (count
<= sizeof (sbuf
))
265 kbuf
= kmem_alloc(PAGESIZE
, KM_SLEEP
);
266 if ((rc
= uiomove(kbuf
, count
, UIO_WRITE
, uio
)) != 0)
269 mutex_enter(&port_user_lock
);
270 for (i
= 0; i
< (count
/ sizeof (evtchn_port_t
)); i
++)
271 if ((kbuf
[i
] < NR_EVENT_CHANNELS
) &&
272 (port_user
[kbuf
[i
]] == ep
)) {
273 flags
= intr_clear();
274 ec_unmask_evtchn(kbuf
[i
]);
277 mutex_exit(&port_user_lock
);
281 kmem_free(kbuf
, PAGESIZE
);
286 evtchn_bind_to_user(struct evtsoftdata
*u
, int port
)
291 * save away the PID of the last process to bind to this event channel.
292 * Useful for debugging.
294 u
->pid
= ddi_get_pid();
296 mutex_enter(&port_user_lock
);
297 ASSERT(port_user
[port
] == NULL
);
299 ec_irq_add_evtchn(ec_dev_irq
, port
);
300 flags
= intr_clear();
301 ec_unmask_evtchn(port
);
303 mutex_exit(&port_user_lock
);
307 evtchndrv_close_evtchn(int port
)
309 struct evtsoftdata
*ep
;
311 ASSERT(MUTEX_HELD(&port_user_lock
));
312 ep
= port_user
[port
];
314 (void) ec_mask_evtchn(port
);
316 * It is possible the event is in transit to us.
317 * If it is already in the ring buffer, then a client may
318 * get a spurious event notification on the next read of
319 * of the evtchn device. Clients will need to be able to
320 * handle getting a spurious event notification.
322 port_user
[port
] = NULL
;
324 * The event is masked and should stay so, clean it up.
326 ec_irq_rm_evtchn(ec_dev_irq
, port
);
331 evtchndrv_ioctl(dev_t dev
, int cmd
, intptr_t data
, int flag
, cred_t
*cr
,
335 struct evtsoftdata
*ep
;
336 minor_t minor
= getminor(dev
);
338 if (secpolicy_xvm_control(cr
))
341 ep
= EVTCHNDRV_INST2SOFTS(EVTCHNDRV_MINOR2INST(minor
));
346 case IOCTL_EVTCHN_BIND_VIRQ
: {
347 struct ioctl_evtchn_bind_virq bind
;
349 if (copyin((void *)data
, &bind
, sizeof (bind
))) {
354 if ((err
= xen_bind_virq(bind
.virq
, 0, rvalp
)) != 0)
357 evtchn_bind_to_user(ep
, *rvalp
);
361 case IOCTL_EVTCHN_BIND_INTERDOMAIN
: {
362 struct ioctl_evtchn_bind_interdomain bind
;
364 if (copyin((void *)data
, &bind
, sizeof (bind
))) {
369 if ((err
= xen_bind_interdomain(bind
.remote_domain
,
370 bind
.remote_port
, rvalp
)) != 0)
373 ec_bind_vcpu(*rvalp
, 0);
374 evtchn_bind_to_user(ep
, *rvalp
);
378 case IOCTL_EVTCHN_BIND_UNBOUND_PORT
: {
379 struct ioctl_evtchn_bind_unbound_port bind
;
381 if (copyin((void *)data
, &bind
, sizeof (bind
))) {
386 if ((err
= xen_alloc_unbound_evtchn(bind
.remote_domain
,
390 evtchn_bind_to_user(ep
, *rvalp
);
394 case IOCTL_EVTCHN_UNBIND
: {
395 struct ioctl_evtchn_unbind unbind
;
397 if (copyin((void *)data
, &unbind
, sizeof (unbind
))) {
402 if (unbind
.port
>= NR_EVENT_CHANNELS
) {
407 mutex_enter(&port_user_lock
);
409 if (port_user
[unbind
.port
] != ep
) {
410 mutex_exit(&port_user_lock
);
415 evtchndrv_close_evtchn(unbind
.port
);
416 mutex_exit(&port_user_lock
);
420 case IOCTL_EVTCHN_NOTIFY
: {
421 struct ioctl_evtchn_notify notify
;
423 if (copyin((void *)data
, ¬ify
, sizeof (notify
))) {
428 if (notify
.port
>= NR_EVENT_CHANNELS
) {
430 } else if (port_user
[notify
.port
] != ep
) {
433 ec_notify_via_evtchn(notify
.port
);
446 evtchndrv_poll(dev_t dev
, short ev
, int anyyet
, short *revp
, pollhead_t
**phpp
)
448 struct evtsoftdata
*ep
;
449 minor_t minor
= getminor(dev
);
452 ep
= EVTCHNDRV_INST2SOFTS(EVTCHNDRV_MINOR2INST(minor
));
457 if (ep
->ring_overflow
)
459 if (ev
& (POLLIN
| POLLRDNORM
)) {
460 mutex_enter(&ep
->evtchn_lock
);
461 if (ep
->ring_cons
!= ep
->ring_prod
)
462 mask
|= (POLLIN
| POLLRDNORM
) & ev
;
464 if (mask
== 0 && !anyyet
)
465 *phpp
= &ep
->evtchn_pollhead
;
466 mutex_exit(&ep
->evtchn_lock
);
475 evtchndrv_open(dev_t
*devp
, int flag
, int otyp
, cred_t
*credp
)
477 struct evtsoftdata
*ep
;
478 minor_t minor
= getminor(*devp
);
480 if (otyp
== OTYP_BLK
)
484 * only allow open on minor = 0 - the clone device
490 * find a free slot and grab it
492 mutex_enter(&evtchndrv_clone_tab_mutex
);
493 for (minor
= 1; minor
< evtchndrv_nclones
; minor
++) {
494 if (evtchndrv_clone_tab
[minor
] == 0) {
495 evtchndrv_clone_tab
[minor
] = 1;
499 mutex_exit(&evtchndrv_clone_tab_mutex
);
500 if (minor
== evtchndrv_nclones
)
503 /* Allocate softstate structure */
504 if (ddi_soft_state_zalloc(evtchndrv_statep
,
505 EVTCHNDRV_MINOR2INST(minor
)) != DDI_SUCCESS
) {
506 mutex_enter(&evtchndrv_clone_tab_mutex
);
507 evtchndrv_clone_tab
[minor
] = 0;
508 mutex_exit(&evtchndrv_clone_tab_mutex
);
511 ep
= EVTCHNDRV_INST2SOFTS(EVTCHNDRV_MINOR2INST(minor
));
513 /* ... and init it */
514 ep
->dip
= evtchndrv_dip
;
516 cv_init(&ep
->evtchn_wait
, NULL
, CV_DEFAULT
, NULL
);
517 mutex_init(&ep
->evtchn_lock
, NULL
, MUTEX_DEFAULT
, NULL
);
519 ep
->ring
= kmem_alloc(PAGESIZE
, KM_SLEEP
);
522 *devp
= makedevice(getmajor(*devp
), minor
);
529 evtchndrv_close(dev_t dev
, int flag
, int otyp
, struct cred
*credp
)
531 struct evtsoftdata
*ep
;
532 minor_t minor
= getminor(dev
);
535 ep
= EVTCHNDRV_INST2SOFTS(EVTCHNDRV_MINOR2INST(minor
));
539 mutex_enter(&port_user_lock
);
542 for (i
= 0; i
< NR_EVENT_CHANNELS
; i
++) {
543 if (port_user
[i
] != ep
)
546 evtchndrv_close_evtchn(i
);
549 mutex_exit(&port_user_lock
);
551 kmem_free(ep
->ring
, PAGESIZE
);
552 ddi_soft_state_free(evtchndrv_statep
, EVTCHNDRV_MINOR2INST(minor
));
555 * free clone tab slot
557 mutex_enter(&evtchndrv_clone_tab_mutex
);
558 evtchndrv_clone_tab
[minor
] = 0;
559 mutex_exit(&evtchndrv_clone_tab_mutex
);
566 evtchndrv_info(dev_info_t
*dip
, ddi_info_cmd_t cmd
, void *arg
, void **result
)
568 dev_t dev
= (dev_t
)arg
;
569 minor_t minor
= getminor(dev
);
573 case DDI_INFO_DEVT2DEVINFO
:
574 if (minor
!= 0 || evtchndrv_dip
== NULL
) {
576 retval
= DDI_FAILURE
;
578 *result
= (void *)evtchndrv_dip
;
579 retval
= DDI_SUCCESS
;
582 case DDI_INFO_DEVT2INSTANCE
:
584 retval
= DDI_SUCCESS
;
587 retval
= DDI_FAILURE
;
594 evtchndrv_attach(dev_info_t
*dip
, ddi_attach_cmd_t cmd
)
597 int unit
= ddi_get_instance(dip
);
604 return (DDI_SUCCESS
);
606 cmn_err(CE_WARN
, "evtchn_attach: unknown cmd 0x%x\n", cmd
);
607 return (DDI_FAILURE
);
613 * only one instance - but we clone using the open routine
615 if (ddi_get_instance(dip
) > 0)
616 return (DDI_FAILURE
);
618 mutex_init(&evtchndrv_clone_tab_mutex
, NULL
, MUTEX_DRIVER
,
621 error
= ddi_create_minor_node(dip
, "evtchn", S_IFCHR
, unit
,
623 if (error
!= DDI_SUCCESS
)
627 * save dip for getinfo
632 mutex_init(&port_user_lock
, NULL
, MUTEX_DRIVER
, NULL
);
633 (void) memset(port_user
, 0, sizeof (port_user
));
635 ec_dev_irq
= ec_dev_alloc_irq();
636 (void) add_avintr(NULL
, IPL_EVTCHN
, (avfunc
)evtchn_device_upcall
,
637 "evtchn_driver", ec_dev_irq
, NULL
, NULL
, NULL
, dip
);
639 return (DDI_SUCCESS
);
642 (void) evtchndrv_detach(dip
, DDI_DETACH
);
648 evtchndrv_detach(dev_info_t
*dip
, ddi_detach_cmd_t cmd
)
651 * Don't allow detach for now.
653 return (DDI_FAILURE
);
656 /* Solaris driver framework */
658 static struct cb_ops evtchndrv_cb_ops
= {
659 evtchndrv_open
, /* cb_open */
660 evtchndrv_close
, /* cb_close */
661 nodev
, /* cb_strategy */
662 nodev
, /* cb_print */
664 evtchndrv_read
, /* cb_read */
665 evtchndrv_write
, /* cb_write */
666 evtchndrv_ioctl
, /* cb_ioctl */
667 nodev
, /* cb_devmap */
669 nodev
, /* cb_segmap */
670 evtchndrv_poll
, /* cb_chpoll */
671 ddi_prop_op
, /* cb_prop_op */
673 D_NEW
| D_MP
| D_64BIT
/* cb_flag */
676 static struct dev_ops evtchndrv_dev_ops
= {
677 DEVO_REV
, /* devo_rev */
679 evtchndrv_info
, /* devo_getinfo */
680 nulldev
, /* devo_identify */
681 nulldev
, /* devo_probe */
682 evtchndrv_attach
, /* devo_attach */
683 evtchndrv_detach
, /* devo_detach */
684 nodev
, /* devo_reset */
685 &evtchndrv_cb_ops
, /* devo_cb_ops */
686 NULL
, /* devo_bus_ops */
688 ddi_quiesce_not_needed
, /* devo_quiesce */
691 static struct modldrv modldrv
= {
692 &mod_driverops
, /* Type of module. This one is a driver */
693 "Evtchn driver", /* Name of the module. */
694 &evtchndrv_dev_ops
/* driver ops */
697 static struct modlinkage modlinkage
= {
708 err
= ddi_soft_state_init(&evtchndrv_statep
,
709 sizeof (struct evtsoftdata
), 1);
713 err
= mod_install(&modlinkage
);
715 ddi_soft_state_fini(&evtchndrv_statep
);
717 evtchndrv_clone_tab
= kmem_zalloc(
718 sizeof (int) * evtchndrv_nclones
, KM_SLEEP
);
727 e
= mod_remove(&modlinkage
);
731 ddi_soft_state_fini(&evtchndrv_statep
);
737 _info(struct modinfo
*modinfop
)
739 return (mod_info(&modlinkage
, modinfop
));