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
16 #include <stdlib.h>
17 #include <assert.h>
18 #include <errno.h>
19
20 #include <sys/mman.h>
21
22 #include "private.h"
23
all_restrict_cb(Xentoolcore__Active_Handle * ah,domid_t domid)24 static int all_restrict_cb(Xentoolcore__Active_Handle *ah, domid_t domid) {
25 xenforeignmemory_handle *fmem = CONTAINER_OF(ah, *fmem, tc_ah);
26
27 if (fmem->fd < 0)
28 /* just in case */
29 return 0;
30
31 return xenforeignmemory_restrict(fmem, domid);
32 }
33
xenforeignmemory_open(xentoollog_logger * logger,unsigned open_flags)34 xenforeignmemory_handle *xenforeignmemory_open(xentoollog_logger *logger,
35 unsigned open_flags)
36 {
37 xenforeignmemory_handle *fmem = malloc(sizeof(*fmem));
38 int rc;
39
40 if (!fmem) return NULL;
41
42 fmem->fd = -1;
43 fmem->logger = logger;
44 fmem->logger_tofree = NULL;
45
46 fmem->tc_ah.restrict_callback = all_restrict_cb;
47 xentoolcore__register_active_handle(&fmem->tc_ah);
48
49 if (!fmem->logger) {
50 fmem->logger = fmem->logger_tofree =
51 (xentoollog_logger*)
52 xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0);
53 if (!fmem->logger) goto err;
54 }
55
56 rc = osdep_xenforeignmemory_open(fmem);
57 if ( rc < 0 ) goto err;
58
59 return fmem;
60
61 err:
62 xentoolcore__deregister_active_handle(&fmem->tc_ah);
63 osdep_xenforeignmemory_close(fmem);
64 xtl_logger_destroy(fmem->logger_tofree);
65 free(fmem);
66 return NULL;
67 }
68
xenforeignmemory_close(xenforeignmemory_handle * fmem)69 int xenforeignmemory_close(xenforeignmemory_handle *fmem)
70 {
71 int rc;
72
73 if ( !fmem )
74 return 0;
75
76 xentoolcore__deregister_active_handle(&fmem->tc_ah);
77 rc = osdep_xenforeignmemory_close(fmem);
78 xtl_logger_destroy(fmem->logger_tofree);
79 free(fmem);
80 return rc;
81 }
82
xenforeignmemory_map2(xenforeignmemory_handle * fmem,uint32_t dom,void * addr,int prot,int flags,size_t num,const xen_pfn_t arr[],int err[])83 void *xenforeignmemory_map2(xenforeignmemory_handle *fmem,
84 uint32_t dom, void *addr,
85 int prot, int flags, size_t num,
86 const xen_pfn_t arr[/*num*/], int err[/*num*/])
87 {
88 void *ret;
89 int *err_to_free = NULL;
90
91 if ( err == NULL )
92 err = err_to_free = malloc(num * sizeof(int));
93
94 if ( err == NULL )
95 return NULL;
96
97 ret = osdep_xenforeignmemory_map(fmem, dom, addr, prot, flags, num, arr, err);
98
99 if ( ret && err_to_free )
100 {
101 int i;
102
103 for ( i = 0 ; i < num ; i++ )
104 {
105 if ( err[i] )
106 {
107 errno = -err[i];
108 (void)osdep_xenforeignmemory_unmap(fmem, ret, num);
109 ret = NULL;
110 break;
111 }
112 }
113 }
114
115 free(err_to_free);
116
117 return ret;
118 }
119
xenforeignmemory_map(xenforeignmemory_handle * fmem,uint32_t dom,int prot,size_t num,const xen_pfn_t arr[],int err[])120 void *xenforeignmemory_map(xenforeignmemory_handle *fmem,
121 uint32_t dom, int prot,
122 size_t num,
123 const xen_pfn_t arr[/*num*/], int err[/*num*/])
124 {
125 return xenforeignmemory_map2(fmem, dom, NULL, prot, 0, num, arr, err);
126 }
127
xenforeignmemory_unmap(xenforeignmemory_handle * fmem,void * addr,size_t num)128 int xenforeignmemory_unmap(xenforeignmemory_handle *fmem,
129 void *addr, size_t num)
130 {
131 return osdep_xenforeignmemory_unmap(fmem, addr, num);
132 }
133
xenforeignmemory_restrict(xenforeignmemory_handle * fmem,domid_t domid)134 int xenforeignmemory_restrict(xenforeignmemory_handle *fmem,
135 domid_t domid)
136 {
137 return osdep_xenforeignmemory_restrict(fmem, domid);
138 }
139
xenforeignmemory_map_resource(xenforeignmemory_handle * fmem,domid_t domid,unsigned int type,unsigned int id,unsigned long frame,unsigned long nr_frames,void ** paddr,int prot,int flags)140 xenforeignmemory_resource_handle *xenforeignmemory_map_resource(
141 xenforeignmemory_handle *fmem, domid_t domid, unsigned int type,
142 unsigned int id, unsigned long frame, unsigned long nr_frames,
143 void **paddr, int prot, int flags)
144 {
145 xenforeignmemory_resource_handle *fres;
146 int rc;
147
148 /* Check flags only contains POSIX defined values */
149 if ( flags & ~(MAP_SHARED | MAP_PRIVATE) )
150 {
151 errno = EINVAL;
152 return NULL;
153 }
154
155 fres = calloc(1, sizeof(*fres));
156 if ( !fres )
157 {
158 errno = ENOMEM;
159 return NULL;
160 }
161
162 fres->domid = domid;
163 fres->type = type;
164 fres->id = id;
165 fres->frame = frame;
166 fres->nr_frames = nr_frames;
167 fres->addr = *paddr;
168 fres->prot = prot;
169 fres->flags = flags;
170
171 rc = osdep_xenforeignmemory_map_resource(fmem, fres);
172 if ( rc )
173 {
174 free(fres);
175 fres = NULL;
176 } else
177 *paddr = fres->addr;
178
179 return fres;
180 }
181
xenforeignmemory_unmap_resource(xenforeignmemory_handle * fmem,xenforeignmemory_resource_handle * fres)182 int xenforeignmemory_unmap_resource(
183 xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres)
184 {
185 int rc = osdep_xenforeignmemory_unmap_resource(fmem, fres);
186
187 free(fres);
188 return rc;
189 }
190
191 /*
192 * Local variables:
193 * mode: C
194 * c-file-style: "BSD"
195 * c-basic-offset: 4
196 * tab-width: 4
197 * indent-tabs-mode: nil
198 * End:
199 */
200