ia64/xen-unstable

changeset 19170:1dfcb2444c6e

Add a new domctl to get a single record from the HVM save context

Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Feb 05 12:16:28 2009 +0000 (2009-02-05)
parents 8303bd33d030
children 7eb8b094a207
files xen/arch/x86/domctl.c xen/common/hvm/save.c xen/include/public/domctl.h xen/include/xen/hvm/save.h xen/xsm/flask/hooks.c
line diff
     1.1 --- a/xen/arch/x86/domctl.c	Thu Feb 05 12:14:09 2009 +0000
     1.2 +++ b/xen/arch/x86/domctl.c	Thu Feb 05 12:16:28 2009 +0000
     1.3 @@ -417,6 +417,34 @@ long arch_do_domctl(
     1.4      }
     1.5      break;
     1.6  
     1.7 +    case XEN_DOMCTL_gethvmcontext_partial:
     1.8 +    { 
     1.9 +        struct domain *d;
    1.10 +
    1.11 +        ret = -ESRCH;
    1.12 +        if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL )
    1.13 +            break;
    1.14 +
    1.15 +        ret = xsm_hvmcontext(d, domctl->cmd);
    1.16 +        if ( ret )
    1.17 +            goto gethvmcontext_partial_out;
    1.18 +
    1.19 +        ret = -EINVAL;
    1.20 +        if ( !is_hvm_domain(d) ) 
    1.21 +            goto gethvmcontext_partial_out;
    1.22 +
    1.23 +        domain_pause(d);
    1.24 +        ret = hvm_save_one(d, domctl->u.hvmcontext_partial.type,
    1.25 +                           domctl->u.hvmcontext_partial.instance,
    1.26 +                           domctl->u.hvmcontext_partial.buffer);
    1.27 +        domain_unpause(d);
    1.28 +
    1.29 +    gethvmcontext_partial_out:
    1.30 +        rcu_unlock_domain(d);
    1.31 +    }
    1.32 +    break;
    1.33 +
    1.34 +
    1.35      case XEN_DOMCTL_set_address_size:
    1.36      {
    1.37          struct domain *d;
     2.1 --- a/xen/common/hvm/save.c	Thu Feb 05 12:14:09 2009 +0000
     2.2 +++ b/xen/common/hvm/save.c	Thu Feb 05 12:16:28 2009 +0000
     2.3 @@ -26,6 +26,7 @@
     2.4  #include <xen/version.h>
     2.5  #include <public/version.h>
     2.6  #include <xen/sched.h>
     2.7 +#include <xen/guest_access.h>
     2.8  
     2.9  #include <asm/hvm/support.h>
    2.10  
    2.11 @@ -75,6 +76,53 @@ size_t hvm_save_size(struct domain *d)
    2.12      return sz;
    2.13  }
    2.14  
    2.15 +/* Extract a single instance of a save record, by marshalling all
    2.16 + * records of that type and copying out the one we need. */
    2.17 +int hvm_save_one(struct domain *d, uint16_t typecode, uint16_t instance, 
    2.18 +                 XEN_GUEST_HANDLE_64(uint8) handle)
    2.19 +{
    2.20 +    int rv = 0;
    2.21 +    size_t sz = 0;
    2.22 +    struct vcpu *v;
    2.23 +    hvm_domain_context_t ctxt = { 0, };
    2.24 +
    2.25 +    if ( d->is_dying 
    2.26 +         || typecode > HVM_SAVE_CODE_MAX 
    2.27 +         || hvm_sr_handlers[typecode].size < sizeof(struct hvm_save_descriptor)
    2.28 +         || hvm_sr_handlers[typecode].save == NULL )
    2.29 +        return -EINVAL;
    2.30 +
    2.31 +    if ( hvm_sr_handlers[typecode].kind == HVMSR_PER_VCPU )
    2.32 +        for_each_vcpu(d, v)
    2.33 +            sz += hvm_sr_handlers[typecode].size;
    2.34 +    else 
    2.35 +        sz = hvm_sr_handlers[typecode].size;
    2.36 +    
    2.37 +    if ( (instance + 1) * hvm_sr_handlers[typecode].size > sz )
    2.38 +        return -EINVAL;
    2.39 +
    2.40 +    ctxt.size = sz;
    2.41 +    ctxt.data = xmalloc_bytes(sz);
    2.42 +    if ( !ctxt.data )
    2.43 +        return -ENOMEM;
    2.44 +
    2.45 +    if ( hvm_sr_handlers[typecode].save(d, &ctxt) != 0 )
    2.46 +    {
    2.47 +        gdprintk(XENLOG_ERR, 
    2.48 +                 "HVM save: failed to save type %"PRIu16"\n", typecode);
    2.49 +        rv = -EFAULT;
    2.50 +    }
    2.51 +    else if ( copy_to_guest(handle,
    2.52 +                            ctxt.data 
    2.53 +                            + (instance * hvm_sr_handlers[typecode].size) 
    2.54 +                            + sizeof (struct hvm_save_descriptor), 
    2.55 +                            hvm_sr_handlers[typecode].size
    2.56 +                            - sizeof (struct hvm_save_descriptor)) )
    2.57 +        rv = -EFAULT;
    2.58 +
    2.59 +    xfree(ctxt.data);
    2.60 +    return rv;
    2.61 +}
    2.62  
    2.63  int hvm_save(struct domain *d, hvm_domain_context_t *h)
    2.64  {
     3.1 --- a/xen/include/public/domctl.h	Thu Feb 05 12:14:09 2009 +0000
     3.2 +++ b/xen/include/public/domctl.h	Thu Feb 05 12:16:28 2009 +0000
     3.3 @@ -630,6 +630,17 @@ struct xen_domctl_debug_op {
     3.4  typedef struct xen_domctl_debug_op xen_domctl_debug_op_t;
     3.5  DEFINE_XEN_GUEST_HANDLE(xen_domctl_debug_op_t);
     3.6  
     3.7 +/*
     3.8 + * Request a particular record from the HVM context
     3.9 + */
    3.10 +#define XEN_DOMCTL_gethvmcontext_partial   55
    3.11 +typedef struct xen_domctl_hvmcontext_partial {
    3.12 +    uint32_t type;                      /* IN: Type of record required */
    3.13 +    uint32_t instance;                  /* IN: Instance of that type */
    3.14 +    XEN_GUEST_HANDLE_64(uint8) buffer;  /* OUT: buffer to write record into */
    3.15 +} xen_domctl_hvmcontext_partial_t;
    3.16 +DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_partial_t);
    3.17 +
    3.18  
    3.19  struct xen_domctl {
    3.20      uint32_t cmd;
    3.21 @@ -658,6 +669,7 @@ struct xen_domctl {
    3.22          struct xen_domctl_settimeoffset     settimeoffset;
    3.23          struct xen_domctl_real_mode_area    real_mode_area;
    3.24          struct xen_domctl_hvmcontext        hvmcontext;
    3.25 +        struct xen_domctl_hvmcontext_partial hvmcontext_partial;
    3.26          struct xen_domctl_address_size      address_size;
    3.27          struct xen_domctl_sendtrigger       sendtrigger;
    3.28          struct xen_domctl_get_device_group  get_device_group;
     4.1 --- a/xen/include/xen/hvm/save.h	Thu Feb 05 12:14:09 2009 +0000
     4.2 +++ b/xen/include/xen/hvm/save.h	Thu Feb 05 12:16:28 2009 +0000
     4.3 @@ -152,6 +152,8 @@ static int __hvm_register_##_x##_save_an
     4.4  /* Entry points for saving and restoring HVM domain state */
     4.5  size_t hvm_save_size(struct domain *d);
     4.6  int hvm_save(struct domain *d, hvm_domain_context_t *h);
     4.7 +int hvm_save_one(struct domain *d,  uint16_t typecode, uint16_t instance, 
     4.8 +                 XEN_GUEST_HANDLE_64(uint8) handle);
     4.9  int hvm_load(struct domain *d, hvm_domain_context_t *h);
    4.10  
    4.11  /* Arch-specific definitions. */
     5.1 --- a/xen/xsm/flask/hooks.c	Thu Feb 05 12:14:09 2009 +0000
     5.2 +++ b/xen/xsm/flask/hooks.c	Thu Feb 05 12:16:28 2009 +0000
     5.3 @@ -820,6 +820,7 @@ static int flask_hvmcontext(struct domai
     5.4              perm = HVM__SETHVMC;
     5.5          break;
     5.6          case XEN_DOMCTL_gethvmcontext:
     5.7 +        case XEN_DOMCTL_gethvmcontext_partial:
     5.8              perm = HVM__GETHVMC;
     5.9          break;
    5.10          default: