ia64/xen-unstable

view tools/libxc/xc_domain.c @ 16197:b3fa9b58a102

hvm, vt-d: Add memory cache-attribute pinning domctl for HVM
guests. Use this to pin virtual framebuffer VRAM as attribute WB, even
if guest tries to map with other attributes.
Signed-off-by: Disheng Su <disheng.su@intel.com>
author Keir Fraser <keir@xensource.com>
date Tue Oct 23 14:38:47 2007 +0100 (2007-10-23)
parents acfa9290746f
children 2d238ca6d51a
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 int ret;
59 DECLARE_DOMCTL;
60 domctl.cmd = XEN_DOMCTL_destroydomain;
61 domctl.domain = (domid_t)domid;
62 do {
63 ret = do_domctl(xc_handle, &domctl);
64 } while ( ret && (errno == EAGAIN) );
65 return ret;
66 }
68 int xc_domain_shutdown(int xc_handle,
69 uint32_t domid,
70 int reason)
71 {
72 int ret = -1;
73 sched_remote_shutdown_t arg;
74 DECLARE_HYPERCALL;
76 hypercall.op = __HYPERVISOR_sched_op;
77 hypercall.arg[0] = (unsigned long)SCHEDOP_remote_shutdown;
78 hypercall.arg[1] = (unsigned long)&arg;
79 arg.domain_id = domid;
80 arg.reason = reason;
82 if ( lock_pages(&arg, sizeof(arg)) != 0 )
83 {
84 PERROR("Could not lock memory for Xen hypercall");
85 goto out1;
86 }
88 ret = do_xen_hypercall(xc_handle, &hypercall);
90 unlock_pages(&arg, sizeof(arg));
92 out1:
93 return ret;
94 }
97 int xc_vcpu_setaffinity(int xc_handle,
98 uint32_t domid,
99 int vcpu,
100 uint64_t cpumap)
101 {
102 DECLARE_DOMCTL;
103 int ret = -1;
104 uint8_t local[sizeof (cpumap)];
106 domctl.cmd = XEN_DOMCTL_setvcpuaffinity;
107 domctl.domain = (domid_t)domid;
108 domctl.u.vcpuaffinity.vcpu = vcpu;
110 bitmap_64_to_byte(local, &cpumap, sizeof(cpumap) * 8);
112 set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, local);
114 domctl.u.vcpuaffinity.cpumap.nr_cpus = sizeof(cpumap) * 8;
116 if ( lock_pages(local, sizeof(local)) != 0 )
117 {
118 PERROR("Could not lock memory for Xen hypercall");
119 goto out;
120 }
122 ret = do_domctl(xc_handle, &domctl);
124 unlock_pages(local, sizeof(local));
126 out:
127 return ret;
128 }
131 int xc_vcpu_getaffinity(int xc_handle,
132 uint32_t domid,
133 int vcpu,
134 uint64_t *cpumap)
135 {
136 DECLARE_DOMCTL;
137 int ret = -1;
138 uint8_t local[sizeof (cpumap)];
140 domctl.cmd = XEN_DOMCTL_getvcpuaffinity;
141 domctl.domain = (domid_t)domid;
142 domctl.u.vcpuaffinity.vcpu = vcpu;
144 set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, local);
145 domctl.u.vcpuaffinity.cpumap.nr_cpus = sizeof(cpumap) * 8;
147 if ( lock_pages(local, sizeof(local)) != 0 )
148 {
149 PERROR("Could not lock memory for Xen hypercall");
150 goto out;
151 }
153 ret = do_domctl(xc_handle, &domctl);
155 unlock_pages(local, sizeof (local));
156 bitmap_byte_to_64(cpumap, local, sizeof(local) * 8);
157 out:
158 return ret;
159 }
162 int xc_domain_getinfo(int xc_handle,
163 uint32_t first_domid,
164 unsigned int max_doms,
165 xc_dominfo_t *info)
166 {
167 unsigned int nr_doms;
168 uint32_t next_domid = first_domid;
169 DECLARE_DOMCTL;
170 int rc = 0;
172 memset(info, 0, max_doms*sizeof(xc_dominfo_t));
174 for ( nr_doms = 0; nr_doms < max_doms; nr_doms++ )
175 {
176 domctl.cmd = XEN_DOMCTL_getdomaininfo;
177 domctl.domain = (domid_t)next_domid;
178 if ( (rc = do_domctl(xc_handle, &domctl)) < 0 )
179 break;
180 info->domid = (uint16_t)domctl.domain;
182 info->dying = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_dying);
183 info->shutdown = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_shutdown);
184 info->paused = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_paused);
185 info->blocked = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_blocked);
186 info->running = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_running);
187 info->hvm = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_hvm_guest);
188 info->debugged = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_debugged);
190 info->shutdown_reason =
191 (domctl.u.getdomaininfo.flags>>XEN_DOMINF_shutdownshift) &
192 XEN_DOMINF_shutdownmask;
194 if ( info->shutdown && (info->shutdown_reason == SHUTDOWN_crash) )
195 {
196 info->shutdown = 0;
197 info->crashed = 1;
198 }
200 info->ssidref = domctl.u.getdomaininfo.ssidref;
201 info->nr_pages = domctl.u.getdomaininfo.tot_pages;
202 info->max_memkb = domctl.u.getdomaininfo.max_pages << (PAGE_SHIFT-10);
203 info->shared_info_frame = domctl.u.getdomaininfo.shared_info_frame;
204 info->cpu_time = domctl.u.getdomaininfo.cpu_time;
205 info->nr_online_vcpus = domctl.u.getdomaininfo.nr_online_vcpus;
206 info->max_vcpu_id = domctl.u.getdomaininfo.max_vcpu_id;
208 memcpy(info->handle, domctl.u.getdomaininfo.handle,
209 sizeof(xen_domain_handle_t));
211 next_domid = (uint16_t)domctl.domain + 1;
212 info++;
213 }
215 if ( nr_doms == 0 )
216 return rc;
218 return nr_doms;
219 }
221 int xc_domain_getinfolist(int xc_handle,
222 uint32_t first_domain,
223 unsigned int max_domains,
224 xc_domaininfo_t *info)
225 {
226 int ret = 0;
227 DECLARE_SYSCTL;
229 if ( lock_pages(info, max_domains*sizeof(xc_domaininfo_t)) != 0 )
230 return -1;
232 sysctl.cmd = XEN_SYSCTL_getdomaininfolist;
233 sysctl.u.getdomaininfolist.first_domain = first_domain;
234 sysctl.u.getdomaininfolist.max_domains = max_domains;
235 set_xen_guest_handle(sysctl.u.getdomaininfolist.buffer, info);
237 if ( xc_sysctl(xc_handle, &sysctl) < 0 )
238 ret = -1;
239 else
240 ret = sysctl.u.getdomaininfolist.num_domains;
242 unlock_pages(info, max_domains*sizeof(xc_domaininfo_t));
244 return ret;
245 }
247 /* get info from hvm guest for save */
248 int xc_domain_hvm_getcontext(int xc_handle,
249 uint32_t domid,
250 uint8_t *ctxt_buf,
251 uint32_t size)
252 {
253 int ret;
254 DECLARE_DOMCTL;
256 domctl.cmd = XEN_DOMCTL_gethvmcontext;
257 domctl.domain = (domid_t)domid;
258 domctl.u.hvmcontext.size = size;
259 set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf);
261 if ( ctxt_buf )
262 if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
263 return ret;
265 ret = do_domctl(xc_handle, &domctl);
267 if ( ctxt_buf )
268 unlock_pages(ctxt_buf, size);
270 return (ret < 0 ? -1 : domctl.u.hvmcontext.size);
271 }
273 /* set info to hvm guest for restore */
274 int xc_domain_hvm_setcontext(int xc_handle,
275 uint32_t domid,
276 uint8_t *ctxt_buf,
277 uint32_t size)
278 {
279 int ret;
280 DECLARE_DOMCTL;
282 domctl.cmd = XEN_DOMCTL_sethvmcontext;
283 domctl.domain = domid;
284 domctl.u.hvmcontext.size = size;
285 set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf);
287 if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
288 return ret;
290 ret = do_domctl(xc_handle, &domctl);
292 unlock_pages(ctxt_buf, size);
294 return ret;
295 }
297 int xc_vcpu_getcontext(int xc_handle,
298 uint32_t domid,
299 uint32_t vcpu,
300 vcpu_guest_context_t *ctxt)
301 {
302 int rc;
303 DECLARE_DOMCTL;
305 domctl.cmd = XEN_DOMCTL_getvcpucontext;
306 domctl.domain = (domid_t)domid;
307 domctl.u.vcpucontext.vcpu = (uint16_t)vcpu;
308 set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt);
310 if ( (rc = lock_pages(ctxt, sizeof(*ctxt))) != 0 )
311 return rc;
313 rc = do_domctl(xc_handle, &domctl);
315 unlock_pages(ctxt, sizeof(*ctxt));
317 return rc;
318 }
321 int xc_shadow_control(int xc_handle,
322 uint32_t domid,
323 unsigned int sop,
324 unsigned long *dirty_bitmap,
325 unsigned long pages,
326 unsigned long *mb,
327 uint32_t mode,
328 xc_shadow_op_stats_t *stats)
329 {
330 int rc;
331 DECLARE_DOMCTL;
332 domctl.cmd = XEN_DOMCTL_shadow_op;
333 domctl.domain = (domid_t)domid;
334 domctl.u.shadow_op.op = sop;
335 domctl.u.shadow_op.pages = pages;
336 domctl.u.shadow_op.mb = mb ? *mb : 0;
337 domctl.u.shadow_op.mode = mode;
338 set_xen_guest_handle(domctl.u.shadow_op.dirty_bitmap,
339 (uint8_t *)dirty_bitmap);
341 rc = do_domctl(xc_handle, &domctl);
343 if ( stats )
344 memcpy(stats, &domctl.u.shadow_op.stats,
345 sizeof(xc_shadow_op_stats_t));
347 if ( mb )
348 *mb = domctl.u.shadow_op.mb;
350 return (rc == 0) ? domctl.u.shadow_op.pages : rc;
351 }
353 int xc_domain_setcpuweight(int xc_handle,
354 uint32_t domid,
355 float weight)
356 {
357 int sched_id;
358 int ret;
360 /* Figure out which scheduler is currently used: */
361 if ( (ret = xc_sched_id(xc_handle, &sched_id)) != 0 )
362 return ret;
364 /* No-op. */
365 return 0;
366 }
368 int xc_domain_setmaxmem(int xc_handle,
369 uint32_t domid,
370 unsigned int max_memkb)
371 {
372 DECLARE_DOMCTL;
373 domctl.cmd = XEN_DOMCTL_max_mem;
374 domctl.domain = (domid_t)domid;
375 domctl.u.max_mem.max_memkb = max_memkb;
376 return do_domctl(xc_handle, &domctl);
377 }
379 int xc_domain_pin_memory_cacheattr(int xc_handle,
380 uint32_t domid,
381 unsigned long start,
382 unsigned long end,
383 unsigned int type)
384 {
385 DECLARE_DOMCTL;
386 domctl.cmd = XEN_DOMCTL_pin_mem_cacheattr;
387 domctl.domain = (domid_t)domid;
388 domctl.u.pin_mem_cacheattr.start = start;
389 domctl.u.pin_mem_cacheattr.end = end;
390 domctl.u.pin_mem_cacheattr.type = type;
391 return do_domctl(xc_handle, &domctl);
392 }
394 #if defined(__i386__) || defined(__x86_64__)
395 #include "xc_e820.h"
396 int xc_domain_set_memmap_limit(int xc_handle,
397 uint32_t domid,
398 unsigned long map_limitkb)
399 {
400 int rc;
402 struct xen_foreign_memory_map fmap = {
403 .domid = domid,
404 .map = { .nr_entries = 1 }
405 };
407 struct e820entry e820 = {
408 .addr = 0,
409 .size = (uint64_t)map_limitkb << 10,
410 .type = E820_RAM
411 };
413 set_xen_guest_handle(fmap.map.buffer, &e820);
415 if ( lock_pages(&fmap, sizeof(fmap)) || lock_pages(&e820, sizeof(e820)) )
416 {
417 PERROR("Could not lock memory for Xen hypercall");
418 rc = -1;
419 goto out;
420 }
422 rc = xc_memory_op(xc_handle, XENMEM_set_memory_map, &fmap);
424 out:
425 unlock_pages(&fmap, sizeof(fmap));
426 unlock_pages(&e820, sizeof(e820));
427 return rc;
428 }
429 #else
430 int xc_domain_set_memmap_limit(int xc_handle,
431 uint32_t domid,
432 unsigned long map_limitkb)
433 {
434 PERROR("Function not implemented");
435 errno = ENOSYS;
436 return -1;
437 }
438 #endif
440 int xc_domain_set_time_offset(int xc_handle,
441 uint32_t domid,
442 int32_t time_offset_seconds)
443 {
444 DECLARE_DOMCTL;
445 domctl.cmd = XEN_DOMCTL_settimeoffset;
446 domctl.domain = (domid_t)domid;
447 domctl.u.settimeoffset.time_offset_seconds = time_offset_seconds;
448 return do_domctl(xc_handle, &domctl);
449 }
451 int xc_domain_memory_increase_reservation(int xc_handle,
452 uint32_t domid,
453 unsigned long nr_extents,
454 unsigned int extent_order,
455 unsigned int address_bits,
456 xen_pfn_t *extent_start)
457 {
458 int err;
459 struct xen_memory_reservation reservation = {
460 .nr_extents = nr_extents,
461 .extent_order = extent_order,
462 .address_bits = address_bits,
463 .domid = domid
464 };
466 /* may be NULL */
467 set_xen_guest_handle(reservation.extent_start, extent_start);
469 err = xc_memory_op(xc_handle, XENMEM_increase_reservation, &reservation);
470 if ( err == nr_extents )
471 return 0;
473 if ( err >= 0 )
474 {
475 DPRINTF("Failed allocation for dom %d: "
476 "%ld extents of order %d, addr_bits %d\n",
477 domid, nr_extents, extent_order, address_bits);
478 errno = ENOMEM;
479 err = -1;
480 }
482 return err;
483 }
485 int xc_domain_memory_decrease_reservation(int xc_handle,
486 uint32_t domid,
487 unsigned long nr_extents,
488 unsigned int extent_order,
489 xen_pfn_t *extent_start)
490 {
491 int err;
492 struct xen_memory_reservation reservation = {
493 .nr_extents = nr_extents,
494 .extent_order = extent_order,
495 .address_bits = 0,
496 .domid = domid
497 };
499 set_xen_guest_handle(reservation.extent_start, extent_start);
501 if ( extent_start == NULL )
502 {
503 DPRINTF("decrease_reservation extent_start is NULL!\n");
504 errno = EINVAL;
505 return -1;
506 }
508 err = xc_memory_op(xc_handle, XENMEM_decrease_reservation, &reservation);
509 if ( err == nr_extents )
510 return 0;
512 if ( err >= 0 )
513 {
514 DPRINTF("Failed deallocation for dom %d: %ld extents of order %d\n",
515 domid, nr_extents, extent_order);
516 errno = EINVAL;
517 err = -1;
518 }
520 return err;
521 }
523 int xc_domain_memory_populate_physmap(int xc_handle,
524 uint32_t domid,
525 unsigned long nr_extents,
526 unsigned int extent_order,
527 unsigned int address_bits,
528 xen_pfn_t *extent_start)
529 {
530 int err;
531 struct xen_memory_reservation reservation = {
532 .nr_extents = nr_extents,
533 .extent_order = extent_order,
534 .address_bits = address_bits,
535 .domid = domid
536 };
537 set_xen_guest_handle(reservation.extent_start, extent_start);
539 err = xc_memory_op(xc_handle, XENMEM_populate_physmap, &reservation);
540 if ( err == nr_extents )
541 return 0;
543 if ( err >= 0 )
544 {
545 DPRINTF("Failed allocation for dom %d: %ld extents of order %d\n",
546 domid, nr_extents, extent_order);
547 errno = EBUSY;
548 err = -1;
549 }
551 return err;
552 }
554 int xc_domain_max_vcpus(int xc_handle, uint32_t domid, unsigned int max)
555 {
556 DECLARE_DOMCTL;
557 domctl.cmd = XEN_DOMCTL_max_vcpus;
558 domctl.domain = (domid_t)domid;
559 domctl.u.max_vcpus.max = max;
560 return do_domctl(xc_handle, &domctl);
561 }
563 int xc_domain_sethandle(int xc_handle, uint32_t domid,
564 xen_domain_handle_t handle)
565 {
566 DECLARE_DOMCTL;
567 domctl.cmd = XEN_DOMCTL_setdomainhandle;
568 domctl.domain = (domid_t)domid;
569 memcpy(domctl.u.setdomainhandle.handle, handle,
570 sizeof(xen_domain_handle_t));
571 return do_domctl(xc_handle, &domctl);
572 }
574 int xc_vcpu_getinfo(int xc_handle,
575 uint32_t domid,
576 uint32_t vcpu,
577 xc_vcpuinfo_t *info)
578 {
579 int rc;
580 DECLARE_DOMCTL;
582 domctl.cmd = XEN_DOMCTL_getvcpuinfo;
583 domctl.domain = (domid_t)domid;
584 domctl.u.getvcpuinfo.vcpu = (uint16_t)vcpu;
586 rc = do_domctl(xc_handle, &domctl);
588 memcpy(info, &domctl.u.getvcpuinfo, sizeof(*info));
590 return rc;
591 }
593 int xc_domain_ioport_permission(int xc_handle,
594 uint32_t domid,
595 uint32_t first_port,
596 uint32_t nr_ports,
597 uint32_t allow_access)
598 {
599 DECLARE_DOMCTL;
601 domctl.cmd = XEN_DOMCTL_ioport_permission;
602 domctl.domain = (domid_t)domid;
603 domctl.u.ioport_permission.first_port = first_port;
604 domctl.u.ioport_permission.nr_ports = nr_ports;
605 domctl.u.ioport_permission.allow_access = allow_access;
607 return do_domctl(xc_handle, &domctl);
608 }
610 int xc_availheap(int xc_handle,
611 int min_width,
612 int max_width,
613 int node,
614 uint64_t *bytes)
615 {
616 DECLARE_SYSCTL;
617 int rc;
619 sysctl.cmd = XEN_SYSCTL_availheap;
620 sysctl.u.availheap.min_bitwidth = min_width;
621 sysctl.u.availheap.max_bitwidth = max_width;
622 sysctl.u.availheap.node = node;
624 rc = xc_sysctl(xc_handle, &sysctl);
626 *bytes = sysctl.u.availheap.avail_bytes;
628 return rc;
629 }
631 int xc_vcpu_setcontext(int xc_handle,
632 uint32_t domid,
633 uint32_t vcpu,
634 vcpu_guest_context_t *ctxt)
635 {
636 DECLARE_DOMCTL;
637 int rc;
639 domctl.cmd = XEN_DOMCTL_setvcpucontext;
640 domctl.domain = domid;
641 domctl.u.vcpucontext.vcpu = vcpu;
642 set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt);
644 if ( (ctxt != NULL) && ((rc = lock_pages(ctxt, sizeof(*ctxt))) != 0) )
645 return rc;
647 rc = do_domctl(xc_handle, &domctl);
649 if ( ctxt != NULL )
650 unlock_pages(ctxt, sizeof(*ctxt));
652 return rc;
653 }
655 int xc_domain_irq_permission(int xc_handle,
656 uint32_t domid,
657 uint8_t pirq,
658 uint8_t allow_access)
659 {
660 DECLARE_DOMCTL;
662 domctl.cmd = XEN_DOMCTL_irq_permission;
663 domctl.domain = domid;
664 domctl.u.irq_permission.pirq = pirq;
665 domctl.u.irq_permission.allow_access = allow_access;
667 return do_domctl(xc_handle, &domctl);
668 }
670 int xc_domain_iomem_permission(int xc_handle,
671 uint32_t domid,
672 unsigned long first_mfn,
673 unsigned long nr_mfns,
674 uint8_t allow_access)
675 {
676 DECLARE_DOMCTL;
678 domctl.cmd = XEN_DOMCTL_iomem_permission;
679 domctl.domain = domid;
680 domctl.u.iomem_permission.first_mfn = first_mfn;
681 domctl.u.iomem_permission.nr_mfns = nr_mfns;
682 domctl.u.iomem_permission.allow_access = allow_access;
684 return do_domctl(xc_handle, &domctl);
685 }
687 int xc_domain_send_trigger(int xc_handle,
688 uint32_t domid,
689 uint32_t trigger,
690 uint32_t vcpu)
691 {
692 DECLARE_DOMCTL;
694 domctl.cmd = XEN_DOMCTL_sendtrigger;
695 domctl.domain = domid;
696 domctl.u.sendtrigger.trigger = trigger;
697 domctl.u.sendtrigger.vcpu = vcpu;
699 return do_domctl(xc_handle, &domctl);
700 }
702 int xc_set_hvm_param(int handle, domid_t dom, int param, unsigned long value)
703 {
704 DECLARE_HYPERCALL;
705 xen_hvm_param_t arg;
706 int rc;
708 hypercall.op = __HYPERVISOR_hvm_op;
709 hypercall.arg[0] = HVMOP_set_param;
710 hypercall.arg[1] = (unsigned long)&arg;
711 arg.domid = dom;
712 arg.index = param;
713 arg.value = value;
714 if ( lock_pages(&arg, sizeof(arg)) != 0 )
715 return -1;
716 rc = do_xen_hypercall(handle, &hypercall);
717 unlock_pages(&arg, sizeof(arg));
718 return rc;
719 }
721 int xc_get_hvm_param(int handle, domid_t dom, int param, unsigned long *value)
722 {
723 DECLARE_HYPERCALL;
724 xen_hvm_param_t arg;
725 int rc;
727 hypercall.op = __HYPERVISOR_hvm_op;
728 hypercall.arg[0] = HVMOP_get_param;
729 hypercall.arg[1] = (unsigned long)&arg;
730 arg.domid = dom;
731 arg.index = param;
732 if ( lock_pages(&arg, sizeof(arg)) != 0 )
733 return -1;
734 rc = do_xen_hypercall(handle, &hypercall);
735 unlock_pages(&arg, sizeof(arg));
736 *value = arg.value;
737 return rc;
738 }
740 int xc_domain_setdebugging(int xc_handle,
741 uint32_t domid,
742 unsigned int enable)
743 {
744 DECLARE_DOMCTL;
746 domctl.cmd = XEN_DOMCTL_setdebugging;
747 domctl.domain = domid;
748 domctl.u.setdebugging.enable = enable;
749 return do_domctl(xc_handle, &domctl);
750 }
752 int xc_assign_device(
753 int xc_handle,
754 uint32_t domid,
755 uint32_t machine_bdf)
756 {
757 DECLARE_DOMCTL;
759 domctl.cmd = XEN_DOMCTL_assign_device;
760 domctl.domain = domid;
761 domctl.u.assign_device.machine_bdf = machine_bdf;
763 return do_domctl(xc_handle, &domctl);
764 }
766 /* Pass-through: binds machine irq to guests irq */
767 int xc_domain_bind_pt_irq(
768 int xc_handle,
769 uint32_t domid,
770 uint8_t machine_irq,
771 uint8_t irq_type,
772 uint8_t bus,
773 uint8_t device,
774 uint8_t intx,
775 uint8_t isa_irq)
776 {
777 int rc;
778 xen_domctl_bind_pt_irq_t * bind;
779 DECLARE_DOMCTL;
781 domctl.cmd = XEN_DOMCTL_bind_pt_irq;
782 domctl.domain = (domid_t)domid;
784 bind = &(domctl.u.bind_pt_irq);
785 bind->hvm_domid = domid;
786 bind->irq_type = irq_type;
787 bind->machine_irq = machine_irq;
788 bind->u.pci.bus = bus;
789 bind->u.pci.device = device;
790 bind->u.pci.intx = intx;
791 bind->u.isa.isa_irq = isa_irq;
793 rc = do_domctl(xc_handle, &domctl);
794 return rc;
795 }
797 int xc_domain_bind_pt_pci_irq(
798 int xc_handle,
799 uint32_t domid,
800 uint8_t machine_irq,
801 uint8_t bus,
802 uint8_t device,
803 uint8_t intx)
804 {
806 return (xc_domain_bind_pt_irq(xc_handle, domid, machine_irq,
807 PT_IRQ_TYPE_PCI, bus, device, intx, 0));
808 }
810 int xc_domain_bind_pt_isa_irq(
811 int xc_handle,
812 uint32_t domid,
813 uint8_t machine_irq)
814 {
816 return (xc_domain_bind_pt_irq(xc_handle, domid, machine_irq,
817 PT_IRQ_TYPE_ISA, 0, 0, 0, machine_irq));
818 }
820 int xc_domain_memory_mapping(
821 int xc_handle,
822 uint32_t domid,
823 unsigned long first_gfn,
824 unsigned long first_mfn,
825 unsigned long nr_mfns,
826 uint32_t add_mapping)
827 {
828 DECLARE_DOMCTL;
830 domctl.cmd = XEN_DOMCTL_memory_mapping;
831 domctl.domain = domid;
832 domctl.u.memory_mapping.first_gfn = first_gfn;
833 domctl.u.memory_mapping.first_mfn = first_mfn;
834 domctl.u.memory_mapping.nr_mfns = nr_mfns;
835 domctl.u.memory_mapping.add_mapping = add_mapping;
837 return do_domctl(xc_handle, &domctl);
838 }
840 int xc_domain_ioport_mapping(
841 int xc_handle,
842 uint32_t domid,
843 uint32_t first_gport,
844 uint32_t first_mport,
845 uint32_t nr_ports,
846 uint32_t add_mapping)
847 {
848 DECLARE_DOMCTL;
850 domctl.cmd = XEN_DOMCTL_ioport_mapping;
851 domctl.domain = domid;
852 domctl.u.ioport_mapping.first_gport = first_gport;
853 domctl.u.ioport_mapping.first_mport = first_mport;
854 domctl.u.ioport_mapping.nr_ports = nr_ports;
855 domctl.u.ioport_mapping.add_mapping = add_mapping;
857 return do_domctl(xc_handle, &domctl);
858 }
860 /*
861 * Local variables:
862 * mode: C
863 * c-set-style: "BSD"
864 * c-basic-offset: 4
865 * tab-width: 4
866 * indent-tabs-mode: nil
867 * End:
868 */