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