direct-io.hg

view tools/libxc/xc_domain.c @ 15478:05331a29f3cb

Export debugger attached state to xc API.
Signed-off-by: Tristan Gingold <tgingold@free.fr>
author kfraser@localhost.localdomain
date Fri Jul 06 14:42:55 2007 +0100 (2007-07-06)
parents 7eeddd787d2f
children d7e3224b661a
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 <xen/memory.h>
11 #include <xen/hvm/hvm_op.h>
13 int xc_domain_create(int xc_handle,
14 uint32_t ssidref,
15 xen_domain_handle_t handle,
16 uint32_t flags,
17 uint32_t *pdomid)
18 {
19 int err;
20 DECLARE_DOMCTL;
22 domctl.cmd = XEN_DOMCTL_createdomain;
23 domctl.domain = (domid_t)*pdomid;
24 domctl.u.createdomain.ssidref = ssidref;
25 domctl.u.createdomain.flags = flags;
26 memcpy(domctl.u.createdomain.handle, handle, sizeof(xen_domain_handle_t));
27 if ( (err = do_domctl(xc_handle, &domctl)) != 0 )
28 return err;
30 *pdomid = (uint16_t)domctl.domain;
31 return 0;
32 }
35 int xc_domain_pause(int xc_handle,
36 uint32_t domid)
37 {
38 DECLARE_DOMCTL;
39 domctl.cmd = XEN_DOMCTL_pausedomain;
40 domctl.domain = (domid_t)domid;
41 return do_domctl(xc_handle, &domctl);
42 }
45 int xc_domain_unpause(int xc_handle,
46 uint32_t domid)
47 {
48 DECLARE_DOMCTL;
49 domctl.cmd = XEN_DOMCTL_unpausedomain;
50 domctl.domain = (domid_t)domid;
51 return do_domctl(xc_handle, &domctl);
52 }
55 int xc_domain_destroy(int xc_handle,
56 uint32_t domid)
57 {
58 DECLARE_DOMCTL;
59 domctl.cmd = XEN_DOMCTL_destroydomain;
60 domctl.domain = (domid_t)domid;
61 return do_domctl(xc_handle, &domctl);
62 }
64 int xc_domain_shutdown(int xc_handle,
65 uint32_t domid,
66 int reason)
67 {
68 int ret = -1;
69 sched_remote_shutdown_t arg;
70 DECLARE_HYPERCALL;
72 hypercall.op = __HYPERVISOR_sched_op;
73 hypercall.arg[0] = (unsigned long)SCHEDOP_remote_shutdown;
74 hypercall.arg[1] = (unsigned long)&arg;
75 arg.domain_id = domid;
76 arg.reason = reason;
78 if ( lock_pages(&arg, sizeof(arg)) != 0 )
79 {
80 PERROR("Could not lock memory for Xen hypercall");
81 goto out1;
82 }
84 ret = do_xen_hypercall(xc_handle, &hypercall);
86 unlock_pages(&arg, sizeof(arg));
88 out1:
89 return ret;
90 }
93 int xc_vcpu_setaffinity(int xc_handle,
94 uint32_t domid,
95 int vcpu,
96 uint64_t cpumap)
97 {
98 DECLARE_DOMCTL;
99 int ret = -1;
100 uint8_t local[sizeof (cpumap)];
102 domctl.cmd = XEN_DOMCTL_setvcpuaffinity;
103 domctl.domain = (domid_t)domid;
104 domctl.u.vcpuaffinity.vcpu = vcpu;
106 bitmap_64_to_byte(local, &cpumap, sizeof(cpumap) * 8);
108 set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, local);
110 domctl.u.vcpuaffinity.cpumap.nr_cpus = sizeof(cpumap) * 8;
112 if ( lock_pages(local, sizeof(local)) != 0 )
113 {
114 PERROR("Could not lock memory for Xen hypercall");
115 goto out;
116 }
118 ret = do_domctl(xc_handle, &domctl);
120 unlock_pages(local, sizeof(local));
122 out:
123 return ret;
124 }
127 int xc_vcpu_getaffinity(int xc_handle,
128 uint32_t domid,
129 int vcpu,
130 uint64_t *cpumap)
131 {
132 DECLARE_DOMCTL;
133 int ret = -1;
134 uint8_t local[sizeof (cpumap)];
136 domctl.cmd = XEN_DOMCTL_getvcpuaffinity;
137 domctl.domain = (domid_t)domid;
138 domctl.u.vcpuaffinity.vcpu = vcpu;
140 set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, local);
141 domctl.u.vcpuaffinity.cpumap.nr_cpus = sizeof(cpumap) * 8;
143 if ( lock_pages(local, sizeof(local)) != 0 )
144 {
145 PERROR("Could not lock memory for Xen hypercall");
146 goto out;
147 }
149 ret = do_domctl(xc_handle, &domctl);
151 unlock_pages(local, sizeof (local));
152 bitmap_byte_to_64(cpumap, local, sizeof(local) * 8);
153 out:
154 return ret;
155 }
158 int xc_domain_getinfo(int xc_handle,
159 uint32_t first_domid,
160 unsigned int max_doms,
161 xc_dominfo_t *info)
162 {
163 unsigned int nr_doms;
164 uint32_t next_domid = first_domid;
165 DECLARE_DOMCTL;
166 int rc = 0;
168 memset(info, 0, max_doms*sizeof(xc_dominfo_t));
170 for ( nr_doms = 0; nr_doms < max_doms; nr_doms++ )
171 {
172 domctl.cmd = XEN_DOMCTL_getdomaininfo;
173 domctl.domain = (domid_t)next_domid;
174 if ( (rc = do_domctl(xc_handle, &domctl)) < 0 )
175 break;
176 info->domid = (uint16_t)domctl.domain;
178 info->dying = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_dying);
179 info->shutdown = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_shutdown);
180 info->paused = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_paused);
181 info->blocked = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_blocked);
182 info->running = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_running);
183 info->hvm = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_hvm_guest);
184 info->debugged = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_debugged);
186 info->shutdown_reason =
187 (domctl.u.getdomaininfo.flags>>XEN_DOMINF_shutdownshift) &
188 XEN_DOMINF_shutdownmask;
190 if ( info->shutdown && (info->shutdown_reason == SHUTDOWN_crash) )
191 {
192 info->shutdown = 0;
193 info->crashed = 1;
194 }
196 info->ssidref = domctl.u.getdomaininfo.ssidref;
197 info->nr_pages = domctl.u.getdomaininfo.tot_pages;
198 info->max_memkb = domctl.u.getdomaininfo.max_pages << (PAGE_SHIFT-10);
199 info->shared_info_frame = domctl.u.getdomaininfo.shared_info_frame;
200 info->cpu_time = domctl.u.getdomaininfo.cpu_time;
201 info->nr_online_vcpus = domctl.u.getdomaininfo.nr_online_vcpus;
202 info->max_vcpu_id = domctl.u.getdomaininfo.max_vcpu_id;
204 memcpy(info->handle, domctl.u.getdomaininfo.handle,
205 sizeof(xen_domain_handle_t));
207 next_domid = (uint16_t)domctl.domain + 1;
208 info++;
209 }
211 if ( nr_doms == 0 )
212 return rc;
214 return nr_doms;
215 }
217 int xc_domain_getinfolist(int xc_handle,
218 uint32_t first_domain,
219 unsigned int max_domains,
220 xc_domaininfo_t *info)
221 {
222 int ret = 0;
223 DECLARE_SYSCTL;
225 if ( lock_pages(info, max_domains*sizeof(xc_domaininfo_t)) != 0 )
226 return -1;
228 sysctl.cmd = XEN_SYSCTL_getdomaininfolist;
229 sysctl.u.getdomaininfolist.first_domain = first_domain;
230 sysctl.u.getdomaininfolist.max_domains = max_domains;
231 set_xen_guest_handle(sysctl.u.getdomaininfolist.buffer, info);
233 if ( xc_sysctl(xc_handle, &sysctl) < 0 )
234 ret = -1;
235 else
236 ret = sysctl.u.getdomaininfolist.num_domains;
238 unlock_pages(info, max_domains*sizeof(xc_domaininfo_t));
240 return ret;
241 }
243 /* get info from hvm guest for save */
244 int xc_domain_hvm_getcontext(int xc_handle,
245 uint32_t domid,
246 uint8_t *ctxt_buf,
247 uint32_t size)
248 {
249 int ret;
250 DECLARE_DOMCTL;
252 domctl.cmd = XEN_DOMCTL_gethvmcontext;
253 domctl.domain = (domid_t)domid;
254 domctl.u.hvmcontext.size = size;
255 set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf);
257 if ( ctxt_buf )
258 if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
259 return ret;
261 ret = do_domctl(xc_handle, &domctl);
263 if ( ctxt_buf )
264 unlock_pages(ctxt_buf, size);
266 return (ret < 0 ? -1 : domctl.u.hvmcontext.size);
267 }
269 /* set info to hvm guest for restore */
270 int xc_domain_hvm_setcontext(int xc_handle,
271 uint32_t domid,
272 uint8_t *ctxt_buf,
273 uint32_t size)
274 {
275 int ret;
276 DECLARE_DOMCTL;
278 domctl.cmd = XEN_DOMCTL_sethvmcontext;
279 domctl.domain = domid;
280 domctl.u.hvmcontext.size = size;
281 set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf);
283 if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
284 return ret;
286 ret = do_domctl(xc_handle, &domctl);
288 unlock_pages(ctxt_buf, size);
290 return ret;
291 }
293 int xc_vcpu_getcontext(int xc_handle,
294 uint32_t domid,
295 uint32_t vcpu,
296 vcpu_guest_context_t *ctxt)
297 {
298 int rc;
299 DECLARE_DOMCTL;
301 domctl.cmd = XEN_DOMCTL_getvcpucontext;
302 domctl.domain = (domid_t)domid;
303 domctl.u.vcpucontext.vcpu = (uint16_t)vcpu;
304 set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt);
306 if ( (rc = lock_pages(ctxt, sizeof(*ctxt))) != 0 )
307 return rc;
309 rc = do_domctl(xc_handle, &domctl);
311 unlock_pages(ctxt, sizeof(*ctxt));
313 return rc;
314 }
317 int xc_shadow_control(int xc_handle,
318 uint32_t domid,
319 unsigned int sop,
320 unsigned long *dirty_bitmap,
321 unsigned long pages,
322 unsigned long *mb,
323 uint32_t mode,
324 xc_shadow_op_stats_t *stats)
325 {
326 int rc;
327 DECLARE_DOMCTL;
328 domctl.cmd = XEN_DOMCTL_shadow_op;
329 domctl.domain = (domid_t)domid;
330 domctl.u.shadow_op.op = sop;
331 domctl.u.shadow_op.pages = pages;
332 domctl.u.shadow_op.mb = mb ? *mb : 0;
333 domctl.u.shadow_op.mode = mode;
334 set_xen_guest_handle(domctl.u.shadow_op.dirty_bitmap,
335 (uint8_t *)dirty_bitmap);
337 rc = do_domctl(xc_handle, &domctl);
339 if ( stats )
340 memcpy(stats, &domctl.u.shadow_op.stats,
341 sizeof(xc_shadow_op_stats_t));
343 if ( mb )
344 *mb = domctl.u.shadow_op.mb;
346 return (rc == 0) ? domctl.u.shadow_op.pages : rc;
347 }
349 int xc_domain_setcpuweight(int xc_handle,
350 uint32_t domid,
351 float weight)
352 {
353 int sched_id;
354 int ret;
356 /* Figure out which scheduler is currently used: */
357 if ( (ret = xc_sched_id(xc_handle, &sched_id)) != 0 )
358 return ret;
360 /* No-op. */
361 return 0;
362 }
364 int xc_domain_setmaxmem(int xc_handle,
365 uint32_t domid,
366 unsigned int max_memkb)
367 {
368 DECLARE_DOMCTL;
369 domctl.cmd = XEN_DOMCTL_max_mem;
370 domctl.domain = (domid_t)domid;
371 domctl.u.max_mem.max_memkb = max_memkb;
372 return do_domctl(xc_handle, &domctl);
373 }
375 #if defined(__i386__) || defined(__x86_64__)
376 #include "xc_e820.h"
377 int xc_domain_set_memmap_limit(int xc_handle,
378 uint32_t domid,
379 unsigned long map_limitkb)
380 {
381 int rc;
383 struct xen_foreign_memory_map fmap = {
384 .domid = domid,
385 .map = { .nr_entries = 1 }
386 };
388 struct e820entry e820 = {
389 .addr = 0,
390 .size = (uint64_t)map_limitkb << 10,
391 .type = E820_RAM
392 };
394 set_xen_guest_handle(fmap.map.buffer, &e820);
396 if ( lock_pages(&fmap, sizeof(fmap)) || lock_pages(&e820, sizeof(e820)) )
397 {
398 PERROR("Could not lock memory for Xen hypercall");
399 rc = -1;
400 goto out;
401 }
403 rc = xc_memory_op(xc_handle, XENMEM_set_memory_map, &fmap);
405 out:
406 unlock_pages(&fmap, sizeof(fmap));
407 unlock_pages(&e820, sizeof(e820));
408 return rc;
409 }
410 #else
411 int xc_domain_set_memmap_limit(int xc_handle,
412 uint32_t domid,
413 unsigned long map_limitkb)
414 {
415 PERROR("Function not implemented");
416 errno = ENOSYS;
417 return -1;
418 }
419 #endif
421 int xc_domain_set_time_offset(int xc_handle,
422 uint32_t domid,
423 int32_t time_offset_seconds)
424 {
425 DECLARE_DOMCTL;
426 domctl.cmd = XEN_DOMCTL_settimeoffset;
427 domctl.domain = (domid_t)domid;
428 domctl.u.settimeoffset.time_offset_seconds = time_offset_seconds;
429 return do_domctl(xc_handle, &domctl);
430 }
432 int xc_domain_memory_increase_reservation(int xc_handle,
433 uint32_t domid,
434 unsigned long nr_extents,
435 unsigned int extent_order,
436 unsigned int address_bits,
437 xen_pfn_t *extent_start)
438 {
439 int err;
440 struct xen_memory_reservation reservation = {
441 .nr_extents = nr_extents,
442 .extent_order = extent_order,
443 .address_bits = address_bits,
444 .domid = domid
445 };
447 /* may be NULL */
448 set_xen_guest_handle(reservation.extent_start, extent_start);
450 err = xc_memory_op(xc_handle, XENMEM_increase_reservation, &reservation);
451 if ( err == nr_extents )
452 return 0;
454 if ( err >= 0 )
455 {
456 DPRINTF("Failed allocation for dom %d: "
457 "%ld extents of order %d, addr_bits %d\n",
458 domid, nr_extents, extent_order, address_bits);
459 errno = ENOMEM;
460 err = -1;
461 }
463 return err;
464 }
466 int xc_domain_memory_decrease_reservation(int xc_handle,
467 uint32_t domid,
468 unsigned long nr_extents,
469 unsigned int extent_order,
470 xen_pfn_t *extent_start)
471 {
472 int err;
473 struct xen_memory_reservation reservation = {
474 .nr_extents = nr_extents,
475 .extent_order = extent_order,
476 .address_bits = 0,
477 .domid = domid
478 };
480 set_xen_guest_handle(reservation.extent_start, extent_start);
482 if ( extent_start == NULL )
483 {
484 DPRINTF("decrease_reservation extent_start is NULL!\n");
485 errno = EINVAL;
486 return -1;
487 }
489 err = xc_memory_op(xc_handle, XENMEM_decrease_reservation, &reservation);
490 if ( err == nr_extents )
491 return 0;
493 if ( err >= 0 )
494 {
495 DPRINTF("Failed deallocation for dom %d: %ld extents of order %d\n",
496 domid, nr_extents, extent_order);
497 errno = EINVAL;
498 err = -1;
499 }
501 return err;
502 }
504 int xc_domain_memory_populate_physmap(int xc_handle,
505 uint32_t domid,
506 unsigned long nr_extents,
507 unsigned int extent_order,
508 unsigned int address_bits,
509 xen_pfn_t *extent_start)
510 {
511 int err;
512 struct xen_memory_reservation reservation = {
513 .nr_extents = nr_extents,
514 .extent_order = extent_order,
515 .address_bits = address_bits,
516 .domid = domid
517 };
518 set_xen_guest_handle(reservation.extent_start, extent_start);
520 err = xc_memory_op(xc_handle, XENMEM_populate_physmap, &reservation);
521 if ( err == nr_extents )
522 return 0;
524 if ( err >= 0 )
525 {
526 DPRINTF("Failed allocation for dom %d: %ld extents of order %d\n",
527 domid, nr_extents, extent_order);
528 errno = EBUSY;
529 err = -1;
530 }
532 return err;
533 }
535 int xc_domain_max_vcpus(int xc_handle, uint32_t domid, unsigned int max)
536 {
537 DECLARE_DOMCTL;
538 domctl.cmd = XEN_DOMCTL_max_vcpus;
539 domctl.domain = (domid_t)domid;
540 domctl.u.max_vcpus.max = max;
541 return do_domctl(xc_handle, &domctl);
542 }
544 int xc_domain_sethandle(int xc_handle, uint32_t domid,
545 xen_domain_handle_t handle)
546 {
547 DECLARE_DOMCTL;
548 domctl.cmd = XEN_DOMCTL_setdomainhandle;
549 domctl.domain = (domid_t)domid;
550 memcpy(domctl.u.setdomainhandle.handle, handle,
551 sizeof(xen_domain_handle_t));
552 return do_domctl(xc_handle, &domctl);
553 }
555 int xc_vcpu_getinfo(int xc_handle,
556 uint32_t domid,
557 uint32_t vcpu,
558 xc_vcpuinfo_t *info)
559 {
560 int rc;
561 DECLARE_DOMCTL;
563 domctl.cmd = XEN_DOMCTL_getvcpuinfo;
564 domctl.domain = (domid_t)domid;
565 domctl.u.getvcpuinfo.vcpu = (uint16_t)vcpu;
567 rc = do_domctl(xc_handle, &domctl);
569 memcpy(info, &domctl.u.getvcpuinfo, sizeof(*info));
571 return rc;
572 }
574 int xc_domain_ioport_permission(int xc_handle,
575 uint32_t domid,
576 uint32_t first_port,
577 uint32_t nr_ports,
578 uint32_t allow_access)
579 {
580 DECLARE_DOMCTL;
582 domctl.cmd = XEN_DOMCTL_ioport_permission;
583 domctl.domain = (domid_t)domid;
584 domctl.u.ioport_permission.first_port = first_port;
585 domctl.u.ioport_permission.nr_ports = nr_ports;
586 domctl.u.ioport_permission.allow_access = allow_access;
588 return do_domctl(xc_handle, &domctl);
589 }
591 int xc_vcpu_setcontext(int xc_handle,
592 uint32_t domid,
593 uint32_t vcpu,
594 vcpu_guest_context_t *ctxt)
595 {
596 DECLARE_DOMCTL;
597 int rc;
599 domctl.cmd = XEN_DOMCTL_setvcpucontext;
600 domctl.domain = domid;
601 domctl.u.vcpucontext.vcpu = vcpu;
602 set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt);
604 if ( (ctxt != NULL) && ((rc = lock_pages(ctxt, sizeof(*ctxt))) != 0) )
605 return rc;
607 rc = do_domctl(xc_handle, &domctl);
609 if ( ctxt != NULL )
610 unlock_pages(ctxt, sizeof(*ctxt));
612 return rc;
613 }
615 int xc_domain_irq_permission(int xc_handle,
616 uint32_t domid,
617 uint8_t pirq,
618 uint8_t allow_access)
619 {
620 DECLARE_DOMCTL;
622 domctl.cmd = XEN_DOMCTL_irq_permission;
623 domctl.domain = domid;
624 domctl.u.irq_permission.pirq = pirq;
625 domctl.u.irq_permission.allow_access = allow_access;
627 return do_domctl(xc_handle, &domctl);
628 }
630 int xc_domain_iomem_permission(int xc_handle,
631 uint32_t domid,
632 unsigned long first_mfn,
633 unsigned long nr_mfns,
634 uint8_t allow_access)
635 {
636 DECLARE_DOMCTL;
638 domctl.cmd = XEN_DOMCTL_iomem_permission;
639 domctl.domain = domid;
640 domctl.u.iomem_permission.first_mfn = first_mfn;
641 domctl.u.iomem_permission.nr_mfns = nr_mfns;
642 domctl.u.iomem_permission.allow_access = allow_access;
644 return do_domctl(xc_handle, &domctl);
645 }
647 int xc_domain_send_trigger(int xc_handle,
648 uint32_t domid,
649 uint32_t trigger,
650 uint32_t vcpu)
651 {
652 DECLARE_DOMCTL;
654 domctl.cmd = XEN_DOMCTL_sendtrigger;
655 domctl.domain = domid;
656 domctl.u.sendtrigger.trigger = trigger;
657 domctl.u.sendtrigger.vcpu = vcpu;
659 return do_domctl(xc_handle, &domctl);
660 }
662 int xc_set_hvm_param(int handle, domid_t dom, int param, unsigned long value)
663 {
664 DECLARE_HYPERCALL;
665 xen_hvm_param_t arg;
666 int rc;
668 hypercall.op = __HYPERVISOR_hvm_op;
669 hypercall.arg[0] = HVMOP_set_param;
670 hypercall.arg[1] = (unsigned long)&arg;
671 arg.domid = dom;
672 arg.index = param;
673 arg.value = value;
674 if ( lock_pages(&arg, sizeof(arg)) != 0 )
675 return -1;
676 rc = do_xen_hypercall(handle, &hypercall);
677 unlock_pages(&arg, sizeof(arg));
678 return rc;
679 }
681 int xc_get_hvm_param(int handle, domid_t dom, int param, unsigned long *value)
682 {
683 DECLARE_HYPERCALL;
684 xen_hvm_param_t arg;
685 int rc;
687 hypercall.op = __HYPERVISOR_hvm_op;
688 hypercall.arg[0] = HVMOP_get_param;
689 hypercall.arg[1] = (unsigned long)&arg;
690 arg.domid = dom;
691 arg.index = param;
692 if ( lock_pages(&arg, sizeof(arg)) != 0 )
693 return -1;
694 rc = do_xen_hypercall(handle, &hypercall);
695 unlock_pages(&arg, sizeof(arg));
696 *value = arg.value;
697 return rc;
698 }
700 /*
701 * Local variables:
702 * mode: C
703 * c-set-style: "BSD"
704 * c-basic-offset: 4
705 * tab-width: 4
706 * indent-tabs-mode: nil
707 * End:
708 */