ia64/xen-unstable

view tools/libxc/xc_private.c @ 10691:dab0a5650e6d

[IA64] Creates tools/libxc/ia64 directory.

Split and move xc_ia64_stubs.c into ia64/xc_ia64_hvm_build.c and
ia64/xc_ia64_stubs.c
Creates ia64/Makefile.
Clean up (static in const) in xc_ia64_hvm_build.c

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
[whitespace cleanups in new files]
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
author awilliam@xenbuild.aw
date Tue Jul 11 11:29:25 2006 -0600 (2006-07-11)
parents 74018b65c369
children 86d26e6ec89b
line source
1 /******************************************************************************
2 * xc_private.c
3 *
4 * Helper functions for the rest of the library.
5 */
7 #include <inttypes.h>
8 #include "xc_private.h"
10 /* NB: arr must be mlock'ed */
11 int xc_get_pfn_type_batch(int xc_handle,
12 uint32_t dom, int num, unsigned long *arr)
13 {
14 DECLARE_DOM0_OP;
15 op.cmd = DOM0_GETPAGEFRAMEINFO2;
16 op.u.getpageframeinfo2.domain = (domid_t)dom;
17 op.u.getpageframeinfo2.num = num;
18 set_xen_guest_handle(op.u.getpageframeinfo2.array, arr);
19 return do_dom0_op(xc_handle, &op);
20 }
22 #define GETPFN_ERR (~0U)
23 unsigned int get_pfn_type(int xc_handle,
24 unsigned long mfn,
25 uint32_t dom)
26 {
27 DECLARE_DOM0_OP;
28 op.cmd = DOM0_GETPAGEFRAMEINFO;
29 op.u.getpageframeinfo.gmfn = mfn;
30 op.u.getpageframeinfo.domain = (domid_t)dom;
31 if ( do_dom0_op(xc_handle, &op) < 0 )
32 {
33 PERROR("Unexpected failure when getting page frame info!");
34 return GETPFN_ERR;
35 }
36 return op.u.getpageframeinfo.type;
37 }
39 int xc_mmuext_op(
40 int xc_handle,
41 struct mmuext_op *op,
42 unsigned int nr_ops,
43 domid_t dom)
44 {
45 DECLARE_HYPERCALL;
46 long ret = -EINVAL;
48 hypercall.op = __HYPERVISOR_mmuext_op;
49 hypercall.arg[0] = (unsigned long)op;
50 hypercall.arg[1] = (unsigned long)nr_ops;
51 hypercall.arg[2] = (unsigned long)0;
52 hypercall.arg[3] = (unsigned long)dom;
54 if ( mlock(op, nr_ops*sizeof(*op)) != 0 )
55 {
56 PERROR("Could not lock memory for Xen hypercall");
57 goto out1;
58 }
60 ret = do_xen_hypercall(xc_handle, &hypercall);
62 safe_munlock(op, nr_ops*sizeof(*op));
64 out1:
65 return ret;
66 }
68 static int flush_mmu_updates(int xc_handle, xc_mmu_t *mmu)
69 {
70 int err = 0;
71 DECLARE_HYPERCALL;
73 if ( mmu->idx == 0 )
74 return 0;
76 hypercall.op = __HYPERVISOR_mmu_update;
77 hypercall.arg[0] = (unsigned long)mmu->updates;
78 hypercall.arg[1] = (unsigned long)mmu->idx;
79 hypercall.arg[2] = 0;
80 hypercall.arg[3] = mmu->subject;
82 if ( mlock(mmu->updates, sizeof(mmu->updates)) != 0 )
83 {
84 PERROR("flush_mmu_updates: mmu updates mlock failed");
85 err = 1;
86 goto out;
87 }
89 if ( do_xen_hypercall(xc_handle, &hypercall) < 0 )
90 {
91 ERROR("Failure when submitting mmu updates");
92 err = 1;
93 }
95 mmu->idx = 0;
97 safe_munlock(mmu->updates, sizeof(mmu->updates));
99 out:
100 return err;
101 }
103 xc_mmu_t *xc_init_mmu_updates(int xc_handle, domid_t dom)
104 {
105 xc_mmu_t *mmu = malloc(sizeof(xc_mmu_t));
106 if ( mmu == NULL )
107 return mmu;
108 mmu->idx = 0;
109 mmu->subject = dom;
110 return mmu;
111 }
113 int xc_add_mmu_update(int xc_handle, xc_mmu_t *mmu,
114 unsigned long long ptr, unsigned long long val)
115 {
116 mmu->updates[mmu->idx].ptr = ptr;
117 mmu->updates[mmu->idx].val = val;
119 if ( ++mmu->idx == MAX_MMU_UPDATES )
120 return flush_mmu_updates(xc_handle, mmu);
122 return 0;
123 }
125 int xc_finish_mmu_updates(int xc_handle, xc_mmu_t *mmu)
126 {
127 return flush_mmu_updates(xc_handle, mmu);
128 }
130 int xc_memory_op(int xc_handle,
131 int cmd,
132 void *arg)
133 {
134 DECLARE_HYPERCALL;
135 struct xen_memory_reservation *reservation = arg;
136 struct xen_machphys_mfn_list *xmml = arg;
137 struct xen_translate_gpfn_list *trans = arg;
138 xen_pfn_t *extent_start;
139 xen_pfn_t *gpfn_list;
140 xen_pfn_t *mfn_list;
141 long ret = -EINVAL;
143 hypercall.op = __HYPERVISOR_memory_op;
144 hypercall.arg[0] = (unsigned long)cmd;
145 hypercall.arg[1] = (unsigned long)arg;
147 switch ( cmd )
148 {
149 case XENMEM_increase_reservation:
150 case XENMEM_decrease_reservation:
151 case XENMEM_populate_physmap:
152 if ( mlock(reservation, sizeof(*reservation)) != 0 )
153 {
154 PERROR("Could not mlock");
155 goto out1;
156 }
157 get_xen_guest_handle(extent_start, reservation->extent_start);
158 if ( (extent_start != NULL) &&
159 (mlock(extent_start,
160 reservation->nr_extents * sizeof(xen_pfn_t)) != 0) )
161 {
162 PERROR("Could not mlock");
163 safe_munlock(reservation, sizeof(*reservation));
164 goto out1;
165 }
166 break;
167 case XENMEM_machphys_mfn_list:
168 if ( mlock(xmml, sizeof(*xmml)) != 0 )
169 {
170 PERROR("Could not mlock");
171 goto out1;
172 }
173 get_xen_guest_handle(extent_start, xmml->extent_start);
174 if ( mlock(extent_start,
175 xmml->max_extents * sizeof(xen_pfn_t)) != 0 )
176 {
177 PERROR("Could not mlock");
178 safe_munlock(xmml, sizeof(*xmml));
179 goto out1;
180 }
181 break;
182 case XENMEM_add_to_physmap:
183 if ( mlock(arg, sizeof(struct xen_add_to_physmap)) )
184 {
185 PERROR("Could not mlock");
186 goto out1;
187 }
188 break;
189 case XENMEM_translate_gpfn_list:
190 if ( mlock(trans, sizeof(*trans)) != 0 )
191 {
192 PERROR("Could not mlock");
193 goto out1;
194 }
195 get_xen_guest_handle(gpfn_list, trans->gpfn_list);
196 if ( mlock(gpfn_list, trans->nr_gpfns * sizeof(xen_pfn_t)) != 0 )
197 {
198 PERROR("Could not mlock");
199 safe_munlock(trans, sizeof(*trans));
200 goto out1;
201 }
202 get_xen_guest_handle(mfn_list, trans->mfn_list);
203 if ( mlock(mfn_list, trans->nr_gpfns * sizeof(xen_pfn_t)) != 0 )
204 {
205 PERROR("Could not mlock");
206 safe_munlock(gpfn_list, trans->nr_gpfns * sizeof(xen_pfn_t));
207 safe_munlock(trans, sizeof(*trans));
208 goto out1;
209 }
210 break;
211 }
213 ret = do_xen_hypercall(xc_handle, &hypercall);
215 switch ( cmd )
216 {
217 case XENMEM_increase_reservation:
218 case XENMEM_decrease_reservation:
219 case XENMEM_populate_physmap:
220 safe_munlock(reservation, sizeof(*reservation));
221 get_xen_guest_handle(extent_start, reservation->extent_start);
222 if ( extent_start != NULL )
223 safe_munlock(extent_start,
224 reservation->nr_extents * sizeof(xen_pfn_t));
225 break;
226 case XENMEM_machphys_mfn_list:
227 safe_munlock(xmml, sizeof(*xmml));
228 get_xen_guest_handle(extent_start, xmml->extent_start);
229 safe_munlock(extent_start,
230 xmml->max_extents * sizeof(xen_pfn_t));
231 break;
232 case XENMEM_add_to_physmap:
233 safe_munlock(arg, sizeof(struct xen_add_to_physmap));
234 break;
235 case XENMEM_translate_gpfn_list:
236 get_xen_guest_handle(mfn_list, trans->mfn_list);
237 safe_munlock(mfn_list, trans->nr_gpfns * sizeof(xen_pfn_t));
238 get_xen_guest_handle(gpfn_list, trans->gpfn_list);
239 safe_munlock(gpfn_list, trans->nr_gpfns * sizeof(xen_pfn_t));
240 safe_munlock(trans, sizeof(*trans));
241 break;
242 }
244 out1:
245 return ret;
246 }
249 long long xc_domain_get_cpu_usage( int xc_handle, domid_t domid, int vcpu )
250 {
251 DECLARE_DOM0_OP;
253 op.cmd = DOM0_GETVCPUINFO;
254 op.u.getvcpuinfo.domain = (domid_t)domid;
255 op.u.getvcpuinfo.vcpu = (uint16_t)vcpu;
256 if ( (do_dom0_op(xc_handle, &op) < 0) )
257 {
258 PERROR("Could not get info on domain");
259 return -1;
260 }
261 return op.u.getvcpuinfo.cpu_time;
262 }
265 #ifndef __ia64__
266 int xc_get_pfn_list(int xc_handle,
267 uint32_t domid,
268 xen_pfn_t *pfn_buf,
269 unsigned long max_pfns)
270 {
271 DECLARE_DOM0_OP;
272 int ret;
273 op.cmd = DOM0_GETMEMLIST;
274 op.u.getmemlist.domain = (domid_t)domid;
275 op.u.getmemlist.max_pfns = max_pfns;
276 set_xen_guest_handle(op.u.getmemlist.buffer, pfn_buf);
278 #ifdef VALGRIND
279 memset(pfn_buf, 0, max_pfns * sizeof(xen_pfn_t));
280 #endif
282 if ( mlock(pfn_buf, max_pfns * sizeof(xen_pfn_t)) != 0 )
283 {
284 PERROR("xc_get_pfn_list: pfn_buf mlock failed");
285 return -1;
286 }
288 ret = do_dom0_op(xc_handle, &op);
290 safe_munlock(pfn_buf, max_pfns * sizeof(xen_pfn_t));
292 #if 0
293 #ifdef DEBUG
294 DPRINTF(("Ret for xc_get_pfn_list is %d\n", ret));
295 if (ret >= 0) {
296 int i, j;
297 for (i = 0; i < op.u.getmemlist.num_pfns; i += 16) {
298 DPRINTF("0x%x: ", i);
299 for (j = 0; j < 16; j++)
300 DPRINTF("0x%lx ", pfn_buf[i + j]);
301 DPRINTF("\n");
302 }
303 }
304 #endif
305 #endif
307 return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
308 }
309 #endif
311 long xc_get_tot_pages(int xc_handle, uint32_t domid)
312 {
313 DECLARE_DOM0_OP;
314 op.cmd = DOM0_GETDOMAININFO;
315 op.u.getdomaininfo.domain = (domid_t)domid;
316 return (do_dom0_op(xc_handle, &op) < 0) ?
317 -1 : op.u.getdomaininfo.tot_pages;
318 }
320 int xc_copy_to_domain_page(int xc_handle,
321 uint32_t domid,
322 unsigned long dst_pfn,
323 const char *src_page)
324 {
325 void *vaddr = xc_map_foreign_range(
326 xc_handle, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
327 if ( vaddr == NULL )
328 return -1;
329 memcpy(vaddr, src_page, PAGE_SIZE);
330 munmap(vaddr, PAGE_SIZE);
331 return 0;
332 }
334 int xc_clear_domain_page(int xc_handle,
335 uint32_t domid,
336 unsigned long dst_pfn)
337 {
338 void *vaddr = xc_map_foreign_range(
339 xc_handle, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
340 if ( vaddr == NULL )
341 return -1;
342 memset(vaddr, 0, PAGE_SIZE);
343 munmap(vaddr, PAGE_SIZE);
344 return 0;
345 }
347 unsigned long xc_get_filesz(int fd)
348 {
349 uint16_t sig;
350 uint32_t _sz = 0;
351 unsigned long sz;
353 lseek(fd, 0, SEEK_SET);
354 if ( read(fd, &sig, sizeof(sig)) != sizeof(sig) )
355 return 0;
356 sz = lseek(fd, 0, SEEK_END);
357 if ( sig == 0x8b1f ) /* GZIP signature? */
358 {
359 lseek(fd, -4, SEEK_END);
360 if ( read(fd, &_sz, 4) != 4 )
361 return 0;
362 sz = _sz;
363 }
364 lseek(fd, 0, SEEK_SET);
366 return sz;
367 }
369 void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size,
370 int xch, uint32_t dom, xen_pfn_t *parray,
371 unsigned long vstart)
372 {
373 char *va;
374 unsigned long chunksz, done, pa;
376 for ( done = 0; done < size; done += chunksz )
377 {
378 pa = dst + done - vstart;
379 va = xc_map_foreign_range(
380 xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
381 chunksz = size - done;
382 if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
383 chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
384 memcpy(va + (pa & (PAGE_SIZE-1)), src + done, chunksz);
385 munmap(va, PAGE_SIZE);
386 }
387 }
389 int xc_dom0_op(int xc_handle, dom0_op_t *op)
390 {
391 return do_dom0_op(xc_handle, op);
392 }
394 int xc_version(int xc_handle, int cmd, void *arg)
395 {
396 int rc, argsize = 0;
398 switch ( cmd )
399 {
400 case XENVER_extraversion:
401 argsize = sizeof(xen_extraversion_t);
402 break;
403 case XENVER_compile_info:
404 argsize = sizeof(xen_compile_info_t);
405 break;
406 case XENVER_capabilities:
407 argsize = sizeof(xen_capabilities_info_t);
408 break;
409 case XENVER_changeset:
410 argsize = sizeof(xen_changeset_info_t);
411 break;
412 case XENVER_platform_parameters:
413 argsize = sizeof(xen_platform_parameters_t);
414 break;
415 }
417 if ( (argsize != 0) && (mlock(arg, argsize) != 0) )
418 {
419 PERROR("Could not lock memory for version hypercall");
420 return -ENOMEM;
421 }
423 #ifdef VALGRIND
424 if (argsize != 0)
425 memset(arg, 0, argsize);
426 #endif
428 rc = do_xen_version(xc_handle, cmd, arg);
430 if ( argsize != 0 )
431 safe_munlock(arg, argsize);
433 return rc;
434 }
436 unsigned long xc_make_page_below_4G(
437 int xc_handle, uint32_t domid, unsigned long mfn)
438 {
439 xen_pfn_t old_mfn = mfn;
440 xen_pfn_t new_mfn;
442 if ( xc_domain_memory_decrease_reservation(
443 xc_handle, domid, 1, 0, &old_mfn) != 0 )
444 {
445 DPRINTF("xc_make_page_below_4G decrease failed. mfn=%lx\n",mfn);
446 return 0;
447 }
449 if ( xc_domain_memory_increase_reservation(
450 xc_handle, domid, 1, 0, 32, &new_mfn) != 0 )
451 {
452 DPRINTF("xc_make_page_below_4G increase failed. mfn=%lx\n",mfn);
453 return 0;
454 }
456 return new_mfn;
457 }
459 /*
460 * Local variables:
461 * mode: C
462 * c-set-style: "BSD"
463 * c-basic-offset: 4
464 * tab-width: 4
465 * indent-tabs-mode: nil
466 * End:
467 */