debuggers.hg

view tools/libxc/xc_minios.c @ 21067:b4a1832a916f

Update Xen version to 4.0.0-rc6
author Keir Fraser <keir.fraser@citrix.com>
date Tue Mar 09 18:18:05 2010 +0000 (2010-03-09)
parents a56216b3f62d
children 3ffdb094c2c0 779c0ef9682c
line source
1 /******************************************************************************
2 *
3 * Copyright 2007-2008 Samuel Thibault <samuel.thibault@eu.citrix.com>.
4 * All rights reserved.
5 * Use is subject to license terms.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2 of the
10 * License.
11 */
13 #undef NDEBUG
14 #include <mini-os/types.h>
15 #include <mini-os/os.h>
16 #include <mini-os/mm.h>
17 #include <mini-os/lib.h>
18 #include <mini-os/gntmap.h>
19 #include <mini-os/events.h>
20 #include <mini-os/wait.h>
21 #include <sys/mman.h>
22 #include <errno.h>
24 #include <xen/memory.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <stdio.h>
28 #include <assert.h>
29 #include <stdint.h>
30 #include <inttypes.h>
32 #include "xc_private.h"
34 extern struct wait_queue_head event_queue;
36 int xc_interface_open(void)
37 {
38 return alloc_fd(FTYPE_XC);
39 }
41 int xc_interface_close(int xc_handle)
42 {
43 files[xc_handle].type = FTYPE_NONE;
44 return 0;
45 }
47 void *xc_map_foreign_bulk(int xc_handle, uint32_t dom, int prot,
48 const xen_pfn_t *arr, int *err, unsigned int num)
49 {
50 unsigned long pt_prot = 0;
51 #ifdef __ia64__
52 /* TODO */
53 #else
54 if (prot & PROT_READ)
55 pt_prot = L1_PROT_RO;
56 if (prot & PROT_WRITE)
57 pt_prot = L1_PROT;
58 #endif
59 return map_frames_ex(arr, num, 1, 0, 1, dom, err, pt_prot);
60 }
62 void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
63 xen_pfn_t *arr, int num)
64 {
65 unsigned long pt_prot = 0;
66 int err[num];
67 int i;
68 unsigned long addr;
70 #ifdef __ia64__
71 /* TODO */
72 #else
73 if (prot & PROT_READ)
74 pt_prot = L1_PROT_RO;
75 if (prot & PROT_WRITE)
76 pt_prot = L1_PROT;
77 #endif
78 addr = (unsigned long) map_frames_ex(arr, num, 1, 0, 1, dom, err, pt_prot);
79 for (i = 0; i < num; i++) {
80 if (err[i])
81 arr[i] |= 0xF0000000;
82 }
83 return (void *) addr;
84 }
86 void *xc_map_foreign_range(int xc_handle, uint32_t dom,
87 int size, int prot,
88 unsigned long mfn)
89 {
90 unsigned long pt_prot = 0;
91 #ifdef __ia64__
92 /* TODO */
93 #else
94 if (prot & PROT_READ)
95 pt_prot = L1_PROT_RO;
96 if (prot & PROT_WRITE)
97 pt_prot = L1_PROT;
98 #endif
99 assert(!(size % getpagesize()));
100 return map_frames_ex(&mfn, size / getpagesize(), 0, 1, 1, dom, NULL, pt_prot);
101 }
103 void *xc_map_foreign_ranges(int xc_handle, uint32_t dom,
104 size_t size, int prot, size_t chunksize,
105 privcmd_mmap_entry_t entries[], int nentries)
106 {
107 unsigned long *mfns;
108 int i, j, n;
109 unsigned long pt_prot = 0;
110 void *ret;
111 #ifdef __ia64__
112 /* TODO */
113 #else
114 if (prot & PROT_READ)
115 pt_prot = L1_PROT_RO;
116 if (prot & PROT_WRITE)
117 pt_prot = L1_PROT;
118 #endif
120 mfns = malloc((size / PAGE_SIZE) * sizeof(*mfns));
122 n = 0;
123 for (i = 0; i < nentries; i++)
124 for (j = 0; j < chunksize / PAGE_SIZE; j++)
125 mfns[n++] = entries[i].mfn + j;
127 ret = map_frames_ex(mfns, n, 1, 0, 1, dom, NULL, pt_prot);
128 free(mfns);
129 return ret;
130 }
133 int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall)
134 {
135 multicall_entry_t call;
136 int i, ret;
138 call.op = hypercall->op;
139 for (i = 0; i < sizeof(hypercall->arg) / sizeof(*hypercall->arg); i++)
140 call.args[i] = hypercall->arg[i];
142 ret = HYPERVISOR_multicall(&call, 1);
144 if (ret < 0) {
145 errno = -ret;
146 return -1;
147 }
148 if ((long) call.result < 0) {
149 errno = - (long) call.result;
150 return -1;
151 }
152 return call.result;
153 }
155 int xc_find_device_number(const char *name)
156 {
157 printf("xc_find_device_number(%s)\n", name);
158 do_exit();
159 }
161 int xc_evtchn_open(void)
162 {
163 int fd = alloc_fd(FTYPE_EVTCHN), i;
164 for (i = 0; i < MAX_EVTCHN_PORTS; i++) {
165 files[fd].evtchn.ports[i].port = -1;
166 files[fd].evtchn.ports[i].bound = 0;
167 }
168 printf("evtchn_open() -> %d\n", fd);
169 return fd;
170 }
172 int xc_evtchn_close(int xce_handle)
173 {
174 int i;
175 for (i = 0; i < MAX_EVTCHN_PORTS; i++)
176 if (files[xce_handle].evtchn.ports[i].bound)
177 unbind_evtchn(files[xce_handle].evtchn.ports[i].port);
178 files[xce_handle].type = FTYPE_NONE;
179 return 0;
180 }
182 int xc_evtchn_fd(int xce_handle)
183 {
184 return xce_handle;
185 }
187 int xc_evtchn_notify(int xce_handle, evtchn_port_t port)
188 {
189 int ret;
191 ret = notify_remote_via_evtchn(port);
193 if (ret < 0) {
194 errno = -ret;
195 ret = -1;
196 }
197 return ret;
198 }
200 /* XXX Note: This is not threadsafe */
201 static int port_alloc(int xce_handle) {
202 int i;
203 for (i= 0; i < MAX_EVTCHN_PORTS; i++)
204 if (files[xce_handle].evtchn.ports[i].port == -1)
205 break;
206 if (i == MAX_EVTCHN_PORTS) {
207 printf("Too many ports in xc handle\n");
208 errno = EMFILE;
209 return -1;
210 }
211 files[xce_handle].evtchn.ports[i].pending = 0;
212 return i;
213 }
215 static void evtchn_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
216 {
217 int xce_handle = (intptr_t) data;
218 int i;
219 assert(files[xce_handle].type == FTYPE_EVTCHN);
220 mask_evtchn(port);
221 for (i= 0; i < MAX_EVTCHN_PORTS; i++)
222 if (files[xce_handle].evtchn.ports[i].port == port)
223 break;
224 if (i == MAX_EVTCHN_PORTS) {
225 printk("Unknown port for handle %d\n", xce_handle);
226 return;
227 }
228 files[xce_handle].evtchn.ports[i].pending = 1;
229 files[xce_handle].read = 1;
230 wake_up(&event_queue);
231 }
233 evtchn_port_or_error_t xc_evtchn_bind_unbound_port(int xce_handle, int domid)
234 {
235 int ret, i;
236 evtchn_port_t port;
238 assert(get_current() == main_thread);
239 i = port_alloc(xce_handle);
240 if (i == -1)
241 return -1;
243 printf("xc_evtchn_bind_unbound_port(%d)", domid);
244 ret = evtchn_alloc_unbound(domid, evtchn_handler, (void*)(intptr_t)xce_handle, &port);
245 printf(" = %d\n", ret);
247 if (ret < 0) {
248 errno = -ret;
249 return -1;
250 }
251 files[xce_handle].evtchn.ports[i].bound = 1;
252 files[xce_handle].evtchn.ports[i].port = port;
253 unmask_evtchn(port);
254 return port;
255 }
257 evtchn_port_or_error_t xc_evtchn_bind_interdomain(int xce_handle, int domid,
258 evtchn_port_t remote_port)
259 {
260 evtchn_port_t local_port;
261 int ret, i;
263 assert(get_current() == main_thread);
264 i = port_alloc(xce_handle);
265 if (i == -1)
266 return -1;
268 printf("xc_evtchn_bind_interdomain(%d, %"PRId32")", domid, remote_port);
269 ret = evtchn_bind_interdomain(domid, remote_port, evtchn_handler, (void*)(intptr_t)xce_handle, &local_port);
270 printf(" = %d\n", ret);
272 if (ret < 0) {
273 errno = -ret;
274 return -1;
275 }
276 files[xce_handle].evtchn.ports[i].bound = 1;
277 files[xce_handle].evtchn.ports[i].port = local_port;
278 unmask_evtchn(local_port);
279 return local_port;
280 }
282 int xc_evtchn_unbind(int xce_handle, evtchn_port_t port)
283 {
284 int i;
285 for (i = 0; i < MAX_EVTCHN_PORTS; i++)
286 if (files[xce_handle].evtchn.ports[i].port == port) {
287 files[xce_handle].evtchn.ports[i].port = -1;
288 break;
289 }
290 if (i == MAX_EVTCHN_PORTS) {
291 printf("Warning: couldn't find port %"PRId32" for xc handle %x\n", port, xce_handle);
292 errno = -EINVAL;
293 return -1;
294 }
295 files[xce_handle].evtchn.ports[i].bound = 0;
296 unbind_evtchn(port);
297 return 0;
298 }
300 evtchn_port_or_error_t xc_evtchn_bind_virq(int xce_handle, unsigned int virq)
301 {
302 evtchn_port_t port;
303 int i;
305 assert(get_current() == main_thread);
306 i = port_alloc(xce_handle);
307 if (i == -1)
308 return -1;
310 printf("xc_evtchn_bind_virq(%d)", virq);
311 port = bind_virq(virq, evtchn_handler, (void*)(intptr_t)xce_handle);
313 if (port < 0) {
314 errno = -port;
315 return -1;
316 }
317 files[xce_handle].evtchn.ports[i].bound = 1;
318 files[xce_handle].evtchn.ports[i].port = port;
319 unmask_evtchn(port);
320 return port;
321 }
323 evtchn_port_or_error_t xc_evtchn_pending(int xce_handle)
324 {
325 int i;
326 unsigned long flags;
327 evtchn_port_t ret = -1;
329 local_irq_save(flags);
330 files[xce_handle].read = 0;
331 for (i = 0; i < MAX_EVTCHN_PORTS; i++) {
332 evtchn_port_t port = files[xce_handle].evtchn.ports[i].port;
333 if (port != -1 && files[xce_handle].evtchn.ports[i].pending) {
334 if (ret == -1) {
335 ret = port;
336 files[xce_handle].evtchn.ports[i].pending = 0;
337 } else {
338 files[xce_handle].read = 1;
339 break;
340 }
341 }
342 }
343 local_irq_restore(flags);
344 return ret;
345 }
347 int xc_evtchn_unmask(int xce_handle, evtchn_port_t port)
348 {
349 unmask_evtchn(port);
350 return 0;
351 }
353 /* Optionally flush file to disk and discard page cache */
354 void discard_file_cache(int fd, int flush)
355 {
356 if (flush)
357 fsync(fd);
358 }
360 int xc_gnttab_open(void)
361 {
362 int xcg_handle;
363 xcg_handle = alloc_fd(FTYPE_GNTMAP);
364 gntmap_init(&files[xcg_handle].gntmap);
365 return xcg_handle;
366 }
368 int xc_gnttab_close(int xcg_handle)
369 {
370 gntmap_fini(&files[xcg_handle].gntmap);
371 files[xcg_handle].type = FTYPE_NONE;
372 return 0;
373 }
375 void *xc_gnttab_map_grant_ref(int xcg_handle,
376 uint32_t domid,
377 uint32_t ref,
378 int prot)
379 {
380 return gntmap_map_grant_refs(&files[xcg_handle].gntmap,
381 1,
382 &domid, 0,
383 &ref,
384 prot & PROT_WRITE);
385 }
387 void *xc_gnttab_map_grant_refs(int xcg_handle,
388 uint32_t count,
389 uint32_t *domids,
390 uint32_t *refs,
391 int prot)
392 {
393 return gntmap_map_grant_refs(&files[xcg_handle].gntmap,
394 count,
395 domids, 1,
396 refs,
397 prot & PROT_WRITE);
398 }
400 void *xc_gnttab_map_domain_grant_refs(int xcg_handle,
401 uint32_t count,
402 uint32_t domid,
403 uint32_t *refs,
404 int prot)
405 {
406 return gntmap_map_grant_refs(&files[xcg_handle].gntmap,
407 count,
408 &domid, 0,
409 refs,
410 prot & PROT_WRITE);
411 }
413 int xc_gnttab_munmap(int xcg_handle,
414 void *start_address,
415 uint32_t count)
416 {
417 int ret;
418 ret = gntmap_munmap(&files[xcg_handle].gntmap,
419 (unsigned long) start_address,
420 count);
421 if (ret < 0) {
422 errno = -ret;
423 return -1;
424 }
425 return ret;
426 }
428 int xc_gnttab_set_max_grants(int xcg_handle,
429 uint32_t count)
430 {
431 int ret;
432 ret = gntmap_set_max_grants(&files[xcg_handle].gntmap,
433 count);
434 if (ret < 0) {
435 errno = -ret;
436 return -1;
437 }
438 return ret;
439 }
441 grant_entry_v1_t *xc_gnttab_map_table_v1(
442 int xc_handle, int domid, int *gnt_num)
443 {
444 return NULL;
445 }
447 grant_entry_v2_t *xc_gnttab_map_table_v2(
448 int xc_handle, int domid, int *gnt_num)
449 {
450 return NULL;
451 }
453 /*
454 * Local variables:
455 * mode: C
456 * c-set-style: "BSD"
457 * c-basic-offset: 4
458 * tab-width: 4
459 * indent-tabs-mode: nil
460 * End:
461 */