debuggers.hg

view tools/python/xen/lowlevel/xc/xc.c @ 16630:ef83b50fc4a4

vt-d: Test device assignability in xend, but defer actual assignment to qemu-dm.
Signed-off-by: Weidong Han <weidong.han@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Dec 12 10:29:35 2007 +0000 (2007-12-12)
parents f9ca1d8c9e65
children cff4c8a1aa28
line source
1 /******************************************************************************
2 * Xc.c
3 *
4 * Copyright (c) 2003-2004, K A Fraser (University of Cambridge)
5 */
7 #include <Python.h>
8 #include <xenctrl.h>
9 #include <xenguest.h>
10 #include <zlib.h>
11 #include <fcntl.h>
12 #include <netinet/in.h>
13 #include <netinet/tcp.h>
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <sys/mman.h>
17 #include <netdb.h>
18 #include <arpa/inet.h>
20 #include "xenctrl.h"
21 #include <xen/elfnote.h>
22 #include "xc_dom.h"
23 #include <xen/hvm/hvm_info_table.h>
24 #include <xen/hvm/params.h>
26 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
28 /* Needed for Python versions earlier than 2.3. */
29 #ifndef PyMODINIT_FUNC
30 #define PyMODINIT_FUNC DL_EXPORT(void)
31 #endif
33 #define PKG "xen.lowlevel.xc"
34 #define CLS "xc"
36 static PyObject *xc_error_obj, *zero;
38 typedef struct {
39 PyObject_HEAD;
40 int xc_handle;
41 } XcObject;
44 static PyObject *dom_op(XcObject *self, PyObject *args,
45 int (*fn)(int, uint32_t));
47 static PyObject *pyxc_error_to_exception(void)
48 {
49 PyObject *pyerr;
50 const xc_error *err = xc_get_last_error();
51 const char *desc = xc_error_code_to_desc(err->code);
53 if ( err->code == XC_ERROR_NONE )
54 return PyErr_SetFromErrno(xc_error_obj);
56 if ( err->message[0] != '\0' )
57 pyerr = Py_BuildValue("(iss)", err->code, desc, err->message);
58 else
59 pyerr = Py_BuildValue("(is)", err->code, desc);
61 xc_clear_last_error();
63 if ( pyerr != NULL )
64 {
65 PyErr_SetObject(xc_error_obj, pyerr);
66 Py_DECREF(pyerr);
67 }
69 return NULL;
70 }
72 static PyObject *pyxc_domain_dumpcore(XcObject *self, PyObject *args)
73 {
74 uint32_t dom;
75 char *corefile;
77 if ( !PyArg_ParseTuple(args, "is", &dom, &corefile) )
78 return NULL;
80 if ( (corefile == NULL) || (corefile[0] == '\0') )
81 return NULL;
83 if ( xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0 )
84 return pyxc_error_to_exception();
86 Py_INCREF(zero);
87 return zero;
88 }
90 static PyObject *pyxc_handle(XcObject *self)
91 {
92 return PyInt_FromLong(self->xc_handle);
93 }
95 static PyObject *pyxc_domain_create(XcObject *self,
96 PyObject *args,
97 PyObject *kwds)
98 {
99 uint32_t dom = 0, ssidref = 0, flags = 0;
100 int ret, i, hvm = 0;
101 PyObject *pyhandle = NULL;
102 xen_domain_handle_t handle = {
103 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
104 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef };
106 static char *kwd_list[] = { "domid", "ssidref", "handle", "hvm", NULL };
108 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiOi", kwd_list,
109 &dom, &ssidref, &pyhandle, &hvm))
110 return NULL;
112 if ( pyhandle != NULL )
113 {
114 if ( !PyList_Check(pyhandle) ||
115 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
116 goto out_exception;
118 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
119 {
120 PyObject *p = PyList_GetItem(pyhandle, i);
121 if ( !PyInt_Check(p) )
122 goto out_exception;
123 handle[i] = (uint8_t)PyInt_AsLong(p);
124 }
125 }
127 if ( hvm )
128 flags |= XEN_DOMCTL_CDF_hvm_guest;
130 if ( (ret = xc_domain_create(self->xc_handle, ssidref,
131 handle, flags, &dom)) < 0 )
132 return pyxc_error_to_exception();
134 return PyInt_FromLong(dom);
136 out_exception:
137 errno = EINVAL;
138 PyErr_SetFromErrno(xc_error_obj);
139 return NULL;
140 }
142 static PyObject *pyxc_domain_max_vcpus(XcObject *self, PyObject *args)
143 {
144 uint32_t dom, max;
146 if (!PyArg_ParseTuple(args, "ii", &dom, &max))
147 return NULL;
149 if (xc_domain_max_vcpus(self->xc_handle, dom, max) != 0)
150 return pyxc_error_to_exception();
152 Py_INCREF(zero);
153 return zero;
154 }
156 static PyObject *pyxc_domain_pause(XcObject *self, PyObject *args)
157 {
158 return dom_op(self, args, xc_domain_pause);
159 }
161 static PyObject *pyxc_domain_unpause(XcObject *self, PyObject *args)
162 {
163 return dom_op(self, args, xc_domain_unpause);
164 }
166 static PyObject *pyxc_domain_destroy_hook(XcObject *self, PyObject *args)
167 {
168 #ifdef __ia64__
169 dom_op(self, args, xc_ia64_save_to_nvram);
170 #endif
172 Py_INCREF(zero);
173 return zero;
174 }
176 static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args)
177 {
178 return dom_op(self, args, xc_domain_destroy);
179 }
181 static PyObject *pyxc_domain_shutdown(XcObject *self, PyObject *args)
182 {
183 uint32_t dom, reason;
185 if ( !PyArg_ParseTuple(args, "ii", &dom, &reason) )
186 return NULL;
188 if ( xc_domain_shutdown(self->xc_handle, dom, reason) != 0 )
189 return pyxc_error_to_exception();
191 Py_INCREF(zero);
192 return zero;
193 }
195 static PyObject *pyxc_domain_resume(XcObject *self, PyObject *args)
196 {
197 uint32_t dom;
198 int fast;
200 if ( !PyArg_ParseTuple(args, "ii", &dom, &fast) )
201 return NULL;
203 if ( xc_domain_resume(self->xc_handle, dom, fast) != 0 )
204 return pyxc_error_to_exception();
206 Py_INCREF(zero);
207 return zero;
208 }
210 static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
211 PyObject *args,
212 PyObject *kwds)
213 {
214 uint32_t dom;
215 int vcpu = 0, i;
216 uint64_t cpumap = ~0ULL;
217 PyObject *cpulist = NULL;
219 static char *kwd_list[] = { "domid", "vcpu", "cpumap", NULL };
221 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|iO", kwd_list,
222 &dom, &vcpu, &cpulist) )
223 return NULL;
225 if ( (cpulist != NULL) && PyList_Check(cpulist) )
226 {
227 cpumap = 0ULL;
228 for ( i = 0; i < PyList_Size(cpulist); i++ )
229 cpumap |= (uint64_t)1 << PyInt_AsLong(PyList_GetItem(cpulist, i));
230 }
232 if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 )
233 return pyxc_error_to_exception();
235 Py_INCREF(zero);
236 return zero;
237 }
239 static PyObject *pyxc_domain_setcpuweight(XcObject *self,
240 PyObject *args,
241 PyObject *kwds)
242 {
243 uint32_t dom;
244 float cpuweight = 1;
246 static char *kwd_list[] = { "domid", "cpuweight", NULL };
248 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|f", kwd_list,
249 &dom, &cpuweight) )
250 return NULL;
252 if ( xc_domain_setcpuweight(self->xc_handle, dom, cpuweight) != 0 )
253 return pyxc_error_to_exception();
255 Py_INCREF(zero);
256 return zero;
257 }
259 static PyObject *pyxc_domain_sethandle(XcObject *self, PyObject *args)
260 {
261 int i;
262 uint32_t dom;
263 PyObject *pyhandle;
264 xen_domain_handle_t handle;
266 if (!PyArg_ParseTuple(args, "iO", &dom, &pyhandle))
267 return NULL;
269 if ( !PyList_Check(pyhandle) ||
270 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
271 {
272 goto out_exception;
273 }
275 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
276 {
277 PyObject *p = PyList_GetItem(pyhandle, i);
278 if ( !PyInt_Check(p) )
279 goto out_exception;
280 handle[i] = (uint8_t)PyInt_AsLong(p);
281 }
283 if (xc_domain_sethandle(self->xc_handle, dom, handle) < 0)
284 return pyxc_error_to_exception();
286 Py_INCREF(zero);
287 return zero;
289 out_exception:
290 PyErr_SetFromErrno(xc_error_obj);
291 return NULL;
292 }
295 static PyObject *pyxc_domain_getinfo(XcObject *self,
296 PyObject *args,
297 PyObject *kwds)
298 {
299 PyObject *list, *info_dict, *pyhandle;
301 uint32_t first_dom = 0;
302 int max_doms = 1024, nr_doms, i, j;
303 xc_dominfo_t *info;
305 static char *kwd_list[] = { "first_dom", "max_doms", NULL };
307 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
308 &first_dom, &max_doms) )
309 return NULL;
311 if ( (info = malloc(max_doms * sizeof(xc_dominfo_t))) == NULL )
312 return PyErr_NoMemory();
314 nr_doms = xc_domain_getinfo(self->xc_handle, first_dom, max_doms, info);
316 if (nr_doms < 0)
317 {
318 free(info);
319 return pyxc_error_to_exception();
320 }
322 list = PyList_New(nr_doms);
323 for ( i = 0 ; i < nr_doms; i++ )
324 {
325 info_dict = Py_BuildValue(
326 "{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
327 ",s:L,s:L,s:L,s:i,s:i}",
328 "domid", (int)info[i].domid,
329 "online_vcpus", info[i].nr_online_vcpus,
330 "max_vcpu_id", info[i].max_vcpu_id,
331 "hvm", info[i].hvm,
332 "dying", info[i].dying,
333 "crashed", info[i].crashed,
334 "shutdown", info[i].shutdown,
335 "paused", info[i].paused,
336 "blocked", info[i].blocked,
337 "running", info[i].running,
338 "mem_kb", (long long)info[i].nr_pages*(XC_PAGE_SIZE/1024),
339 "cpu_time", (long long)info[i].cpu_time,
340 "maxmem_kb", (long long)info[i].max_memkb,
341 "ssidref", (int)info[i].ssidref,
342 "shutdown_reason", info[i].shutdown_reason);
343 pyhandle = PyList_New(sizeof(xen_domain_handle_t));
344 if ( (pyhandle == NULL) || (info_dict == NULL) )
345 {
346 Py_DECREF(list);
347 if ( pyhandle != NULL ) { Py_DECREF(pyhandle); }
348 if ( info_dict != NULL ) { Py_DECREF(info_dict); }
349 free(info);
350 return NULL;
351 }
352 for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
353 PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
354 PyDict_SetItemString(info_dict, "handle", pyhandle);
355 Py_DECREF(pyhandle);
356 PyList_SetItem(list, i, info_dict);
357 }
359 free(info);
361 return list;
362 }
364 static PyObject *pyxc_vcpu_getinfo(XcObject *self,
365 PyObject *args,
366 PyObject *kwds)
367 {
368 PyObject *info_dict, *cpulist;
370 uint32_t dom, vcpu = 0;
371 xc_vcpuinfo_t info;
372 int rc, i;
373 uint64_t cpumap;
375 static char *kwd_list[] = { "domid", "vcpu", NULL };
377 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
378 &dom, &vcpu) )
379 return NULL;
381 rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info);
382 if ( rc < 0 )
383 return pyxc_error_to_exception();
384 rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, &cpumap);
385 if ( rc < 0 )
386 return pyxc_error_to_exception();
388 info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}",
389 "online", info.online,
390 "blocked", info.blocked,
391 "running", info.running,
392 "cpu_time", info.cpu_time,
393 "cpu", info.cpu);
395 cpulist = PyList_New(0);
396 for ( i = 0; cpumap != 0; i++ )
397 {
398 if ( cpumap & 1 )
399 PyList_Append(cpulist, PyInt_FromLong(i));
400 cpumap >>= 1;
401 }
402 PyDict_SetItemString(info_dict, "cpumap", cpulist);
403 Py_DECREF(cpulist);
404 return info_dict;
405 }
407 static PyObject *pyxc_linux_build(XcObject *self,
408 PyObject *args,
409 PyObject *kwds)
410 {
411 uint32_t domid;
412 struct xc_dom_image *dom;
413 char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
414 int flags = 0;
415 int store_evtchn, console_evtchn;
416 int vhpt = 0;
417 unsigned int mem_mb;
418 unsigned long store_mfn = 0;
419 unsigned long console_mfn = 0;
420 PyObject* elfnote_dict;
421 PyObject* elfnote = NULL;
422 PyObject* ret;
423 int i;
425 static char *kwd_list[] = { "domid", "store_evtchn", "memsize",
426 "console_evtchn", "image",
427 /* optional */
428 "ramdisk", "cmdline", "flags",
429 "features", "vhpt", NULL };
431 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssisi", kwd_list,
432 &domid, &store_evtchn, &mem_mb,
433 &console_evtchn, &image,
434 /* optional */
435 &ramdisk, &cmdline, &flags,
436 &features, &vhpt) )
437 return NULL;
439 xc_dom_loginit();
440 if (!(dom = xc_dom_allocate(cmdline, features)))
441 return pyxc_error_to_exception();
443 /* for IA64 */
444 dom->vhpt_size_log2 = vhpt;
446 if ( xc_dom_linux_build(self->xc_handle, dom, domid, mem_mb, image,
447 ramdisk, flags, store_evtchn, &store_mfn,
448 console_evtchn, &console_mfn) != 0 ) {
449 goto out;
450 }
452 if ( !(elfnote_dict = PyDict_New()) )
453 goto out;
455 for ( i = 0; i < ARRAY_SIZE(dom->parms.elf_notes); i++ )
456 {
457 switch ( dom->parms.elf_notes[i].type )
458 {
459 case XEN_ENT_NONE:
460 continue;
461 case XEN_ENT_LONG:
462 elfnote = Py_BuildValue("k", dom->parms.elf_notes[i].data.num);
463 break;
464 case XEN_ENT_STR:
465 elfnote = Py_BuildValue("s", dom->parms.elf_notes[i].data.str);
466 break;
467 }
468 PyDict_SetItemString(elfnote_dict,
469 dom->parms.elf_notes[i].name,
470 elfnote);
471 Py_DECREF(elfnote);
472 }
474 ret = Py_BuildValue("{s:i,s:i,s:N}",
475 "store_mfn", store_mfn,
476 "console_mfn", console_mfn,
477 "notes", elfnote_dict);
479 if ( dom->arch_hooks->native_protocol )
480 {
481 PyObject *native_protocol =
482 Py_BuildValue("s", dom->arch_hooks->native_protocol);
483 PyDict_SetItemString(ret, "native_protocol", native_protocol);
484 Py_DECREF(native_protocol);
485 }
487 xc_dom_release(dom);
489 return ret;
491 out:
492 xc_dom_release(dom);
493 return pyxc_error_to_exception();
494 }
496 static PyObject *pyxc_get_hvm_param(XcObject *self,
497 PyObject *args,
498 PyObject *kwds)
499 {
500 uint32_t dom;
501 int param;
502 unsigned long value;
504 static char *kwd_list[] = { "domid", "param", NULL };
505 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
506 &dom, &param) )
507 return NULL;
509 if ( xc_get_hvm_param(self->xc_handle, dom, param, &value) != 0 )
510 return pyxc_error_to_exception();
512 return PyLong_FromUnsignedLong(value);
514 }
516 static PyObject *pyxc_set_hvm_param(XcObject *self,
517 PyObject *args,
518 PyObject *kwds)
519 {
520 uint32_t dom;
521 int param;
522 uint64_t value;
524 static char *kwd_list[] = { "domid", "param", "value", NULL };
525 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiL", kwd_list,
526 &dom, &param, &value) )
527 return NULL;
529 if ( xc_set_hvm_param(self->xc_handle, dom, param, value) != 0 )
530 return pyxc_error_to_exception();
532 Py_INCREF(zero);
533 return zero;
534 }
536 static int token_value(char *token)
537 {
538 token = strchr(token, 'x') + 1;
539 return strtol(token, NULL, 16);
540 }
542 static int next_bdf(char **str, int *seg, int *bus, int *dev, int *func)
543 {
544 char *token;
546 if ( !(*str) || !strchr(*str, ',') )
547 return 0;
549 token = *str;
550 *seg = token_value(token);
551 token = strchr(token, ',') + 1;
552 *bus = token_value(token);
553 token = strchr(token, ',') + 1;
554 *dev = token_value(token);
555 token = strchr(token, ',') + 1;
556 *func = token_value(token);
557 token = strchr(token, ',');
558 *str = token ? token + 1 : NULL;
560 return 1;
561 }
563 static PyObject *pyxc_test_assign_device(XcObject *self,
564 PyObject *args,
565 PyObject *kwds)
566 {
567 uint32_t dom;
568 char *pci_str;
569 uint32_t bdf = 0;
570 int seg, bus, dev, func;
572 static char *kwd_list[] = { "domid", "pci", NULL };
573 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is", kwd_list,
574 &dom, &pci_str) )
575 return NULL;
577 while ( next_bdf(&pci_str, &seg, &bus, &dev, &func) )
578 {
579 bdf |= (bus & 0xff) << 16;
580 bdf |= (dev & 0x1f) << 11;
581 bdf |= (func & 0x7) << 8;
583 if ( xc_test_assign_device(self->xc_handle, dom, bdf) != 0 )
584 break;
586 bdf = 0;
587 }
589 return Py_BuildValue("i", bdf);
590 }
592 #ifdef __ia64__
593 static PyObject *pyxc_nvram_init(XcObject *self,
594 PyObject *args)
595 {
596 char *dom_name;
597 uint32_t dom;
599 if ( !PyArg_ParseTuple(args, "si", &dom_name, &dom) )
600 return NULL;
602 xc_ia64_nvram_init(self->xc_handle, dom_name, dom);
604 Py_INCREF(zero);
605 return zero;
606 }
608 static PyObject *pyxc_set_os_type(XcObject *self,
609 PyObject *args)
610 {
611 char *os_type;
612 uint32_t dom;
614 if ( !PyArg_ParseTuple(args, "si", &os_type, &dom) )
615 return NULL;
617 xc_ia64_set_os_type(self->xc_handle, os_type, dom);
619 Py_INCREF(zero);
620 return zero;
621 }
622 #endif /* __ia64__ */
624 static PyObject *pyxc_hvm_build(XcObject *self,
625 PyObject *args,
626 PyObject *kwds)
627 {
628 uint32_t dom;
629 #if !defined(__ia64__)
630 struct hvm_info_table *va_hvm;
631 uint8_t *va_map, sum;
632 int i;
633 #endif
634 char *image;
635 int memsize, vcpus = 1, acpi = 0, apic = 1;
637 static char *kwd_list[] = { "domid",
638 "memsize", "image", "vcpus", "acpi",
639 "apic", NULL };
640 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iii", kwd_list,
641 &dom, &memsize,
642 &image, &vcpus, &acpi, &apic) )
643 return NULL;
645 if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
646 return pyxc_error_to_exception();
648 #if !defined(__ia64__)
649 /* Set up the HVM info table. */
650 va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE,
651 PROT_READ | PROT_WRITE,
652 HVM_INFO_PFN);
653 if ( va_map == NULL )
654 return PyErr_SetFromErrno(xc_error_obj);
655 va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
656 memset(va_hvm, 0, sizeof(*va_hvm));
657 strncpy(va_hvm->signature, "HVM INFO", 8);
658 va_hvm->length = sizeof(struct hvm_info_table);
659 va_hvm->acpi_enabled = acpi;
660 va_hvm->apic_mode = apic;
661 va_hvm->nr_vcpus = vcpus;
662 for ( i = 0, sum = 0; i < va_hvm->length; i++ )
663 sum += ((uint8_t *)va_hvm)[i];
664 va_hvm->checksum = -sum;
665 munmap(va_map, XC_PAGE_SIZE);
666 #endif
668 return Py_BuildValue("{}");
669 }
671 static PyObject *pyxc_evtchn_alloc_unbound(XcObject *self,
672 PyObject *args,
673 PyObject *kwds)
674 {
675 uint32_t dom, remote_dom;
676 int port;
678 static char *kwd_list[] = { "domid", "remote_dom", NULL };
680 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
681 &dom, &remote_dom) )
682 return NULL;
684 if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom)) < 0 )
685 return pyxc_error_to_exception();
687 return PyInt_FromLong(port);
688 }
690 static PyObject *pyxc_evtchn_reset(XcObject *self,
691 PyObject *args,
692 PyObject *kwds)
693 {
694 uint32_t dom;
696 static char *kwd_list[] = { "dom", NULL };
698 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
699 return NULL;
701 if ( xc_evtchn_reset(self->xc_handle, dom) < 0 )
702 return pyxc_error_to_exception();
704 Py_INCREF(zero);
705 return zero;
706 }
708 static PyObject *pyxc_physdev_pci_access_modify(XcObject *self,
709 PyObject *args,
710 PyObject *kwds)
711 {
712 uint32_t dom;
713 int bus, dev, func, enable, ret;
715 static char *kwd_list[] = { "domid", "bus", "dev", "func", "enable", NULL };
717 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiii", kwd_list,
718 &dom, &bus, &dev, &func, &enable) )
719 return NULL;
721 ret = xc_physdev_pci_access_modify(
722 self->xc_handle, dom, bus, dev, func, enable);
723 if ( ret != 0 )
724 return pyxc_error_to_exception();
726 Py_INCREF(zero);
727 return zero;
728 }
730 static PyObject *pyxc_readconsolering(XcObject *self,
731 PyObject *args,
732 PyObject *kwds)
733 {
734 unsigned int clear = 0, index = 0, incremental = 0;
735 char _str[32768], *str = _str;
736 unsigned int count = 32768;
737 int ret;
739 static char *kwd_list[] = { "clear", "index", "incremental", NULL };
741 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iii", kwd_list,
742 &clear, &index, &incremental) )
743 return NULL;
745 ret = xc_readconsolering(self->xc_handle, &str, &count, clear,
746 incremental, &index);
747 if ( ret < 0 )
748 return pyxc_error_to_exception();
750 return PyString_FromStringAndSize(str, count);
751 }
754 static unsigned long pages_to_kib(unsigned long pages)
755 {
756 return pages * (XC_PAGE_SIZE / 1024);
757 }
760 static PyObject *pyxc_pages_to_kib(XcObject *self, PyObject *args)
761 {
762 unsigned long pages;
764 if (!PyArg_ParseTuple(args, "l", &pages))
765 return NULL;
767 return PyLong_FromUnsignedLong(pages_to_kib(pages));
768 }
771 static PyObject *pyxc_physinfo(XcObject *self)
772 {
773 #define MAX_CPU_ID 255
774 xc_physinfo_t info;
775 char cpu_cap[128], *p=cpu_cap, *q=cpu_cap;
776 int i, j, max_cpu_id;
777 PyObject *ret_obj, *node_to_cpu_obj;
778 xc_cpu_to_node_t map[MAX_CPU_ID + 1];
780 set_xen_guest_handle(info.cpu_to_node, map);
781 info.max_cpu_id = MAX_CPU_ID;
783 if ( xc_physinfo(self->xc_handle, &info) != 0 )
784 return pyxc_error_to_exception();
786 *q = 0;
787 for ( i = 0; i < sizeof(info.hw_cap)/4; i++ )
788 {
789 p += sprintf(p, "%08x:", info.hw_cap[i]);
790 if ( info.hw_cap[i] )
791 q = p;
792 }
793 if ( q > cpu_cap )
794 *(q-1) = 0;
796 ret_obj = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:l,s:l,s:l,s:i,s:s}",
797 "nr_nodes", info.nr_nodes,
798 "max_cpu_id", info.max_cpu_id,
799 "threads_per_core", info.threads_per_core,
800 "cores_per_socket", info.cores_per_socket,
801 "nr_cpus", info.nr_cpus,
802 "total_memory", pages_to_kib(info.total_pages),
803 "free_memory", pages_to_kib(info.free_pages),
804 "scrub_memory", pages_to_kib(info.scrub_pages),
805 "cpu_khz", info.cpu_khz,
806 "hw_caps", cpu_cap);
808 max_cpu_id = info.max_cpu_id;
809 if ( max_cpu_id > MAX_CPU_ID )
810 max_cpu_id = MAX_CPU_ID;
812 /* Construct node-to-cpu lists. */
813 node_to_cpu_obj = PyList_New(0);
815 /* Make a list for each node. */
816 for ( i = 0; i < info.nr_nodes; i++ )
817 {
818 PyObject *cpus = PyList_New(0);
819 for ( j = 0; j <= max_cpu_id; j++ )
820 if ( i == map[j])
821 PyList_Append(cpus, PyInt_FromLong(j));
822 PyList_Append(node_to_cpu_obj, cpus);
823 }
825 PyDict_SetItemString(ret_obj, "node_to_cpu", node_to_cpu_obj);
827 return ret_obj;
828 #undef MAX_CPU_ID
829 }
831 static PyObject *pyxc_xeninfo(XcObject *self)
832 {
833 xen_extraversion_t xen_extra;
834 xen_compile_info_t xen_cc;
835 xen_changeset_info_t xen_chgset;
836 xen_capabilities_info_t xen_caps;
837 xen_platform_parameters_t p_parms;
838 long xen_version;
839 long xen_pagesize;
840 char str[128];
842 xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
844 if ( xc_version(self->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
845 return pyxc_error_to_exception();
847 if ( xc_version(self->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
848 return pyxc_error_to_exception();
850 if ( xc_version(self->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
851 return pyxc_error_to_exception();
853 if ( xc_version(self->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
854 return pyxc_error_to_exception();
856 if ( xc_version(self->xc_handle, XENVER_platform_parameters, &p_parms) != 0 )
857 return pyxc_error_to_exception();
859 sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
861 xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
862 if (xen_pagesize < 0 )
863 return pyxc_error_to_exception();
865 return Py_BuildValue("{s:i,s:i,s:s,s:s,s:i,s:s,s:s,s:s,s:s,s:s,s:s}",
866 "xen_major", xen_version >> 16,
867 "xen_minor", (xen_version & 0xffff),
868 "xen_extra", xen_extra,
869 "xen_caps", xen_caps,
870 "xen_pagesize", xen_pagesize,
871 "platform_params", str,
872 "xen_changeset", xen_chgset,
873 "cc_compiler", xen_cc.compiler,
874 "cc_compile_by", xen_cc.compile_by,
875 "cc_compile_domain", xen_cc.compile_domain,
876 "cc_compile_date", xen_cc.compile_date);
877 }
880 static PyObject *pyxc_sedf_domain_set(XcObject *self,
881 PyObject *args,
882 PyObject *kwds)
883 {
884 uint32_t domid;
885 uint64_t period, slice, latency;
886 uint16_t extratime, weight;
887 static char *kwd_list[] = { "domid", "period", "slice",
888 "latency", "extratime", "weight",NULL };
890 if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLhh", kwd_list,
891 &domid, &period, &slice,
892 &latency, &extratime, &weight) )
893 return NULL;
894 if ( xc_sedf_domain_set(self->xc_handle, domid, period,
895 slice, latency, extratime,weight) != 0 )
896 return pyxc_error_to_exception();
898 Py_INCREF(zero);
899 return zero;
900 }
902 static PyObject *pyxc_sedf_domain_get(XcObject *self, PyObject *args)
903 {
904 uint32_t domid;
905 uint64_t period, slice,latency;
906 uint16_t weight, extratime;
908 if(!PyArg_ParseTuple(args, "i", &domid))
909 return NULL;
911 if (xc_sedf_domain_get(self->xc_handle, domid, &period,
912 &slice,&latency,&extratime,&weight))
913 return pyxc_error_to_exception();
915 return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
916 "domid", domid,
917 "period", period,
918 "slice", slice,
919 "latency", latency,
920 "extratime", extratime,
921 "weight", weight);
922 }
924 static PyObject *pyxc_shadow_control(PyObject *self,
925 PyObject *args,
926 PyObject *kwds)
927 {
928 XcObject *xc = (XcObject *)self;
930 uint32_t dom;
931 int op=0;
933 static char *kwd_list[] = { "dom", "op", NULL };
935 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
936 &dom, &op) )
937 return NULL;
939 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL, 0, NULL)
940 < 0 )
941 return pyxc_error_to_exception();
943 Py_INCREF(zero);
944 return zero;
945 }
947 static PyObject *pyxc_shadow_mem_control(PyObject *self,
948 PyObject *args,
949 PyObject *kwds)
950 {
951 XcObject *xc = (XcObject *)self;
952 int op;
953 uint32_t dom;
954 int mbarg = -1;
955 unsigned long mb;
957 static char *kwd_list[] = { "dom", "mb", NULL };
959 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
960 &dom, &mbarg) )
961 return NULL;
963 if ( mbarg < 0 )
964 op = XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION;
965 else
966 {
967 mb = mbarg;
968 op = XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION;
969 }
970 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, &mb, 0, NULL) < 0 )
971 return pyxc_error_to_exception();
973 mbarg = mb;
974 return Py_BuildValue("i", mbarg);
975 }
977 static PyObject *pyxc_sched_id_get(XcObject *self) {
979 int sched_id;
980 if (xc_sched_id(self->xc_handle, &sched_id) != 0)
981 return PyErr_SetFromErrno(xc_error_obj);
983 return Py_BuildValue("i", sched_id);
984 }
986 static PyObject *pyxc_sched_credit_domain_set(XcObject *self,
987 PyObject *args,
988 PyObject *kwds)
989 {
990 uint32_t domid;
991 uint16_t weight;
992 uint16_t cap;
993 static char *kwd_list[] = { "domid", "weight", "cap", NULL };
994 static char kwd_type[] = "I|HH";
995 struct xen_domctl_sched_credit sdom;
997 weight = 0;
998 cap = (uint16_t)~0U;
999 if( !PyArg_ParseTupleAndKeywords(args, kwds, kwd_type, kwd_list,
1000 &domid, &weight, &cap) )
1001 return NULL;
1003 sdom.weight = weight;
1004 sdom.cap = cap;
1006 if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 )
1007 return pyxc_error_to_exception();
1009 Py_INCREF(zero);
1010 return zero;
1013 static PyObject *pyxc_sched_credit_domain_get(XcObject *self, PyObject *args)
1015 uint32_t domid;
1016 struct xen_domctl_sched_credit sdom;
1018 if( !PyArg_ParseTuple(args, "I", &domid) )
1019 return NULL;
1021 if ( xc_sched_credit_domain_get(self->xc_handle, domid, &sdom) != 0 )
1022 return pyxc_error_to_exception();
1024 return Py_BuildValue("{s:H,s:H}",
1025 "weight", sdom.weight,
1026 "cap", sdom.cap);
1029 static PyObject *pyxc_domain_setmaxmem(XcObject *self, PyObject *args)
1031 uint32_t dom;
1032 unsigned int maxmem_kb;
1034 if (!PyArg_ParseTuple(args, "ii", &dom, &maxmem_kb))
1035 return NULL;
1037 if (xc_domain_setmaxmem(self->xc_handle, dom, maxmem_kb) != 0)
1038 return pyxc_error_to_exception();
1040 Py_INCREF(zero);
1041 return zero;
1044 static PyObject *pyxc_domain_set_memmap_limit(XcObject *self, PyObject *args)
1046 uint32_t dom;
1047 unsigned int maplimit_kb;
1049 if ( !PyArg_ParseTuple(args, "ii", &dom, &maplimit_kb) )
1050 return NULL;
1052 if ( xc_domain_set_memmap_limit(self->xc_handle, dom, maplimit_kb) != 0 )
1053 return pyxc_error_to_exception();
1055 Py_INCREF(zero);
1056 return zero;
1059 static PyObject *pyxc_domain_memory_increase_reservation(XcObject *self,
1060 PyObject *args,
1061 PyObject *kwds)
1063 uint32_t dom;
1064 unsigned long mem_kb;
1065 unsigned int extent_order = 0 , address_bits = 0;
1066 unsigned long nr_extents;
1068 static char *kwd_list[] = { "domid", "mem_kb", "extent_order", "address_bits", NULL };
1070 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "il|ii", kwd_list,
1071 &dom, &mem_kb, &extent_order, &address_bits) )
1072 return NULL;
1074 /* round down to nearest power of 2. Assume callers using extent_order>0
1075 know what they are doing */
1076 nr_extents = (mem_kb / (XC_PAGE_SIZE/1024)) >> extent_order;
1077 if ( xc_domain_memory_increase_reservation(self->xc_handle, dom,
1078 nr_extents, extent_order,
1079 address_bits, NULL) )
1080 return pyxc_error_to_exception();
1082 Py_INCREF(zero);
1083 return zero;
1086 static PyObject *pyxc_domain_ioport_permission(XcObject *self,
1087 PyObject *args,
1088 PyObject *kwds)
1090 uint32_t dom;
1091 int first_port, nr_ports, allow_access, ret;
1093 static char *kwd_list[] = { "domid", "first_port", "nr_ports", "allow_access", NULL };
1095 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiii", kwd_list,
1096 &dom, &first_port, &nr_ports, &allow_access) )
1097 return NULL;
1099 ret = xc_domain_ioport_permission(
1100 self->xc_handle, dom, first_port, nr_ports, allow_access);
1101 if ( ret != 0 )
1102 return pyxc_error_to_exception();
1104 Py_INCREF(zero);
1105 return zero;
1108 static PyObject *pyxc_domain_irq_permission(PyObject *self,
1109 PyObject *args,
1110 PyObject *kwds)
1112 XcObject *xc = (XcObject *)self;
1113 uint32_t dom;
1114 int pirq, allow_access, ret;
1116 static char *kwd_list[] = { "domid", "pirq", "allow_access", NULL };
1118 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list,
1119 &dom, &pirq, &allow_access) )
1120 return NULL;
1122 ret = xc_domain_irq_permission(
1123 xc->xc_handle, dom, pirq, allow_access);
1124 if ( ret != 0 )
1125 return pyxc_error_to_exception();
1127 Py_INCREF(zero);
1128 return zero;
1131 static PyObject *pyxc_domain_iomem_permission(PyObject *self,
1132 PyObject *args,
1133 PyObject *kwds)
1135 XcObject *xc = (XcObject *)self;
1136 uint32_t dom;
1137 unsigned long first_pfn, nr_pfns, allow_access, ret;
1139 static char *kwd_list[] = { "domid", "first_pfn", "nr_pfns", "allow_access", NULL };
1141 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illi", kwd_list,
1142 &dom, &first_pfn, &nr_pfns, &allow_access) )
1143 return NULL;
1145 ret = xc_domain_iomem_permission(
1146 xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
1147 if ( ret != 0 )
1148 return pyxc_error_to_exception();
1150 Py_INCREF(zero);
1151 return zero;
1154 static PyObject *pyxc_domain_set_time_offset(XcObject *self, PyObject *args)
1156 uint32_t dom;
1157 int32_t time_offset_seconds;
1158 time_t calendar_time;
1159 struct tm local_time;
1160 struct tm utc_time;
1162 if (!PyArg_ParseTuple(args, "i", &dom))
1163 return NULL;
1165 calendar_time = time(NULL);
1166 localtime_r(&calendar_time, &local_time);
1167 gmtime_r(&calendar_time, &utc_time);
1168 /* set up to get calendar time based on utc_time, with local dst setting */
1169 utc_time.tm_isdst = local_time.tm_isdst;
1170 time_offset_seconds = (int32_t)difftime(calendar_time, mktime(&utc_time));
1172 if (xc_domain_set_time_offset(self->xc_handle, dom, time_offset_seconds) != 0)
1173 return NULL;
1175 Py_INCREF(zero);
1176 return zero;
1179 static PyObject *pyxc_domain_send_trigger(XcObject *self,
1180 PyObject *args,
1181 PyObject *kwds)
1183 uint32_t dom;
1184 int trigger, vcpu = 0;
1186 static char *kwd_list[] = { "domid", "trigger", "vcpu", NULL };
1188 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii|i", kwd_list,
1189 &dom, &trigger, &vcpu) )
1190 return NULL;
1192 if (xc_domain_send_trigger(self->xc_handle, dom, trigger, vcpu) != 0)
1193 return pyxc_error_to_exception();
1195 Py_INCREF(zero);
1196 return zero;
1199 static PyObject *pyxc_send_debug_keys(XcObject *self,
1200 PyObject *args,
1201 PyObject *kwds)
1203 char *keys;
1205 static char *kwd_list[] = { "keys", NULL };
1207 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list, &keys) )
1208 return NULL;
1210 if ( xc_send_debug_keys(self->xc_handle, keys) != 0 )
1211 return pyxc_error_to_exception();
1213 Py_INCREF(zero);
1214 return zero;
1217 static PyObject *dom_op(XcObject *self, PyObject *args,
1218 int (*fn)(int, uint32_t))
1220 uint32_t dom;
1222 if (!PyArg_ParseTuple(args, "i", &dom))
1223 return NULL;
1225 if (fn(self->xc_handle, dom) != 0)
1226 return pyxc_error_to_exception();
1228 Py_INCREF(zero);
1229 return zero;
1232 #ifdef __powerpc__
1233 static PyObject *pyxc_alloc_real_mode_area(XcObject *self,
1234 PyObject *args,
1235 PyObject *kwds)
1237 uint32_t dom;
1238 unsigned int log;
1240 static char *kwd_list[] = { "dom", "log", NULL };
1242 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
1243 &dom, &log) )
1244 return NULL;
1246 if ( xc_alloc_real_mode_area(self->xc_handle, dom, log) )
1247 return pyxc_error_to_exception();
1249 Py_INCREF(zero);
1250 return zero;
1252 #endif /* powerpc */
1254 static PyMethodDef pyxc_methods[] = {
1255 { "handle",
1256 (PyCFunction)pyxc_handle,
1257 METH_NOARGS, "\n"
1258 "Query the xc control interface file descriptor.\n\n"
1259 "Returns: [int] file descriptor\n" },
1261 { "domain_create",
1262 (PyCFunction)pyxc_domain_create,
1263 METH_VARARGS | METH_KEYWORDS, "\n"
1264 "Create a new domain.\n"
1265 " dom [int, 0]: Domain identifier to use (allocated if zero).\n"
1266 "Returns: [int] new domain identifier; -1 on error.\n" },
1268 { "domain_max_vcpus",
1269 (PyCFunction)pyxc_domain_max_vcpus,
1270 METH_VARARGS, "\n"
1271 "Set the maximum number of VCPUs a domain may create.\n"
1272 " dom [int, 0]: Domain identifier to use.\n"
1273 " max [int, 0]: New maximum number of VCPUs in domain.\n"
1274 "Returns: [int] 0 on success; -1 on error.\n" },
1276 { "domain_dumpcore",
1277 (PyCFunction)pyxc_domain_dumpcore,
1278 METH_VARARGS, "\n"
1279 "Dump core of a domain.\n"
1280 " dom [int]: Identifier of domain to dump core of.\n"
1281 " corefile [string]: Name of corefile to be created.\n\n"
1282 "Returns: [int] 0 on success; -1 on error.\n" },
1284 { "domain_pause",
1285 (PyCFunction)pyxc_domain_pause,
1286 METH_VARARGS, "\n"
1287 "Temporarily pause execution of a domain.\n"
1288 " dom [int]: Identifier of domain to be paused.\n\n"
1289 "Returns: [int] 0 on success; -1 on error.\n" },
1291 { "domain_unpause",
1292 (PyCFunction)pyxc_domain_unpause,
1293 METH_VARARGS, "\n"
1294 "(Re)start execution of a domain.\n"
1295 " dom [int]: Identifier of domain to be unpaused.\n\n"
1296 "Returns: [int] 0 on success; -1 on error.\n" },
1298 { "domain_destroy",
1299 (PyCFunction)pyxc_domain_destroy,
1300 METH_VARARGS, "\n"
1301 "Destroy a domain.\n"
1302 " dom [int]: Identifier of domain to be destroyed.\n\n"
1303 "Returns: [int] 0 on success; -1 on error.\n" },
1305 { "domain_destroy_hook",
1306 (PyCFunction)pyxc_domain_destroy_hook,
1307 METH_VARARGS, "\n"
1308 "Add a hook for arch stuff before destroy a domain.\n"
1309 " dom [int]: Identifier of domain to be destroyed.\n\n"
1310 "Returns: [int] 0 on success; -1 on error.\n" },
1312 { "domain_resume",
1313 (PyCFunction)pyxc_domain_resume,
1314 METH_VARARGS, "\n"
1315 "Resume execution of a suspended domain.\n"
1316 " dom [int]: Identifier of domain to be resumed.\n"
1317 " fast [int]: Use cooperative resume.\n\n"
1318 "Returns: [int] 0 on success; -1 on error.\n" },
1320 { "domain_shutdown",
1321 (PyCFunction)pyxc_domain_shutdown,
1322 METH_VARARGS, "\n"
1323 "Shutdown a domain.\n"
1324 " dom [int, 0]: Domain identifier to use.\n"
1325 " reason [int, 0]: Reason for shutdown.\n"
1326 "Returns: [int] 0 on success; -1 on error.\n" },
1328 { "vcpu_setaffinity",
1329 (PyCFunction)pyxc_vcpu_setaffinity,
1330 METH_VARARGS | METH_KEYWORDS, "\n"
1331 "Pin a VCPU to a specified set CPUs.\n"
1332 " dom [int]: Identifier of domain to which VCPU belongs.\n"
1333 " vcpu [int, 0]: VCPU being pinned.\n"
1334 " cpumap [list, []]: list of usable CPUs.\n\n"
1335 "Returns: [int] 0 on success; -1 on error.\n" },
1337 { "domain_setcpuweight",
1338 (PyCFunction)pyxc_domain_setcpuweight,
1339 METH_VARARGS | METH_KEYWORDS, "\n"
1340 "Set cpuweight scheduler parameter for domain.\n"
1341 " dom [int]: Identifier of domain to be changed.\n"
1342 " cpuweight [float, 1]: VCPU being pinned.\n"
1343 "Returns: [int] 0 on success; -1 on error.\n" },
1345 { "domain_sethandle",
1346 (PyCFunction)pyxc_domain_sethandle,
1347 METH_VARARGS, "\n"
1348 "Set domain's opaque handle.\n"
1349 " dom [int]: Identifier of domain.\n"
1350 " handle [list of 16 ints]: New opaque handle.\n"
1351 "Returns: [int] 0 on success; -1 on error.\n" },
1353 { "domain_getinfo",
1354 (PyCFunction)pyxc_domain_getinfo,
1355 METH_VARARGS | METH_KEYWORDS, "\n"
1356 "Get information regarding a set of domains, in increasing id order.\n"
1357 " first_dom [int, 0]: First domain to retrieve info about.\n"
1358 " max_doms [int, 1024]: Maximum number of domains to retrieve info"
1359 " about.\n\n"
1360 "Returns: [list of dicts] if list length is less than 'max_doms'\n"
1361 " parameter then there was an error, or the end of the\n"
1362 " domain-id space was reached.\n"
1363 " dom [int]: Identifier of domain to which this info pertains\n"
1364 " cpu [int]: CPU to which this domain is bound\n"
1365 " vcpus [int]: Number of Virtual CPUS in this domain\n"
1366 " dying [int]: Bool - is the domain dying?\n"
1367 " crashed [int]: Bool - has the domain crashed?\n"
1368 " shutdown [int]: Bool - has the domain shut itself down?\n"
1369 " paused [int]: Bool - is the domain paused by control software?\n"
1370 " blocked [int]: Bool - is the domain blocked waiting for an event?\n"
1371 " running [int]: Bool - is the domain currently running?\n"
1372 " mem_kb [int]: Memory reservation, in kilobytes\n"
1373 " maxmem_kb [int]: Maximum memory limit, in kilobytes\n"
1374 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1375 " shutdown_reason [int]: Numeric code from guest OS, explaining "
1376 "reason why it shut itself down.\n" },
1378 { "vcpu_getinfo",
1379 (PyCFunction)pyxc_vcpu_getinfo,
1380 METH_VARARGS | METH_KEYWORDS, "\n"
1381 "Get information regarding a VCPU.\n"
1382 " dom [int]: Domain to retrieve info about.\n"
1383 " vcpu [int, 0]: VCPU to retrieve info about.\n\n"
1384 "Returns: [dict]\n"
1385 " online [int]: Bool - Is this VCPU currently online?\n"
1386 " blocked [int]: Bool - Is this VCPU blocked waiting for an event?\n"
1387 " running [int]: Bool - Is this VCPU currently running on a CPU?\n"
1388 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1389 " cpumap [int]: Bitmap of CPUs this VCPU can run on\n"
1390 " cpu [int]: CPU that this VCPU is currently bound to\n" },
1392 { "linux_build",
1393 (PyCFunction)pyxc_linux_build,
1394 METH_VARARGS | METH_KEYWORDS, "\n"
1395 "Build a new Linux guest OS.\n"
1396 " dom [int]: Identifier of domain to build into.\n"
1397 " image [str]: Name of kernel image file. May be gzipped.\n"
1398 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
1399 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
1400 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1401 "Returns: [int] 0 on success; -1 on error.\n" },
1403 { "hvm_build",
1404 (PyCFunction)pyxc_hvm_build,
1405 METH_VARARGS | METH_KEYWORDS, "\n"
1406 "Build a new HVM guest OS.\n"
1407 " dom [int]: Identifier of domain to build into.\n"
1408 " image [str]: Name of HVM loader image file.\n"
1409 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1410 "Returns: [int] 0 on success; -1 on error.\n" },
1412 { "hvm_get_param",
1413 (PyCFunction)pyxc_get_hvm_param,
1414 METH_VARARGS | METH_KEYWORDS, "\n"
1415 "get a parameter of HVM guest OS.\n"
1416 " dom [int]: Identifier of domain to build into.\n"
1417 " param [int]: No. of HVM param.\n"
1418 "Returns: [long] value of the param.\n" },
1420 { "hvm_set_param",
1421 (PyCFunction)pyxc_set_hvm_param,
1422 METH_VARARGS | METH_KEYWORDS, "\n"
1423 "set a parameter of HVM guest OS.\n"
1424 " dom [int]: Identifier of domain to build into.\n"
1425 " param [int]: No. of HVM param.\n"
1426 " value [long]: Value of param.\n"
1427 "Returns: [int] 0 on success.\n" },
1429 { "test_assign_device",
1430 (PyCFunction)pyxc_test_assign_device,
1431 METH_VARARGS | METH_KEYWORDS, "\n"
1432 "test device assignment with VT-d.\n"
1433 " dom [int]: Identifier of domain to build into.\n"
1434 " pci_str [str]: PCI devices.\n"
1435 "Returns: [int] 0 on success, or device bdf that can't be assigned.\n" },
1437 { "sched_id_get",
1438 (PyCFunction)pyxc_sched_id_get,
1439 METH_NOARGS, "\n"
1440 "Get the current scheduler type in use.\n"
1441 "Returns: [int] sched_id.\n" },
1443 { "sedf_domain_set",
1444 (PyCFunction)pyxc_sedf_domain_set,
1445 METH_KEYWORDS, "\n"
1446 "Set the scheduling parameters for a domain when running with Atropos.\n"
1447 " dom [int]: domain to set\n"
1448 " period [long]: domain's scheduling period\n"
1449 " slice [long]: domain's slice per period\n"
1450 " latency [long]: domain's wakeup latency hint\n"
1451 " extratime [int]: domain aware of extratime?\n"
1452 "Returns: [int] 0 on success; -1 on error.\n" },
1454 { "sedf_domain_get",
1455 (PyCFunction)pyxc_sedf_domain_get,
1456 METH_VARARGS, "\n"
1457 "Get the current scheduling parameters for a domain when running with\n"
1458 "the Atropos scheduler."
1459 " dom [int]: domain to query\n"
1460 "Returns: [dict]\n"
1461 " domain [int]: domain ID\n"
1462 " period [long]: scheduler period\n"
1463 " slice [long]: CPU reservation per period\n"
1464 " latency [long]: domain's wakeup latency hint\n"
1465 " extratime [int]: domain aware of extratime?\n"},
1467 { "sched_credit_domain_set",
1468 (PyCFunction)pyxc_sched_credit_domain_set,
1469 METH_KEYWORDS, "\n"
1470 "Set the scheduling parameters for a domain when running with the\n"
1471 "SMP credit scheduler.\n"
1472 " domid [int]: domain id to set\n"
1473 " weight [short]: domain's scheduling weight\n"
1474 "Returns: [int] 0 on success; -1 on error.\n" },
1476 { "sched_credit_domain_get",
1477 (PyCFunction)pyxc_sched_credit_domain_get,
1478 METH_VARARGS, "\n"
1479 "Get the scheduling parameters for a domain when running with the\n"
1480 "SMP credit scheduler.\n"
1481 " domid [int]: domain id to get\n"
1482 "Returns: [dict]\n"
1483 " weight [short]: domain's scheduling weight\n"},
1485 { "evtchn_alloc_unbound",
1486 (PyCFunction)pyxc_evtchn_alloc_unbound,
1487 METH_VARARGS | METH_KEYWORDS, "\n"
1488 "Allocate an unbound port that will await a remote connection.\n"
1489 " dom [int]: Domain whose port space to allocate from.\n"
1490 " remote_dom [int]: Remote domain to accept connections from.\n\n"
1491 "Returns: [int] Unbound event-channel port.\n" },
1493 { "evtchn_reset",
1494 (PyCFunction)pyxc_evtchn_reset,
1495 METH_VARARGS | METH_KEYWORDS, "\n"
1496 "Reset all connections.\n"
1497 " dom [int]: Domain to reset.\n" },
1499 { "physdev_pci_access_modify",
1500 (PyCFunction)pyxc_physdev_pci_access_modify,
1501 METH_VARARGS | METH_KEYWORDS, "\n"
1502 "Allow a domain access to a PCI device\n"
1503 " dom [int]: Identifier of domain to be allowed access.\n"
1504 " bus [int]: PCI bus\n"
1505 " dev [int]: PCI slot\n"
1506 " func [int]: PCI function\n"
1507 " enable [int]: Non-zero means enable access; else disable access\n\n"
1508 "Returns: [int] 0 on success; -1 on error.\n" },
1510 { "readconsolering",
1511 (PyCFunction)pyxc_readconsolering,
1512 METH_VARARGS | METH_KEYWORDS, "\n"
1513 "Read Xen's console ring.\n"
1514 " clear [int, 0]: Bool - clear the ring after reading from it?\n\n"
1515 "Returns: [str] string is empty on failure.\n" },
1517 { "physinfo",
1518 (PyCFunction)pyxc_physinfo,
1519 METH_NOARGS, "\n"
1520 "Get information about the physical host machine\n"
1521 "Returns [dict]: information about the hardware"
1522 " [None]: on failure.\n" },
1524 { "xeninfo",
1525 (PyCFunction)pyxc_xeninfo,
1526 METH_NOARGS, "\n"
1527 "Get information about the Xen host\n"
1528 "Returns [dict]: information about Xen"
1529 " [None]: on failure.\n" },
1531 { "shadow_control",
1532 (PyCFunction)pyxc_shadow_control,
1533 METH_VARARGS | METH_KEYWORDS, "\n"
1534 "Set parameter for shadow pagetable interface\n"
1535 " dom [int]: Identifier of domain.\n"
1536 " op [int, 0]: operation\n\n"
1537 "Returns: [int] 0 on success; -1 on error.\n" },
1539 { "shadow_mem_control",
1540 (PyCFunction)pyxc_shadow_mem_control,
1541 METH_VARARGS | METH_KEYWORDS, "\n"
1542 "Set or read shadow pagetable memory use\n"
1543 " dom [int]: Identifier of domain.\n"
1544 " mb [int, -1]: MB of shadow memory this domain should have.\n\n"
1545 "Returns: [int] MB of shadow memory in use by this domain.\n" },
1547 { "domain_setmaxmem",
1548 (PyCFunction)pyxc_domain_setmaxmem,
1549 METH_VARARGS, "\n"
1550 "Set a domain's memory limit\n"
1551 " dom [int]: Identifier of domain.\n"
1552 " maxmem_kb [int]: .\n"
1553 "Returns: [int] 0 on success; -1 on error.\n" },
1555 { "domain_set_memmap_limit",
1556 (PyCFunction)pyxc_domain_set_memmap_limit,
1557 METH_VARARGS, "\n"
1558 "Set a domain's physical memory mappping limit\n"
1559 " dom [int]: Identifier of domain.\n"
1560 " map_limitkb [int]: .\n"
1561 "Returns: [int] 0 on success; -1 on error.\n" },
1563 { "domain_memory_increase_reservation",
1564 (PyCFunction)pyxc_domain_memory_increase_reservation,
1565 METH_VARARGS | METH_KEYWORDS, "\n"
1566 "Increase a domain's memory reservation\n"
1567 " dom [int]: Identifier of domain.\n"
1568 " mem_kb [long]: .\n"
1569 "Returns: [int] 0 on success; -1 on error.\n" },
1570 #ifdef __ia64__
1571 { "nvram_init",
1572 (PyCFunction)pyxc_nvram_init,
1573 METH_VARARGS, "\n"
1574 "Init nvram in IA64 platform\n"
1575 "Returns: [int] 0 on success; -1 on error.\n" },
1576 { "set_os_type",
1577 (PyCFunction)pyxc_set_os_type,
1578 METH_VARARGS, "\n"
1579 "Set guest OS type on IA64 platform\n"
1580 "Returns: [int] 0 on success; -1 on error.\n" },
1581 #endif /* __ia64__ */
1582 { "domain_ioport_permission",
1583 (PyCFunction)pyxc_domain_ioport_permission,
1584 METH_VARARGS | METH_KEYWORDS, "\n"
1585 "Allow a domain access to a range of IO ports\n"
1586 " dom [int]: Identifier of domain to be allowed access.\n"
1587 " first_port [int]: First IO port\n"
1588 " nr_ports [int]: Number of IO ports\n"
1589 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1590 "Returns: [int] 0 on success; -1 on error.\n" },
1592 { "domain_irq_permission",
1593 (PyCFunction)pyxc_domain_irq_permission,
1594 METH_VARARGS | METH_KEYWORDS, "\n"
1595 "Allow a domain access to a physical IRQ\n"
1596 " dom [int]: Identifier of domain to be allowed access.\n"
1597 " pirq [int]: The Physical IRQ\n"
1598 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1599 "Returns: [int] 0 on success; -1 on error.\n" },
1601 { "domain_iomem_permission",
1602 (PyCFunction)pyxc_domain_iomem_permission,
1603 METH_VARARGS | METH_KEYWORDS, "\n"
1604 "Allow a domain access to a range of IO memory pages\n"
1605 " dom [int]: Identifier of domain to be allowed access.\n"
1606 " first_pfn [long]: First page of I/O Memory\n"
1607 " nr_pfns [long]: Number of pages of I/O Memory (>0)\n"
1608 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1609 "Returns: [int] 0 on success; -1 on error.\n" },
1611 { "pages_to_kib",
1612 (PyCFunction)pyxc_pages_to_kib,
1613 METH_VARARGS, "\n"
1614 "Returns: [int]: The size in KiB of memory spanning the given number "
1615 "of pages.\n" },
1617 { "domain_set_time_offset",
1618 (PyCFunction)pyxc_domain_set_time_offset,
1619 METH_VARARGS, "\n"
1620 "Set a domain's time offset to Dom0's localtime\n"
1621 " dom [int]: Domain whose time offset is being set.\n"
1622 "Returns: [int] 0 on success; -1 on error.\n" },
1624 { "domain_send_trigger",
1625 (PyCFunction)pyxc_domain_send_trigger,
1626 METH_VARARGS | METH_KEYWORDS, "\n"
1627 "Send trigger to a domain.\n"
1628 " dom [int]: Identifier of domain to be sent trigger.\n"
1629 " trigger [int]: Trigger type number.\n"
1630 " vcpu [int]: VCPU to be sent trigger.\n"
1631 "Returns: [int] 0 on success; -1 on error.\n" },
1633 { "send_debug_keys",
1634 (PyCFunction)pyxc_send_debug_keys,
1635 METH_VARARGS | METH_KEYWORDS, "\n"
1636 "Inject debug keys into Xen.\n"
1637 " keys [str]: String of keys to inject.\n" },
1639 #ifdef __powerpc__
1640 { "arch_alloc_real_mode_area",
1641 (PyCFunction)pyxc_alloc_real_mode_area,
1642 METH_VARARGS | METH_KEYWORDS, "\n"
1643 "Allocate a domain's real mode area.\n"
1644 " dom [int]: Identifier of domain.\n"
1645 " log [int]: Specifies the area's size.\n"
1646 "Returns: [int] 0 on success; -1 on error.\n" },
1647 #endif /* __powerpc */
1649 { NULL, NULL, 0, NULL }
1650 };
1653 static PyObject *PyXc_getattr(PyObject *obj, char *name)
1655 return Py_FindMethod(pyxc_methods, obj, name);
1658 static PyObject *PyXc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1660 XcObject *self = (XcObject *)type->tp_alloc(type, 0);
1662 if (self == NULL)
1663 return NULL;
1665 self->xc_handle = -1;
1667 return (PyObject *)self;
1670 static int
1671 PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
1673 if ((self->xc_handle = xc_interface_open()) == -1) {
1674 pyxc_error_to_exception();
1675 return -1;
1678 return 0;
1681 static void PyXc_dealloc(XcObject *self)
1683 if (self->xc_handle != -1) {
1684 xc_interface_close(self->xc_handle);
1685 self->xc_handle = -1;
1688 self->ob_type->tp_free((PyObject *)self);
1691 static PyTypeObject PyXcType = {
1692 PyObject_HEAD_INIT(NULL)
1693 0,
1694 PKG "." CLS,
1695 sizeof(XcObject),
1696 0,
1697 (destructor)PyXc_dealloc, /* tp_dealloc */
1698 NULL, /* tp_print */
1699 PyXc_getattr, /* tp_getattr */
1700 NULL, /* tp_setattr */
1701 NULL, /* tp_compare */
1702 NULL, /* tp_repr */
1703 NULL, /* tp_as_number */
1704 NULL, /* tp_as_sequence */
1705 NULL, /* tp_as_mapping */
1706 NULL, /* tp_hash */
1707 NULL, /* tp_call */
1708 NULL, /* tp_str */
1709 NULL, /* tp_getattro */
1710 NULL, /* tp_setattro */
1711 NULL, /* tp_as_buffer */
1712 Py_TPFLAGS_DEFAULT, /* tp_flags */
1713 "Xen client connections", /* tp_doc */
1714 NULL, /* tp_traverse */
1715 NULL, /* tp_clear */
1716 NULL, /* tp_richcompare */
1717 0, /* tp_weaklistoffset */
1718 NULL, /* tp_iter */
1719 NULL, /* tp_iternext */
1720 pyxc_methods, /* tp_methods */
1721 NULL, /* tp_members */
1722 NULL, /* tp_getset */
1723 NULL, /* tp_base */
1724 NULL, /* tp_dict */
1725 NULL, /* tp_descr_get */
1726 NULL, /* tp_descr_set */
1727 0, /* tp_dictoffset */
1728 (initproc)PyXc_init, /* tp_init */
1729 NULL, /* tp_alloc */
1730 PyXc_new, /* tp_new */
1731 };
1733 static PyMethodDef xc_methods[] = { { NULL } };
1735 PyMODINIT_FUNC initxc(void)
1737 PyObject *m;
1739 if (PyType_Ready(&PyXcType) < 0)
1740 return;
1742 m = Py_InitModule(PKG, xc_methods);
1744 if (m == NULL)
1745 return;
1747 xc_error_obj = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
1748 zero = PyInt_FromLong(0);
1750 /* KAF: This ensures that we get debug output in a timely manner. */
1751 setbuf(stdout, NULL);
1752 setbuf(stderr, NULL);
1754 Py_INCREF(&PyXcType);
1755 PyModule_AddObject(m, CLS, (PyObject *)&PyXcType);
1757 Py_INCREF(xc_error_obj);
1758 PyModule_AddObject(m, "Error", xc_error_obj);
1760 /* Expose some libxc constants to Python */
1761 PyModule_AddIntConstant(m, "XEN_SCHEDULER_SEDF", XEN_SCHEDULER_SEDF);
1762 PyModule_AddIntConstant(m, "XEN_SCHEDULER_CREDIT", XEN_SCHEDULER_CREDIT);
1767 /*
1768 * Local variables:
1769 * c-indent-level: 4
1770 * c-basic-offset: 4
1771 * End:
1772 */