ia64/xen-unstable

changeset 4849:a68686aaebc3

bitkeeper revision 1.1389.15.13 (42821f23dLMLc5Ql8Y-rUwoatYBI6g)

Split out context fetching into separate DOM0 op
make GETDOMAININFO a little more sensible with respect to MP
make coredump dump all cpu contexts
Signed-off-by: Kip Macy <kmacy@netapp.com>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk[cl349]
date Wed May 11 15:05:07 2005 +0000 (2005-05-11)
parents 3ac0994c8240
children b78b16c06b85
files tools/libxc/xc.h tools/libxc/xc_core.c tools/libxc/xc_domain.c tools/libxc/xc_linux_build.c tools/libxc/xc_linux_restore.c tools/libxc/xc_linux_save.c tools/libxc/xc_plan9_build.c tools/libxc/xc_private.c tools/libxc/xc_ptrace.c tools/libxc/xc_vmx_build.c xen/common/dom0_ops.c xen/include/public/dom0_ops.h
line diff
     1.1 --- a/tools/libxc/xc.h	Wed May 11 14:15:56 2005 +0000
     1.2 +++ b/tools/libxc/xc.h	Wed May 11 15:05:07 2005 +0000
     1.3 @@ -110,8 +110,10 @@ int xc_waitdomain_core(int domain,
     1.4  
     1.5  typedef struct {
     1.6      u32           domid;
     1.7 -    unsigned int  cpu;
     1.8 +    unsigned int  flags;
     1.9 +    unsigned int  processors;
    1.10      unsigned int  vcpus;
    1.11 +    u16           n_vcpus;	
    1.12      unsigned int  dying:1, crashed:1, shutdown:1, 
    1.13                    paused:1, blocked:1, running:1;
    1.14      unsigned int  shutdown_reason; /* only meaningful if shutdown==1 */
    1.15 @@ -199,11 +201,11 @@ int xc_domain_getinfo(int xc_handle,
    1.16   *            domain
    1.17   * @return 0 on success, -1 on failure
    1.18   */
    1.19 -int xc_domain_getfullinfo(int xc_handle,
    1.20 -                          u32 domid,
    1.21 -                          u32 vcpu,
    1.22 -                          xc_domaininfo_t *info,
    1.23 -                          vcpu_guest_context_t *ctxt);
    1.24 +int xc_domain_get_vcpu_context(int xc_handle,
    1.25 +			      u32 domid,
    1.26 +			      u32 vcpu,
    1.27 +			      vcpu_guest_context_t *ctxt);
    1.28 +
    1.29  int xc_domain_setcpuweight(int xc_handle,
    1.30                             u32 domid,
    1.31                             float weight);
     2.1 --- a/tools/libxc/xc_core.c	Wed May 11 14:15:56 2005 +0000
     2.2 +++ b/tools/libxc/xc_core.c	Wed May 11 15:05:07 2005 +0000
     2.3 @@ -7,6 +7,7 @@
     2.4  /* number of pages to write at a time */
     2.5  #define DUMP_INCREMENT 4 * 1024
     2.6  #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
     2.7 +
     2.8  static int
     2.9  copy_from_domain_page(int xc_handle,
    2.10  		      u32 domid,
    2.11 @@ -28,13 +29,14 @@ xc_domain_dumpcore(int xc_handle,
    2.12  		   u32 domid,
    2.13  		   const char *corename)
    2.14  {
    2.15 -	vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
    2.16  	unsigned long nr_pages;
    2.17  	unsigned long *page_array;
    2.18 -	xc_domaininfo_t st_info, *info = &st_info;
    2.19 +	xc_dominfo_t info;
    2.20  	int i, dump_fd;
    2.21  	char *dump_mem, *dump_mem_start = NULL;
    2.22  	struct xc_core_header header;
    2.23 +	vcpu_guest_context_t     ctxt[MAX_VIRT_CPUS];
    2.24 +
    2.25  	
    2.26  	if ((dump_fd = open(corename, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR)) < 0) {
    2.27  		PERROR("Could not open corefile %s: %s", corename, strerror(errno));
    2.28 @@ -46,14 +48,22 @@ xc_domain_dumpcore(int xc_handle,
    2.29  		goto error_out;
    2.30  	}
    2.31  	
    2.32 -	if (xc_domain_getfullinfo(xc_handle, domid, 0/* XXX hardcode */, info, ctxt)) {
    2.33 -		PERROR("Could not get full info for domain");
    2.34 +	if (xc_domain_getinfo(xc_handle, domid, 1, &info)) {
    2.35 +		PERROR("Could not get info for domain");
    2.36  		goto error_out;
    2.37  	}
    2.38 +	
    2.39 +	for (i = 0; i < info.n_vcpus; i++) {
    2.40 +		if (xc_domain_get_vcpu_context(xc_handle, domid, i, &ctxt[i])) {
    2.41 +			PERROR("Could not get all vcpu contexts for domain");
    2.42 +			goto error_out;
    2.43 +		}
    2.44 +	}
    2.45 +	
    2.46 +	nr_pages = info.nr_pages;
    2.47  
    2.48 -	nr_pages = info->tot_pages;
    2.49  	header.xch_magic = 0xF00FEBED; 
    2.50 -	header.xch_nr_vcpus = 1; /* no interface to query at the moment */
    2.51 +	header.xch_nr_vcpus = info.n_vcpus;
    2.52  	header.xch_nr_pages = nr_pages;
    2.53  	header.xch_ctxt_offset = sizeof(struct xc_core_header);
    2.54  	header.xch_index_offset = sizeof(struct xc_core_header) +
    2.55 @@ -62,7 +72,7 @@ xc_domain_dumpcore(int xc_handle,
    2.56  	    sizeof(vcpu_guest_context_t) + nr_pages * sizeof(unsigned long));
    2.57  
    2.58  	write(dump_fd, &header, sizeof(struct xc_core_header));
    2.59 -	write(dump_fd, ctxt, sizeof(st_ctxt));
    2.60 +	write(dump_fd, &ctxt, sizeof(ctxt[0]) * info.n_vcpus);
    2.61  
    2.62  	if ((page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) {
    2.63  	    printf("Could not allocate memory\n");
     3.1 --- a/tools/libxc/xc_domain.c	Wed May 11 14:15:56 2005 +0000
     3.2 +++ b/tools/libxc/xc_domain.c	Wed May 11 15:05:07 2005 +0000
     3.3 @@ -112,14 +112,12 @@ int xc_domain_getinfo(int xc_handle,
     3.4      {
     3.5          op.cmd = DOM0_GETDOMAININFO;
     3.6          op.u.getdomaininfo.domain = (domid_t)next_domid;
     3.7 -        op.u.getdomaininfo.exec_domain = 0; // FIX ME?!?
     3.8 -        op.u.getdomaininfo.ctxt = NULL; /* no exec context info, thanks. */
     3.9          if ( (rc = do_dom0_op(xc_handle, &op)) < 0 )
    3.10              break;
    3.11 -        info->domid   = (u16)op.u.getdomaininfo.domain;
    3.12 -
    3.13 -        info->cpu     =
    3.14 -            (op.u.getdomaininfo.flags>>DOMFLAGS_CPUSHIFT) & DOMFLAGS_CPUMASK;
    3.15 +        info->domid      = (u16)op.u.getdomaininfo.domain;
    3.16 +        info->processors = op.u.getdomaininfo.processors;
    3.17 +	info->n_vcpus    = op.u.getdomaininfo.n_active_vcpus;
    3.18 +	info->flags      = op.u.getdomaininfo.flags;
    3.19  
    3.20          info->dying    = !!(op.u.getdomaininfo.flags & DOMFLAGS_DYING);
    3.21          info->crashed  = !!(op.u.getdomaininfo.flags & DOMFLAGS_CRASHED);
    3.22 @@ -142,28 +140,27 @@ int xc_domain_getinfo(int xc_handle,
    3.23          memcpy(&info->cpumap, &op.u.getdomaininfo.cpumap, 
    3.24                 sizeof(info->cpumap));
    3.25  
    3.26 -        next_domid = (u16)op.u.getdomaininfo.domain + 1;
    3.27 -        info++;
    3.28 +       next_domid = (u16)op.u.getdomaininfo.domain + 1;
    3.29 +       info++;
    3.30      }
    3.31  
    3.32 -    if(!nr_doms) return rc; 
    3.33 +    if( !nr_doms ) return rc; 
    3.34  
    3.35      return nr_doms;
    3.36  }
    3.37  
    3.38 -int xc_domain_getfullinfo(int xc_handle,
    3.39 -                          u32 domid,
    3.40 -                          u32 vcpu,
    3.41 -                          xc_domaininfo_t *info,
    3.42 -                          vcpu_guest_context_t *ctxt)
    3.43 +int xc_domain_get_vcpu_context(int xc_handle,
    3.44 +			       u32 domid,
    3.45 +			       u32 vcpu,
    3.46 +			       vcpu_guest_context_t *ctxt)
    3.47  {
    3.48      int rc, errno_saved;
    3.49      dom0_op_t op;
    3.50  
    3.51 -    op.cmd = DOM0_GETDOMAININFO;
    3.52 -    op.u.getdomaininfo.domain = (domid_t)domid;
    3.53 -    op.u.getdomaininfo.exec_domain = (u16)vcpu;
    3.54 -    op.u.getdomaininfo.ctxt = ctxt;
    3.55 +    op.cmd = DOM0_GETVCPUCONTEXT;
    3.56 +    op.u.getvcpucontext.domain = (domid_t)domid;
    3.57 +    op.u.getvcpucontext.exec_domain = (u16)vcpu;
    3.58 +    op.u.getvcpucontext.ctxt = ctxt;
    3.59  
    3.60      if ( (ctxt != NULL) &&
    3.61           ((rc = mlock(ctxt, sizeof(*ctxt))) != 0) )
    3.62 @@ -178,10 +175,7 @@ int xc_domain_getfullinfo(int xc_handle,
    3.63          errno = errno_saved;
    3.64      }
    3.65  
    3.66 -    if ( info != NULL )
    3.67 -        memcpy(info, &op.u.getdomaininfo, sizeof(*info));
    3.68 -
    3.69 -    if ( ((u16)op.u.getdomaininfo.domain != domid) && (rc > 0) )
    3.70 +    if ( rc > 0 )
    3.71          return -ESRCH;
    3.72      else
    3.73          return rc;
     4.1 --- a/tools/libxc/xc_linux_build.c	Wed May 11 14:15:56 2005 +0000
     4.2 +++ b/tools/libxc/xc_linux_build.c	Wed May 11 15:05:07 2005 +0000
     4.3 @@ -356,14 +356,19 @@ int xc_linux_build(int xc_handle,
     4.4  
     4.5      op.cmd = DOM0_GETDOMAININFO;
     4.6      op.u.getdomaininfo.domain = (domid_t)domid;
     4.7 -    op.u.getdomaininfo.exec_domain = 0;
     4.8 -    op.u.getdomaininfo.ctxt = ctxt;
     4.9      if ( (do_dom0_op(xc_handle, &op) < 0) || 
    4.10           ((u16)op.u.getdomaininfo.domain != domid) )
    4.11      {
    4.12          PERROR("Could not get info on domain");
    4.13          goto error_out;
    4.14      }
    4.15 +
    4.16 +    if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) )
    4.17 +    {
    4.18 +        PERROR("Could not get vcpu context");
    4.19 +        goto error_out;
    4.20 +    }
    4.21 +
    4.22      if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ||
    4.23           (ctxt->pt_base != 0) )
    4.24      {
     5.1 --- a/tools/libxc/xc_linux_restore.c	Wed May 11 14:15:56 2005 +0000
     5.2 +++ b/tools/libxc/xc_linux_restore.c	Wed May 11 15:05:07 2005 +0000
     5.3 @@ -181,8 +181,6 @@ int xc_linux_restore(int xc_handle, XcIO
     5.4      /* Get the domain's shared-info frame. */
     5.5      op.cmd = DOM0_GETDOMAININFO;
     5.6      op.u.getdomaininfo.domain = (domid_t)dom;
     5.7 -    op.u.getdomaininfo.exec_domain = 0;
     5.8 -    op.u.getdomaininfo.ctxt = NULL;
     5.9      if ( do_dom0_op(xc_handle, &op) < 0 )
    5.10      {
    5.11          xcio_error(ioctxt, "Could not get information on new domain");
     6.1 --- a/tools/libxc/xc_linux_save.c	Wed May 11 14:15:56 2005 +0000
     6.2 +++ b/tools/libxc/xc_linux_save.c	Wed May 11 15:05:07 2005 +0000
     6.3 @@ -324,7 +324,7 @@ static int analysis_phase( int xc_handle
     6.4  
     6.5  
     6.6  int suspend_and_state(int xc_handle, XcIOContext *ioctxt,		      
     6.7 -                      xc_domaininfo_t *info,
     6.8 +                      xc_dominfo_t *info,
     6.9                        vcpu_guest_context_t *ctxt)
    6.10  {
    6.11      int i=0;
    6.12 @@ -333,13 +333,18 @@ int suspend_and_state(int xc_handle, XcI
    6.13  
    6.14  retry:
    6.15  
    6.16 -    if ( xc_domain_getfullinfo(xc_handle, ioctxt->domain, /* FIXME */ 0, 
    6.17 -                               info, ctxt) )
    6.18 +    if ( xc_domain_getinfo(xc_handle, ioctxt->domain, 1, info) )
    6.19      {
    6.20  	xcio_error(ioctxt, "Could not get full domain info");
    6.21  	return -1;
    6.22      }
    6.23  
    6.24 +    if ( xc_domain_get_vcpu_context(xc_handle, ioctxt->domain, 0 /* XXX */, 
    6.25 +				    ctxt) )
    6.26 +    {
    6.27 +        xcio_error(ioctxt, "Could not get vcpu context");
    6.28 +    }
    6.29 +
    6.30      if ( (info->flags & 
    6.31            (DOMFLAGS_SHUTDOWN | (SHUTDOWN_suspend<<DOMFLAGS_SHUTDOWNSHIFT))) ==
    6.32           (DOMFLAGS_SHUTDOWN | (SHUTDOWN_suspend<<DOMFLAGS_SHUTDOWNSHIFT)) )
    6.33 @@ -374,7 +379,7 @@ retry:
    6.34  
    6.35  int xc_linux_save(int xc_handle, XcIOContext *ioctxt)
    6.36  {
    6.37 -    xc_domaininfo_t info;
    6.38 +    xc_dominfo_t info;
    6.39  
    6.40      int rc = 1, i, j, k, last_iter, iter = 0;
    6.41      unsigned long mfn;
    6.42 @@ -444,13 +449,18 @@ int xc_linux_save(int xc_handle, XcIOCon
    6.43          xcio_perror(ioctxt, "Unable to mlock ctxt");
    6.44          return 1;
    6.45      }
    6.46 -
    6.47 -    if ( xc_domain_getfullinfo( xc_handle, domid, /* FIXME */ 0, 
    6.48 -                                &info, &ctxt) )
    6.49 +    
    6.50 +    if ( xc_domain_getinfo(xc_handle, domid, 1, &info) )
    6.51      {
    6.52          xcio_error(ioctxt, "Could not get full domain info");
    6.53          goto out;
    6.54      }
    6.55 +    if ( xc_domain_get_vcpu_context( xc_handle, domid, /* FIXME */ 0, 
    6.56 +                                &ctxt) )
    6.57 +    {
    6.58 +        xcio_error(ioctxt, "Could not get vcpu context");
    6.59 +        goto out;
    6.60 +    }
    6.61      shared_info_frame = info.shared_info_frame;
    6.62  
    6.63      /* A cheesy test to see whether the domain contains valid state. */
    6.64 @@ -459,7 +469,7 @@ int xc_linux_save(int xc_handle, XcIOCon
    6.65          goto out;
    6.66      }
    6.67      
    6.68 -    nr_pfns = info.max_pages; 
    6.69 +    nr_pfns = info.nr_pages; 
    6.70  
    6.71      /* cheesy sanity check */
    6.72      if ( nr_pfns > 1024*1024 ){
     7.1 --- a/tools/libxc/xc_plan9_build.c	Wed May 11 14:15:56 2005 +0000
     7.2 +++ b/tools/libxc/xc_plan9_build.c	Wed May 11 15:05:07 2005 +0000
     7.3 @@ -440,17 +440,21 @@ xc_plan9_build(int xc_handle,
     7.4  
     7.5  	op.cmd = DOM0_GETDOMAININFO;
     7.6  	op.u.getdomaininfo.domain = (domid_t) domid;
     7.7 -        op.u.getdomaininfo.exec_domain = 0;
     7.8 -	op.u.getdomaininfo.ctxt = ctxt;
     7.9  	if ((do_dom0_op(xc_handle, &op) < 0) ||
    7.10  	    ((u32) op.u.getdomaininfo.domain != domid)) {
    7.11  		PERROR("Could not get info on domain");
    7.12  		goto error_out;
    7.13  	}
    7.14  	DPRINTF(("xc_get_tot_pages returns %ld pages\n", tot_pages));
    7.15 +	
    7.16 +	if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) )
    7.17 +	{
    7.18 +	    PERROR("Could not get vcpu context");
    7.19 +	    goto error_out;
    7.20 +	}
    7.21  
    7.22  	if (!(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED)
    7.23 -	    || (op.u.getdomaininfo.ctxt->pt_base != 0)) {
    7.24 +	    || (ctxt->pt_base != 0)) {
    7.25  		ERROR("Domain is already constructed");
    7.26  		goto error_out;
    7.27  	}
     8.1 --- a/tools/libxc/xc_private.c	Wed May 11 14:15:56 2005 +0000
     8.2 +++ b/tools/libxc/xc_private.c	Wed May 11 15:05:07 2005 +0000
     8.3 @@ -173,17 +173,16 @@ long long xc_domain_get_cpu_usage( int x
     8.4  {
     8.5      dom0_op_t op;
     8.6  
     8.7 -    op.cmd = DOM0_GETDOMAININFO;
     8.8 -    op.u.getdomaininfo.domain = (domid_t)domid;
     8.9 -    op.u.getdomaininfo.exec_domain = (u16)vcpu;
    8.10 -    op.u.getdomaininfo.ctxt = NULL;
    8.11 -    if ( (do_dom0_op(xc_handle, &op) < 0) || 
    8.12 -         ((u16)op.u.getdomaininfo.domain != domid) )
    8.13 +    op.cmd = DOM0_GETVCPUCONTEXT;
    8.14 +    op.u.getvcpucontext.domain = (domid_t)domid;
    8.15 +    op.u.getvcpucontext.exec_domain = (u16)vcpu;
    8.16 +    op.u.getvcpucontext.ctxt = NULL;
    8.17 +    if ( (do_dom0_op(xc_handle, &op) < 0) )
    8.18      {
    8.19          PERROR("Could not get info on domain");
    8.20          return -1;
    8.21      }
    8.22 -    return op.u.getdomaininfo.cpu_time;
    8.23 +    return op.u.getvcpucontext.cpu_time;
    8.24  }
    8.25  
    8.26  
    8.27 @@ -258,8 +257,6 @@ long xc_get_tot_pages(int xc_handle, u32
    8.28      dom0_op_t op;
    8.29      op.cmd = DOM0_GETDOMAININFO;
    8.30      op.u.getdomaininfo.domain = (domid_t)domid;
    8.31 -    op.u.getdomaininfo.exec_domain = 0;
    8.32 -    op.u.getdomaininfo.ctxt = NULL;
    8.33      return (do_dom0_op(xc_handle, &op) < 0) ? 
    8.34          -1 : op.u.getdomaininfo.tot_pages;
    8.35  }
     9.1 --- a/tools/libxc/xc_ptrace.c	Wed May 11 14:15:56 2005 +0000
     9.2 +++ b/tools/libxc/xc_ptrace.c	Wed May 11 15:05:07 2005 +0000
     9.3 @@ -71,7 +71,7 @@ struct gdb_regs {
     9.4  #define FETCH_REGS(cpu) \
     9.5      if (!regs_valid[cpu]) \
     9.6      {                \
     9.7 -	int retval = xc_domain_getfullinfo(xc_handle, domid, cpu, NULL, &ctxt[cpu]); \
     9.8 +	int retval = xc_domain_get_vcpu_context(xc_handle, domid, cpu, &ctxt[cpu]); \
     9.9  	if (retval) \
    9.10  	    goto error_out; \
    9.11  	cr3[cpu] = ctxt[cpu].pt_base; /* physical address */ \
    9.12 @@ -221,7 +221,6 @@ xc_waitdomain(int domain, int *status, i
    9.13  {
    9.14      dom0_op_t op;
    9.15      int retval;
    9.16 -    vcpu_guest_context_t ctxt;
    9.17      struct timespec ts;
    9.18      ts.tv_sec = 0;
    9.19      ts.tv_nsec = 10*1000*1000;
    9.20 @@ -234,12 +233,10 @@ xc_waitdomain(int domain, int *status, i
    9.21  	}
    9.22      op.cmd = DOM0_GETDOMAININFO;
    9.23      op.u.getdomaininfo.domain = domain;
    9.24 -    op.u.getdomaininfo.exec_domain = 0;
    9.25 -    op.u.getdomaininfo.ctxt = &ctxt;
    9.26   retry:
    9.27  
    9.28      retval = do_dom0_op(xc_handle, &op);
    9.29 -    if (retval) {
    9.30 +    if (retval || op.u.getdomaininfo.domain != domain) {
    9.31  	printf("getdomaininfo failed\n");
    9.32  	goto done;
    9.33      }
    9.34 @@ -325,10 +322,8 @@ xc_ptrace(enum __ptrace_request request,
    9.35      case PTRACE_ATTACH:
    9.36  	op.cmd = DOM0_GETDOMAININFO;
    9.37  	op.u.getdomaininfo.domain = domid;
    9.38 -	op.u.getdomaininfo.exec_domain = 0;
    9.39 -	op.u.getdomaininfo.ctxt = NULL;
    9.40  	retval = do_dom0_op(xc_handle, &op);
    9.41 -	if (retval) {
    9.42 +	if (retval || op.u.getdomaininfo.domain != domid) {
    9.43  	    perror("dom0 op failed");
    9.44  	    goto error_out;
    9.45  	}
    10.1 --- a/tools/libxc/xc_vmx_build.c	Wed May 11 14:15:56 2005 +0000
    10.2 +++ b/tools/libxc/xc_vmx_build.c	Wed May 11 15:05:07 2005 +0000
    10.3 @@ -543,14 +543,19 @@ int xc_vmx_build(int xc_handle,
    10.4  
    10.5      op.cmd = DOM0_GETDOMAININFO;
    10.6      op.u.getdomaininfo.domain = (domid_t)domid;
    10.7 -    op.u.getdomaininfo.exec_domain = 0;
    10.8 -    op.u.getdomaininfo.ctxt = ctxt;
    10.9      if ( (do_dom0_op(xc_handle, &op) < 0) || 
   10.10           ((u16)op.u.getdomaininfo.domain != domid) )
   10.11      {
   10.12          PERROR("Could not get info on domain");
   10.13          goto error_out;
   10.14      }
   10.15 +
   10.16 +    if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) )
   10.17 +    {
   10.18 +        PERROR("Could not get vcpu context");
   10.19 +        goto error_out;
   10.20 +    }
   10.21 +
   10.22      if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ||
   10.23           (ctxt->pt_base != 0) )
   10.24      {
    11.1 --- a/xen/common/dom0_ops.c	Wed May 11 14:15:56 2005 +0000
    11.2 +++ b/xen/common/dom0_ops.c	Wed May 11 15:05:07 2005 +0000
    11.3 @@ -299,9 +299,16 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
    11.4  
    11.5      case DOM0_GETDOMAININFO:
    11.6      { 
    11.7 -        struct vcpu_guest_context *c;
    11.8 -        struct domain            *d;
    11.9 -        struct exec_domain       *ed;
   11.10 +        struct domain             *d;
   11.11 +        struct exec_domain        *ed;
   11.12 +        u64 cpu_time = 0;
   11.13 +        int vcpu_count = 0;
   11.14 +        u32 processors = 0;
   11.15 +        int flags = DOMFLAGS_PAUSED | DOMFLAGS_BLOCKED;
   11.16 +
   11.17 +#if MAX_VIRT_CPUS > 32
   11.18 +#error "update processors field in GETDOMAININFO"
   11.19 +#endif
   11.20  
   11.21          read_lock(&domlist_lock);
   11.22  
   11.23 @@ -322,13 +329,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   11.24  
   11.25          op->u.getdomaininfo.domain = d->id;
   11.26  
   11.27 -        if ( (op->u.getdomaininfo.exec_domain >= MAX_VIRT_CPUS) ||
   11.28 -             !d->exec_domain[op->u.getdomaininfo.exec_domain] )
   11.29 -        {
   11.30 -            ret = -EINVAL;
   11.31 -            break;
   11.32 -        }
   11.33 -        
   11.34          memset(&op->u.getdomaininfo.vcpu_to_cpu, -1,
   11.35                 sizeof(op->u.getdomaininfo.vcpu_to_cpu));
   11.36          memset(&op->u.getdomaininfo.cpumap, 0,
   11.37 @@ -338,28 +338,86 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   11.38              op->u.getdomaininfo.cpumap[ed->id]      = ed->cpumap;
   11.39          }
   11.40  
   11.41 -        ed = d->exec_domain[op->u.getdomaininfo.exec_domain];
   11.42 +        /* 
   11.43 +         * - domain is marked as paused or blocked only if all its vcpus 
   11.44 +         *   are paused or blocked 
   11.45 +         * - domain is marked as running if any of its vcpus is running
   11.46 +         */
   11.47 +        
   11.48 +        for_each_exec_domain(d, ed)  
   11.49 +        { 
   11.50 +            if (!((flags & DOMFLAGS_PAUSED) && test_bit(EDF_CTRLPAUSE, &ed->flags)))
   11.51 +                flags &=  ~DOMFLAGS_PAUSED;
   11.52 +            if (!((flags & DOMFLAGS_BLOCKED) && test_bit(EDF_BLOCKED, &ed->flags)))
   11.53 +                flags &=  ~DOMFLAGS_BLOCKED;                
   11.54 +            flags |= (test_bit(EDF_RUNNING,   &ed->flags) ? DOMFLAGS_RUNNING  : 0);
   11.55 +
   11.56 +            set_bit(ed->processor, &processors);
   11.57 +            if ( ed->cpu_time > cpu_time )
   11.58 +                cpu_time += ed->cpu_time;
   11.59 +            vcpu_count++;
   11.60 +        }
   11.61 +        op->u.getdomaininfo.n_active_vcpus = vcpu_count;
   11.62 +        op->u.getdomaininfo.cpu_time = cpu_time;
   11.63  
   11.64          op->u.getdomaininfo.flags =
   11.65              (test_bit( DF_DYING,      &d->flags)  ? DOMFLAGS_DYING    : 0) |
   11.66              (test_bit( DF_CRASHED,    &d->flags)  ? DOMFLAGS_CRASHED  : 0) |
   11.67              (test_bit( DF_SHUTDOWN,   &d->flags)  ? DOMFLAGS_SHUTDOWN : 0) |
   11.68 -            (test_bit(EDF_CTRLPAUSE, &ed->flags) ? DOMFLAGS_PAUSED   : 0) |
   11.69 -            (test_bit(EDF_BLOCKED,   &ed->flags) ? DOMFLAGS_BLOCKED  : 0) |
   11.70 -            (test_bit(EDF_RUNNING,   &ed->flags) ? DOMFLAGS_RUNNING  : 0);
   11.71 +            flags;
   11.72  
   11.73 -        op->u.getdomaininfo.flags |= ed->processor << DOMFLAGS_CPUSHIFT;
   11.74          op->u.getdomaininfo.flags |= 
   11.75              d->shutdown_code << DOMFLAGS_SHUTDOWNSHIFT;
   11.76  
   11.77 +        op->u.getdomaininfo.processors  = processors;
   11.78          op->u.getdomaininfo.tot_pages   = d->tot_pages;
   11.79          op->u.getdomaininfo.max_pages   = d->max_pages;
   11.80 -        op->u.getdomaininfo.cpu_time    = ed->cpu_time;
   11.81          op->u.getdomaininfo.n_vcpu      = d->shared_info->n_vcpu;
   11.82          op->u.getdomaininfo.shared_info_frame = 
   11.83              __pa(d->shared_info) >> PAGE_SHIFT;
   11.84  
   11.85 -        if ( op->u.getdomaininfo.ctxt != NULL )
   11.86 +        if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )     
   11.87 +            ret = -EINVAL;
   11.88 +
   11.89 +        put_domain(d);
   11.90 +    }
   11.91 +    break;
   11.92 +
   11.93 +    case DOM0_GETVCPUCONTEXT:
   11.94 +    { 
   11.95 +        struct vcpu_guest_context *c;
   11.96 +        struct domain             *d;
   11.97 +        struct exec_domain        *ed;
   11.98 +        int active_index = 0; 
   11.99 +        int exec_domain_index;
  11.100 +
  11.101 +        exec_domain_index = op->u.getvcpucontext.exec_domain;
  11.102 +        d = find_domain_by_id(op->u.getvcpucontext.domain);
  11.103 +
  11.104 +        if ( d == NULL )
  11.105 +        {
  11.106 +            ret = -ESRCH;
  11.107 +            break;
  11.108 +        }
  11.109 +
  11.110 +        if ( (exec_domain_index >= MAX_VIRT_CPUS) )
  11.111 +        {
  11.112 +            ret = -EINVAL;
  11.113 +            break;
  11.114 +        }
  11.115 +        
  11.116 +        for_each_exec_domain(d, ed)
  11.117 +        {
  11.118 +            if ( exec_domain_index == active_index ) 
  11.119 +            {
  11.120 +                op->u.getvcpucontext.exec_domain = ed->id;
  11.121 +                break;
  11.122 +            }
  11.123 +            active_index++;
  11.124 +        }
  11.125 +        op->u.getvcpucontext.cpu_time = ed->cpu_time;
  11.126 +
  11.127 +        if ( op->u.getvcpucontext.ctxt != NULL )
  11.128          {
  11.129              if ( (c = xmalloc(struct vcpu_guest_context)) == NULL )
  11.130              {
  11.131 @@ -376,7 +434,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
  11.132              if ( ed != current )
  11.133                  exec_domain_unpause(ed);
  11.134  
  11.135 -            if ( copy_to_user(op->u.getdomaininfo.ctxt, c, sizeof(*c)) )
  11.136 +            if ( copy_to_user(op->u.getvcpucontext.ctxt, c, sizeof(*c)) )
  11.137                  ret = -EINVAL;
  11.138  
  11.139              xfree(c);
    12.1 --- a/xen/include/public/dom0_ops.h	Wed May 11 14:15:56 2005 +0000
    12.2 +++ b/xen/include/public/dom0_ops.h	Wed May 11 15:05:07 2005 +0000
    12.3 @@ -70,7 +70,7 @@ typedef struct {
    12.4  typedef struct {
    12.5      /* IN variables. */
    12.6      domid_t  domain;                  /* NB. IN/OUT variable. */
    12.7 -    u16      exec_domain;
    12.8 +    u16      n_active_vcpus;          /* # of vcpus currently active */
    12.9      /* OUT variables. */
   12.10  #define DOMFLAGS_DYING     (1<<0) /* Domain is scheduled to die.             */
   12.11  #define DOMFLAGS_CRASHED   (1<<1) /* Crashed domain; frozen for postmortem.  */
   12.12 @@ -83,7 +83,7 @@ typedef struct {
   12.13  #define DOMFLAGS_SHUTDOWNMASK 255 /* DOMFLAGS_SHUTDOWN guest-supplied code.  */
   12.14  #define DOMFLAGS_SHUTDOWNSHIFT 16
   12.15      u32      flags;
   12.16 -    vcpu_guest_context_t *ctxt;   /* NB. IN/OUT variable. */
   12.17 +    u32      processors;	
   12.18      memory_t tot_pages;
   12.19      memory_t max_pages;
   12.20      memory_t shared_info_frame;       /* MFN of shared_info struct */
   12.21 @@ -345,6 +345,15 @@ typedef struct {
   12.22      u16     allow_access;             /* allow or deny access to range? */
   12.23  } dom0_ioport_permission_t;
   12.24  
   12.25 +#define DOM0_GETVCPUCONTEXT      37
   12.26 +typedef struct {
   12.27 +    domid_t domain;                   /* domain to be affected */
   12.28 +    u16     exec_domain;              /* NB. IN: nth active cpu / OUT: actual cpu # */
   12.29 +    vcpu_guest_context_t *ctxt;       /* NB. IN/OUT variable. */
   12.30 +    u64     cpu_time;                 
   12.31 +} dom0_getvcpucontext_t;
   12.32 +
   12.33 +
   12.34  typedef struct {
   12.35      u32 cmd;
   12.36      u32 interface_version; /* DOM0_INTERFACE_VERSION */
   12.37 @@ -376,6 +385,7 @@ typedef struct {
   12.38          dom0_perfccontrol_t      perfccontrol;
   12.39          dom0_microcode_t         microcode;
   12.40          dom0_ioport_permission_t ioport_permission;
   12.41 +        dom0_getvcpucontext_t    getvcpucontext;
   12.42      } u;
   12.43  } dom0_op_t;
   12.44