1 /******************************************************************************
2  * xc_evtchn.c
3  *
4  * API for manipulating and accessing inter-domain event channels.
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  * Copyright (c) 2004, K A Fraser.
20  */
21 
22 #include "xc_private.h"
23 
do_evtchn_op(xc_interface * xch,int cmd,void * arg,size_t arg_size,int silently_fail)24 static int do_evtchn_op(xc_interface *xch, int cmd, void *arg,
25                         size_t arg_size, int silently_fail)
26 {
27     int ret = -1;
28     DECLARE_HYPERCALL_BOUNCE(arg, arg_size, XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
29 
30     if ( xc_hypercall_bounce_pre(xch, arg) )
31     {
32         PERROR("do_evtchn_op: bouncing arg failed");
33         goto out;
34     }
35 
36     ret = xencall2(xch->xcall, __HYPERVISOR_event_channel_op,
37                    cmd, HYPERCALL_BUFFER_AS_ARG(arg));
38     if ( ret < 0 && !silently_fail )
39         ERROR("do_evtchn_op: HYPERVISOR_event_channel_op failed: %d", ret);
40 
41     xc_hypercall_bounce_post(xch, arg);
42  out:
43     return ret;
44 }
45 
46 xc_evtchn_port_or_error_t
xc_evtchn_alloc_unbound(xc_interface * xch,uint32_t dom,uint32_t remote_dom)47 xc_evtchn_alloc_unbound(xc_interface *xch,
48                         uint32_t dom,
49                         uint32_t remote_dom)
50 {
51     int rc;
52     struct evtchn_alloc_unbound arg = {
53         .dom        = dom,
54         .remote_dom = remote_dom,
55     };
56 
57     rc = do_evtchn_op(xch, EVTCHNOP_alloc_unbound, &arg, sizeof(arg), 0);
58     if ( rc == 0 )
59         rc = arg.port;
60 
61     return rc;
62 }
63 
xc_evtchn_reset(xc_interface * xch,uint32_t dom)64 int xc_evtchn_reset(xc_interface *xch,
65                     uint32_t dom)
66 {
67     struct evtchn_reset arg = { .dom = dom };
68     return do_evtchn_op(xch, EVTCHNOP_reset, &arg, sizeof(arg), 0);
69 }
70 
xc_evtchn_status(xc_interface * xch,xc_evtchn_status_t * status)71 int xc_evtchn_status(xc_interface *xch, xc_evtchn_status_t *status)
72 {
73     return do_evtchn_op(xch, EVTCHNOP_status, status,
74                         sizeof(*status), 1);
75 }
76 
77 /*
78  * Local variables:
79  * mode: C
80  * c-file-style: "BSD"
81  * c-basic-offset: 4
82  * tab-width: 4
83  * indent-tabs-mode: nil
84  * End:
85  */
86