1  /******************************************************************************
2  *
3  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
4  * Use is subject to license terms.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation;
9  * version 2.1 of the License.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; If not, see <http://www.gnu.org/licenses/>.
18  *
19  * Split off from xc_freebsd_osdep.c
20  */
21 
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <unistd.h>
25 
26 #include <sys/ioctl.h>
27 
28 #include <xen/sys/evtchn.h>
29 
30 #include "private.h"
31 
32 #define EVTCHN_DEV      "/dev/xen/evtchn"
33 
osdep_evtchn_open(xenevtchn_handle * xce,unsigned int flags)34 int osdep_evtchn_open(xenevtchn_handle *xce, unsigned int flags)
35 {
36     int open_flags = O_RDWR;
37     int fd;
38 
39     if ( !(flags & XENEVTCHN_NO_CLOEXEC) )
40         open_flags |= O_CLOEXEC;
41 
42     fd = open(EVTCHN_DEV, open_flags);
43     if ( fd == -1 )
44         return -1;
45 
46     xce->fd = fd;
47 
48     return 0;
49 }
50 
osdep_evtchn_close(xenevtchn_handle * xce)51 int osdep_evtchn_close(xenevtchn_handle *xce)
52 {
53     if ( xce->fd == -1 )
54         return 0;
55 
56     return close(xce->fd);
57 }
58 
osdep_evtchn_restrict(xenevtchn_handle * xce,domid_t domid)59 int osdep_evtchn_restrict(xenevtchn_handle *xce, domid_t domid)
60 {
61     errno = EOPNOTSUPP;
62 
63     return -1;
64 }
65 
xenevtchn_notify(xenevtchn_handle * xce,evtchn_port_t port)66 int xenevtchn_notify(xenevtchn_handle *xce, evtchn_port_t port)
67 {
68     int fd = xce->fd;
69     struct ioctl_evtchn_notify notify;
70 
71     notify.port = port;
72 
73     return ioctl(fd, IOCTL_EVTCHN_NOTIFY, &notify);
74 }
75 
xenevtchn_bind_unbound_port(xenevtchn_handle * xce,uint32_t domid)76 xenevtchn_port_or_error_t xenevtchn_bind_unbound_port(xenevtchn_handle *xce,
77                                                       uint32_t domid)
78 {
79     int ret, fd = xce->fd;
80     struct ioctl_evtchn_bind_unbound_port bind;
81 
82     bind.remote_domain = domid;
83 
84     ret = ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind);
85 
86     return ret ?: bind.port;
87 }
88 
xenevtchn_bind_interdomain(xenevtchn_handle * xce,uint32_t domid,evtchn_port_t remote_port)89 xenevtchn_port_or_error_t xenevtchn_bind_interdomain(xenevtchn_handle *xce,
90                                                      uint32_t domid,
91                                                      evtchn_port_t remote_port)
92 {
93     int ret, fd = xce->fd;
94     struct ioctl_evtchn_bind_interdomain bind;
95 
96     bind.remote_domain = domid;
97     bind.remote_port = remote_port;
98 
99     ret = ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
100 
101     return ret ?: bind.port;
102 }
103 
xenevtchn_bind_virq(xenevtchn_handle * xce,unsigned int virq)104 xenevtchn_port_or_error_t xenevtchn_bind_virq(xenevtchn_handle *xce,
105                                               unsigned int virq)
106 {
107     int ret, fd = xce->fd;
108     struct ioctl_evtchn_bind_virq bind;
109 
110     bind.virq = virq;
111 
112     ret = ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
113 
114     return ret ?: bind.port;
115 }
116 
xenevtchn_unbind(xenevtchn_handle * xce,evtchn_port_t port)117 int xenevtchn_unbind(xenevtchn_handle *xce, evtchn_port_t port)
118 {
119     int fd = xce->fd;
120     struct ioctl_evtchn_unbind unbind;
121 
122     unbind.port = port;
123 
124     return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind);
125 }
126 
xenevtchn_pending(xenevtchn_handle * xce)127 xenevtchn_port_or_error_t xenevtchn_pending(xenevtchn_handle *xce)
128 {
129     int fd = xce->fd;
130     evtchn_port_t port;
131 
132     if ( read(fd, &port, sizeof(port)) != sizeof(port) )
133         return -1;
134 
135     return port;
136 }
137 
xenevtchn_unmask(xenevtchn_handle * xce,evtchn_port_t port)138 int xenevtchn_unmask(xenevtchn_handle *xce, evtchn_port_t port)
139 {
140     int fd = xce->fd;
141 
142     if ( write(fd, &port, sizeof(port)) != sizeof(port) )
143         return -1;
144 
145     return 0;
146 }
147 
148 /*
149  * Local variables:
150  * mode: C
151  * c-file-style: "BSD"
152  * c-basic-offset: 4
153  * tab-width: 4
154  * indent-tabs-mode: nil
155  * End:
156  */
157