ia64/xen-unstable

changeset 13793:5e66c05c67ad

[HVM] Save/restore: clean up the new hypercall interface
Pass a buffer and size through instead of fixed-size structure.

Signed-off-by: Zhai Edwin <edwin.zhai@intel.com>
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
author Tim Deegan <Tim.Deegan@xensource.com>
date Wed Jan 31 17:22:00 2007 +0000 (2007-01-31)
parents 54678a99e102
children 5d09e6098f93
files tools/libxc/xc_domain.c tools/libxc/xc_hvm_restore.c tools/libxc/xc_hvm_save.c tools/libxc/xenctrl.h xen/arch/x86/domctl.c xen/arch/x86/hvm/intercept.c xen/include/asm-x86/hvm/domain.h xen/include/asm-x86/hvm/support.h xen/include/public/domctl.h
line diff
     1.1 --- a/tools/libxc/xc_domain.c	Wed Jan 31 12:23:35 2007 +0000
     1.2 +++ b/tools/libxc/xc_domain.c	Wed Jan 31 17:22:00 2007 +0000
     1.3 @@ -241,45 +241,49 @@ int xc_domain_getinfolist(int xc_handle,
     1.4  /* get info from hvm guest for save */
     1.5  int xc_domain_hvm_getcontext(int xc_handle,
     1.6                               uint32_t domid,
     1.7 -                             hvm_domain_context_t *hvm_ctxt)
     1.8 +                             uint8_t *ctxt_buf,
     1.9 +                             uint32_t size)
    1.10  {
    1.11 -    int rc;
    1.12 +    int ret;
    1.13      DECLARE_DOMCTL;
    1.14  
    1.15      domctl.cmd = XEN_DOMCTL_gethvmcontext;
    1.16      domctl.domain = (domid_t)domid;
    1.17 -    set_xen_guest_handle(domctl.u.hvmcontext.ctxt, hvm_ctxt);
    1.18 +    domctl.u.hvmcontext.size = size;
    1.19 +    set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf);
    1.20  
    1.21 -    if ( (rc = mlock(hvm_ctxt, sizeof(*hvm_ctxt))) != 0 )
    1.22 -        return rc;
    1.23 +    if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
    1.24 +        return ret;
    1.25  
    1.26 -    rc = do_domctl(xc_handle, &domctl);
    1.27 +    ret = do_domctl(xc_handle, &domctl);
    1.28  
    1.29 -    safe_munlock(hvm_ctxt, sizeof(*hvm_ctxt));
    1.30 +    unlock_pages(ctxt_buf, size);
    1.31  
    1.32 -    return rc;
    1.33 +    return (ret < 0 ? -1 : domctl.u.hvmcontext.size);
    1.34  }
    1.35  
    1.36  /* set info to hvm guest for restore */
    1.37  int xc_domain_hvm_setcontext(int xc_handle,
    1.38                               uint32_t domid,
    1.39 -                             hvm_domain_context_t *hvm_ctxt)
    1.40 +                             uint8_t *ctxt_buf,
    1.41 +                             uint32_t size)
    1.42  {
    1.43 -    int rc;
    1.44 +    int ret;
    1.45      DECLARE_DOMCTL;
    1.46  
    1.47      domctl.cmd = XEN_DOMCTL_sethvmcontext;
    1.48      domctl.domain = domid;
    1.49 -    set_xen_guest_handle(domctl.u.hvmcontext.ctxt, hvm_ctxt);
    1.50 +    domctl.u.hvmcontext.size = size;
    1.51 +    set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf);
    1.52  
    1.53 -    if ( (rc = mlock(hvm_ctxt, sizeof(*hvm_ctxt))) != 0 )
    1.54 -        return rc;
    1.55 +    if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
    1.56 +        return ret;
    1.57  
    1.58 -    rc = do_domctl(xc_handle, &domctl);
    1.59 +    ret = do_domctl(xc_handle, &domctl);
    1.60  
    1.61 -    safe_munlock(hvm_ctxt, sizeof(*hvm_ctxt));
    1.62 +    unlock_pages(ctxt_buf, size);
    1.63  
    1.64 -    return rc;
    1.65 +    return ret;
    1.66  }
    1.67  
    1.68  int xc_vcpu_getcontext(int xc_handle,
     2.1 --- a/tools/libxc/xc_hvm_restore.c	Wed Jan 31 12:23:35 2007 +0000
     2.2 +++ b/tools/libxc/xc_hvm_restore.c	Wed Jan 31 17:22:00 2007 +0000
     2.3 @@ -87,7 +87,7 @@ int xc_hvm_restore(int xc_handle, int io
     2.4      xc_dominfo_t info;
     2.5      unsigned int rc = 1, n, i;
     2.6      uint32_t rec_len, nr_vcpus;
     2.7 -    hvm_domain_context_t hvm_ctxt;
     2.8 +    uint8_t *hvm_buf = NULL;
     2.9      unsigned long long v_end, memsize;
    2.10      unsigned long shared_page_nr;
    2.11  
    2.12 @@ -128,8 +128,7 @@ int xc_hvm_restore(int xc_handle, int io
    2.13      }
    2.14  
    2.15  
    2.16 -    p2m        = malloc(max_pfn * sizeof(xen_pfn_t));
    2.17 -
    2.18 +    p2m = malloc(max_pfn * sizeof(xen_pfn_t));
    2.19      if (p2m == NULL) {
    2.20          ERROR("memory alloc failed");
    2.21          errno = ENOMEM;
    2.22 @@ -297,18 +296,21 @@ int xc_hvm_restore(int xc_handle, int io
    2.23          ERROR("error read hvm context size!\n");
    2.24          goto out;
    2.25      }
    2.26 -    if (rec_len != sizeof(hvm_ctxt)) {
    2.27 -        ERROR("hvm context size dismatch!\n");
    2.28 +
    2.29 +    hvm_buf = malloc(rec_len);
    2.30 +    if (hvm_buf == NULL) {
    2.31 +        ERROR("memory alloc for hvm context buffer failed");
    2.32 +        errno = ENOMEM;
    2.33          goto out;
    2.34      }
    2.35  
    2.36 -    if (!read_exact(io_fd, &hvm_ctxt, sizeof(hvm_ctxt))) {
    2.37 -        ERROR("error read hvm context!\n");
    2.38 +    if (!read_exact(io_fd, hvm_buf, rec_len)) {
    2.39 +        ERROR("error read hvm buffer!\n");
    2.40          goto out;
    2.41      }
    2.42  
    2.43 -    if (( rc = xc_domain_hvm_setcontext(xc_handle, dom, &hvm_ctxt))) {
    2.44 -        ERROR("error set hvm context!\n");
    2.45 +    if (( rc = xc_domain_hvm_setcontext(xc_handle, dom, hvm_buf, rec_len))) {
    2.46 +        ERROR("error set hvm buffer!\n");
    2.47          goto out;
    2.48      }
    2.49  
    2.50 @@ -361,6 +363,7 @@ int xc_hvm_restore(int xc_handle, int io
    2.51      if ( (rc != 0) && (dom != 0) )
    2.52          xc_domain_destroy(xc_handle, dom);
    2.53      free(p2m);
    2.54 +    free(hvm_buf);
    2.55  
    2.56      DPRINTF("Restore exit with rc=%d\n", rc);
    2.57  
     3.1 --- a/tools/libxc/xc_hvm_save.c	Wed Jan 31 12:23:35 2007 +0000
     3.2 +++ b/tools/libxc/xc_hvm_save.c	Wed Jan 31 17:22:00 2007 +0000
     3.3 @@ -33,6 +33,12 @@
     3.4  #include "xg_save_restore.h"
     3.5  
     3.6  /*
     3.7 + * Size of a buffer big enough to take the HVM state of a domain.
     3.8 + * Ought to calculate this a bit more carefully, or maybe ask Xen.
     3.9 + */
    3.10 +#define HVM_CTXT_SIZE 8192
    3.11 +
    3.12 +/*
    3.13  ** Default values for important tuning parameters. Can override by passing
    3.14  ** non-zero replacement values to xc_hvm_save().
    3.15  **
    3.16 @@ -279,8 +285,8 @@ int xc_hvm_save(int xc_handle, int io_fd
    3.17      unsigned long *pfn_type = NULL;
    3.18      unsigned long *pfn_batch = NULL;
    3.19  
    3.20 -    /* A copy of hvm domain context */
    3.21 -    hvm_domain_context_t hvm_ctxt;
    3.22 +    /* A copy of hvm domain context buffer*/
    3.23 +    uint8_t *hvm_buf = NULL;
    3.24  
    3.25      /* Live mapping of shared info structure */
    3.26      shared_info_t *live_shinfo = NULL;
    3.27 @@ -423,8 +429,12 @@ int xc_hvm_save(int xc_handle, int io_fd
    3.28      to_send = malloc(BITMAP_SIZE);
    3.29      to_skip = malloc(BITMAP_SIZE);
    3.30  
    3.31 -    if (!to_send ||!to_skip) {
    3.32 -        ERROR("Couldn't allocate to_send array");
    3.33 +    page_array = (unsigned long *) malloc( sizeof(unsigned long) * max_pfn);
    3.34 +
    3.35 +    hvm_buf = malloc(HVM_CTXT_SIZE);
    3.36 +
    3.37 +    if (!to_send ||!to_skip ||!page_array ||!hvm_buf ) {
    3.38 +        ERROR("Couldn't allocate memory");
    3.39          goto out;
    3.40      }
    3.41  
    3.42 @@ -444,11 +454,6 @@ int xc_hvm_save(int xc_handle, int io_fd
    3.43      analysis_phase(xc_handle, dom, max_pfn, to_skip, 0);
    3.44  
    3.45      /* get all the HVM domain pfns */
    3.46 -    if ( (page_array = (unsigned long *) malloc (sizeof(unsigned long) * max_pfn)) == NULL) {
    3.47 -        ERROR("HVM:malloc fail!\n");
    3.48 -        goto out;
    3.49 -    }
    3.50 -
    3.51      for ( i = 0; i < max_pfn; i++)
    3.52          page_array[i] = i;
    3.53  
    3.54 @@ -655,24 +660,18 @@ int xc_hvm_save(int xc_handle, int io_fd
    3.55          goto out;
    3.56      }
    3.57  
    3.58 -    /* save hvm hypervisor state including pic/pit/shpage */
    3.59 -    if (mlock(&hvm_ctxt, sizeof(hvm_ctxt))) {
    3.60 -        ERROR("Unable to mlock ctxt");
    3.61 -        return 1;
    3.62 -    }
    3.63 -
    3.64 -    if (xc_domain_hvm_getcontext(xc_handle, dom, &hvm_ctxt)){
    3.65 -        ERROR("HVM:Could not get hvm context");
    3.66 +    if ( (rec_size = xc_domain_hvm_getcontext(xc_handle, dom, hvm_buf, 
    3.67 +                                              HVM_CTXT_SIZE)) == -1) {
    3.68 +        ERROR("HVM:Could not get hvm buffer");
    3.69          goto out;
    3.70      }
    3.71  
    3.72 -    rec_size = sizeof(hvm_ctxt);
    3.73      if (!write_exact(io_fd, &rec_size, sizeof(uint32_t))) {
    3.74 -        ERROR("error write hvm ctxt size");
    3.75 +        ERROR("error write hvm buffer size");
    3.76          goto out;
    3.77      }
    3.78  
    3.79 -    if ( !write_exact(io_fd, &hvm_ctxt, sizeof(hvm_ctxt)) ) {
    3.80 +    if ( !write_exact(io_fd, hvm_buf, rec_size) ) {
    3.81          ERROR("write HVM info failed!\n");
    3.82      }
    3.83  
    3.84 @@ -722,6 +721,7 @@ int xc_hvm_save(int xc_handle, int io_fd
    3.85          }
    3.86      }
    3.87  
    3.88 +    free(hvm_buf);
    3.89      free(page_array);
    3.90  
    3.91      free(pfn_type);
     4.1 --- a/tools/libxc/xenctrl.h	Wed Jan 31 12:23:35 2007 +0000
     4.2 +++ b/tools/libxc/xenctrl.h	Wed Jan 31 17:22:00 2007 +0000
     4.3 @@ -328,13 +328,15 @@ int xc_domain_getinfolist(int xc_handle,
     4.4   * This function returns information about the context of a hvm domain
     4.5   * @parm xc_handle a handle to an open hypervisor interface
     4.6   * @parm domid the domain to get information from
     4.7 - * @parm hvm_ctxt a pointer to a structure to store the execution context of the
     4.8 - *            hvm domain
     4.9 + * @parm ctxt_buf a pointer to a structure to store the execution context of
    4.10 + *            the hvm domain
    4.11 + * @parm size the size of ctxt_buf in bytes
    4.12   * @return 0 on success, -1 on failure
    4.13   */
    4.14  int xc_domain_hvm_getcontext(int xc_handle,
    4.15                               uint32_t domid,
    4.16 -                             hvm_domain_context_t *hvm_ctxt);
    4.17 +                             uint8_t *ctxt_buf,
    4.18 +                             uint32_t size);
    4.19  
    4.20  /**
    4.21   * This function will set the context for hvm domain
    4.22 @@ -342,11 +344,13 @@ int xc_domain_hvm_getcontext(int xc_hand
    4.23   * @parm xc_handle a handle to an open hypervisor interface
    4.24   * @parm domid the domain to set the hvm domain context for
    4.25   * @parm hvm_ctxt pointer to the the hvm context with the values to set
    4.26 + * @parm size the size of hvm_ctxt in bytes
    4.27   * @return 0 on success, -1 on failure
    4.28   */
    4.29  int xc_domain_hvm_setcontext(int xc_handle,
    4.30                               uint32_t domid,
    4.31 -                             hvm_domain_context_t *hvm_ctxt);
    4.32 +                             uint8_t *hvm_ctxt,
    4.33 +                             uint32_t size);
    4.34  
    4.35  /**
    4.36   * This function returns information about the execution context of a
     5.1 --- a/xen/arch/x86/domctl.c	Wed Jan 31 12:23:35 2007 +0000
     5.2 +++ b/xen/arch/x86/domctl.c	Wed Jan 31 17:22:00 2007 +0000
     5.3 @@ -288,71 +288,73 @@ long arch_do_domctl(
     5.4  
     5.5      case XEN_DOMCTL_sethvmcontext:
     5.6      { 
     5.7 -        struct hvm_domain_context *c;
     5.8 +        struct hvm_domain_context c;
     5.9          struct domain             *d;
    5.10  
    5.11 +        c.cur = 0;
    5.12 +        c.size = domctl->u.hvmcontext.size;
    5.13 +        c.data = NULL;
    5.14 +        
    5.15          ret = -ESRCH;
    5.16          if ( (d = get_domain_by_id(domctl->domain)) == NULL )
    5.17              break;
    5.18  
    5.19 -        ret = -ENOMEM;
    5.20 -        if ( (c = xmalloc(struct hvm_domain_context)) == NULL )
    5.21 -            goto sethvmcontext_out;
    5.22 -        
    5.23 -        ret = -EFAULT;
    5.24 -        if ( copy_from_guest(c, domctl->u.hvmcontext.ctxt, 1) != 0 )
    5.25 -            goto sethvmcontext_out;
    5.26 -        c->size = sizeof (c->data);
    5.27 -        c->cur = 0;
    5.28 -
    5.29          ret = -EINVAL;
    5.30          if ( !is_hvm_domain(d) ) 
    5.31              goto sethvmcontext_out;
    5.32  
    5.33 -        ret = hvm_load(d, c);
    5.34 +        ret = -ENOMEM;
    5.35 +        if ( (c.data = xmalloc_bytes(c.size)) == NULL )
    5.36 +            goto sethvmcontext_out;
    5.37  
    5.38 -        xfree(c);
    5.39 +        ret = -EFAULT;
    5.40 +        if ( copy_from_guest(c.data, domctl->u.hvmcontext.buffer, c.size) != 0)
    5.41 +            goto sethvmcontext_out;
    5.42 +
    5.43 +        ret = hvm_load(d, &c);
    5.44  
    5.45      sethvmcontext_out:
    5.46 +        if ( c.data != NULL )
    5.47 +            xfree(c.data);
    5.48 +
    5.49          put_domain(d);
    5.50 -
    5.51      }
    5.52      break;
    5.53  
    5.54      case XEN_DOMCTL_gethvmcontext:
    5.55      { 
    5.56 -        struct hvm_domain_context *c;
    5.57 +        struct hvm_domain_context c;
    5.58          struct domain             *d;
    5.59  
    5.60 +        c.cur = 0;
    5.61 +        c.size = domctl->u.hvmcontext.size;
    5.62 +        c.data = NULL;
    5.63 +
    5.64          ret = -ESRCH;
    5.65          if ( (d = get_domain_by_id(domctl->domain)) == NULL )
    5.66              break;
    5.67  
    5.68 -        ret = -ENOMEM;
    5.69 -        if ( (c = xmalloc(struct hvm_domain_context)) == NULL )
    5.70 -            goto gethvmcontext_out;
    5.71 -        memset(c, 0, sizeof(*c));
    5.72 -        c->size = sizeof (c->data);
    5.73 -        
    5.74 -        ret = -ENODATA;
    5.75 +        ret = -EINVAL;
    5.76          if ( !is_hvm_domain(d) ) 
    5.77              goto gethvmcontext_out;
    5.78 -        
    5.79 -        ret = 0;
    5.80 -        if (hvm_save(d, c) != 0)
    5.81 -            ret = -EFAULT;
    5.82 +
    5.83 +        ret = -ENOMEM;
    5.84 +        if ( (c.data = xmalloc_bytes(c.size)) == NULL )
    5.85 +            goto gethvmcontext_out;
    5.86  
    5.87 -        if ( copy_to_guest(domctl->u.hvmcontext.ctxt, c, 1) )
    5.88 +        ret = hvm_save(d, &c);
    5.89 +
    5.90 +        if ( copy_to_guest(domctl->u.hvmcontext.buffer, c.data, c.size) != 0 )
    5.91              ret = -EFAULT;
    5.92  
    5.93 -        xfree(c);
    5.94 -
    5.95          if ( copy_to_guest(u_domctl, domctl, 1) )
    5.96              ret = -EFAULT;
    5.97  
    5.98      gethvmcontext_out:
    5.99 +        if ( c.data != NULL )
   5.100 +            xfree(c.data);
   5.101 +
   5.102          put_domain(d);
   5.103 -
   5.104      }
   5.105      break;
   5.106  
     6.1 --- a/xen/arch/x86/hvm/intercept.c	Wed Jan 31 12:23:35 2007 +0000
     6.2 +++ b/xen/arch/x86/hvm/intercept.c	Wed Jan 31 17:22:00 2007 +0000
     6.3 @@ -205,7 +205,7 @@ int hvm_save(struct domain *d, hvm_domai
     6.4      if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 )
     6.5      {
     6.6          gdprintk(XENLOG_ERR, "HVM save: failed to write header\n");
     6.7 -        return -1;
     6.8 +        return -EFAULT;
     6.9      } 
    6.10  
    6.11      /* Save all available kinds of state */
    6.12 @@ -219,7 +219,7 @@ int hvm_save(struct domain *d, hvm_domai
    6.13              {
    6.14                  gdprintk(XENLOG_ERR, 
    6.15                           "HVM save: failed to save type %"PRIu16"\n", i);
    6.16 -                return -1;
    6.17 +                return -EFAULT;
    6.18              } 
    6.19          }
    6.20      }
    6.21 @@ -229,7 +229,7 @@ int hvm_save(struct domain *d, hvm_domai
    6.22      {
    6.23          /* Run out of data */
    6.24          gdprintk(XENLOG_ERR, "HVM save: no room for end marker.\n");
    6.25 -        return -1;
    6.26 +        return -EFAULT;
    6.27      }
    6.28  
    6.29      /* Save macros should not have let us overrun */
     7.1 --- a/xen/include/asm-x86/hvm/domain.h	Wed Jan 31 12:23:35 2007 +0000
     7.2 +++ b/xen/include/asm-x86/hvm/domain.h	Wed Jan 31 17:22:00 2007 +0000
     7.3 @@ -49,8 +49,6 @@ struct hvm_domain {
     7.4      spinlock_t             pbuf_lock;
     7.5  
     7.6      uint64_t               params[HVM_NR_PARAMS];
     7.7 -
     7.8 -    struct hvm_domain_context *hvm_ctxt;
     7.9  };
    7.10  
    7.11  #endif /* __ASM_X86_HVM_DOMAIN_H__ */
     8.1 --- a/xen/include/asm-x86/hvm/support.h	Wed Jan 31 12:23:35 2007 +0000
     8.2 +++ b/xen/include/asm-x86/hvm/support.h	Wed Jan 31 17:22:00 2007 +0000
     8.3 @@ -123,6 +123,13 @@ extern unsigned int opt_hvm_debug_level;
     8.4   * Save/restore support 
     8.5   */
     8.6  
     8.7 +/* Marshalling and unmarshalling uses a buffer with size and cursor. */
     8.8 +typedef struct hvm_domain_context {
     8.9 +    uint32_t cur;
    8.10 +    uint32_t size;
    8.11 +    uint8_t *data;
    8.12 +} hvm_domain_context_t;
    8.13 +
    8.14  /* Marshalling an entry: check space and fill in the header */
    8.15  static inline int _hvm_init_entry(struct hvm_domain_context *h,
    8.16                                    uint16_t tc, uint16_t inst, uint32_t len)
     9.1 --- a/xen/include/public/domctl.h	Wed Jan 31 12:23:35 2007 +0000
     9.2 +++ b/xen/include/public/domctl.h	Wed Jan 31 17:22:00 2007 +0000
     9.3 @@ -386,18 +386,11 @@ struct xen_domctl_settimeoffset {
     9.4  typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t;
     9.5  DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t);
     9.6   
     9.7 -#define HVM_CTXT_SIZE        8192
     9.8 -typedef struct hvm_domain_context {
     9.9 -    uint32_t cur;
    9.10 -    uint32_t size;
    9.11 -    uint8_t data[HVM_CTXT_SIZE];
    9.12 -} hvm_domain_context_t;
    9.13 -DEFINE_XEN_GUEST_HANDLE(hvm_domain_context_t);
    9.14 -
    9.15  #define XEN_DOMCTL_gethvmcontext   33
    9.16  #define XEN_DOMCTL_sethvmcontext   34
    9.17  typedef struct xen_domctl_hvmcontext {
    9.18 -    XEN_GUEST_HANDLE_64(hvm_domain_context_t) ctxt;  /* IN/OUT */
    9.19 +    uint32_t size; /* IN/OUT: size of buffer / bytes filled */
    9.20 +    XEN_GUEST_HANDLE(uint8_t) buffer; /* IN/OUT */
    9.21  } xen_domctl_hvmcontext_t;
    9.22  DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_t);
    9.23