1 /*
2  * Copyright (C) 2006-2007 XenSource Ltd.
3  * Copyright (C) 2008      Citrix Ltd.
4  * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published
8  * by the Free Software Foundation; version 2.1 only. with the special
9  * exception on linking described in file LICENSE.
10  *
11  * This program 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
14  * GNU Lesser General Public License for more details.
15  */
16 
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <fcntl.h>
20 #include <unistd.h>
21 #include <errno.h>
22 #include <stdint.h>
23 #include <sys/ioctl.h>
24 #include <xen/xen.h>
25 #include <xen/sys/evtchn.h>
26 #include <xenevtchn.h>
27 
28 #define CAML_NAME_SPACE
29 #include <caml/mlvalues.h>
30 #include <caml/memory.h>
31 #include <caml/alloc.h>
32 #include <caml/custom.h>
33 #include <caml/callback.h>
34 #include <caml/fail.h>
35 #include <caml/signals.h>
36 
37 #define _H(__h) ((xenevtchn_handle *)(__h))
38 
stub_eventchn_init(void)39 CAMLprim value stub_eventchn_init(void)
40 {
41 	CAMLparam0();
42 	CAMLlocal1(result);
43 	xenevtchn_handle *xce;
44 
45 	caml_enter_blocking_section();
46 	xce = xenevtchn_open(NULL, 0);
47 	caml_leave_blocking_section();
48 
49 	if (xce == NULL)
50 		caml_failwith("open failed");
51 
52 	result = (value)xce;
53 	CAMLreturn(result);
54 }
55 
stub_eventchn_fd(value xce)56 CAMLprim value stub_eventchn_fd(value xce)
57 {
58 	CAMLparam1(xce);
59 	CAMLlocal1(result);
60 	int fd;
61 
62 	fd = xenevtchn_fd(_H(xce));
63 	if (fd == -1)
64 		caml_failwith("evtchn fd failed");
65 
66 	result = Val_int(fd);
67 
68 	CAMLreturn(result);
69 }
70 
stub_eventchn_notify(value xce,value port)71 CAMLprim value stub_eventchn_notify(value xce, value port)
72 {
73 	CAMLparam2(xce, port);
74 	int rc;
75 
76 	caml_enter_blocking_section();
77 	rc = xenevtchn_notify(_H(xce), Int_val(port));
78 	caml_leave_blocking_section();
79 
80 	if (rc == -1)
81 		caml_failwith("evtchn notify failed");
82 
83 	CAMLreturn(Val_unit);
84 }
85 
stub_eventchn_bind_interdomain(value xce,value domid,value remote_port)86 CAMLprim value stub_eventchn_bind_interdomain(value xce, value domid,
87                                               value remote_port)
88 {
89 	CAMLparam3(xce, domid, remote_port);
90 	CAMLlocal1(port);
91 	xenevtchn_port_or_error_t rc;
92 
93 	caml_enter_blocking_section();
94 	rc = xenevtchn_bind_interdomain(_H(xce), Int_val(domid), Int_val(remote_port));
95 	caml_leave_blocking_section();
96 
97 	if (rc == -1)
98 		caml_failwith("evtchn bind_interdomain failed");
99 	port = Val_int(rc);
100 
101 	CAMLreturn(port);
102 }
103 
stub_eventchn_bind_virq(value xce,value virq_type)104 CAMLprim value stub_eventchn_bind_virq(value xce, value virq_type)
105 {
106 	CAMLparam2(xce, virq_type);
107 	CAMLlocal1(port);
108 	xenevtchn_port_or_error_t rc;
109 
110 	caml_enter_blocking_section();
111 	rc = xenevtchn_bind_virq(_H(xce), Int_val(virq_type));
112 	caml_leave_blocking_section();
113 
114 	if (rc == -1)
115 		caml_failwith("evtchn bind_virq failed");
116 	port = Val_int(rc);
117 
118 	CAMLreturn(port);
119 }
120 
stub_eventchn_unbind(value xce,value port)121 CAMLprim value stub_eventchn_unbind(value xce, value port)
122 {
123 	CAMLparam2(xce, port);
124 	int rc;
125 
126 	caml_enter_blocking_section();
127 	rc = xenevtchn_unbind(_H(xce), Int_val(port));
128 	caml_leave_blocking_section();
129 
130 	if (rc == -1)
131 		caml_failwith("evtchn unbind failed");
132 
133 	CAMLreturn(Val_unit);
134 }
135 
stub_eventchn_pending(value xce)136 CAMLprim value stub_eventchn_pending(value xce)
137 {
138 	CAMLparam1(xce);
139 	CAMLlocal1(result);
140 	xenevtchn_port_or_error_t port;
141 
142 	caml_enter_blocking_section();
143 	port = xenevtchn_pending(_H(xce));
144 	caml_leave_blocking_section();
145 
146 	if (port == -1)
147 		caml_failwith("evtchn pending failed");
148 	result = Val_int(port);
149 
150 	CAMLreturn(result);
151 }
152 
stub_eventchn_unmask(value xce,value _port)153 CAMLprim value stub_eventchn_unmask(value xce, value _port)
154 {
155 	CAMLparam2(xce, _port);
156 	evtchn_port_t port;
157 	int rc;
158 
159 	port = Int_val(_port);
160 
161 	caml_enter_blocking_section();
162 	rc = xenevtchn_unmask(_H(xce), port);
163 	caml_leave_blocking_section();
164 
165 	if (rc)
166 		caml_failwith("evtchn unmask failed");
167 	CAMLreturn(Val_unit);
168 }
169