From 6fecb4c1223cef5fc3203794e6fb1e9865d93ce5 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Tue, 27 Apr 2004 13:12:58 +0000 Subject: [PATCH] bitkeeper revision 1.875.1.1 (408e5c5aIA7qWjhncD0DlSXVXY2xtg) Suspend/resume now fixed fix objdump 'debug' option in Makefile --- tools/examples/xc_dom_create.py | 40 +++++---- tools/xc/lib/xc.h | 22 +++++ tools/xc/lib/xc_domain.c | 35 ++++++++ tools/xc/lib/xc_linux_restore.c | 21 +++-- tools/xc/py/Xc.c | 77 ++++++++++++++-- xen/Makefile | 2 +- xen/common/dom0_ops.c | 55 +++++++++++- xen/common/domain.c | 9 +- xen/include/hypervisor-ifs/dom0_ops.h | 122 ++++++++++++++++---------- 9 files changed, 292 insertions(+), 91 deletions(-) diff --git a/tools/examples/xc_dom_create.py b/tools/examples/xc_dom_create.py index 332b3d4d85..799319c6a6 100755 --- a/tools/examples/xc_dom_create.py +++ b/tools/examples/xc_dom_create.py @@ -221,30 +221,32 @@ def make_domain(): print "Ramdisk file '" + ramdisk + "' does not exist" sys.exit() + id = xc.domain_create( mem_kb=mem_size*1024, name=domain_name ) + if id <= 0: + print "Error creating domain" + sys.exit() + + cmsg = 'new_control_interface(dom='+str(id)+', console_port='+str(console_port)+')' + + xend_response = xenctl.utils.xend_control_message(cmsg) + + if not xend_response['success']: + print "Error creating initial event channel" + print "Error type: " + xend_response['error_type'] + if xend_response['error_type'] == 'exception': + print "Exception type: " + xend_response['exception_type'] + print "Exception value: " + xend_response['exception_value'] + xc.domain_destroy ( dom=id ) + sys.exit() + if restore: - ret = eval('xc.%s_restore ( state_file=state_file, progress=1 )' % builder_fn) + ret = eval('xc.%s_restore ( dom=id, state_file=state_file, progress=1 )' % builder_fn) if ret < 0: print "Error restoring domain" - sys.exit() - else: - id = ret - else: - id = xc.domain_create( mem_kb=mem_size*1024, name=domain_name ) - if id <= 0: - print "Error creating domain" - sys.exit() - - cmsg = 'new_control_interface(dom='+str(id)+', console_port='+str(console_port)+')' - - xend_response = xenctl.utils.xend_control_message(cmsg) - if not xend_response['success']: - print "Error creating initial event channel" - print "Error type: " + xend_response['error_type'] - if xend_response['error_type'] == 'exception': - print "Exception type: " + xend_response['exception_type'] - print "Exception value: " + xend_response['exception_value'] + print "Return code = " + str(ret) xc.domain_destroy ( dom=id ) sys.exit() + else: ret = eval('xc.%s_build ( dom=id, image=image, ramdisk=ramdisk, cmdline=cmdline, control_evtchn=xend_response["remote_port"] )' % builder_fn) if ret < 0: diff --git a/tools/xc/lib/xc.h b/tools/xc/lib/xc.h index 936dd852c0..4afb905955 100644 --- a/tools/xc/lib/xc.h +++ b/tools/xc/lib/xc.h @@ -32,6 +32,7 @@ typedef struct { u64 cpu_time; #define XC_DOMINFO_MAXNAME 16 char name[XC_DOMINFO_MAXNAME]; + unsigned long max_memkb; } xc_dominfo_t; int xc_domain_create(int xc_handle, @@ -61,10 +62,13 @@ int xc_linux_save(int xc_handle, u64 domid, const char *state_file, int verbose); + int xc_linux_restore(int xc_handle, + u64 domid, const char *state_file, int verbose, u64 *pdomid); + int xc_linux_build(int xc_handle, u64 domid, const char *image_name, @@ -237,4 +241,22 @@ int xc_readconsolering(int xc_handle, int xc_physinfo(int xc_handle, xc_physinfo_t *info); + +int xc_shadow_control(int xc_handle, + u64 domid, + unsigned int sop); + +int xc_domain_setname(int xc_handle, + u64 domid, + char *name); + +int xc_domain_setinitialmem(int xc_handle, + u64 domid, + unsigned int initial_memkb); + +int xc_domain_setmaxmem(int xc_handle, + u64 domid, + unsigned int max_memkb); + + #endif /* __XC_H__ */ diff --git a/tools/xc/lib/xc_domain.c b/tools/xc/lib/xc_domain.c index e4d2fc0981..ec28f2686b 100644 --- a/tools/xc/lib/xc_domain.c +++ b/tools/xc/lib/xc_domain.c @@ -91,6 +91,7 @@ int xc_domain_getinfo(int xc_handle, info->has_cpu = op.u.getdomaininfo.has_cpu; info->stopped = (op.u.getdomaininfo.state == DOMSTATE_STOPPED); info->nr_pages = op.u.getdomaininfo.tot_pages; + info->max_memkb = op.u.getdomaininfo.max_pages<<(PAGE_SHIFT-10); info->shared_info_frame = op.u.getdomaininfo.shared_info_frame; info->cpu_time = op.u.getdomaininfo.cpu_time; strncpy(info->name, op.u.getdomaininfo.name, XC_DOMINFO_MAXNAME); @@ -113,3 +114,37 @@ int xc_shadow_control(int xc_handle, op.u.shadow_control.op = sop; return do_dom0_op(xc_handle, &op); } + +int xc_domain_setname(int xc_handle, + u64 domid, + char *name) +{ + dom0_op_t op; + op.cmd = DOM0_SETDOMAINNAME; + op.u.setdomainname.domain = (domid_t)domid; + strncpy(op.u.setdomainname.name, name, MAX_DOMAIN_NAME); + return do_dom0_op(xc_handle, &op); +} + +int xc_domain_setinitialmem(int xc_handle, + u64 domid, + unsigned int initial_memkb) +{ + dom0_op_t op; + op.cmd = DOM0_SETDOMAININITIALMEM; + op.u.setdomaininitialmem.domain = (domid_t)domid; + op.u.setdomaininitialmem.initial_memkb = initial_memkb; + return do_dom0_op(xc_handle, &op); +} + +int xc_domain_setmaxmem(int xc_handle, + u64 domid, + unsigned int max_memkb) +{ + dom0_op_t op; + op.cmd = DOM0_SETDOMAINMAXMEM; + op.u.setdomainmaxmem.domain = (domid_t)domid; + op.u.setdomainmaxmem.max_memkb = max_memkb; + return do_dom0_op(xc_handle, &op); +} + diff --git a/tools/xc/lib/xc_linux_restore.c b/tools/xc/lib/xc_linux_restore.c index 3decb28559..239df65984 100644 --- a/tools/xc/lib/xc_linux_restore.c +++ b/tools/xc/lib/xc_linux_restore.c @@ -52,6 +52,7 @@ static int checked_read(gzFile fd, void *buf, size_t count) } int xc_linux_restore(int xc_handle, + u64 dom, const char *state_file, int verbose, u64 *pdomid) @@ -59,7 +60,6 @@ int xc_linux_restore(int xc_handle, dom0_op_t op; int rc = 1, i, j; unsigned long mfn, pfn; - u64 dom = 0ULL; unsigned int prev_pc, this_pc; /* Number of page frames in use by this Linux session. */ @@ -165,16 +165,21 @@ int xc_linux_restore(int xc_handle, goto out; } - /* Create a new domain of the appropriate size, and find it's dom_id. */ - op.cmd = DOM0_CREATEDOMAIN; - op.u.createdomain.memory_kb = nr_pfns * (PAGE_SIZE / 1024); - memcpy(op.u.createdomain.name, name, MAX_DOMAIN_NAME); - if ( do_dom0_op(xc_handle, &op) < 0 ) + /* Set the domain's name to that from the restore file */ + if ( xc_domain_setname( xc_handle, dom, name ) ) + { + ERROR("Could not set domain name"); + goto out; + } + + /* Set the domain's initial memory allocation + to that from the restore file */ + + if ( xc_domain_setinitialmem( xc_handle, dom, nr_pfns * (PAGE_SIZE / 1024)) ) { - ERROR("Could not create new domain"); + ERROR("Could not set domain initial memory"); goto out; } - dom = (u64)op.u.createdomain.domain; /* Get the domain's shared-info frame. */ op.cmd = DOM0_GETDOMAININFO; diff --git a/tools/xc/py/Xc.c b/tools/xc/py/Xc.c index 04308f4f56..92f77f7051 100644 --- a/tools/xc/py/Xc.c +++ b/tools/xc/py/Xc.c @@ -29,7 +29,7 @@ static PyObject *pyxc_domain_create(PyObject *self, { XcObject *xc = (XcObject *)self; - unsigned int mem_kb = 65536; + unsigned int mem_kb = 0; char *name = "(anon)"; u64 dom; int ret; @@ -157,14 +157,16 @@ static PyObject *pyxc_domain_getinfo(PyObject *self, { PyList_SetItem( list, i, - Py_BuildValue("{s:L,s:i,s:i,s:i,s:l,s:L,s:s}", + Py_BuildValue("{s:L,s:i,s:i,s:i,s:l,s:L,s:s,s:l}", "dom", info[i].domid, "cpu", info[i].cpu, "running", info[i].has_cpu, "stopped", info[i].stopped, "mem_kb", info[i].nr_pages*4, "cpu_time", info[i].cpu_time, - "name", info[i].name)); + "name", info[i].name, + "maxmem_kb",info[i].max_memkb + )); } free(info); @@ -205,16 +207,17 @@ static PyObject *pyxc_linux_restore(PyObject *self, int progress = 1; u64 dom; - static char *kwd_list[] = { "state_file", "progress", NULL }; + static char *kwd_list[] = { "dom", "state_file", "progress", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s|i", kwd_list, - &state_file, &progress) ) + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "Ls|i", kwd_list, + &dom, &state_file, &progress) ) return NULL; - if ( xc_linux_restore(xc->xc_handle, state_file, progress, &dom) != 0 ) + if ( xc_linux_restore(xc->xc_handle, dom, state_file, progress, &dom) != 0 ) return PyErr_SetFromErrno(xc_error); - return PyLong_FromUnsignedLongLong(dom); + Py_INCREF(zero); + return zero; } static PyObject *pyxc_linux_build(PyObject *self, @@ -1032,6 +1035,49 @@ static PyObject *pyxc_rrobin_global_get(PyObject *self, return Py_BuildValue("{s:L}", "slice", slice); } +static PyObject *pyxc_domain_setname(PyObject *self, + PyObject *args, + PyObject *kwds) +{ + XcObject *xc = (XcObject *)self; + u64 dom; + char *name; + + static char *kwd_list[] = { "dom", "name", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "Ls", kwd_list, + &dom, &name) ) + return NULL; + + if ( xc_domain_setname(xc->xc_handle, dom, name) != 0 ) + return PyErr_SetFromErrno(xc_error); + + Py_INCREF(zero); + return zero; +} + +static PyObject *pyxc_domain_setmaxmem(PyObject *self, + PyObject *args, + PyObject *kwds) +{ + XcObject *xc = (XcObject *)self; + + u64 dom; + unsigned long max_memkb; + + static char *kwd_list[] = { "dom", "max_memkb", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "Li", kwd_list, + &dom, &max_memkb) ) + return NULL; + + if ( xc_domain_setmaxmem(xc->xc_handle, dom, max_memkb) != 0 ) + return PyErr_SetFromErrno(xc_error); + + Py_INCREF(zero); + return zero; +} + static PyMethodDef pyxc_methods[] = { { "domain_create", @@ -1379,6 +1425,21 @@ static PyMethodDef pyxc_methods[] = { " op [int, 0]: operation\n\n" "Returns: [int] 0 on success; -1 on error.\n" }, + { "domain_setname", + (PyCFunction)pyxc_domain_setname, + METH_VARARGS | METH_KEYWORDS, "\n" + "Set domain informative textual name\n" + " dom [long]: Identifier of domain.\n" + " name [str]: Text string.\n\n" + "Returns: [int] 0 on success; -1 on error.\n" }, + + { "domain_setmaxmem", + (PyCFunction)pyxc_domain_setname, + METH_VARARGS | METH_KEYWORDS, "\n" + "Set a domain's memory limit\n" + " dom [long]: Identifier of domain.\n" + " max_memkb [long]: .\n" + "Returns: [int] 0 on success; -1 on error.\n" }, { NULL, NULL, 0, NULL } }; diff --git a/xen/Makefile b/xen/Makefile index 2bfa261c39..90bd0a8cfc 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -15,7 +15,7 @@ default: $(TARGET) gzip -f -9 < $(TARGET) > $(TARGET).gz debug: - objdump -D -S $(TARGET) > $(TARGET).s + objdump -D -S $(TARGET).dbg > $(TARGET).s install: $(TARGET) gzip -f -9 < $(TARGET) > $(TARGET).gz diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 7251b71d63..c6ca8149c6 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -117,7 +117,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) static unsigned int pro = 0; domid_t dom; ret = -ENOMEM; - + spin_lock_irq(&create_dom_lock); if ( (dom = get_domnr()) == 0 ) @@ -287,6 +287,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) op->u.getdomaininfo.state = DOMSTATE_STOPPED; op->u.getdomaininfo.hyp_events = p->hyp_events; op->u.getdomaininfo.tot_pages = p->tot_pages; + op->u.getdomaininfo.max_pages = p->max_pages; op->u.getdomaininfo.cpu_time = p->cpu_time; op->u.getdomaininfo.shared_info_frame = __pa(p->shared_info) >> PAGE_SHIFT; @@ -498,14 +499,15 @@ long do_dom0_op(dom0_op_t *u_dom0_op) case DOM0_SHADOW_CONTROL: { - struct task_struct *p; - + struct task_struct *p; + ret = -ESRCH; p = find_domain_by_id( op->u.shadow_control.domain ); if ( p ) { ret = shadow_mode_control(p, op->u.shadow_control.op ); put_task_struct(p); } + } break; @@ -516,7 +518,52 @@ long do_dom0_op(dom0_op_t *u_dom0_op) copy_to_user(u_dom0_op, op, sizeof(*op)); ret = 0; } - + break; + + case DOM0_SETDOMAINNAME: + { + struct task_struct *p; + p = find_domain_by_id( op->u.setdomainname.domain ); + if ( p ) + { + strncpy(p->name, op->u.setdomainname.name, MAX_DOMAIN_NAME); + } + else + ret = -ESRCH; + } + break; + + case DOM0_SETDOMAININITIALMEM: + { + struct task_struct *p; + ret = -ESRCH; + p = find_domain_by_id( op->u.setdomaininitialmem.domain ); + if ( p ) + { + /* should only be used *before* domain is built. */ + if ( ! test_bit(PF_CONSTRUCTED, &p->flags) ) + ret = alloc_new_dom_mem( + p, op->u.setdomaininitialmem.initial_memkb ); + else + ret = -EINVAL; + } + } + break; + + case DOM0_SETDOMAINMAXMEM: + { + struct task_struct *p; + p = find_domain_by_id( op->u.setdomainmaxmem.domain ); + if ( p ) + { + p->max_pages = + (op->u.setdomainmaxmem.max_memkb+PAGE_SIZE-1)>> PAGE_SHIFT; + } + else + ret = -ESRCH; + } + break; + default: ret = -ENOSYS; diff --git a/xen/common/domain.c b/xen/common/domain.c index 87b4d19aa0..2b1372a6af 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -483,12 +483,11 @@ unsigned int alloc_new_dom_mem(struct task_struct *p, unsigned int kbytes) { unsigned int alloc_pfns, nr_pages; - nr_pages = kbytes >> (PAGE_SHIFT - 10); + nr_pages = (kbytes + ((PAGE_SIZE-1)>>10)) >> (PAGE_SHIFT - 10); + p->max_pages = nr_pages; /* this can now be controlled independently */ - /* TEMPORARY: max_pages should be explicitly specified. */ - p->max_pages = nr_pages; - - for ( alloc_pfns = 0; alloc_pfns < nr_pages; alloc_pfns++ ) + /* grow the allocation if necessary */ + for ( alloc_pfns = p->tot_pages; alloc_pfns < nr_pages; alloc_pfns++ ) { if ( unlikely(alloc_domain_page(p) == NULL) || unlikely(free_pfns < (SLACK_DOMAIN_MEM_KILOBYTES >> diff --git a/xen/include/hypervisor-ifs/dom0_ops.h b/xen/include/hypervisor-ifs/dom0_ops.h index eee92b3cd9..e943338a0d 100644 --- a/xen/include/hypervisor-ifs/dom0_ops.h +++ b/xen/include/hypervisor-ifs/dom0_ops.h @@ -22,6 +22,27 @@ #define MAX_DOMAIN_NAME 16 +/************************************************************************/ + +#define DOM0_GETMEMLIST 2 +typedef struct dom0_getmemlist_st +{ + /* IN variables. */ + domid_t domain; + unsigned long max_pfns; + void *buffer; + /* OUT variables. */ + unsigned long num_pfns; +} dom0_getmemlist_t; + +#define DOM0_SCHEDCTL 6 + /* struct sched_ctl_cmd is from sched-ctl.h */ +typedef struct sched_ctl_cmd dom0_schedctl_t; + +#define DOM0_ADJUSTDOM 7 +/* struct sched_adjdom_cmd is from sched-ctl.h */ +typedef struct sched_adjdom_cmd dom0_adjustdom_t; + #define DOM0_CREATEDOMAIN 8 typedef struct dom0_createdomain_st { @@ -32,6 +53,14 @@ typedef struct dom0_createdomain_st domid_t domain; } dom0_createdomain_t; +#define DOM0_DESTROYDOMAIN 9 +typedef struct dom0_destroydomain_st +{ + /* IN variables. */ + domid_t domain; + int force; +} dom0_destroydomain_t; + #define DOM0_STARTDOMAIN 10 typedef struct dom0_startdomain_st { @@ -46,42 +75,6 @@ typedef struct dom0_stopdomain_st domid_t domain; } dom0_stopdomain_t; -#define DOM0_DESTROYDOMAIN 9 -typedef struct dom0_destroydomain_st -{ - /* IN variables. */ - domid_t domain; - int force; -} dom0_destroydomain_t; - -#define DOM0_GETMEMLIST 2 -typedef struct dom0_getmemlist_st -{ - /* IN variables. */ - domid_t domain; - unsigned long max_pfns; - void *buffer; - /* OUT variables. */ - unsigned long num_pfns; -} dom0_getmemlist_t; - -#define DOM0_BUILDDOMAIN 13 -typedef struct dom0_builddomain_st -{ - /* IN variables. */ - domid_t domain; - unsigned int num_vifs; - full_execution_context_t ctxt; -} dom0_builddomain_t; - -#define DOM0_SCHEDCTL 6 - /* struct sched_ctl_cmd is from sched-ctl.h */ -typedef struct sched_ctl_cmd dom0_schedctl_t; - -#define DOM0_ADJUSTDOM 7 -/* struct sched_adjdom_cmd is from sched-ctl.h */ -typedef struct sched_adjdom_cmd dom0_adjustdom_t; - #define DOM0_GETDOMAININFO 12 typedef struct dom0_getdomaininfo_st { @@ -95,22 +88,20 @@ typedef struct dom0_getdomaininfo_st #define DOMSTATE_STOPPED 1 int state; int hyp_events; - unsigned int tot_pages; + unsigned int tot_pages, max_pages; long long cpu_time; unsigned long shared_info_frame; /* MFN of shared_info struct */ full_execution_context_t ctxt; } dom0_getdomaininfo_t; -#define DOM0_GETPAGEFRAMEINFO 18 -typedef struct dom0_getpageframeinfo_st +#define DOM0_BUILDDOMAIN 13 +typedef struct dom0_builddomain_st { /* IN variables. */ - unsigned long pfn; /* Machine page frame number to query. */ - domid_t domain; /* To which domain does the frame belong? */ - /* OUT variables. */ - /* Is the page PINNED to a type? */ - enum { NONE, L1TAB, L2TAB, L3TAB, L4TAB } type; -} dom0_getpageframeinfo_t; + domid_t domain; + unsigned int num_vifs; + full_execution_context_t ctxt; +} dom0_builddomain_t; #define DOM0_IOPL 14 typedef struct dom0_iopl_st @@ -153,6 +144,18 @@ typedef struct dom0_settime_st u64 system_time; } dom0_settime_t; +#define DOM0_GETPAGEFRAMEINFO 18 +typedef struct dom0_getpageframeinfo_st +{ + /* IN variables. */ + unsigned long pfn; /* Machine page frame number to query. */ + domid_t domain; /* To which domain does the frame belong? */ + /* OUT variables. */ + /* Is the page PINNED to a type? */ + enum { NONE, L1TAB, L2TAB, L3TAB, L4TAB } type; +} dom0_getpageframeinfo_t; + + /* * Read console content from Xen buffer ring. */ @@ -225,7 +228,7 @@ typedef struct dom0_sched_id_st /* * Control shadow pagetables operation */ -#define DOM0_SHADOW_CONTROL 25 +#define DOM0_SHADOW_CONTROL 25 #define DOM0_SHADOW_CONTROL_OP_OFF 0 #define DOM0_SHADOW_CONTROL_OP_ENABLE_TEST 1 @@ -239,6 +242,30 @@ typedef struct dom0_shadow_control_st int op; } dom0_shadow_control_t; +#define DOM0_SETDOMAINNAME 26 +typedef struct dom0_setdomainname_st +{ + /* IN variables. */ + domid_t domain; + char name[MAX_DOMAIN_NAME]; +} dom0_setdomainname_t; + +#define DOM0_SETDOMAININITIALMEM 27 +typedef struct dom0_setdomaininitialmem_st +{ + /* IN variables. */ + domid_t domain; + unsigned int initial_memkb; /* use before domain is built */ +} dom0_setdomaininitialmem_t; + +#define DOM0_SETDOMAINMAXMEM 28 +typedef struct dom0_setdomainmaxmem_st +{ + /* IN variables. */ + domid_t domain; + unsigned int max_memkb; +} dom0_setdomainmaxmem_t; + typedef struct dom0_op_st { @@ -267,6 +294,9 @@ typedef struct dom0_op_st dom0_pcidev_access_t pcidev_access; dom0_sched_id_t sched_id; dom0_shadow_control_t shadow_control; + dom0_setdomainname_t setdomainname; + dom0_setdomaininitialmem_t setdomaininitialmem; + dom0_setdomainmaxmem_t setdomainmaxmem; } u; } dom0_op_t; -- 2.30.2