ia64/xen-unstable

view tools/libxc/xc_domain.c @ 13971:4bd0ea9c499f

libxc: Fix xc_vcpu_{set,get}_affinity (Xen-bugzilla No.900).
http://bugzilla.xensource.com/bugzilla/show_bug.cgi?id=900

Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
author kfraser@localhost.localdomain
date Thu Feb 15 13:36:00 2007 +0000 (2007-02-15)
parents 4d7ee9f4336a
children 6c938630de54
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>
12 int xc_domain_create(int xc_handle,
13 uint32_t ssidref,
14 xen_domain_handle_t handle,
15 uint32_t flags,
16 uint32_t *pdomid)
17 {
18 int err;
19 DECLARE_DOMCTL;
21 domctl.cmd = XEN_DOMCTL_createdomain;
22 domctl.domain = (domid_t)*pdomid;
23 domctl.u.createdomain.ssidref = ssidref;
24 domctl.u.createdomain.flags = flags;
25 memcpy(domctl.u.createdomain.handle, handle, sizeof(xen_domain_handle_t));
26 if ( (err = do_domctl(xc_handle, &domctl)) != 0 )
27 return err;
29 *pdomid = (uint16_t)domctl.domain;
30 return 0;
31 }
34 int xc_domain_pause(int xc_handle,
35 uint32_t domid)
36 {
37 DECLARE_DOMCTL;
38 domctl.cmd = XEN_DOMCTL_pausedomain;
39 domctl.domain = (domid_t)domid;
40 return do_domctl(xc_handle, &domctl);
41 }
44 int xc_domain_unpause(int xc_handle,
45 uint32_t domid)
46 {
47 DECLARE_DOMCTL;
48 domctl.cmd = XEN_DOMCTL_unpausedomain;
49 domctl.domain = (domid_t)domid;
50 return do_domctl(xc_handle, &domctl);
51 }
54 int xc_domain_destroy(int xc_handle,
55 uint32_t domid)
56 {
57 DECLARE_DOMCTL;
58 domctl.cmd = XEN_DOMCTL_destroydomain;
59 domctl.domain = (domid_t)domid;
60 return do_domctl(xc_handle, &domctl);
61 }
63 int xc_domain_shutdown(int xc_handle,
64 uint32_t domid,
65 int reason)
66 {
67 int ret = -1;
68 sched_remote_shutdown_t arg;
69 DECLARE_HYPERCALL;
71 hypercall.op = __HYPERVISOR_sched_op;
72 hypercall.arg[0] = (unsigned long)SCHEDOP_remote_shutdown;
73 hypercall.arg[1] = (unsigned long)&arg;
74 arg.domain_id = domid;
75 arg.reason = reason;
77 if ( lock_pages(&arg, sizeof(arg)) != 0 )
78 {
79 PERROR("Could not lock memory for Xen hypercall");
80 goto out1;
81 }
83 ret = do_xen_hypercall(xc_handle, &hypercall);
85 unlock_pages(&arg, sizeof(arg));
87 out1:
88 return ret;
89 }
92 int xc_vcpu_setaffinity(int xc_handle,
93 uint32_t domid,
94 int vcpu,
95 uint64_t cpumap)
96 {
97 DECLARE_DOMCTL;
98 int ret = -1;
99 uint8_t local[sizeof (cpumap)];
101 domctl.cmd = XEN_DOMCTL_setvcpuaffinity;
102 domctl.domain = (domid_t)domid;
103 domctl.u.vcpuaffinity.vcpu = vcpu;
105 bitmap_64_to_byte(local, &cpumap, sizeof(cpumap) * 8);
107 set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, local);
109 domctl.u.vcpuaffinity.cpumap.nr_cpus = sizeof(cpumap) * 8;
111 if ( lock_pages(local, sizeof(local)) != 0 )
112 {
113 PERROR("Could not lock memory for Xen hypercall");
114 goto out;
115 }
117 ret = do_domctl(xc_handle, &domctl);
119 unlock_pages(local, sizeof(local));
121 out:
122 return ret;
123 }
126 int xc_vcpu_getaffinity(int xc_handle,
127 uint32_t domid,
128 int vcpu,
129 uint64_t *cpumap)
130 {
131 DECLARE_DOMCTL;
132 int ret = -1;
133 uint8_t local[sizeof (cpumap)];
135 domctl.cmd = XEN_DOMCTL_getvcpuaffinity;
136 domctl.domain = (domid_t)domid;
137 domctl.u.vcpuaffinity.vcpu = vcpu;
139 set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, local);
140 domctl.u.vcpuaffinity.cpumap.nr_cpus = sizeof(cpumap) * 8;
142 if ( lock_pages(local, sizeof(local)) != 0 )
143 {
144 PERROR("Could not lock memory for Xen hypercall");
145 goto out;
146 }
148 ret = do_domctl(xc_handle, &domctl);
150 unlock_pages(local, sizeof (local));
151 bitmap_byte_to_64(cpumap, local, sizeof(local) * 8);
152 out:
153 return ret;
154 }
157 int xc_domain_getinfo(int xc_handle,
158 uint32_t first_domid,
159 unsigned int max_doms,
160 xc_dominfo_t *info)
161 {
162 unsigned int nr_doms;
163 uint32_t next_domid = first_domid;
164 DECLARE_DOMCTL;
165 int rc = 0;
167 memset(info, 0, max_doms*sizeof(xc_dominfo_t));
169 for ( nr_doms = 0; nr_doms < max_doms; nr_doms++ )
170 {
171 domctl.cmd = XEN_DOMCTL_getdomaininfo;
172 domctl.domain = (domid_t)next_domid;
173 if ( (rc = do_domctl(xc_handle, &domctl)) < 0 )
174 break;
175 info->domid = (uint16_t)domctl.domain;
177 info->dying = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_dying);
178 info->shutdown = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_shutdown);
179 info->paused = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_paused);
180 info->blocked = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_blocked);
181 info->running = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_running);
182 info->hvm = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_hvm_guest);
184 info->shutdown_reason =
185 (domctl.u.getdomaininfo.flags>>XEN_DOMINF_shutdownshift) &
186 XEN_DOMINF_shutdownmask;
188 if ( info->shutdown && (info->shutdown_reason == SHUTDOWN_crash) )
189 {
190 info->shutdown = 0;
191 info->crashed = 1;
192 }
194 info->ssidref = domctl.u.getdomaininfo.ssidref;
195 info->nr_pages = domctl.u.getdomaininfo.tot_pages;
196 info->max_memkb = domctl.u.getdomaininfo.max_pages << (PAGE_SHIFT-10);
197 info->shared_info_frame = domctl.u.getdomaininfo.shared_info_frame;
198 info->cpu_time = domctl.u.getdomaininfo.cpu_time;
199 info->nr_online_vcpus = domctl.u.getdomaininfo.nr_online_vcpus;
200 info->max_vcpu_id = domctl.u.getdomaininfo.max_vcpu_id;
202 memcpy(info->handle, domctl.u.getdomaininfo.handle,
203 sizeof(xen_domain_handle_t));
205 next_domid = (uint16_t)domctl.domain + 1;
206 info++;
207 }
209 if ( nr_doms == 0 )
210 return rc;
212 return nr_doms;
213 }
215 int xc_domain_getinfolist(int xc_handle,
216 uint32_t first_domain,
217 unsigned int max_domains,
218 xc_domaininfo_t *info)
219 {
220 int ret = 0;
221 DECLARE_SYSCTL;
223 if ( lock_pages(info, max_domains*sizeof(xc_domaininfo_t)) != 0 )
224 return -1;
226 sysctl.cmd = XEN_SYSCTL_getdomaininfolist;
227 sysctl.u.getdomaininfolist.first_domain = first_domain;
228 sysctl.u.getdomaininfolist.max_domains = max_domains;
229 set_xen_guest_handle(sysctl.u.getdomaininfolist.buffer, info);
231 if ( xc_sysctl(xc_handle, &sysctl) < 0 )
232 ret = -1;
233 else
234 ret = sysctl.u.getdomaininfolist.num_domains;
236 unlock_pages(info, max_domains*sizeof(xc_domaininfo_t));
238 return ret;
239 }
241 /* get info from hvm guest for save */
242 int xc_domain_hvm_getcontext(int xc_handle,
243 uint32_t domid,
244 uint8_t *ctxt_buf,
245 uint32_t size)
246 {
247 int ret;
248 DECLARE_DOMCTL;
250 domctl.cmd = XEN_DOMCTL_gethvmcontext;
251 domctl.domain = (domid_t)domid;
252 domctl.u.hvmcontext.size = size;
253 set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf);
255 if ( ctxt_buf )
256 if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
257 return ret;
259 ret = do_domctl(xc_handle, &domctl);
261 if ( ctxt_buf )
262 unlock_pages(ctxt_buf, size);
264 return (ret < 0 ? -1 : domctl.u.hvmcontext.size);
265 }
267 /* set info to hvm guest for restore */
268 int xc_domain_hvm_setcontext(int xc_handle,
269 uint32_t domid,
270 uint8_t *ctxt_buf,
271 uint32_t size)
272 {
273 int ret;
274 DECLARE_DOMCTL;
276 domctl.cmd = XEN_DOMCTL_sethvmcontext;
277 domctl.domain = domid;
278 domctl.u.hvmcontext.size = size;
279 set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf);
281 if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
282 return ret;
284 ret = do_domctl(xc_handle, &domctl);
286 unlock_pages(ctxt_buf, size);
288 return ret;
289 }
291 int xc_vcpu_getcontext(int xc_handle,
292 uint32_t domid,
293 uint32_t vcpu,
294 vcpu_guest_context_t *ctxt)
295 {
296 int rc;
297 DECLARE_DOMCTL;
299 domctl.cmd = XEN_DOMCTL_getvcpucontext;
300 domctl.domain = (domid_t)domid;
301 domctl.u.vcpucontext.vcpu = (uint16_t)vcpu;
302 set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt);
304 if ( (rc = lock_pages(ctxt, sizeof(*ctxt))) != 0 )
305 return rc;
307 rc = do_domctl(xc_handle, &domctl);
309 unlock_pages(ctxt, sizeof(*ctxt));
311 return rc;
312 }
315 int xc_shadow_control(int xc_handle,
316 uint32_t domid,
317 unsigned int sop,
318 unsigned long *dirty_bitmap,
319 unsigned long pages,
320 unsigned long *mb,
321 uint32_t mode,
322 xc_shadow_op_stats_t *stats)
323 {
324 int rc;
325 DECLARE_DOMCTL;
326 domctl.cmd = XEN_DOMCTL_shadow_op;
327 domctl.domain = (domid_t)domid;
328 domctl.u.shadow_op.op = sop;
329 domctl.u.shadow_op.pages = pages;
330 domctl.u.shadow_op.mb = mb ? *mb : 0;
331 domctl.u.shadow_op.mode = mode;
332 set_xen_guest_handle(domctl.u.shadow_op.dirty_bitmap,
333 (uint8_t *)dirty_bitmap);
335 rc = do_domctl(xc_handle, &domctl);
337 if ( stats )
338 memcpy(stats, &domctl.u.shadow_op.stats,
339 sizeof(xc_shadow_op_stats_t));
341 if ( mb )
342 *mb = domctl.u.shadow_op.mb;
344 return (rc == 0) ? domctl.u.shadow_op.pages : rc;
345 }
347 int xc_domain_setcpuweight(int xc_handle,
348 uint32_t domid,
349 float weight)
350 {
351 int sched_id;
352 int ret;
354 /* Figure out which scheduler is currently used: */
355 if ( (ret = xc_sched_id(xc_handle, &sched_id)) != 0 )
356 return ret;
358 /* No-op. */
359 return 0;
360 }
362 int xc_domain_setmaxmem(int xc_handle,
363 uint32_t domid,
364 unsigned int max_memkb)
365 {
366 DECLARE_DOMCTL;
367 domctl.cmd = XEN_DOMCTL_max_mem;
368 domctl.domain = (domid_t)domid;
369 domctl.u.max_mem.max_memkb = max_memkb;
370 return do_domctl(xc_handle, &domctl);
371 }
373 #if defined(__i386__) || defined(__x86_64__)
374 #include <xen/hvm/e820.h>
375 int xc_domain_set_memmap_limit(int xc_handle,
376 uint32_t domid,
377 unsigned long map_limitkb)
378 {
379 int rc;
381 struct xen_foreign_memory_map fmap = {
382 .domid = domid,
383 .map = { .nr_entries = 1 }
384 };
386 struct e820entry e820 = {
387 .addr = 0,
388 .size = (uint64_t)map_limitkb << 10,
389 .type = E820_RAM
390 };
392 set_xen_guest_handle(fmap.map.buffer, &e820);
394 if ( lock_pages(&fmap, sizeof(fmap)) || lock_pages(&e820, sizeof(e820)) )
395 {
396 PERROR("Could not lock memory for Xen hypercall");
397 rc = -1;
398 goto out;
399 }
401 rc = xc_memory_op(xc_handle, XENMEM_set_memory_map, &fmap);
403 out:
404 unlock_pages(&fmap, sizeof(fmap));
405 unlock_pages(&e820, sizeof(e820));
406 return rc;
407 }
408 #else
409 int xc_domain_set_memmap_limit(int xc_handle,
410 uint32_t domid,
411 unsigned long map_limitkb)
412 {
413 PERROR("Function not implemented");
414 errno = ENOSYS;
415 return -1;
416 }
417 #endif
419 int xc_domain_set_time_offset(int xc_handle,
420 uint32_t domid,
421 int32_t time_offset_seconds)
422 {
423 DECLARE_DOMCTL;
424 domctl.cmd = XEN_DOMCTL_settimeoffset;
425 domctl.domain = (domid_t)domid;
426 domctl.u.settimeoffset.time_offset_seconds = time_offset_seconds;
427 return do_domctl(xc_handle, &domctl);
428 }
430 int xc_domain_memory_increase_reservation(int xc_handle,
431 uint32_t domid,
432 unsigned long nr_extents,
433 unsigned int extent_order,
434 unsigned int address_bits,
435 xen_pfn_t *extent_start)
436 {
437 int err;
438 struct xen_memory_reservation reservation = {
439 .nr_extents = nr_extents,
440 .extent_order = extent_order,
441 .address_bits = address_bits,
442 .domid = domid
443 };
445 /* may be NULL */
446 set_xen_guest_handle(reservation.extent_start, extent_start);
448 err = xc_memory_op(xc_handle, XENMEM_increase_reservation, &reservation);
449 if ( err == nr_extents )
450 return 0;
452 if ( err >= 0 )
453 {
454 DPRINTF("Failed allocation for dom %d: "
455 "%ld extents of order %d, addr_bits %d\n",
456 domid, nr_extents, extent_order, address_bits);
457 errno = ENOMEM;
458 err = -1;
459 }
461 return err;
462 }
464 int xc_domain_memory_decrease_reservation(int xc_handle,
465 uint32_t domid,
466 unsigned long nr_extents,
467 unsigned int extent_order,
468 xen_pfn_t *extent_start)
469 {
470 int err;
471 struct xen_memory_reservation reservation = {
472 .nr_extents = nr_extents,
473 .extent_order = extent_order,
474 .address_bits = 0,
475 .domid = domid
476 };
478 set_xen_guest_handle(reservation.extent_start, extent_start);
480 if ( extent_start == NULL )
481 {
482 DPRINTF("decrease_reservation extent_start is NULL!\n");
483 errno = EINVAL;
484 return -1;
485 }
487 err = xc_memory_op(xc_handle, XENMEM_decrease_reservation, &reservation);
488 if ( err == nr_extents )
489 return 0;
491 if ( err >= 0 )
492 {
493 DPRINTF("Failed deallocation for dom %d: %ld extents of order %d\n",
494 domid, nr_extents, extent_order);
495 errno = EINVAL;
496 err = -1;
497 }
499 return err;
500 }
502 int xc_domain_memory_populate_physmap(int xc_handle,
503 uint32_t domid,
504 unsigned long nr_extents,
505 unsigned int extent_order,
506 unsigned int address_bits,
507 xen_pfn_t *extent_start)
508 {
509 int err;
510 struct xen_memory_reservation reservation = {
511 .nr_extents = nr_extents,
512 .extent_order = extent_order,
513 .address_bits = address_bits,
514 .domid = domid
515 };
516 set_xen_guest_handle(reservation.extent_start, extent_start);
518 err = xc_memory_op(xc_handle, XENMEM_populate_physmap, &reservation);
519 if ( err == nr_extents )
520 return 0;
522 if ( err >= 0 )
523 {
524 DPRINTF("Failed allocation for dom %d: %ld extents of order %d\n",
525 domid, nr_extents, extent_order);
526 errno = EBUSY;
527 err = -1;
528 }
530 return err;
531 }
533 int xc_domain_max_vcpus(int xc_handle, uint32_t domid, unsigned int max)
534 {
535 DECLARE_DOMCTL;
536 domctl.cmd = XEN_DOMCTL_max_vcpus;
537 domctl.domain = (domid_t)domid;
538 domctl.u.max_vcpus.max = max;
539 return do_domctl(xc_handle, &domctl);
540 }
542 int xc_domain_sethandle(int xc_handle, uint32_t domid,
543 xen_domain_handle_t handle)
544 {
545 DECLARE_DOMCTL;
546 domctl.cmd = XEN_DOMCTL_setdomainhandle;
547 domctl.domain = (domid_t)domid;
548 memcpy(domctl.u.setdomainhandle.handle, handle,
549 sizeof(xen_domain_handle_t));
550 return do_domctl(xc_handle, &domctl);
551 }
553 int xc_vcpu_getinfo(int xc_handle,
554 uint32_t domid,
555 uint32_t vcpu,
556 xc_vcpuinfo_t *info)
557 {
558 int rc;
559 DECLARE_DOMCTL;
561 domctl.cmd = XEN_DOMCTL_getvcpuinfo;
562 domctl.domain = (domid_t)domid;
563 domctl.u.getvcpuinfo.vcpu = (uint16_t)vcpu;
565 rc = do_domctl(xc_handle, &domctl);
567 memcpy(info, &domctl.u.getvcpuinfo, sizeof(*info));
569 return rc;
570 }
572 int xc_domain_ioport_permission(int xc_handle,
573 uint32_t domid,
574 uint32_t first_port,
575 uint32_t nr_ports,
576 uint32_t allow_access)
577 {
578 DECLARE_DOMCTL;
580 domctl.cmd = XEN_DOMCTL_ioport_permission;
581 domctl.domain = (domid_t)domid;
582 domctl.u.ioport_permission.first_port = first_port;
583 domctl.u.ioport_permission.nr_ports = nr_ports;
584 domctl.u.ioport_permission.allow_access = allow_access;
586 return do_domctl(xc_handle, &domctl);
587 }
589 int xc_vcpu_setcontext(int xc_handle,
590 uint32_t domid,
591 uint32_t vcpu,
592 vcpu_guest_context_t *ctxt)
593 {
594 DECLARE_DOMCTL;
595 int rc;
597 domctl.cmd = XEN_DOMCTL_setvcpucontext;
598 domctl.domain = domid;
599 domctl.u.vcpucontext.vcpu = vcpu;
600 set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt);
602 if ( (ctxt != NULL) && ((rc = lock_pages(ctxt, sizeof(*ctxt))) != 0) )
603 return rc;
605 rc = do_domctl(xc_handle, &domctl);
607 if ( ctxt != NULL )
608 unlock_pages(ctxt, sizeof(*ctxt));
610 return rc;
611 }
613 int xc_domain_irq_permission(int xc_handle,
614 uint32_t domid,
615 uint8_t pirq,
616 uint8_t allow_access)
617 {
618 DECLARE_DOMCTL;
620 domctl.cmd = XEN_DOMCTL_irq_permission;
621 domctl.domain = domid;
622 domctl.u.irq_permission.pirq = pirq;
623 domctl.u.irq_permission.allow_access = allow_access;
625 return do_domctl(xc_handle, &domctl);
626 }
628 int xc_domain_iomem_permission(int xc_handle,
629 uint32_t domid,
630 unsigned long first_mfn,
631 unsigned long nr_mfns,
632 uint8_t allow_access)
633 {
634 DECLARE_DOMCTL;
636 domctl.cmd = XEN_DOMCTL_iomem_permission;
637 domctl.domain = domid;
638 domctl.u.iomem_permission.first_mfn = first_mfn;
639 domctl.u.iomem_permission.nr_mfns = nr_mfns;
640 domctl.u.iomem_permission.allow_access = allow_access;
642 return do_domctl(xc_handle, &domctl);
643 }
645 /*
646 * Local variables:
647 * mode: C
648 * c-set-style: "BSD"
649 * c-basic-offset: 4
650 * tab-width: 4
651 * indent-tabs-mode: nil
652 * End:
653 */