ia64/xen-unstable

view tools/libxc/xc_private.c @ 9488:0a6f5527ca4b

[IA64] set itv handoff as masked and enable reading irr[0-3]

Set initial vcpu itv handoff state to mask the timer vector.
This seems to match hardware and makes logical sense from a
spurious interrupt perspective. Enable vcpu_get_irr[0-3]
functions as they seem to work and have the proper backing.
This enables the check_sal_cache_flush() in arch/ia64/kernel.sal.c
to work unmodified, allowing us to remove the Xen changes from
the file (and thus the file from the sparse tree).

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