* Mike Wray <mike.wray@xxxxxx> [2005-05-03 12:01]:
> Ryan Harper wrote:
> >Here is an update to the previous pincpu patches. This patch updates
> >the pincpu dom0op to use a cpumap_t pointer, rather than specifying a
> >size in the interface. cpumap_t is current typedef'ed to an unsigned
> >long. xm list -v now truncates the cpumap field to only show the bits
> >of the map that are relevant. That is, if you have four VCPUS, you will
> >only see the first four bits of the cpumap.
> >
> >This patch compiles against current unstable tree, but I could not test
> >it as the current unstable tree crashes dom0 when booting domU. I back
> >ported the patch to 20050420 snapshot and it worked there.
> >
>
> This patch causes the dom0 crash I reported on the current unstable
> (attached) so it needs fixing before applying.
I was not able to recreate dom0 crash with the previous patch against
current nightly snapshot (20050503). None-the-less addressing some of
your feedback.
Attached is an updated patch.
o bumped cpumap_t up to u64, per Ian and Keir
o Fixed deref of user-space pointer without copy_from_user(), Mike Wray
o Added put_domain() in ed > MAX_VIRT_CPUS error path, Mike Wray
--
Ryan Harper
Software Engineer; Linux Technology Center
IBM Corp., Austin, Tx
(512) 838-9253 T/L: 678-9253
ryanh@xxxxxxxxxx
diffstat output:
tools/libxc/xc.h | 6 ++
tools/libxc/xc_domain.c | 16 +++++-
tools/python/xen/lowlevel/xc/xc.c | 71 ++++++++++++++++++------------
tools/python/xen/xend/XendClient.py | 5 +-
tools/python/xen/xend/XendDomain.py | 11 ++--
tools/python/xen/xend/XendDomainInfo.py | 6 ++
tools/python/xen/xend/server/SrvDomain.py | 3 -
tools/python/xen/xend/server/SrvUsbif.py | 1
tools/python/xen/xm/main.py | 67 +++++++++++++++++++++++-----
xen/arch/x86/domain.c | 1
xen/common/dom0_ops.c | 38 +++++++++++++---
xen/common/domain.c | 1
xen/include/public/dom0_ops.h | 7 ++
xen/include/public/xen.h | 2
xen/include/xen/sched.h | 4 +
15 files changed, 179 insertions(+), 60 deletions(-)
Signed-off-by: Ryan Harper <ryanh@xxxxxxxxxx>
---
diff -urN a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c 2005-05-02 22:11:47.000000000 -0500
+++ b/tools/libxc/xc_domain.c 2005-05-03 17:15:27.000000000 -0500
@@ -16,6 +16,8 @@
{
int err, errno_saved;
dom0_op_t op;
+ u32 vcpu = 0; /* FIXME, hard coded initial pin to vcpu 0 */
+ cpumap_t cpumap = 1<<cpu;
op.cmd = DOM0_CREATEDOMAIN;
op.u.createdomain.domain = (domid_t)*pdomid;
@@ -25,7 +27,7 @@
*pdomid = (u16)op.u.createdomain.domain;
if ( (cpu != -1) &&
- ((err = xc_domain_pincpu(xc_handle, *pdomid, cpu)) != 0) )
+ ((err = xc_domain_pincpu(xc_handle, *pdomid, vcpu, &cpumap)) != 0) )
goto fail;
if ( (err = xc_domain_setcpuweight(xc_handle, *pdomid, cpu_weight)) != 0 )
@@ -84,13 +86,14 @@
int xc_domain_pincpu(int xc_handle,
u32 domid,
- int cpu)
+ int vcpu,
+ cpumap_t *cpumap)
{
dom0_op_t op;
op.cmd = DOM0_PINCPUDOMAIN;
op.u.pincpudomain.domain = (domid_t)domid;
- op.u.pincpudomain.exec_domain = 0;
- op.u.pincpudomain.cpu = cpu;
+ op.u.pincpudomain.exec_domain = vcpu;
+ op.u.pincpudomain.cpumap = cpumap;
return do_dom0_op(xc_handle, &op);
}
@@ -132,6 +135,11 @@
info->max_memkb = op.u.getdomaininfo.max_pages<<(PAGE_SHIFT);
info->shared_info_frame = op.u.getdomaininfo.shared_info_frame;
info->cpu_time = op.u.getdomaininfo.cpu_time;
+ info->vcpus = op.u.getdomaininfo.n_vcpu;
+ memcpy(info->vcpu_to_cpu, &op.u.getdomaininfo.vcpu_to_cpu,
+ MAX_VIRT_CPUS*sizeof(u32));
+ memcpy(info->cpumap, &op.u.getdomaininfo.cpumap,
+ MAX_VIRT_CPUS*sizeof(cpumap_t));
next_domid = (u16)op.u.getdomaininfo.domain + 1;
info++;
diff -urN a/tools/libxc/xc.h b/tools/libxc/xc.h
--- a/tools/libxc/xc.h 2005-05-02 22:11:44.000000000 -0500
+++ b/tools/libxc/xc.h 2005-05-03 17:15:27.000000000 -0500
@@ -111,6 +111,7 @@
typedef struct {
u32 domid;
unsigned int cpu;
+ unsigned int vcpus;
unsigned int dying:1, crashed:1, shutdown:1,
paused:1, blocked:1, running:1;
unsigned int shutdown_reason; /* only meaningful if shutdown==1 */
@@ -118,6 +119,8 @@
unsigned long shared_info_frame;
u64 cpu_time;
unsigned long max_memkb;
+ u32 vcpu_to_cpu[MAX_VIRT_CPUS];
+ cpumap_t cpumap[MAX_VIRT_CPUS];
} xc_dominfo_t;
typedef dom0_getdomaininfo_t xc_domaininfo_t;
@@ -167,7 +170,8 @@
u32 domid);
int xc_domain_pincpu(int xc_handle,
u32 domid,
- int cpu);
+ int vcpu,
+ cpumap_t *cpumap);
/**
* This function will return information about one or more domains.
*
diff -urN a/tools/python/xen/lowlevel/xc/xc.c
b/tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c 2005-05-02 22:11:41.000000000 -0500
+++ b/tools/python/xen/lowlevel/xc/xc.c 2005-05-03 17:15:27.000000000 -0500
@@ -155,15 +155,16 @@
XcObject *xc = (XcObject *)self;
u32 dom;
- int cpu = -1;
+ int vcpu = 0;
+ cpumap_t cpumap = 0xFFFFFFFF;
- static char *kwd_list[] = { "dom", "cpu", NULL };
+ static char *kwd_list[] = { "dom", "vcpu", "cpumap", NULL };
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
- &dom, &cpu) )
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|ii", kwd_list,
+ &dom, &vcpu, &cpumap) )
return NULL;
- if ( xc_domain_pincpu(xc->xc_handle, dom, cpu) != 0 )
+ if ( xc_domain_pincpu(xc->xc_handle, dom, vcpu, &cpumap) != 0 )
return PyErr_SetFromErrno(xc_error);
Py_INCREF(zero);
@@ -175,10 +176,10 @@
PyObject *kwds)
{
XcObject *xc = (XcObject *)self;
- PyObject *list;
+ PyObject *list, *vcpu_list, *cpumap_list, *info_dict;
u32 first_dom = 0;
- int max_doms = 1024, nr_doms, i;
+ int max_doms = 1024, nr_doms, i, j;
xc_dominfo_t *info;
static char *kwd_list[] = { "first_dom", "max_doms", NULL };
@@ -195,23 +196,34 @@
list = PyList_New(nr_doms);
for ( i = 0 ; i < nr_doms; i++ )
{
- PyList_SetItem(
- list, i,
- Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
- ",s:l,s:L,s:l,s:i}",
- "dom", info[i].domid,
- "cpu", info[i].cpu,
- "dying", info[i].dying,
- "crashed", info[i].crashed,
- "shutdown", info[i].shutdown,
- "paused", info[i].paused,
- "blocked", info[i].blocked,
- "running", info[i].running,
- "mem_kb", info[i].nr_pages*4,
- "cpu_time", info[i].cpu_time,
- "maxmem_kb", info[i].max_memkb,
- "shutdown_reason", info[i].shutdown_reason
- ));
+ vcpu_list = PyList_New(MAX_VIRT_CPUS);
+ cpumap_list = PyList_New(MAX_VIRT_CPUS);
+ for ( j = 0; j < MAX_VIRT_CPUS; j++ ) {
+ PyList_SetItem( vcpu_list, j,
+ Py_BuildValue("i", info[i].vcpu_to_cpu[j]));
+ PyList_SetItem( cpumap_list, j,
+ Py_BuildValue("i", info[i].cpumap[j]));
+ }
+
+ info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
+ ",s:l,s:L,s:l,s:i}",
+ "dom", info[i].domid,
+ "cpu", info[i].cpu,
+ "vcpus", info[i].vcpus,
+ "dying", info[i].dying,
+ "crashed", info[i].crashed,
+ "shutdown", info[i].shutdown,
+ "paused", info[i].paused,
+ "blocked", info[i].blocked,
+ "running", info[i].running,
+ "mem_kb", info[i].nr_pages*4,
+ "cpu_time", info[i].cpu_time,
+ "maxmem_kb", info[i].max_memkb,
+ "shutdown_reason", info[i].shutdown_reason);
+ PyDict_SetItemString( info_dict, "vcpu_to_cpu", vcpu_list );
+ PyDict_SetItemString( info_dict, "cpumap", cpumap_list );
+ PyList_SetItem( list, i, info_dict);
+
}
free(info);
@@ -913,9 +925,10 @@
{ "domain_pincpu",
(PyCFunction)pyxc_domain_pincpu,
METH_VARARGS | METH_KEYWORDS, "\n"
- "Pin a domain to a specified CPU.\n"
- " dom [int]: Identifier of domain to be pinned.\n"
- " cpu [int, -1]: CPU to pin to, or -1 to unpin\n\n"
+ "Pin a VCPU to a specified set CPUs.\n"
+ " dom [int]: Identifier of domain to which VCPU belongs.\n"
+ " vcpu [int, 0]: VCPU being pinned.\n"
+ " cpumap [int, -1]: Bitmap of usable CPUs.\n\n"
"Returns: [int] 0 on success; -1 on error.\n" },
{ "domain_getinfo",
@@ -930,6 +943,7 @@
" domain-id space was reached.\n"
" dom [int]: Identifier of domain to which this info pertains\n"
" cpu [int]: CPU to which this domain is bound\n"
+ " vcpus [int]: Number of Virtual CPUS in this domain\n"
" dying [int]: Bool - is the domain dying?\n"
" crashed [int]: Bool - has the domain crashed?\n"
" shutdown [int]: Bool - has the domain shut itself down?\n"
@@ -940,7 +954,8 @@
" maxmem_kb [int]: Maximum memory limit, in kilobytes\n"
" cpu_time [long]: CPU time consumed, in nanoseconds\n"
" shutdown_reason [int]: Numeric code from guest OS, explaining "
- "reason why it shut itself down.\n" },
+ "reason why it shut itself down.\n"
+ " vcpu_to_cpu [[int]]: List that maps VCPUS to CPUS\n" },
{ "linux_save",
(PyCFunction)pyxc_linux_save,
diff -urN a/tools/python/xen/xend/server/SrvDomain.py
b/tools/python/xen/xend/server/SrvDomain.py
--- a/tools/python/xen/xend/server/SrvDomain.py 2005-05-02 22:11:46.000000000
-0500
+++ b/tools/python/xen/xend/server/SrvDomain.py 2005-05-03 17:15:27.000000000
-0500
@@ -92,7 +92,8 @@
def op_pincpu(self, op, req):
fn = FormFn(self.xd.domain_pincpu,
[['dom', 'str'],
- ['cpu', 'int']])
+ ['vcpu', 'int'],
+ ['cpumap', 'int']])
val = fn(req.args, {'dom': self.dom.id})
return val
diff -urN a/tools/python/xen/xend/server/SrvUsbif.py
b/tools/python/xen/xend/server/SrvUsbif.py
--- a/tools/python/xen/xend/server/SrvUsbif.py 2005-05-02 22:11:49.000000000
-0500
+++ b/tools/python/xen/xend/server/SrvUsbif.py 2005-05-03 17:15:27.000000000
-0500
@@ -107,6 +107,7 @@
def op_pincpu(self, op, req):
fn = FormFn(self.xd.domain_pincpu,
[['dom', 'str'],
+ ['vcpu', 'int'],
['cpu', 'int']])
val = fn(req.args, {'dom': self.dom.id})
return val
diff -urN a/tools/python/xen/xend/XendClient.py
b/tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py 2005-05-02 22:11:40.000000000
-0500
+++ b/tools/python/xen/xend/XendClient.py 2005-05-03 17:15:27.000000000
-0500
@@ -246,10 +246,11 @@
'live' : live,
'resource' : resource })
- def xend_domain_pincpu(self, id, cpu):
+ def xend_domain_pincpu(self, id, vcpu, cpumap):
return self.xendPost(self.domainurl(id),
{'op' : 'pincpu',
- 'cpu' : cpu })
+ 'vcpu' : vcpu,
+ 'cpumap' : cpumap })
def xend_domain_cpu_bvt_set(self, id, mcuadv, warpback, warpvalue, warpl,
warpu):
return self.xendPost(self.domainurl(id),
diff -urN a/tools/python/xen/xend/XendDomainInfo.py
b/tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py 2005-05-02 22:11:41.000000000
-0500
+++ b/tools/python/xen/xend/XendDomainInfo.py 2005-05-03 17:15:27.000000000
-0500
@@ -372,6 +372,10 @@
sxpr.append(['shutdown_reason', reason])
sxpr.append(['cpu', self.info['cpu']])
sxpr.append(['cpu_time', self.info['cpu_time']/1e9])
+ sxpr.append(['vcpus', self.info['vcpus']])
+ sxpr.append(['cpumap', self.info['cpumap']])
+ sxpr.append(['vcpu_to_cpu', ''.join(map(lambda x: str(x),
+ self.info['vcpu_to_cpu'][0:self.info['vcpus']]))])
if self.start_time:
up_time = time.time() - self.start_time
@@ -449,7 +453,7 @@
raise VmError('missing memory size')
cpu = sxp.child_value(config, 'cpu')
if self.recreate and self.dom and cpu is not None:
- xc.domain_pincpu(self.dom, int(cpu))
+ xc.domain_pincpu(self.dom, 0, 1<<int(cpu))
try:
image = sxp.child_value(self.config, 'image')
self.vcpus = int(sxp.child_value(image, 'vcpus'))
diff -urN a/tools/python/xen/xend/XendDomain.py
b/tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py 2005-05-02 22:11:41.000000000
-0500
+++ b/tools/python/xen/xend/XendDomain.py 2005-05-03 17:15:27.000000000
-0500
@@ -612,15 +612,16 @@
xmigrate = XendMigrate.instance()
return xmigrate.save_begin(dominfo, dst)
- def domain_pincpu(self, id, cpu):
- """Pin a domain to a cpu.
+ def domain_pincpu(self, id, vcpu, cpumap):
+ """Set which cpus vcpu can use
- @param id: domain
- @param cpu: cpu number
+ @param id: domain
+ @param vcpu: vcpu number
+ @param cpumap: bitmap of usbale cpus
"""
dominfo = self.domain_lookup(id)
try:
- return xc.domain_pincpu(int(dominfo.id), cpu)
+ return xc.domain_pincpu(int(dominfo.id), vcpu, cpumap)
except Exception, ex:
raise XendError(str(ex))
diff -urN a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py 2005-05-02 22:11:47.000000000 -0500
+++ b/tools/python/xen/xm/main.py 2005-05-03 17:15:27.000000000 -0500
@@ -6,6 +6,8 @@
import sys
from getopt import getopt
import socket
+import warnings
+warnings.filterwarnings('ignore', category=FutureWarning)
from xen.xend import PrettyPrint
from xen.xend import sxp
@@ -340,8 +342,8 @@
name = "list"
info = """List information about domains."""
- short_options = 'l'
- long_options = ['long']
+ short_options = 'lv'
+ long_options = ['long','vcpus']
def help(self, args):
if help:
@@ -350,11 +352,13 @@
Either all domains or the domains given.
-l, --long Get more detailed information.
+ -v, --vcpus Show VCPU to CPU mapping.
"""
return
def main(self, args):
use_long = 0
+ show_vcpus = 0
(options, params) = getopt(args[1:],
self.short_options,
self.long_options)
@@ -362,6 +366,8 @@
for (k, v) in options:
if k in ['-l', '--long']:
use_long = 1
+ if k in ['-v', '--vcpus']:
+ show_vcpus = 1
if n == 0:
doms = server.xend_domains()
@@ -371,11 +377,13 @@
if use_long:
self.long_list(doms)
+ elif show_vcpus:
+ self.show_vcpus(doms)
else:
self.brief_list(doms)
def brief_list(self, doms):
- print 'Name Id Mem(MB) CPU State Time(s) Console'
+ print 'Name Id Mem(MB) CPU VCPU(s) State Time(s)
Console'
for dom in doms:
info = server.xend_domain(dom)
d = {}
@@ -383,6 +391,7 @@
d['name'] = sxp.child_value(info, 'name', '??')
d['mem'] = int(sxp.child_value(info, 'memory', '0'))
d['cpu'] = int(sxp.child_value(info, 'cpu', '0'))
+ d['vcpus'] = int(sxp.child_value(info, 'vcpus', '0'))
d['state'] = sxp.child_value(info, 'state', '??')
d['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0'))
console = sxp.child(info, 'console')
@@ -390,9 +399,27 @@
d['port'] = sxp.child_value(console, 'console_port')
else:
d['port'] = ''
- print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3d %(state)5s
%(cpu_time)7.1f %(port)4s"
+ print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3d %(vcpus)5d
%(state)5s %(cpu_time)7.1f %(port)4s"
% d)
+ def show_vcpus(self, doms):
+ print 'Name Id VCPU CPU CPUMAP'
+ for dom in doms:
+ info = server.xend_domain(dom)
+ vcpu_to_cpu = sxp.child_value(info, 'vcpu_to_cpu',
'?').replace('-','')
+ cpumap = sxp.child_value(info, 'cpumap', [])
+ mask = ((int(sxp.child_value(info, 'vcpus', '0')))**2) - 1
+ count = 0
+ for cpu in vcpu_to_cpu:
+ d = {}
+ d['name'] = sxp.child_value(info, 'name', '??')
+ d['dom'] = int(sxp.child_value(info, 'id', '-1'))
+ d['vcpu'] = int(count)
+ d['cpu'] = int(cpu)
+ d['cpumap'] = int(cpumap[count])&mask
+ count = count + 1
+ print ("%(name)-16s %(dom)3d %(vcpu)4d %(cpu)3d
0x%(cpumap)x" % d)
+
def long_list(self, doms):
for dom in doms:
info = server.xend_domain(dom)
@@ -474,17 +501,35 @@
class ProgPincpu(Prog):
group = 'domain'
name = "pincpu"
- info = """Pin a domain to a cpu. """
+ info = """Set which cpus a VCPU can use. """
def help(self, args):
- print args[0],'DOM CPU'
- print '\nPin domain DOM to cpu CPU.'
+ print args[0],'DOM VCPU CPUS'
+ print '\nSet which cpus VCPU in domain DOM can use.'
+
+ # convert list of cpus to bitmap integer value
+ def make_map(self, cpulist):
+ cpus = []
+ cpumap = 0
+ for c in cpulist.split(','):
+ if len(c) > 1:
+ (x,y) = c.split('-')
+ for i in range(int(x),int(y)+1):
+ cpus.append(int(i))
+ else:
+ cpus.append(int(c))
+ cpus.sort()
+ for c in cpus:
+ cpumap = cpumap | 1<<c
+
+ return cpumap
def main(self, args):
- if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0])
- dom = args[1]
- cpu = int(args[2])
- server.xend_domain_pincpu(dom, cpu)
+ if len(args) != 4: self.err("%s: Invalid argument(s)" % args[0])
+ dom = args[1]
+ vcpu = int(args[2])
+ cpumap = self.make_map(args[3]);
+ server.xend_domain_pincpu(dom, vcpu, cpumap)
xm.prog(ProgPincpu)
diff -urN a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c 2005-05-02 22:11:43.000000000 -0500
+++ b/xen/arch/x86/domain.c 2005-05-03 17:15:27.000000000 -0500
@@ -252,6 +252,7 @@
d->shared_info = (void *)alloc_xenheap_page();
memset(d->shared_info, 0, PAGE_SIZE);
ed->vcpu_info = &d->shared_info->vcpu_data[ed->eid];
+ ed->cpumap = CPUMAP_RUNANYWHERE;
SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
machine_to_phys_mapping[virt_to_phys(d->shared_info) >>
PAGE_SHIFT] = INVALID_M2P_ENTRY;
diff -urN a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c 2005-05-02 22:11:41.000000000 -0500
+++ b/xen/common/dom0_ops.c 2005-05-03 17:15:27.000000000 -0500
@@ -222,7 +222,8 @@
domid_t dom = op->u.pincpudomain.domain;
struct domain *d = find_domain_by_id(dom);
struct exec_domain *ed;
- int cpu = op->u.pincpudomain.cpu;
+ cpumap_t curmap, *cpumap = &curmap;
+
if ( d == NULL )
{
@@ -230,6 +231,14 @@
break;
}
+ if ( (op->u.pincpudomain.exec_domain >= MAX_VIRT_CPUS) ||
+ !d->exec_domain[op->u.pincpudomain.exec_domain] )
+ {
+ ret = -EINVAL;
+ put_domain(d);
+ break;
+ }
+
ed = d->exec_domain[op->u.pincpudomain.exec_domain];
if ( ed == NULL )
{
@@ -245,20 +254,32 @@
break;
}
- if ( cpu == -1 )
+ if ( copy_from_user(cpumap,
+ op->u.pincpudomain.cpumap, sizeof(*cpumap)) )
+ {
+ ret = -EFAULT;
+ put_domain(d);
+ break;
+ }
+
+ /* update cpumap for this ed */
+ ed->cpumap = *(cpumap);
+ if ( *(cpumap) == CPUMAP_RUNANYWHERE )
{
clear_bit(EDF_CPUPINNED, &ed->ed_flags);
}
else
{
+ /* pick a new cpu from the usable map */
+ int new_cpu = (int)find_first_set_bit(*(cpumap)) % smp_num_cpus;
+
exec_domain_pause(ed);
- if ( ed->processor != (cpu % smp_num_cpus) )
+ if ( ed->processor != new_cpu )
set_bit(EDF_MIGRATED, &ed->ed_flags);
set_bit(EDF_CPUPINNED, &ed->ed_flags);
- ed->processor = cpu % smp_num_cpus;
+ ed->processor = new_cpu;
exec_domain_unpause(ed);
}
-
put_domain(d);
}
break;
@@ -309,6 +330,12 @@
break;
}
+ memset(&op->u.getdomaininfo.vcpu_to_cpu,-1,MAX_VIRT_CPUS*sizeof(u8));
+ for_each_exec_domain ( d, ed ) {
+ op->u.getdomaininfo.vcpu_to_cpu[ed->eid] = ed->processor;
+ op->u.getdomaininfo.cpumap[ed->eid] = ed->cpumap;
+ }
+
ed = d->exec_domain[op->u.getdomaininfo.exec_domain];
op->u.getdomaininfo.flags =
@@ -326,6 +353,7 @@
op->u.getdomaininfo.tot_pages = d->tot_pages;
op->u.getdomaininfo.max_pages = d->max_pages;
op->u.getdomaininfo.cpu_time = ed->cpu_time;
+ op->u.getdomaininfo.n_vcpu = d->shared_info->n_vcpu;
op->u.getdomaininfo.shared_info_frame =
__pa(d->shared_info) >> PAGE_SHIFT;
diff -urN a/xen/common/domain.c b/xen/common/domain.c
--- a/xen/common/domain.c 2005-05-02 22:11:44.000000000 -0500
+++ b/xen/common/domain.c 2005-05-03 17:15:27.000000000 -0500
@@ -294,6 +294,7 @@
ed = d->exec_domain[vcpu];
atomic_set(&ed->pausecnt, 0);
+ ed->cpumap = CPUMAP_RUNANYWHERE;
memcpy(&ed->arch, &idle0_exec_domain.arch, sizeof(ed->arch));
diff -urN a/xen/include/public/dom0_ops.h b/xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h 2005-05-02 22:11:48.000000000 -0500
+++ b/xen/include/public/dom0_ops.h 2005-05-03 17:15:27.000000000 -0500
@@ -88,6 +88,9 @@
memory_t max_pages;
memory_t shared_info_frame; /* MFN of shared_info struct */
u64 cpu_time;
+ u32 n_vcpu;
+ u32 vcpu_to_cpu[MAX_VIRT_CPUS]; /* current mapping */
+ cpumap_t cpumap[MAX_VIRT_CPUS]; /* allowable mapping */
} dom0_getdomaininfo_t;
#define DOM0_SETDOMAININFO 13
@@ -170,14 +173,14 @@
} dom0_readconsole_t;
/*
- * Pin Domain to a particular CPU (use -1 to unpin)
+ * Set which cpus an exec_domain can use
*/
#define DOM0_PINCPUDOMAIN 20
typedef struct {
/* IN variables. */
domid_t domain;
u16 exec_domain;
- s32 cpu; /* -1 implies unpin */
+ cpumap_t *cpumap;
} dom0_pincpudomain_t;
/* Get trace buffers machine base address */
diff -urN a/xen/include/public/xen.h b/xen/include/public/xen.h
--- a/xen/include/public/xen.h 2005-05-02 22:11:42.000000000 -0500
+++ b/xen/include/public/xen.h 2005-05-03 18:04:28.934634128 -0500
@@ -473,6 +473,8 @@
/* For use in guest OSes. */
extern shared_info_t *HYPERVISOR_shared_info;
+typedef u64 cpumap_t;
+
#endif /* !__ASSEMBLY__ */
#endif /* __XEN_PUBLIC_XEN_H__ */
diff -urN a/xen/include/xen/sched.h b/xen/include/xen/sched.h
--- a/xen/include/xen/sched.h 2005-05-02 22:11:41.000000000 -0500
+++ b/xen/include/xen/sched.h 2005-05-03 17:15:27.000000000 -0500
@@ -58,6 +58,8 @@
void destroy_event_channels(struct domain *d);
int init_exec_domain_event_channels(struct exec_domain *ed);
+
+#define CPUMAP_RUNANYWHERE 0xFFFFFFFF
struct exec_domain
{
u32 processor;
@@ -83,6 +85,8 @@
atomic_t pausecnt;
+ cpumap_t cpumap; /* which cpus this domain can run on */
+
struct arch_exec_domain arch;
};
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|