debuggers.hg

view tools/libxc/xc_domain.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 c34435067298
children b64a8d2a80ad
line source
1 /******************************************************************************
2 * xc_domain.c
3 *
4 * API for manipulating and obtaining information on domains.
5 *
6 * Copyright (c) 2003, K A Fraser.
7 */
9 #include "xc_private.h"
10 #include "xg_save_restore.h"
11 #include <xen/memory.h>
12 #include <xen/hvm/hvm_op.h>
14 int xc_domain_create(int xc_handle,
15 uint32_t ssidref,
16 xen_domain_handle_t handle,
17 uint32_t flags,
18 uint32_t *pdomid)
19 {
20 int err;
21 DECLARE_DOMCTL;
23 domctl.cmd = XEN_DOMCTL_createdomain;
24 domctl.domain = (domid_t)*pdomid;
25 domctl.u.createdomain.ssidref = ssidref;
26 domctl.u.createdomain.flags = flags;
27 memcpy(domctl.u.createdomain.handle, handle, sizeof(xen_domain_handle_t));
28 if ( (err = do_domctl(xc_handle, &domctl)) != 0 )
29 return err;
31 *pdomid = (uint16_t)domctl.domain;
32 return 0;
33 }
36 int xc_domain_pause(int xc_handle,
37 uint32_t domid)
38 {
39 DECLARE_DOMCTL;
40 domctl.cmd = XEN_DOMCTL_pausedomain;
41 domctl.domain = (domid_t)domid;
42 return do_domctl(xc_handle, &domctl);
43 }
46 int xc_domain_unpause(int xc_handle,
47 uint32_t domid)
48 {
49 DECLARE_DOMCTL;
50 domctl.cmd = XEN_DOMCTL_unpausedomain;
51 domctl.domain = (domid_t)domid;
52 return do_domctl(xc_handle, &domctl);
53 }
56 int xc_domain_destroy(int xc_handle,
57 uint32_t domid)
58 {
59 int ret;
60 DECLARE_DOMCTL;
61 domctl.cmd = XEN_DOMCTL_destroydomain;
62 domctl.domain = (domid_t)domid;
63 do {
64 ret = do_domctl(xc_handle, &domctl);
65 } while ( ret && (errno == EAGAIN) );
66 return ret;
67 }
69 int xc_domain_shutdown(int xc_handle,
70 uint32_t domid,
71 int reason)
72 {
73 int ret = -1;
74 sched_remote_shutdown_t arg;
75 DECLARE_HYPERCALL;
77 hypercall.op = __HYPERVISOR_sched_op;
78 hypercall.arg[0] = (unsigned long)SCHEDOP_remote_shutdown;
79 hypercall.arg[1] = (unsigned long)&arg;
80 arg.domain_id = domid;
81 arg.reason = reason;
83 if ( lock_pages(&arg, sizeof(arg)) != 0 )
84 {
85 PERROR("Could not lock memory for Xen hypercall");
86 goto out1;
87 }
89 ret = do_xen_hypercall(xc_handle, &hypercall);
91 unlock_pages(&arg, sizeof(arg));
93 out1:
94 return ret;
95 }
98 int xc_vcpu_setaffinity(int xc_handle,
99 uint32_t domid,
100 int vcpu,
101 uint64_t cpumap)
102 {
103 DECLARE_DOMCTL;
104 int ret = -1;
105 uint8_t local[sizeof (cpumap)];
107 domctl.cmd = XEN_DOMCTL_setvcpuaffinity;
108 domctl.domain = (domid_t)domid;
109 domctl.u.vcpuaffinity.vcpu = vcpu;
111 bitmap_64_to_byte(local, &cpumap, sizeof(cpumap) * 8);
113 set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, local);
115 domctl.u.vcpuaffinity.cpumap.nr_cpus = sizeof(cpumap) * 8;
117 if ( lock_pages(local, sizeof(local)) != 0 )
118 {
119 PERROR("Could not lock memory for Xen hypercall");
120 goto out;
121 }
123 ret = do_domctl(xc_handle, &domctl);
125 unlock_pages(local, sizeof(local));
127 out:
128 return ret;
129 }
132 int xc_vcpu_getaffinity(int xc_handle,
133 uint32_t domid,
134 int vcpu,
135 uint64_t *cpumap)
136 {
137 DECLARE_DOMCTL;
138 int ret = -1;
139 uint8_t local[sizeof (cpumap)];
141 domctl.cmd = XEN_DOMCTL_getvcpuaffinity;
142 domctl.domain = (domid_t)domid;
143 domctl.u.vcpuaffinity.vcpu = vcpu;
145 set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, local);
146 domctl.u.vcpuaffinity.cpumap.nr_cpus = sizeof(cpumap) * 8;
148 if ( lock_pages(local, sizeof(local)) != 0 )
149 {
150 PERROR("Could not lock memory for Xen hypercall");
151 goto out;
152 }
154 ret = do_domctl(xc_handle, &domctl);
156 unlock_pages(local, sizeof (local));
157 bitmap_byte_to_64(cpumap, local, sizeof(local) * 8);
158 out:
159 return ret;
160 }
163 int xc_domain_getinfo(int xc_handle,
164 uint32_t first_domid,
165 unsigned int max_doms,
166 xc_dominfo_t *info)
167 {
168 unsigned int nr_doms;
169 uint32_t next_domid = first_domid;
170 DECLARE_DOMCTL;
171 int rc = 0;
173 memset(info, 0, max_doms*sizeof(xc_dominfo_t));
175 for ( nr_doms = 0; nr_doms < max_doms; nr_doms++ )
176 {
177 domctl.cmd = XEN_DOMCTL_getdomaininfo;
178 domctl.domain = (domid_t)next_domid;
179 if ( (rc = do_domctl(xc_handle, &domctl)) < 0 )
180 break;
181 info->domid = (uint16_t)domctl.domain;
183 info->dying = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_dying);
184 info->shutdown = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_shutdown);
185 info->paused = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_paused);
186 info->blocked = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_blocked);
187 info->running = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_running);
188 info->hvm = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_hvm_guest);
189 info->debugged = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_debugged);
191 info->shutdown_reason =
192 (domctl.u.getdomaininfo.flags>>XEN_DOMINF_shutdownshift) &
193 XEN_DOMINF_shutdownmask;
195 if ( info->shutdown && (info->shutdown_reason == SHUTDOWN_crash) )
196 {
197 info->shutdown = 0;
198 info->crashed = 1;
199 }
201 info->ssidref = domctl.u.getdomaininfo.ssidref;
202 info->nr_pages = domctl.u.getdomaininfo.tot_pages;
203 info->nr_shared_pages = domctl.u.getdomaininfo.shr_pages;
204 info->max_memkb = domctl.u.getdomaininfo.max_pages << (PAGE_SHIFT-10);
205 info->shared_info_frame = domctl.u.getdomaininfo.shared_info_frame;
206 info->cpu_time = domctl.u.getdomaininfo.cpu_time;
207 info->nr_online_vcpus = domctl.u.getdomaininfo.nr_online_vcpus;
208 info->max_vcpu_id = domctl.u.getdomaininfo.max_vcpu_id;
210 memcpy(info->handle, domctl.u.getdomaininfo.handle,
211 sizeof(xen_domain_handle_t));
213 next_domid = (uint16_t)domctl.domain + 1;
214 info++;
215 }
217 if ( nr_doms == 0 )
218 return rc;
220 return nr_doms;
221 }
223 int xc_domain_getinfolist(int xc_handle,
224 uint32_t first_domain,
225 unsigned int max_domains,
226 xc_domaininfo_t *info)
227 {
228 int ret = 0;
229 DECLARE_SYSCTL;
231 if ( lock_pages(info, max_domains*sizeof(xc_domaininfo_t)) != 0 )
232 return -1;
234 sysctl.cmd = XEN_SYSCTL_getdomaininfolist;
235 sysctl.u.getdomaininfolist.first_domain = first_domain;
236 sysctl.u.getdomaininfolist.max_domains = max_domains;
237 set_xen_guest_handle(sysctl.u.getdomaininfolist.buffer, info);
239 if ( xc_sysctl(xc_handle, &sysctl) < 0 )
240 ret = -1;
241 else
242 ret = sysctl.u.getdomaininfolist.num_domains;
244 unlock_pages(info, max_domains*sizeof(xc_domaininfo_t));
246 return ret;
247 }
249 /* get info from hvm guest for save */
250 int xc_domain_hvm_getcontext(int xc_handle,
251 uint32_t domid,
252 uint8_t *ctxt_buf,
253 uint32_t size)
254 {
255 int ret;
256 DECLARE_DOMCTL;
258 domctl.cmd = XEN_DOMCTL_gethvmcontext;
259 domctl.domain = (domid_t)domid;
260 domctl.u.hvmcontext.size = size;
261 set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf);
263 if ( ctxt_buf )
264 if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
265 return ret;
267 ret = do_domctl(xc_handle, &domctl);
269 if ( ctxt_buf )
270 unlock_pages(ctxt_buf, size);
272 return (ret < 0 ? -1 : domctl.u.hvmcontext.size);
273 }
275 /* Get just one element of the HVM guest context.
276 * size must be >= HVM_SAVE_LENGTH(type) */
277 int xc_domain_hvm_getcontext_partial(int xc_handle,
278 uint32_t domid,
279 uint16_t typecode,
280 uint16_t instance,
281 void *ctxt_buf,
282 uint32_t size)
283 {
284 int ret;
285 DECLARE_DOMCTL;
287 if ( !ctxt_buf )
288 return -EINVAL;
290 domctl.cmd = XEN_DOMCTL_gethvmcontext_partial;
291 domctl.domain = (domid_t) domid;
292 domctl.u.hvmcontext_partial.type = typecode;
293 domctl.u.hvmcontext_partial.instance = instance;
294 set_xen_guest_handle(domctl.u.hvmcontext_partial.buffer, ctxt_buf);
296 if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
297 return ret;
299 ret = do_domctl(xc_handle, &domctl);
301 if ( ctxt_buf )
302 unlock_pages(ctxt_buf, size);
304 return ret ? -1 : 0;
305 }
307 /* set info to hvm guest for restore */
308 int xc_domain_hvm_setcontext(int xc_handle,
309 uint32_t domid,
310 uint8_t *ctxt_buf,
311 uint32_t size)
312 {
313 int ret;
314 DECLARE_DOMCTL;
316 domctl.cmd = XEN_DOMCTL_sethvmcontext;
317 domctl.domain = domid;
318 domctl.u.hvmcontext.size = size;
319 set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf);
321 if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
322 return ret;
324 ret = do_domctl(xc_handle, &domctl);
326 unlock_pages(ctxt_buf, size);
328 return ret;
329 }
331 int xc_vcpu_getcontext(int xc_handle,
332 uint32_t domid,
333 uint32_t vcpu,
334 vcpu_guest_context_any_t *ctxt)
335 {
336 int rc;
337 DECLARE_DOMCTL;
338 size_t sz = sizeof(vcpu_guest_context_any_t);
340 domctl.cmd = XEN_DOMCTL_getvcpucontext;
341 domctl.domain = (domid_t)domid;
342 domctl.u.vcpucontext.vcpu = (uint16_t)vcpu;
343 set_xen_guest_handle(domctl.u.vcpucontext.ctxt, &ctxt->c);
346 if ( (rc = lock_pages(ctxt, sz)) != 0 )
347 return rc;
348 rc = do_domctl(xc_handle, &domctl);
349 unlock_pages(ctxt, sz);
351 return rc;
352 }
355 int xc_shadow_control(int xc_handle,
356 uint32_t domid,
357 unsigned int sop,
358 unsigned long *dirty_bitmap,
359 unsigned long pages,
360 unsigned long *mb,
361 uint32_t mode,
362 xc_shadow_op_stats_t *stats)
363 {
364 int rc;
365 DECLARE_DOMCTL;
366 domctl.cmd = XEN_DOMCTL_shadow_op;
367 domctl.domain = (domid_t)domid;
368 domctl.u.shadow_op.op = sop;
369 domctl.u.shadow_op.pages = pages;
370 domctl.u.shadow_op.mb = mb ? *mb : 0;
371 domctl.u.shadow_op.mode = mode;
372 set_xen_guest_handle(domctl.u.shadow_op.dirty_bitmap,
373 (uint8_t *)dirty_bitmap);
375 rc = do_domctl(xc_handle, &domctl);
377 if ( stats )
378 memcpy(stats, &domctl.u.shadow_op.stats,
379 sizeof(xc_shadow_op_stats_t));
381 if ( mb )
382 *mb = domctl.u.shadow_op.mb;
384 return (rc == 0) ? domctl.u.shadow_op.pages : rc;
385 }
387 int xc_domain_setmaxmem(int xc_handle,
388 uint32_t domid,
389 unsigned int max_memkb)
390 {
391 DECLARE_DOMCTL;
392 domctl.cmd = XEN_DOMCTL_max_mem;
393 domctl.domain = (domid_t)domid;
394 domctl.u.max_mem.max_memkb = max_memkb;
395 return do_domctl(xc_handle, &domctl);
396 }
398 int xc_domain_pin_memory_cacheattr(int xc_handle,
399 uint32_t domid,
400 uint64_t start,
401 uint64_t end,
402 uint32_t type)
403 {
404 DECLARE_DOMCTL;
405 domctl.cmd = XEN_DOMCTL_pin_mem_cacheattr;
406 domctl.domain = (domid_t)domid;
407 domctl.u.pin_mem_cacheattr.start = start;
408 domctl.u.pin_mem_cacheattr.end = end;
409 domctl.u.pin_mem_cacheattr.type = type;
410 return do_domctl(xc_handle, &domctl);
411 }
413 #if defined(__i386__) || defined(__x86_64__)
414 #include "xc_e820.h"
415 int xc_domain_set_memmap_limit(int xc_handle,
416 uint32_t domid,
417 unsigned long map_limitkb)
418 {
419 int rc;
421 struct xen_foreign_memory_map fmap = {
422 .domid = domid,
423 .map = { .nr_entries = 1 }
424 };
426 struct e820entry e820 = {
427 .addr = 0,
428 .size = (uint64_t)map_limitkb << 10,
429 .type = E820_RAM
430 };
432 set_xen_guest_handle(fmap.map.buffer, &e820);
434 if ( lock_pages(&fmap, sizeof(fmap)) || lock_pages(&e820, sizeof(e820)) )
435 {
436 PERROR("Could not lock memory for Xen hypercall");
437 rc = -1;
438 goto out;
439 }
441 rc = xc_memory_op(xc_handle, XENMEM_set_memory_map, &fmap);
443 out:
444 unlock_pages(&fmap, sizeof(fmap));
445 unlock_pages(&e820, sizeof(e820));
446 return rc;
447 }
448 #else
449 int xc_domain_set_memmap_limit(int xc_handle,
450 uint32_t domid,
451 unsigned long map_limitkb)
452 {
453 PERROR("Function not implemented");
454 errno = ENOSYS;
455 return -1;
456 }
457 #endif
459 int xc_domain_set_time_offset(int xc_handle,
460 uint32_t domid,
461 int32_t time_offset_seconds)
462 {
463 DECLARE_DOMCTL;
464 domctl.cmd = XEN_DOMCTL_settimeoffset;
465 domctl.domain = (domid_t)domid;
466 domctl.u.settimeoffset.time_offset_seconds = time_offset_seconds;
467 return do_domctl(xc_handle, &domctl);
468 }
470 int xc_domain_disable_migrate(int xc_handle, uint32_t domid)
471 {
472 DECLARE_DOMCTL;
473 domctl.cmd = XEN_DOMCTL_disable_migrate;
474 domctl.domain = (domid_t)domid;
475 domctl.u.disable_migrate.disable = 1;
476 return do_domctl(xc_handle, &domctl);
477 }
479 int xc_domain_set_tsc_info(int xc_handle,
480 uint32_t domid,
481 uint32_t tsc_mode,
482 uint64_t elapsed_nsec,
483 uint32_t gtsc_khz,
484 uint32_t incarnation)
485 {
486 DECLARE_DOMCTL;
487 domctl.cmd = XEN_DOMCTL_settscinfo;
488 domctl.domain = (domid_t)domid;
489 domctl.u.tsc_info.info.tsc_mode = tsc_mode;
490 domctl.u.tsc_info.info.elapsed_nsec = elapsed_nsec;
491 domctl.u.tsc_info.info.gtsc_khz = gtsc_khz;
492 domctl.u.tsc_info.info.incarnation = incarnation;
493 return do_domctl(xc_handle, &domctl);
494 }
496 int xc_domain_get_tsc_info(int xc_handle,
497 uint32_t domid,
498 uint32_t *tsc_mode,
499 uint64_t *elapsed_nsec,
500 uint32_t *gtsc_khz,
501 uint32_t *incarnation)
502 {
503 int rc;
504 DECLARE_DOMCTL;
505 xen_guest_tsc_info_t info = { 0 };
507 domctl.cmd = XEN_DOMCTL_gettscinfo;
508 domctl.domain = (domid_t)domid;
509 set_xen_guest_handle(domctl.u.tsc_info.out_info, &info);
510 if ( (rc = lock_pages(&info, sizeof(info))) != 0 )
511 return rc;
512 rc = do_domctl(xc_handle, &domctl);
513 if ( rc == 0 )
514 {
515 *tsc_mode = info.tsc_mode;
516 *elapsed_nsec = info.elapsed_nsec;
517 *gtsc_khz = info.gtsc_khz;
518 *incarnation = info.incarnation;
519 }
520 unlock_pages(&info,sizeof(info));
521 return rc;
522 }
525 int xc_domain_memory_increase_reservation(int xc_handle,
526 uint32_t domid,
527 unsigned long nr_extents,
528 unsigned int extent_order,
529 unsigned int mem_flags,
530 xen_pfn_t *extent_start)
531 {
532 int err;
533 struct xen_memory_reservation reservation = {
534 .nr_extents = nr_extents,
535 .extent_order = extent_order,
536 .mem_flags = mem_flags,
537 .domid = domid
538 };
540 /* may be NULL */
541 set_xen_guest_handle(reservation.extent_start, extent_start);
543 err = xc_memory_op(xc_handle, XENMEM_increase_reservation, &reservation);
544 if ( err == nr_extents )
545 return 0;
547 if ( err >= 0 )
548 {
549 DPRINTF("Failed allocation for dom %d: "
550 "%ld extents of order %d, mem_flags %x\n",
551 domid, nr_extents, extent_order, mem_flags);
552 errno = ENOMEM;
553 err = -1;
554 }
556 return err;
557 }
559 int xc_domain_memory_decrease_reservation(int xc_handle,
560 uint32_t domid,
561 unsigned long nr_extents,
562 unsigned int extent_order,
563 xen_pfn_t *extent_start)
564 {
565 int err;
566 struct xen_memory_reservation reservation = {
567 .nr_extents = nr_extents,
568 .extent_order = extent_order,
569 .mem_flags = 0,
570 .domid = domid
571 };
573 set_xen_guest_handle(reservation.extent_start, extent_start);
575 if ( extent_start == NULL )
576 {
577 DPRINTF("decrease_reservation extent_start is NULL!\n");
578 errno = EINVAL;
579 return -1;
580 }
582 err = xc_memory_op(xc_handle, XENMEM_decrease_reservation, &reservation);
583 if ( err == nr_extents )
584 return 0;
586 if ( err >= 0 )
587 {
588 DPRINTF("Failed deallocation for dom %d: %ld extents of order %d\n",
589 domid, nr_extents, extent_order);
590 errno = EINVAL;
591 err = -1;
592 }
594 return err;
595 }
597 int xc_domain_memory_populate_physmap(int xc_handle,
598 uint32_t domid,
599 unsigned long nr_extents,
600 unsigned int extent_order,
601 unsigned int mem_flags,
602 xen_pfn_t *extent_start)
603 {
604 int err;
605 struct xen_memory_reservation reservation = {
606 .nr_extents = nr_extents,
607 .extent_order = extent_order,
608 .mem_flags = mem_flags,
609 .domid = domid
610 };
611 set_xen_guest_handle(reservation.extent_start, extent_start);
613 err = xc_memory_op(xc_handle, XENMEM_populate_physmap, &reservation);
614 if ( err == nr_extents )
615 return 0;
617 if ( err >= 0 )
618 {
619 DPRINTF("Failed allocation for dom %d: %ld extents of order %d\n",
620 domid, nr_extents, extent_order);
621 errno = EBUSY;
622 err = -1;
623 }
625 return err;
626 }
628 static int xc_domain_memory_pod_target(int xc_handle,
629 int op,
630 uint32_t domid,
631 uint64_t target_pages,
632 uint64_t *tot_pages,
633 uint64_t *pod_cache_pages,
634 uint64_t *pod_entries)
635 {
636 int err;
638 struct xen_pod_target pod_target = {
639 .domid = domid,
640 .target_pages = target_pages
641 };
643 err = xc_memory_op(xc_handle, op, &pod_target);
645 if ( err < 0 )
646 {
647 DPRINTF("Failed %s_memory_target dom %d\n",
648 (op==XENMEM_set_pod_target)?"set":"get",
649 domid);
650 errno = -err;
651 err = -1;
652 }
653 else
654 err = 0;
656 if ( tot_pages )
657 *tot_pages = pod_target.tot_pages;
658 if ( pod_cache_pages )
659 *pod_cache_pages = pod_target.pod_cache_pages;
660 if ( pod_entries )
661 *pod_entries = pod_target.pod_entries;
663 return err;
664 }
667 int xc_domain_memory_set_pod_target(int xc_handle,
668 uint32_t domid,
669 uint64_t target_pages,
670 uint64_t *tot_pages,
671 uint64_t *pod_cache_pages,
672 uint64_t *pod_entries)
673 {
674 return xc_domain_memory_pod_target(xc_handle,
675 XENMEM_set_pod_target,
676 domid,
677 target_pages,
678 tot_pages,
679 pod_cache_pages,
680 pod_entries);
681 }
683 int xc_domain_memory_get_pod_target(int xc_handle,
684 uint32_t domid,
685 uint64_t *tot_pages,
686 uint64_t *pod_cache_pages,
687 uint64_t *pod_entries)
688 {
689 return xc_domain_memory_pod_target(xc_handle,
690 XENMEM_get_pod_target,
691 domid,
692 -1,
693 tot_pages,
694 pod_cache_pages,
695 pod_entries);
696 }
698 int xc_domain_max_vcpus(int xc_handle, uint32_t domid, unsigned int max)
699 {
700 DECLARE_DOMCTL;
701 domctl.cmd = XEN_DOMCTL_max_vcpus;
702 domctl.domain = (domid_t)domid;
703 domctl.u.max_vcpus.max = max;
704 return do_domctl(xc_handle, &domctl);
705 }
707 int xc_domain_sethandle(int xc_handle, uint32_t domid,
708 xen_domain_handle_t handle)
709 {
710 DECLARE_DOMCTL;
711 domctl.cmd = XEN_DOMCTL_setdomainhandle;
712 domctl.domain = (domid_t)domid;
713 memcpy(domctl.u.setdomainhandle.handle, handle,
714 sizeof(xen_domain_handle_t));
715 return do_domctl(xc_handle, &domctl);
716 }
718 int xc_vcpu_getinfo(int xc_handle,
719 uint32_t domid,
720 uint32_t vcpu,
721 xc_vcpuinfo_t *info)
722 {
723 int rc;
724 DECLARE_DOMCTL;
726 domctl.cmd = XEN_DOMCTL_getvcpuinfo;
727 domctl.domain = (domid_t)domid;
728 domctl.u.getvcpuinfo.vcpu = (uint16_t)vcpu;
730 rc = do_domctl(xc_handle, &domctl);
732 memcpy(info, &domctl.u.getvcpuinfo, sizeof(*info));
734 return rc;
735 }
737 int xc_domain_ioport_permission(int xc_handle,
738 uint32_t domid,
739 uint32_t first_port,
740 uint32_t nr_ports,
741 uint32_t allow_access)
742 {
743 DECLARE_DOMCTL;
745 domctl.cmd = XEN_DOMCTL_ioport_permission;
746 domctl.domain = (domid_t)domid;
747 domctl.u.ioport_permission.first_port = first_port;
748 domctl.u.ioport_permission.nr_ports = nr_ports;
749 domctl.u.ioport_permission.allow_access = allow_access;
751 return do_domctl(xc_handle, &domctl);
752 }
754 int xc_availheap(int xc_handle,
755 int min_width,
756 int max_width,
757 int node,
758 uint64_t *bytes)
759 {
760 DECLARE_SYSCTL;
761 int rc;
763 sysctl.cmd = XEN_SYSCTL_availheap;
764 sysctl.u.availheap.min_bitwidth = min_width;
765 sysctl.u.availheap.max_bitwidth = max_width;
766 sysctl.u.availheap.node = node;
768 rc = xc_sysctl(xc_handle, &sysctl);
770 *bytes = sysctl.u.availheap.avail_bytes;
772 return rc;
773 }
775 int xc_vcpu_setcontext(int xc_handle,
776 uint32_t domid,
777 uint32_t vcpu,
778 vcpu_guest_context_any_t *ctxt)
779 {
780 DECLARE_DOMCTL;
781 int rc;
782 size_t sz = sizeof(vcpu_guest_context_any_t);
784 if (ctxt == NULL)
785 {
786 errno = EINVAL;
787 return -1;
788 }
790 domctl.cmd = XEN_DOMCTL_setvcpucontext;
791 domctl.domain = domid;
792 domctl.u.vcpucontext.vcpu = vcpu;
793 set_xen_guest_handle(domctl.u.vcpucontext.ctxt, &ctxt->c);
795 if ( (rc = lock_pages(ctxt, sz)) != 0 )
796 return rc;
797 rc = do_domctl(xc_handle, &domctl);
799 unlock_pages(ctxt, sz);
801 return rc;
802 }
804 int xc_domain_irq_permission(int xc_handle,
805 uint32_t domid,
806 uint8_t pirq,
807 uint8_t allow_access)
808 {
809 DECLARE_DOMCTL;
811 domctl.cmd = XEN_DOMCTL_irq_permission;
812 domctl.domain = domid;
813 domctl.u.irq_permission.pirq = pirq;
814 domctl.u.irq_permission.allow_access = allow_access;
816 return do_domctl(xc_handle, &domctl);
817 }
819 int xc_domain_iomem_permission(int xc_handle,
820 uint32_t domid,
821 unsigned long first_mfn,
822 unsigned long nr_mfns,
823 uint8_t allow_access)
824 {
825 DECLARE_DOMCTL;
827 domctl.cmd = XEN_DOMCTL_iomem_permission;
828 domctl.domain = domid;
829 domctl.u.iomem_permission.first_mfn = first_mfn;
830 domctl.u.iomem_permission.nr_mfns = nr_mfns;
831 domctl.u.iomem_permission.allow_access = allow_access;
833 return do_domctl(xc_handle, &domctl);
834 }
836 int xc_domain_send_trigger(int xc_handle,
837 uint32_t domid,
838 uint32_t trigger,
839 uint32_t vcpu)
840 {
841 DECLARE_DOMCTL;
843 domctl.cmd = XEN_DOMCTL_sendtrigger;
844 domctl.domain = domid;
845 domctl.u.sendtrigger.trigger = trigger;
846 domctl.u.sendtrigger.vcpu = vcpu;
848 return do_domctl(xc_handle, &domctl);
849 }
851 int xc_set_hvm_param(int handle, domid_t dom, int param, unsigned long value)
852 {
853 DECLARE_HYPERCALL;
854 xen_hvm_param_t arg;
855 int rc;
857 hypercall.op = __HYPERVISOR_hvm_op;
858 hypercall.arg[0] = HVMOP_set_param;
859 hypercall.arg[1] = (unsigned long)&arg;
860 arg.domid = dom;
861 arg.index = param;
862 arg.value = value;
863 if ( lock_pages(&arg, sizeof(arg)) != 0 )
864 return -1;
865 rc = do_xen_hypercall(handle, &hypercall);
866 unlock_pages(&arg, sizeof(arg));
867 return rc;
868 }
870 int xc_get_hvm_param(int handle, domid_t dom, int param, unsigned long *value)
871 {
872 DECLARE_HYPERCALL;
873 xen_hvm_param_t arg;
874 int rc;
876 hypercall.op = __HYPERVISOR_hvm_op;
877 hypercall.arg[0] = HVMOP_get_param;
878 hypercall.arg[1] = (unsigned long)&arg;
879 arg.domid = dom;
880 arg.index = param;
881 if ( lock_pages(&arg, sizeof(arg)) != 0 )
882 return -1;
883 rc = do_xen_hypercall(handle, &hypercall);
884 unlock_pages(&arg, sizeof(arg));
885 *value = arg.value;
886 return rc;
887 }
889 int xc_domain_setdebugging(int xc_handle,
890 uint32_t domid,
891 unsigned int enable)
892 {
893 DECLARE_DOMCTL;
895 domctl.cmd = XEN_DOMCTL_setdebugging;
896 domctl.domain = domid;
897 domctl.u.setdebugging.enable = enable;
898 return do_domctl(xc_handle, &domctl);
899 }
901 int xc_assign_device(
902 int xc_handle,
903 uint32_t domid,
904 uint32_t machine_bdf)
905 {
906 DECLARE_DOMCTL;
908 domctl.cmd = XEN_DOMCTL_assign_device;
909 domctl.domain = domid;
910 domctl.u.assign_device.machine_bdf = machine_bdf;
912 return do_domctl(xc_handle, &domctl);
913 }
915 int xc_get_device_group(
916 int xc_handle,
917 uint32_t domid,
918 uint32_t machine_bdf,
919 uint32_t max_sdevs,
920 uint32_t *num_sdevs,
921 uint32_t *sdev_array)
922 {
923 int rc;
924 DECLARE_DOMCTL;
926 domctl.cmd = XEN_DOMCTL_get_device_group;
927 domctl.domain = (domid_t)domid;
929 domctl.u.get_device_group.machine_bdf = machine_bdf;
930 domctl.u.get_device_group.max_sdevs = max_sdevs;
932 set_xen_guest_handle(domctl.u.get_device_group.sdev_array, sdev_array);
934 if ( lock_pages(sdev_array, max_sdevs * sizeof(*sdev_array)) != 0 )
935 {
936 PERROR("Could not lock memory for xc_get_device_group\n");
937 return -ENOMEM;
938 }
939 rc = do_domctl(xc_handle, &domctl);
940 unlock_pages(sdev_array, max_sdevs * sizeof(*sdev_array));
942 *num_sdevs = domctl.u.get_device_group.num_sdevs;
943 return rc;
944 }
946 int xc_test_assign_device(
947 int xc_handle,
948 uint32_t domid,
949 uint32_t machine_bdf)
950 {
951 DECLARE_DOMCTL;
953 domctl.cmd = XEN_DOMCTL_test_assign_device;
954 domctl.domain = domid;
955 domctl.u.assign_device.machine_bdf = machine_bdf;
957 return do_domctl(xc_handle, &domctl);
958 }
960 int xc_deassign_device(
961 int xc_handle,
962 uint32_t domid,
963 uint32_t machine_bdf)
964 {
965 DECLARE_DOMCTL;
967 domctl.cmd = XEN_DOMCTL_deassign_device;
968 domctl.domain = domid;
969 domctl.u.assign_device.machine_bdf = machine_bdf;
971 return do_domctl(xc_handle, &domctl);
972 }
974 int xc_domain_update_msi_irq(
975 int xc_handle,
976 uint32_t domid,
977 uint32_t gvec,
978 uint32_t pirq,
979 uint32_t gflags,
980 uint64_t gtable)
981 {
982 int rc;
983 xen_domctl_bind_pt_irq_t *bind;
985 DECLARE_DOMCTL;
987 domctl.cmd = XEN_DOMCTL_bind_pt_irq;
988 domctl.domain = (domid_t)domid;
990 bind = &(domctl.u.bind_pt_irq);
991 bind->hvm_domid = domid;
992 bind->irq_type = PT_IRQ_TYPE_MSI;
993 bind->machine_irq = pirq;
994 bind->u.msi.gvec = gvec;
995 bind->u.msi.gflags = gflags;
996 bind->u.msi.gtable = gtable;
998 rc = do_domctl(xc_handle, &domctl);
999 return rc;
1002 int xc_domain_unbind_msi_irq(
1003 int xc_handle,
1004 uint32_t domid,
1005 uint32_t gvec,
1006 uint32_t pirq,
1007 uint32_t gflags)
1009 int rc;
1010 xen_domctl_bind_pt_irq_t *bind;
1012 DECLARE_DOMCTL;
1014 domctl.cmd = XEN_DOMCTL_unbind_pt_irq;
1015 domctl.domain = (domid_t)domid;
1017 bind = &(domctl.u.bind_pt_irq);
1018 bind->hvm_domid = domid;
1019 bind->irq_type = PT_IRQ_TYPE_MSI;
1020 bind->machine_irq = pirq;
1021 bind->u.msi.gvec = gvec;
1022 bind->u.msi.gflags = gflags;
1024 rc = do_domctl(xc_handle, &domctl);
1025 return rc;
1028 /* Pass-through: binds machine irq to guests irq */
1029 int xc_domain_bind_pt_irq(
1030 int xc_handle,
1031 uint32_t domid,
1032 uint8_t machine_irq,
1033 uint8_t irq_type,
1034 uint8_t bus,
1035 uint8_t device,
1036 uint8_t intx,
1037 uint8_t isa_irq)
1039 int rc;
1040 xen_domctl_bind_pt_irq_t * bind;
1041 DECLARE_DOMCTL;
1043 domctl.cmd = XEN_DOMCTL_bind_pt_irq;
1044 domctl.domain = (domid_t)domid;
1046 bind = &(domctl.u.bind_pt_irq);
1047 bind->hvm_domid = domid;
1048 bind->irq_type = irq_type;
1049 bind->machine_irq = machine_irq;
1050 if ( irq_type == PT_IRQ_TYPE_PCI ||
1051 irq_type == PT_IRQ_TYPE_MSI_TRANSLATE )
1053 bind->u.pci.bus = bus;
1054 bind->u.pci.device = device;
1055 bind->u.pci.intx = intx;
1057 else if ( irq_type == PT_IRQ_TYPE_ISA )
1058 bind->u.isa.isa_irq = isa_irq;
1060 rc = do_domctl(xc_handle, &domctl);
1061 return rc;
1064 int xc_domain_unbind_pt_irq(
1065 int xc_handle,
1066 uint32_t domid,
1067 uint8_t machine_irq,
1068 uint8_t irq_type,
1069 uint8_t bus,
1070 uint8_t device,
1071 uint8_t intx,
1072 uint8_t isa_irq)
1074 int rc;
1075 xen_domctl_bind_pt_irq_t * bind;
1076 DECLARE_DOMCTL;
1078 domctl.cmd = XEN_DOMCTL_unbind_pt_irq;
1079 domctl.domain = (domid_t)domid;
1081 bind = &(domctl.u.bind_pt_irq);
1082 bind->hvm_domid = domid;
1083 bind->irq_type = irq_type;
1084 bind->machine_irq = machine_irq;
1085 bind->u.pci.bus = bus;
1086 bind->u.pci.device = device;
1087 bind->u.pci.intx = intx;
1088 bind->u.isa.isa_irq = isa_irq;
1090 rc = do_domctl(xc_handle, &domctl);
1091 return rc;
1094 int xc_domain_bind_pt_pci_irq(
1095 int xc_handle,
1096 uint32_t domid,
1097 uint8_t machine_irq,
1098 uint8_t bus,
1099 uint8_t device,
1100 uint8_t intx)
1103 return (xc_domain_bind_pt_irq(xc_handle, domid, machine_irq,
1104 PT_IRQ_TYPE_PCI, bus, device, intx, 0));
1107 int xc_domain_bind_pt_isa_irq(
1108 int xc_handle,
1109 uint32_t domid,
1110 uint8_t machine_irq)
1113 return (xc_domain_bind_pt_irq(xc_handle, domid, machine_irq,
1114 PT_IRQ_TYPE_ISA, 0, 0, 0, machine_irq));
1117 int xc_domain_memory_mapping(
1118 int xc_handle,
1119 uint32_t domid,
1120 unsigned long first_gfn,
1121 unsigned long first_mfn,
1122 unsigned long nr_mfns,
1123 uint32_t add_mapping)
1125 DECLARE_DOMCTL;
1127 domctl.cmd = XEN_DOMCTL_memory_mapping;
1128 domctl.domain = domid;
1129 domctl.u.memory_mapping.first_gfn = first_gfn;
1130 domctl.u.memory_mapping.first_mfn = first_mfn;
1131 domctl.u.memory_mapping.nr_mfns = nr_mfns;
1132 domctl.u.memory_mapping.add_mapping = add_mapping;
1134 return do_domctl(xc_handle, &domctl);
1137 int xc_domain_ioport_mapping(
1138 int xc_handle,
1139 uint32_t domid,
1140 uint32_t first_gport,
1141 uint32_t first_mport,
1142 uint32_t nr_ports,
1143 uint32_t add_mapping)
1145 DECLARE_DOMCTL;
1147 domctl.cmd = XEN_DOMCTL_ioport_mapping;
1148 domctl.domain = domid;
1149 domctl.u.ioport_mapping.first_gport = first_gport;
1150 domctl.u.ioport_mapping.first_mport = first_mport;
1151 domctl.u.ioport_mapping.nr_ports = nr_ports;
1152 domctl.u.ioport_mapping.add_mapping = add_mapping;
1154 return do_domctl(xc_handle, &domctl);
1157 int xc_domain_set_target(
1158 int xc_handle,
1159 uint32_t domid,
1160 uint32_t target)
1162 DECLARE_DOMCTL;
1164 domctl.cmd = XEN_DOMCTL_set_target;
1165 domctl.domain = domid;
1166 domctl.u.set_target.target = target;
1168 return do_domctl(xc_handle, &domctl);
1171 int xc_domain_subscribe_for_suspend(
1172 int xc_handle, domid_t dom, evtchn_port_t port)
1174 DECLARE_DOMCTL;
1176 domctl.cmd = XEN_DOMCTL_subscribe;
1177 domctl.domain = dom;
1178 domctl.u.subscribe.port = port;
1180 return do_domctl(xc_handle, &domctl);
1183 int xc_domain_set_machine_address_size(int xc,
1184 uint32_t domid,
1185 unsigned int width)
1187 DECLARE_DOMCTL;
1189 memset(&domctl, 0, sizeof(domctl));
1190 domctl.domain = domid;
1191 domctl.cmd = XEN_DOMCTL_set_machine_address_size;
1192 domctl.u.address_size.size = width;
1194 return do_domctl(xc, &domctl);
1198 int xc_domain_get_machine_address_size(int xc, uint32_t domid)
1200 DECLARE_DOMCTL;
1201 int rc;
1203 memset(&domctl, 0, sizeof(domctl));
1204 domctl.domain = domid;
1205 domctl.cmd = XEN_DOMCTL_get_machine_address_size;
1207 rc = do_domctl(xc, &domctl);
1209 return rc == 0 ? domctl.u.address_size.size : rc;
1212 int xc_domain_suppress_spurious_page_faults(int xc, uint32_t domid)
1214 DECLARE_DOMCTL;
1216 memset(&domctl, 0, sizeof(domctl));
1217 domctl.domain = domid;
1218 domctl.cmd = XEN_DOMCTL_suppress_spurious_page_faults;
1220 return do_domctl(xc, &domctl);
1224 int xc_domain_debug_control(int xc, uint32_t domid, uint32_t sop, uint32_t vcpu)
1226 DECLARE_DOMCTL;
1228 memset(&domctl, 0, sizeof(domctl));
1229 domctl.domain = (domid_t)domid;
1230 domctl.cmd = XEN_DOMCTL_debug_op;
1231 domctl.u.debug_op.op = sop;
1232 domctl.u.debug_op.vcpu = vcpu;
1234 return do_domctl(xc, &domctl);
1238 /*
1239 * Local variables:
1240 * mode: C
1241 * c-set-style: "BSD"
1242 * c-basic-offset: 4
1243 * tab-width: 4
1244 * indent-tabs-mode: nil
1245 * End:
1246 */