direct-io.hg

view tools/libxc/xc_domain.c @ 10276:b3d901ba705d

Represent PFNs with their own type, rather than 'unsigned long'.
('long' changes size and alignment between 32- and 64-bit ABIs.)
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Jun 06 09:48:17 2006 +0100 (2006-06-06)
parents dfdc32a9814f
children f8af7041bf5b
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 *pdomid)
16 {
17 int err;
18 DECLARE_DOM0_OP;
20 op.cmd = DOM0_CREATEDOMAIN;
21 op.u.createdomain.domain = (domid_t)*pdomid;
22 op.u.createdomain.ssidref = ssidref;
23 memcpy(op.u.createdomain.handle, handle, sizeof(xen_domain_handle_t));
24 if ( (err = do_dom0_op(xc_handle, &op)) != 0 )
25 return err;
27 *pdomid = (uint16_t)op.u.createdomain.domain;
28 return 0;
29 }
32 int xc_domain_pause(int xc_handle,
33 uint32_t domid)
34 {
35 DECLARE_DOM0_OP;
36 op.cmd = DOM0_PAUSEDOMAIN;
37 op.u.pausedomain.domain = (domid_t)domid;
38 return do_dom0_op(xc_handle, &op);
39 }
42 int xc_domain_unpause(int xc_handle,
43 uint32_t domid)
44 {
45 DECLARE_DOM0_OP;
46 op.cmd = DOM0_UNPAUSEDOMAIN;
47 op.u.unpausedomain.domain = (domid_t)domid;
48 return do_dom0_op(xc_handle, &op);
49 }
52 int xc_domain_destroy(int xc_handle,
53 uint32_t domid)
54 {
55 DECLARE_DOM0_OP;
56 op.cmd = DOM0_DESTROYDOMAIN;
57 op.u.destroydomain.domain = (domid_t)domid;
58 return do_dom0_op(xc_handle, &op);
59 }
61 int xc_domain_shutdown(int xc_handle,
62 uint32_t domid,
63 int reason)
64 {
65 int ret = -1;
66 sched_remote_shutdown_t arg;
67 DECLARE_HYPERCALL;
69 hypercall.op = __HYPERVISOR_sched_op;
70 hypercall.arg[0] = (unsigned long)SCHEDOP_remote_shutdown;
71 hypercall.arg[1] = (unsigned long)&arg;
72 arg.domain_id = domid;
73 arg.reason = reason;
75 if ( mlock(&arg, sizeof(arg)) != 0 )
76 {
77 PERROR("Could not lock memory for Xen hypercall");
78 goto out1;
79 }
81 ret = do_xen_hypercall(xc_handle, &hypercall);
83 safe_munlock(&arg, sizeof(arg));
85 out1:
86 return ret;
87 }
90 int xc_vcpu_setaffinity(int xc_handle,
91 uint32_t domid,
92 int vcpu,
93 cpumap_t cpumap)
94 {
95 DECLARE_DOM0_OP;
96 op.cmd = DOM0_SETVCPUAFFINITY;
97 op.u.setvcpuaffinity.domain = (domid_t)domid;
98 op.u.setvcpuaffinity.vcpu = vcpu;
99 op.u.setvcpuaffinity.cpumap = cpumap;
100 return do_dom0_op(xc_handle, &op);
101 }
104 int xc_domain_getinfo(int xc_handle,
105 uint32_t first_domid,
106 unsigned int max_doms,
107 xc_dominfo_t *info)
108 {
109 unsigned int nr_doms;
110 uint32_t next_domid = first_domid;
111 DECLARE_DOM0_OP;
112 int rc = 0;
114 memset(info, 0, max_doms*sizeof(xc_dominfo_t));
116 for ( nr_doms = 0; nr_doms < max_doms; nr_doms++ )
117 {
118 op.cmd = DOM0_GETDOMAININFO;
119 op.u.getdomaininfo.domain = (domid_t)next_domid;
120 if ( (rc = do_dom0_op(xc_handle, &op)) < 0 )
121 break;
122 info->domid = (uint16_t)op.u.getdomaininfo.domain;
124 info->dying = !!(op.u.getdomaininfo.flags & DOMFLAGS_DYING);
125 info->shutdown = !!(op.u.getdomaininfo.flags & DOMFLAGS_SHUTDOWN);
126 info->paused = !!(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED);
127 info->blocked = !!(op.u.getdomaininfo.flags & DOMFLAGS_BLOCKED);
128 info->running = !!(op.u.getdomaininfo.flags & DOMFLAGS_RUNNING);
130 info->shutdown_reason =
131 (op.u.getdomaininfo.flags>>DOMFLAGS_SHUTDOWNSHIFT) &
132 DOMFLAGS_SHUTDOWNMASK;
134 if ( info->shutdown && (info->shutdown_reason == SHUTDOWN_crash) )
135 {
136 info->shutdown = 0;
137 info->crashed = 1;
138 }
140 info->ssidref = op.u.getdomaininfo.ssidref;
141 info->nr_pages = op.u.getdomaininfo.tot_pages;
142 info->max_memkb = op.u.getdomaininfo.max_pages << (PAGE_SHIFT - 10);
143 info->shared_info_frame = op.u.getdomaininfo.shared_info_frame;
144 info->cpu_time = op.u.getdomaininfo.cpu_time;
145 info->nr_online_vcpus = op.u.getdomaininfo.nr_online_vcpus;
146 info->max_vcpu_id = op.u.getdomaininfo.max_vcpu_id;
148 memcpy(info->handle, op.u.getdomaininfo.handle,
149 sizeof(xen_domain_handle_t));
151 next_domid = (uint16_t)op.u.getdomaininfo.domain + 1;
152 info++;
153 }
155 if( !nr_doms ) return rc;
157 return nr_doms;
158 }
160 int xc_domain_getinfolist(int xc_handle,
161 uint32_t first_domain,
162 unsigned int max_domains,
163 xc_domaininfo_t *info)
164 {
165 int ret = 0;
166 DECLARE_DOM0_OP;
168 if ( mlock(info, max_domains*sizeof(xc_domaininfo_t)) != 0 )
169 return -1;
171 op.cmd = DOM0_GETDOMAININFOLIST;
172 op.u.getdomaininfolist.first_domain = first_domain;
173 op.u.getdomaininfolist.max_domains = max_domains;
174 set_xen_guest_handle(op.u.getdomaininfolist.buffer, info);
176 if ( xc_dom0_op(xc_handle, &op) < 0 )
177 ret = -1;
178 else
179 ret = op.u.getdomaininfolist.num_domains;
181 if ( munlock(info, max_domains*sizeof(xc_domaininfo_t)) != 0 )
182 ret = -1;
184 return ret;
185 }
187 int xc_vcpu_getcontext(int xc_handle,
188 uint32_t domid,
189 uint32_t vcpu,
190 vcpu_guest_context_t *ctxt)
191 {
192 int rc;
193 DECLARE_DOM0_OP;
195 op.cmd = DOM0_GETVCPUCONTEXT;
196 op.u.getvcpucontext.domain = (domid_t)domid;
197 op.u.getvcpucontext.vcpu = (uint16_t)vcpu;
198 set_xen_guest_handle(op.u.getvcpucontext.ctxt, ctxt);
200 if ( (rc = mlock(ctxt, sizeof(*ctxt))) != 0 )
201 return rc;
203 rc = do_dom0_op(xc_handle, &op);
205 safe_munlock(ctxt, sizeof(*ctxt));
207 return rc;
208 }
211 int xc_shadow_control(int xc_handle,
212 uint32_t domid,
213 unsigned int sop,
214 unsigned long *dirty_bitmap,
215 unsigned long pages,
216 xc_shadow_control_stats_t *stats )
217 {
218 int rc;
219 DECLARE_DOM0_OP;
220 op.cmd = DOM0_SHADOW_CONTROL;
221 op.u.shadow_control.domain = (domid_t)domid;
222 op.u.shadow_control.op = sop;
223 set_xen_guest_handle(op.u.shadow_control.dirty_bitmap, dirty_bitmap);
224 op.u.shadow_control.pages = pages;
226 rc = do_dom0_op(xc_handle, &op);
228 if ( stats )
229 memcpy(stats, &op.u.shadow_control.stats,
230 sizeof(xc_shadow_control_stats_t));
232 return (rc == 0) ? op.u.shadow_control.pages : rc;
233 }
235 int xc_domain_setcpuweight(int xc_handle,
236 uint32_t domid,
237 float weight)
238 {
239 int sched_id;
240 int ret;
242 /* Figure out which scheduler is currently used: */
243 if ( (ret = xc_sched_id(xc_handle, &sched_id)) != 0 )
244 return ret;
246 switch ( sched_id )
247 {
248 case SCHED_BVT:
249 {
250 uint32_t mcuadv;
251 int warpback;
252 int32_t warpvalue;
253 long long warpl;
254 long long warpu;
256 /* Preserve all the scheduling parameters apart
257 of MCU advance. */
258 if ( (ret = xc_bvtsched_domain_get(
259 xc_handle, domid, &mcuadv,
260 &warpback, &warpvalue, &warpl, &warpu)) != 0 )
261 return ret;
263 /* The MCU advance is inverse of the weight.
264 Default value of the weight is 1, default mcuadv 10.
265 The scaling factor is therefore 10. */
266 if ( weight > 0 )
267 mcuadv = 10 / weight;
269 ret = xc_bvtsched_domain_set(xc_handle, domid, mcuadv,
270 warpback, warpvalue, warpl, warpu);
271 break;
272 }
273 }
275 return ret;
276 }
278 int xc_domain_setmaxmem(int xc_handle,
279 uint32_t domid,
280 unsigned int max_memkb)
281 {
282 DECLARE_DOM0_OP;
283 op.cmd = DOM0_SETDOMAINMAXMEM;
284 op.u.setdomainmaxmem.domain = (domid_t)domid;
285 op.u.setdomainmaxmem.max_memkb = max_memkb;
286 return do_dom0_op(xc_handle, &op);
287 }
289 int xc_domain_memory_increase_reservation(int xc_handle,
290 uint32_t domid,
291 unsigned long nr_extents,
292 unsigned int extent_order,
293 unsigned int address_bits,
294 xen_pfn_t *extent_start)
295 {
296 int err;
297 struct xen_memory_reservation reservation = {
298 .nr_extents = nr_extents,
299 .extent_order = extent_order,
300 .address_bits = address_bits,
301 .domid = domid
302 };
304 /* may be NULL */
305 set_xen_guest_handle(reservation.extent_start, extent_start);
307 err = xc_memory_op(xc_handle, XENMEM_increase_reservation, &reservation);
308 if ( err == nr_extents )
309 return 0;
311 if ( err > 0 )
312 {
313 fprintf(stderr, "Failed allocation for dom %d: "
314 "%ld pages order %d addr_bits %d\n",
315 domid, nr_extents, extent_order, address_bits);
316 errno = ENOMEM;
317 err = -1;
318 }
320 return err;
321 }
323 int xc_domain_memory_decrease_reservation(int xc_handle,
324 uint32_t domid,
325 unsigned long nr_extents,
326 unsigned int extent_order,
327 xen_pfn_t *extent_start)
328 {
329 int err;
330 struct xen_memory_reservation reservation = {
331 .nr_extents = nr_extents,
332 .extent_order = extent_order,
333 .address_bits = 0,
334 .domid = domid
335 };
337 set_xen_guest_handle(reservation.extent_start, extent_start);
339 if ( extent_start == NULL )
340 {
341 fprintf(stderr,"decrease_reservation extent_start is NULL!\n");
342 errno = EINVAL;
343 return -1;
344 }
346 err = xc_memory_op(xc_handle, XENMEM_decrease_reservation, &reservation);
347 if ( err == nr_extents )
348 return 0;
350 if ( err > 0 )
351 {
352 fprintf(stderr,"Failed deallocation for dom %d: %ld pages order %d\n",
353 domid, nr_extents, extent_order);
354 errno = EBUSY;
355 err = -1;
356 }
358 return err;
359 }
361 int xc_domain_memory_populate_physmap(int xc_handle,
362 uint32_t domid,
363 unsigned long nr_extents,
364 unsigned int extent_order,
365 unsigned int address_bits,
366 xen_pfn_t *extent_start)
367 {
368 int err;
369 struct xen_memory_reservation reservation = {
370 .nr_extents = nr_extents,
371 .extent_order = extent_order,
372 .address_bits = address_bits,
373 .domid = domid
374 };
375 set_xen_guest_handle(reservation.extent_start, extent_start);
377 err = xc_memory_op(xc_handle, XENMEM_populate_physmap, &reservation);
378 if ( err == nr_extents )
379 return 0;
381 if ( err > 0 )
382 {
383 fprintf(stderr,"Failed deallocation for dom %d: %ld pages order %d\n",
384 domid, nr_extents, extent_order);
385 errno = EBUSY;
386 err = -1;
387 }
389 return err;
390 }
392 int xc_domain_translate_gpfn_list(int xc_handle,
393 uint32_t domid,
394 unsigned long nr_gpfns,
395 xen_pfn_t *gpfn_list,
396 xen_pfn_t *mfn_list)
397 {
398 struct xen_translate_gpfn_list op = {
399 .domid = domid,
400 .nr_gpfns = nr_gpfns,
401 };
402 set_xen_guest_handle(op.gpfn_list, gpfn_list);
403 set_xen_guest_handle(op.mfn_list, mfn_list);
405 return xc_memory_op(xc_handle, XENMEM_translate_gpfn_list, &op);
406 }
408 int xc_domain_max_vcpus(int xc_handle, uint32_t domid, unsigned int max)
409 {
410 DECLARE_DOM0_OP;
411 op.cmd = DOM0_MAX_VCPUS;
412 op.u.max_vcpus.domain = (domid_t)domid;
413 op.u.max_vcpus.max = max;
414 return do_dom0_op(xc_handle, &op);
415 }
417 int xc_domain_sethandle(int xc_handle, uint32_t domid,
418 xen_domain_handle_t handle)
419 {
420 DECLARE_DOM0_OP;
421 op.cmd = DOM0_SETDOMAINHANDLE;
422 op.u.setdomainhandle.domain = (domid_t)domid;
423 memcpy(op.u.setdomainhandle.handle, handle, sizeof(xen_domain_handle_t));
424 return do_dom0_op(xc_handle, &op);
425 }
427 int xc_vcpu_getinfo(int xc_handle,
428 uint32_t domid,
429 uint32_t vcpu,
430 xc_vcpuinfo_t *info)
431 {
432 int rc;
433 DECLARE_DOM0_OP;
434 op.cmd = DOM0_GETVCPUINFO;
435 op.u.getvcpuinfo.domain = (domid_t)domid;
436 op.u.getvcpuinfo.vcpu = (uint16_t)vcpu;
438 rc = do_dom0_op(xc_handle, &op);
440 memcpy(info, &op.u.getvcpuinfo, sizeof(*info));
442 return rc;
443 }
445 int xc_domain_ioport_permission(int xc_handle,
446 uint32_t domid,
447 uint32_t first_port,
448 uint32_t nr_ports,
449 uint32_t allow_access)
450 {
451 DECLARE_DOM0_OP;
453 op.cmd = DOM0_IOPORT_PERMISSION;
454 op.u.ioport_permission.domain = (domid_t)domid;
455 op.u.ioport_permission.first_port = first_port;
456 op.u.ioport_permission.nr_ports = nr_ports;
457 op.u.ioport_permission.allow_access = allow_access;
459 return do_dom0_op(xc_handle, &op);
460 }
462 int xc_vcpu_setcontext(int xc_handle,
463 uint32_t domid,
464 uint32_t vcpu,
465 vcpu_guest_context_t *ctxt)
466 {
467 dom0_op_t op;
468 int rc;
470 op.cmd = DOM0_SETVCPUCONTEXT;
471 op.u.setvcpucontext.domain = domid;
472 op.u.setvcpucontext.vcpu = vcpu;
473 set_xen_guest_handle(op.u.setvcpucontext.ctxt, ctxt);
475 if ( (rc = mlock(ctxt, sizeof(*ctxt))) != 0 )
476 return rc;
478 rc = do_dom0_op(xc_handle, &op);
480 safe_munlock(ctxt, sizeof(*ctxt));
482 return rc;
484 }
486 int xc_domain_irq_permission(int xc_handle,
487 uint32_t domid,
488 uint8_t pirq,
489 uint8_t allow_access)
490 {
491 dom0_op_t op;
493 op.cmd = DOM0_IRQ_PERMISSION;
494 op.u.irq_permission.domain = domid;
495 op.u.irq_permission.pirq = pirq;
496 op.u.irq_permission.allow_access = allow_access;
498 return do_dom0_op(xc_handle, &op);
499 }
501 int xc_domain_iomem_permission(int xc_handle,
502 uint32_t domid,
503 unsigned long first_mfn,
504 unsigned long nr_mfns,
505 uint8_t allow_access)
506 {
507 dom0_op_t op;
509 op.cmd = DOM0_IOMEM_PERMISSION;
510 op.u.iomem_permission.domain = domid;
511 op.u.iomem_permission.first_mfn = first_mfn;
512 op.u.iomem_permission.nr_mfns = nr_mfns;
513 op.u.iomem_permission.allow_access = allow_access;
515 return do_dom0_op(xc_handle, &op);
516 }
518 /*
519 * Local variables:
520 * mode: C
521 * c-set-style: "BSD"
522 * c-basic-offset: 4
523 * tab-width: 4
524 * indent-tabs-mode: nil
525 * End:
526 */