ia64/xen-unstable

view tools/libxc/xc_private.c @ 8964:8946b6dcd49e

Fix x86_64 Xen build.

event_callback_cs and failsafe_callback_cs are x86_32 only.

Signed-off-by: Ian Campbell <Ian.Campbell@XenSource.com>
author Ian.Campbell@xensource.com
date Wed Feb 22 17:26:39 2006 +0000 (2006-02-22)
parents 0d10fac28427
children a1fcee3b2abe
line source
1 /******************************************************************************
2 * xc_private.c
3 *
4 * Helper functions for the rest of the library.
5 */
7 #include <zlib.h>
8 #include "xc_private.h"
9 #include <xen/memory.h>
11 void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
12 unsigned long *arr, int num )
13 {
14 privcmd_mmapbatch_t ioctlx;
15 void *addr;
16 addr = mmap(NULL, num*PAGE_SIZE, prot, MAP_SHARED, xc_handle, 0);
17 if ( addr == MAP_FAILED )
18 return NULL;
20 ioctlx.num=num;
21 ioctlx.dom=dom;
22 ioctlx.addr=(unsigned long)addr;
23 ioctlx.arr=arr;
24 if ( ioctl( xc_handle, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx ) < 0 )
25 {
26 int saved_errno = errno;
27 perror("XXXXXXXX");
28 (void)munmap(addr, num*PAGE_SIZE);
29 errno = saved_errno;
30 return NULL;
31 }
32 return addr;
34 }
36 /*******************/
38 void *xc_map_foreign_range(int xc_handle, uint32_t dom,
39 int size, int prot,
40 unsigned long mfn )
41 {
42 privcmd_mmap_t ioctlx;
43 privcmd_mmap_entry_t entry;
44 void *addr;
45 addr = mmap(NULL, size, prot, MAP_SHARED, xc_handle, 0);
46 if ( addr == MAP_FAILED )
47 return NULL;
49 ioctlx.num=1;
50 ioctlx.dom=dom;
51 ioctlx.entry=&entry;
52 entry.va=(unsigned long) addr;
53 entry.mfn=mfn;
54 entry.npages=(size+PAGE_SIZE-1)>>PAGE_SHIFT;
55 if ( ioctl( xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx ) < 0 )
56 {
57 int saved_errno = errno;
58 (void)munmap(addr, size);
59 errno = saved_errno;
60 return NULL;
61 }
62 return addr;
63 }
65 /*******************/
67 /* NB: arr must be mlock'ed */
68 int xc_get_pfn_type_batch(int xc_handle,
69 uint32_t dom, int num, unsigned long *arr)
70 {
71 DECLARE_DOM0_OP;
72 op.cmd = DOM0_GETPAGEFRAMEINFO2;
73 op.u.getpageframeinfo2.domain = (domid_t)dom;
74 op.u.getpageframeinfo2.num = num;
75 op.u.getpageframeinfo2.array = arr;
76 return do_dom0_op(xc_handle, &op);
77 }
79 #define GETPFN_ERR (~0U)
80 unsigned int get_pfn_type(int xc_handle,
81 unsigned long mfn,
82 uint32_t dom)
83 {
84 DECLARE_DOM0_OP;
85 op.cmd = DOM0_GETPAGEFRAMEINFO;
86 op.u.getpageframeinfo.mfn = mfn;
87 op.u.getpageframeinfo.domain = (domid_t)dom;
88 if ( do_dom0_op(xc_handle, &op) < 0 )
89 {
90 PERROR("Unexpected failure when getting page frame info!");
91 return GETPFN_ERR;
92 }
93 return op.u.getpageframeinfo.type;
94 }
96 int xc_mmuext_op(
97 int xc_handle,
98 struct mmuext_op *op,
99 unsigned int nr_ops,
100 domid_t dom)
101 {
102 DECLARE_HYPERCALL;
103 long ret = -EINVAL;
105 hypercall.op = __HYPERVISOR_mmuext_op;
106 hypercall.arg[0] = (unsigned long)op;
107 hypercall.arg[1] = (unsigned long)nr_ops;
108 hypercall.arg[2] = (unsigned long)0;
109 hypercall.arg[3] = (unsigned long)dom;
111 if ( mlock(op, nr_ops*sizeof(*op)) != 0 )
112 {
113 PERROR("Could not lock memory for Xen hypercall");
114 goto out1;
115 }
117 ret = do_xen_hypercall(xc_handle, &hypercall);
119 safe_munlock(op, nr_ops*sizeof(*op));
121 out1:
122 return ret;
123 }
125 static int flush_mmu_updates(int xc_handle, xc_mmu_t *mmu)
126 {
127 int err = 0;
128 DECLARE_HYPERCALL;
130 if ( mmu->idx == 0 )
131 return 0;
133 hypercall.op = __HYPERVISOR_mmu_update;
134 hypercall.arg[0] = (unsigned long)mmu->updates;
135 hypercall.arg[1] = (unsigned long)mmu->idx;
136 hypercall.arg[2] = 0;
137 hypercall.arg[3] = mmu->subject;
139 if ( mlock(mmu->updates, sizeof(mmu->updates)) != 0 )
140 {
141 PERROR("flush_mmu_updates: mmu updates mlock failed");
142 err = 1;
143 goto out;
144 }
146 if ( do_xen_hypercall(xc_handle, &hypercall) < 0 )
147 {
148 ERROR("Failure when submitting mmu updates");
149 err = 1;
150 }
152 mmu->idx = 0;
154 safe_munlock(mmu->updates, sizeof(mmu->updates));
156 out:
157 return err;
158 }
160 xc_mmu_t *xc_init_mmu_updates(int xc_handle, domid_t dom)
161 {
162 xc_mmu_t *mmu = malloc(sizeof(xc_mmu_t));
163 if ( mmu == NULL )
164 return mmu;
165 mmu->idx = 0;
166 mmu->subject = dom;
167 return mmu;
168 }
170 int xc_add_mmu_update(int xc_handle, xc_mmu_t *mmu,
171 unsigned long long ptr, unsigned long long val)
172 {
173 mmu->updates[mmu->idx].ptr = ptr;
174 mmu->updates[mmu->idx].val = val;
176 if ( ++mmu->idx == MAX_MMU_UPDATES )
177 return flush_mmu_updates(xc_handle, mmu);
179 return 0;
180 }
182 int xc_finish_mmu_updates(int xc_handle, xc_mmu_t *mmu)
183 {
184 return flush_mmu_updates(xc_handle, mmu);
185 }
187 int xc_memory_op(int xc_handle,
188 int cmd,
189 void *arg)
190 {
191 DECLARE_HYPERCALL;
192 struct xen_memory_reservation *reservation = arg;
193 struct xen_machphys_mfn_list *xmml = arg;
194 struct xen_translate_gpfn_list *trans = arg;
195 long ret = -EINVAL;
197 hypercall.op = __HYPERVISOR_memory_op;
198 hypercall.arg[0] = (unsigned long)cmd;
199 hypercall.arg[1] = (unsigned long)arg;
201 switch ( cmd )
202 {
203 case XENMEM_increase_reservation:
204 case XENMEM_decrease_reservation:
205 case XENMEM_populate_physmap:
206 if ( mlock(reservation, sizeof(*reservation)) != 0 )
207 {
208 PERROR("Could not mlock");
209 goto out1;
210 }
211 if ( (reservation->extent_start != NULL) &&
212 (mlock(reservation->extent_start,
213 reservation->nr_extents * sizeof(unsigned long)) != 0) )
214 {
215 PERROR("Could not mlock");
216 safe_munlock(reservation, sizeof(*reservation));
217 goto out1;
218 }
219 break;
220 case XENMEM_machphys_mfn_list:
221 if ( mlock(xmml, sizeof(*xmml)) != 0 )
222 {
223 PERROR("Could not mlock");
224 goto out1;
225 }
226 if ( mlock(xmml->extent_start,
227 xmml->max_extents * sizeof(unsigned long)) != 0 )
228 {
229 PERROR("Could not mlock");
230 safe_munlock(xmml, sizeof(*xmml));
231 goto out1;
232 }
233 break;
234 case XENMEM_reserved_phys_area:
235 if ( mlock(arg, sizeof(struct xen_reserved_phys_area)) )
236 {
237 PERROR("Could not mlock");
238 goto out1;
239 }
240 break;
241 case XENMEM_translate_gpfn_list:
242 if ( mlock(trans, sizeof(*trans)) != 0 )
243 {
244 PERROR("Could not mlock");
245 goto out1;
246 }
247 if ( mlock(trans->gpfn_list, trans->nr_gpfns * sizeof(long)) != 0 )
248 {
249 PERROR("Could not mlock");
250 safe_munlock(trans, sizeof(*trans));
251 goto out1;
252 }
253 if ( mlock(trans->mfn_list, trans->nr_gpfns * sizeof(long)) != 0 )
254 {
255 PERROR("Could not mlock");
256 safe_munlock(trans->gpfn_list, trans->nr_gpfns * sizeof(long));
257 safe_munlock(trans, sizeof(*trans));
258 goto out1;
259 }
260 break;
261 }
263 ret = do_xen_hypercall(xc_handle, &hypercall);
265 switch ( cmd )
266 {
267 case XENMEM_increase_reservation:
268 case XENMEM_decrease_reservation:
269 case XENMEM_populate_physmap:
270 safe_munlock(reservation, sizeof(*reservation));
271 if ( reservation->extent_start != NULL )
272 safe_munlock(reservation->extent_start,
273 reservation->nr_extents * sizeof(unsigned long));
274 break;
275 case XENMEM_machphys_mfn_list:
276 safe_munlock(xmml, sizeof(*xmml));
277 safe_munlock(xmml->extent_start,
278 xmml->max_extents * sizeof(unsigned long));
279 break;
280 case XENMEM_reserved_phys_area:
281 safe_munlock(arg, sizeof(struct xen_reserved_phys_area));
282 break;
283 case XENMEM_translate_gpfn_list:
284 safe_munlock(trans->mfn_list, trans->nr_gpfns * sizeof(long));
285 safe_munlock(trans->gpfn_list, trans->nr_gpfns * sizeof(long));
286 safe_munlock(trans, sizeof(*trans));
287 break;
288 }
290 out1:
291 return ret;
292 }
295 long long xc_domain_get_cpu_usage( int xc_handle, domid_t domid, int vcpu )
296 {
297 DECLARE_DOM0_OP;
299 op.cmd = DOM0_GETVCPUINFO;
300 op.u.getvcpuinfo.domain = (domid_t)domid;
301 op.u.getvcpuinfo.vcpu = (uint16_t)vcpu;
302 if ( (do_dom0_op(xc_handle, &op) < 0) )
303 {
304 PERROR("Could not get info on domain");
305 return -1;
306 }
307 return op.u.getvcpuinfo.cpu_time;
308 }
311 int xc_get_pfn_list(int xc_handle,
312 uint32_t domid,
313 unsigned long *pfn_buf,
314 unsigned long max_pfns)
315 {
316 DECLARE_DOM0_OP;
317 int ret;
318 op.cmd = DOM0_GETMEMLIST;
319 op.u.getmemlist.domain = (domid_t)domid;
320 op.u.getmemlist.max_pfns = max_pfns;
321 op.u.getmemlist.buffer = pfn_buf;
323 #ifdef VALGRIND
324 memset(pfn_buf, 0, max_pfns * sizeof(unsigned long));
325 #endif
327 if ( mlock(pfn_buf, max_pfns * sizeof(unsigned long)) != 0 )
328 {
329 PERROR("xc_get_pfn_list: pfn_buf mlock failed");
330 return -1;
331 }
333 ret = do_dom0_op(xc_handle, &op);
335 safe_munlock(pfn_buf, max_pfns * sizeof(unsigned long));
337 #if 0
338 #ifdef DEBUG
339 DPRINTF(("Ret for xc_get_pfn_list is %d\n", ret));
340 if (ret >= 0) {
341 int i, j;
342 for (i = 0; i < op.u.getmemlist.num_pfns; i += 16) {
343 fprintf(stderr, "0x%x: ", i);
344 for (j = 0; j < 16; j++)
345 fprintf(stderr, "0x%lx ", pfn_buf[i + j]);
346 fprintf(stderr, "\n");
347 }
348 }
349 #endif
350 #endif
352 return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
353 }
355 long xc_get_tot_pages(int xc_handle, uint32_t domid)
356 {
357 DECLARE_DOM0_OP;
358 op.cmd = DOM0_GETDOMAININFO;
359 op.u.getdomaininfo.domain = (domid_t)domid;
360 return (do_dom0_op(xc_handle, &op) < 0) ?
361 -1 : op.u.getdomaininfo.tot_pages;
362 }
364 int xc_copy_to_domain_page(int xc_handle,
365 uint32_t domid,
366 unsigned long dst_pfn,
367 void *src_page)
368 {
369 void *vaddr = xc_map_foreign_range(
370 xc_handle, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
371 if ( vaddr == NULL )
372 return -1;
373 memcpy(vaddr, src_page, PAGE_SIZE);
374 munmap(vaddr, PAGE_SIZE);
375 return 0;
376 }
378 int xc_clear_domain_page(int xc_handle,
379 uint32_t domid,
380 unsigned long dst_pfn)
381 {
382 void *vaddr = xc_map_foreign_range(
383 xc_handle, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
384 if ( vaddr == NULL )
385 return -1;
386 memset(vaddr, 0, PAGE_SIZE);
387 munmap(vaddr, PAGE_SIZE);
388 return 0;
389 }
391 unsigned long xc_get_filesz(int fd)
392 {
393 uint16_t sig;
394 uint32_t _sz = 0;
395 unsigned long sz;
397 lseek(fd, 0, SEEK_SET);
398 if ( read(fd, &sig, sizeof(sig)) != sizeof(sig) )
399 return 0;
400 sz = lseek(fd, 0, SEEK_END);
401 if ( sig == 0x8b1f ) /* GZIP signature? */
402 {
403 lseek(fd, -4, SEEK_END);
404 if ( read(fd, &_sz, 4) != 4 )
405 return 0;
406 sz = _sz;
407 }
408 lseek(fd, 0, SEEK_SET);
410 return sz;
411 }
413 void xc_map_memcpy(unsigned long dst, char *src, unsigned long size,
414 int xch, uint32_t dom, unsigned long *parray,
415 unsigned long vstart)
416 {
417 char *va;
418 unsigned long chunksz, done, pa;
420 for ( done = 0; done < size; done += chunksz )
421 {
422 pa = dst + done - vstart;
423 va = xc_map_foreign_range(
424 xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
425 chunksz = size - done;
426 if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
427 chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
428 memcpy(va + (pa & (PAGE_SIZE-1)), src + done, chunksz);
429 munmap(va, PAGE_SIZE);
430 }
431 }
433 int xc_dom0_op(int xc_handle, dom0_op_t *op)
434 {
435 return do_dom0_op(xc_handle, op);
436 }
438 int xc_version(int xc_handle, int cmd, void *arg)
439 {
440 int rc, argsize = 0;
442 switch ( cmd )
443 {
444 case XENVER_extraversion:
445 argsize = sizeof(xen_extraversion_t);
446 break;
447 case XENVER_compile_info:
448 argsize = sizeof(xen_compile_info_t);
449 break;
450 case XENVER_capabilities:
451 argsize = sizeof(xen_capabilities_info_t);
452 break;
453 case XENVER_changeset:
454 argsize = sizeof(xen_changeset_info_t);
455 break;
456 case XENVER_platform_parameters:
457 argsize = sizeof(xen_platform_parameters_t);
458 break;
459 }
461 if ( (argsize != 0) && (mlock(arg, argsize) != 0) )
462 {
463 PERROR("Could not lock memory for version hypercall");
464 return -ENOMEM;
465 }
467 #ifdef VALGRIND
468 if (argsize != 0)
469 memset(arg, 0, argsize);
470 #endif
472 rc = do_xen_version(xc_handle, cmd, arg);
474 if ( argsize != 0 )
475 safe_munlock(arg, argsize);
477 return rc;
478 }
480 unsigned long xc_make_page_below_4G(
481 int xc_handle, uint32_t domid, unsigned long mfn)
482 {
483 unsigned long new_mfn;
485 if ( xc_domain_memory_decrease_reservation(
486 xc_handle, domid, 1, 0, &mfn) != 0 )
487 {
488 fprintf(stderr,"xc_make_page_below_4G decrease failed. mfn=%lx\n",mfn);
489 return 0;
490 }
492 if ( xc_domain_memory_increase_reservation(
493 xc_handle, domid, 1, 0, 32, &new_mfn) != 0 )
494 {
495 fprintf(stderr,"xc_make_page_below_4G increase failed. mfn=%lx\n",mfn);
496 return 0;
497 }
499 return new_mfn;
500 }
502 /*
503 * Local variables:
504 * mode: C
505 * c-set-style: "BSD"
506 * c-basic-offset: 4
507 * tab-width: 4
508 * indent-tabs-mode: nil
509 * End:
510 */