direct-io.hg

changeset 13414:44668189f354

[HVM] save restore: new hyper-call

Signed-off-by: Zhai Edwin <edwin.zhai@intel.com>

add a pair of hyper-call for hvm guest context
author Tim Deegan <Tim.Deegan@xensource.com>
date Thu Jan 18 16:48:04 2007 +0000 (2007-01-18)
parents 1e590ddb1277
children 5f340f19bbb7
files tools/libxc/xc_domain.c tools/libxc/xenctrl.h xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/intercept.c xen/common/domctl.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	Thu Jan 18 16:48:03 2007 +0000
     1.2 +++ b/tools/libxc/xc_domain.c	Thu Jan 18 16:48:04 2007 +0000
     1.3 @@ -235,6 +235,50 @@ int xc_domain_getinfolist(int xc_handle,
     1.4      return ret;
     1.5  }
     1.6  
     1.7 +/* get info from hvm guest for save */
     1.8 +int xc_domain_hvm_getcontext(int xc_handle,
     1.9 +                             uint32_t domid,
    1.10 +                             hvm_domain_context_t *hvm_ctxt)
    1.11 +{
    1.12 +    int rc;
    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 +
    1.19 +    if ( (rc = mlock(hvm_ctxt, sizeof(*hvm_ctxt))) != 0 )
    1.20 +        return rc;
    1.21 +
    1.22 +    rc = do_domctl(xc_handle, &domctl);
    1.23 +
    1.24 +    safe_munlock(hvm_ctxt, sizeof(*hvm_ctxt));
    1.25 +
    1.26 +    return rc;
    1.27 +}
    1.28 +
    1.29 +/* set info to hvm guest for restore */
    1.30 +int xc_domain_hvm_setcontext(int xc_handle,
    1.31 +                             uint32_t domid,
    1.32 +                             hvm_domain_context_t *hvm_ctxt)
    1.33 +{
    1.34 +    int rc;
    1.35 +    DECLARE_DOMCTL;
    1.36 +
    1.37 +    domctl.cmd = XEN_DOMCTL_sethvmcontext;
    1.38 +    domctl.domain = domid;
    1.39 +    set_xen_guest_handle(domctl.u.hvmcontext.ctxt, hvm_ctxt);
    1.40 +
    1.41 +    if ( (rc = mlock(hvm_ctxt, sizeof(*hvm_ctxt))) != 0 )
    1.42 +        return rc;
    1.43 +
    1.44 +    rc = do_domctl(xc_handle, &domctl);
    1.45 +
    1.46 +    safe_munlock(hvm_ctxt, sizeof(*hvm_ctxt));
    1.47 +
    1.48 +    return rc;
    1.49 +}
    1.50 +
    1.51  int xc_vcpu_getcontext(int xc_handle,
    1.52                                 uint32_t domid,
    1.53                                 uint32_t vcpu,
     2.1 --- a/tools/libxc/xenctrl.h	Thu Jan 18 16:48:03 2007 +0000
     2.2 +++ b/tools/libxc/xenctrl.h	Thu Jan 18 16:48:04 2007 +0000
     2.3 @@ -313,6 +313,30 @@ int xc_domain_getinfolist(int xc_handle,
     2.4                            xc_domaininfo_t *info);
     2.5  
     2.6  /**
     2.7 + * This function returns information about the context of a hvm domain
     2.8 + * @parm xc_handle a handle to an open hypervisor interface
     2.9 + * @parm domid the domain to get information from
    2.10 + * @parm hvm_ctxt a pointer to a structure to store the execution context of the
    2.11 + *            hvm domain
    2.12 + * @return 0 on success, -1 on failure
    2.13 + */
    2.14 +int xc_domain_hvm_getcontext(int xc_handle,
    2.15 +                             uint32_t domid,
    2.16 +                             hvm_domain_context_t *hvm_ctxt);
    2.17 +
    2.18 +/**
    2.19 + * This function will set the context for hvm domain
    2.20 + *
    2.21 + * @parm xc_handle a handle to an open hypervisor interface
    2.22 + * @parm domid the domain to set the hvm domain context for
    2.23 + * @parm hvm_ctxt pointer to the the hvm context with the values to set
    2.24 + * @return 0 on success, -1 on failure
    2.25 + */
    2.26 +int xc_domain_hvm_setcontext(int xc_handle,
    2.27 +                             uint32_t domid,
    2.28 +                             hvm_domain_context_t *hvm_ctxt);
    2.29 +
    2.30 +/**
    2.31   * This function returns information about the execution context of a
    2.32   * particular vcpu of a domain.
    2.33   *
     3.1 --- a/xen/arch/x86/hvm/hvm.c	Thu Jan 18 16:48:03 2007 +0000
     3.2 +++ b/xen/arch/x86/hvm/hvm.c	Thu Jan 18 16:48:04 2007 +0000
     3.3 @@ -149,11 +149,19 @@ int hvm_domain_initialise(struct domain 
     3.4  
     3.5  void hvm_domain_destroy(struct domain *d)
     3.6  {
     3.7 +    HVMStateEntry *se, *dse;
     3.8      pit_deinit(d);
     3.9      rtc_deinit(d);
    3.10      pmtimer_deinit(d);
    3.11      hpet_deinit(d);
    3.12  
    3.13 +    se = d->arch.hvm_domain.first_se;
    3.14 +    while (se) {
    3.15 +        dse = se;
    3.16 +        se = se->next;
    3.17 +        xfree(dse);
    3.18 +    }
    3.19 + 
    3.20      if ( d->arch.hvm_domain.shared_page_va )
    3.21          unmap_domain_page_global(
    3.22              (void *)d->arch.hvm_domain.shared_page_va);
     4.1 --- a/xen/arch/x86/hvm/intercept.c	Thu Jan 18 16:48:03 2007 +0000
     4.2 +++ b/xen/arch/x86/hvm/intercept.c	Thu Jan 18 16:48:04 2007 +0000
     4.3 @@ -29,6 +29,8 @@
     4.4  #include <asm/current.h>
     4.5  #include <io_ports.h>
     4.6  #include <xen/event.h>
     4.7 +#include <xen/compile.h>
     4.8 +#include <public/version.h>
     4.9  
    4.10  
    4.11  extern struct hvm_mmio_handler hpet_mmio_handler;
    4.12 @@ -155,6 +157,235 @@ static inline void hvm_mmio_access(struc
    4.13      }
    4.14  }
    4.15  
    4.16 +/* save/restore support */
    4.17 +#define HVM_FILE_MAGIC   0x54381286
    4.18 +#define HVM_FILE_VERSION 0x00000001
    4.19 +
    4.20 +int hvm_register_savevm(struct domain *d,
    4.21 +                    const char *idstr,
    4.22 +                    int instance_id,
    4.23 +                    int version_id,
    4.24 +                    SaveStateHandler *save_state,
    4.25 +                    LoadStateHandler *load_state,
    4.26 +                    void *opaque)
    4.27 +{
    4.28 +    HVMStateEntry *se, **pse;
    4.29 +
    4.30 +    if ( (se = xmalloc(struct HVMStateEntry)) == NULL ){
    4.31 +        printk("allocat hvmstate entry fail.\n");
    4.32 +        return -1;
    4.33 +    }
    4.34 +
    4.35 +    strncpy(se->idstr, idstr, HVM_SE_IDSTR_LEN);
    4.36 +
    4.37 +    se->instance_id = instance_id;
    4.38 +    se->version_id = version_id;
    4.39 +    se->save_state = save_state;
    4.40 +    se->load_state = load_state;
    4.41 +    se->opaque = opaque;
    4.42 +    se->next = NULL;
    4.43 +
    4.44 +    /* add at the end of list */
    4.45 +    pse = &d->arch.hvm_domain.first_se;
    4.46 +    while (*pse != NULL)
    4.47 +        pse = &(*pse)->next;
    4.48 +    *pse = se;
    4.49 +    return 0;
    4.50 +}
    4.51 +
    4.52 +int hvm_save(struct vcpu *v, hvm_domain_context_t *h)
    4.53 +{
    4.54 +    uint32_t len, len_pos, cur_pos;
    4.55 +    uint32_t eax, ebx, ecx, edx;
    4.56 +    HVMStateEntry *se;
    4.57 +    char *chgset;
    4.58 +
    4.59 +    if (!is_hvm_vcpu(v)) {
    4.60 +        printk("hvm_save only for hvm guest!\n");
    4.61 +        return -1;
    4.62 +    }
    4.63 +
    4.64 +    memset(h, 0, sizeof(hvm_domain_context_t));
    4.65 +    hvm_put_32u(h, HVM_FILE_MAGIC);
    4.66 +    hvm_put_32u(h, HVM_FILE_VERSION);
    4.67 +
    4.68 +    /* save xen changeset */
    4.69 +    chgset = strrchr(XEN_CHANGESET, ' ') + 1;
    4.70 +
    4.71 +    len = strlen(chgset);
    4.72 +    hvm_put_8u(h, len);
    4.73 +    hvm_put_buffer(h, chgset, len);
    4.74 +
    4.75 +    /* save cpuid */
    4.76 +    cpuid(1, &eax, &ebx, &ecx, &edx);
    4.77 +    hvm_put_32u(h, eax);
    4.78 +
    4.79 +    for(se = v->domain->arch.hvm_domain.first_se; se != NULL; se = se->next) {
    4.80 +        /* ID string */
    4.81 +        len = strnlen(se->idstr, HVM_SE_IDSTR_LEN);
    4.82 +        hvm_put_8u(h, len);
    4.83 +        hvm_put_buffer(h, se->idstr, len);
    4.84 +
    4.85 +        hvm_put_32u(h, se->instance_id);
    4.86 +        hvm_put_32u(h, se->version_id);
    4.87 +
    4.88 +        /* record size */
    4.89 +        len_pos = hvm_ctxt_tell(h);
    4.90 +        hvm_put_32u(h, 0);
    4.91 +
    4.92 +        se->save_state(h, se->opaque);
    4.93 +
    4.94 +        cur_pos = hvm_ctxt_tell(h);
    4.95 +        len = cur_pos - len_pos - 4;
    4.96 +        hvm_ctxt_seek(h, len_pos);
    4.97 +        hvm_put_32u(h, len);
    4.98 +        hvm_ctxt_seek(h, cur_pos);
    4.99 +
   4.100 +    }
   4.101 +
   4.102 +    h->size = hvm_ctxt_tell(h);
   4.103 +    hvm_ctxt_seek(h, 0);
   4.104 +
   4.105 +    if (h->size >= HVM_CTXT_SIZE) {
   4.106 +        printk("hvm_domain_context overflow when hvm_save! need %"PRId32" bytes for use.\n", h->size);
   4.107 +        return -1;
   4.108 +    }
   4.109 +
   4.110 +    return 0;
   4.111 +
   4.112 +}
   4.113 +
   4.114 +static HVMStateEntry *find_se(struct domain *d, const char *idstr, int instance_id)
   4.115 +{
   4.116 +    HVMStateEntry *se;
   4.117 +
   4.118 +    for(se = d->arch.hvm_domain.first_se; se != NULL; se = se->next) {
   4.119 +        if (!strncmp(se->idstr, idstr, HVM_SE_IDSTR_LEN) &&
   4.120 +            instance_id == se->instance_id){
   4.121 +            return se;
   4.122 +        }
   4.123 +    }
   4.124 +    return NULL;
   4.125 +}
   4.126 +
   4.127 +int hvm_load(struct vcpu *v, hvm_domain_context_t *h)
   4.128 +{
   4.129 +    uint32_t len, rec_len, rec_pos, magic, instance_id, version_id;
   4.130 +    uint32_t eax, ebx, ecx, edx;
   4.131 +    HVMStateEntry *se;
   4.132 +    char idstr[HVM_SE_IDSTR_LEN];
   4.133 +    xen_changeset_info_t chgset;
   4.134 +    char *cur_chgset;
   4.135 +    int ret;
   4.136 +
   4.137 +    if (!is_hvm_vcpu(v)) {
   4.138 +        printk("hvm_load only for hvm guest!\n");
   4.139 +        return -1;
   4.140 +    }
   4.141 +
   4.142 +    if (h->size >= HVM_CTXT_SIZE) {
   4.143 +        printk("hvm_load fail! seems hvm_domain_context overflow when hvm_save! need %"PRId32" bytes.\n", h->size);
   4.144 +        return -1;
   4.145 +    }
   4.146 +
   4.147 +    hvm_ctxt_seek(h, 0);
   4.148 +
   4.149 +    magic = hvm_get_32u(h);
   4.150 +    if (magic != HVM_FILE_MAGIC) {
   4.151 +        printk("HVM restore magic dismatch!\n");
   4.152 +        return -1;
   4.153 +    }
   4.154 +
   4.155 +    magic = hvm_get_32u(h);
   4.156 +    if (magic != HVM_FILE_VERSION) {
   4.157 +        printk("HVM restore version dismatch!\n");
   4.158 +        return -1;
   4.159 +    }
   4.160 +
   4.161 +    /* check xen change set */
   4.162 +    cur_chgset = strrchr(XEN_CHANGESET, ' ') + 1;
   4.163 +
   4.164 +    len = hvm_get_8u(h);
   4.165 +    if (len > 20) { /*typical length is 18 -- "revision number:changeset id" */
   4.166 +        printk("wrong change set length %d when hvm restore!\n", len);
   4.167 +        return -1;
   4.168 +    }
   4.169 +
   4.170 +    hvm_get_buffer(h, chgset, len);
   4.171 +    chgset[len] = '\0';
   4.172 +    if (strncmp(cur_chgset, chgset, len + 1))
   4.173 +        printk("warnings: try to restore hvm guest(%s) on a different changeset %s.\n",
   4.174 +                chgset, cur_chgset);
   4.175 +
   4.176 +    /* check cpuid */
   4.177 +    cpuid(1, &eax, &ebx, &ecx, &edx);
   4.178 +    ebx = hvm_get_32u(h);
   4.179 +    /*TODO: need difine how big difference is acceptable */
   4.180 +    if (ebx != eax)
   4.181 +        printk("warnings: try to restore hvm guest(0x%"PRIx32") "
   4.182 +               "on a different type processor(0x%"PRIx32").\n",
   4.183 +                ebx,
   4.184 +                eax);
   4.185 +
   4.186 +    while(1) {
   4.187 +        if (hvm_ctxt_end(h)) {
   4.188 +            break;
   4.189 +        }
   4.190 +
   4.191 +        /* ID string */
   4.192 +        len = hvm_get_8u(h);
   4.193 +        if (len > HVM_SE_IDSTR_LEN) {
   4.194 +            printk("wrong HVM save entry idstr len %d!", len);
   4.195 +            return -1;
   4.196 +        }
   4.197 +
   4.198 +        hvm_get_buffer(h, idstr, len);
   4.199 +        idstr[len] = '\0';
   4.200 +
   4.201 +        instance_id = hvm_get_32u(h);
   4.202 +        version_id = hvm_get_32u(h);
   4.203 +
   4.204 +        rec_len = hvm_get_32u(h);
   4.205 +        rec_pos = hvm_ctxt_tell(h);
   4.206 +
   4.207 +        se = find_se(v->domain, idstr, instance_id);
   4.208 +        if (se == NULL) {
   4.209 +            printk("warnings: hvm load can't find device %s's instance %d!\n",
   4.210 +                    idstr, instance_id);
   4.211 +        } else {
   4.212 +            ret = se->load_state(h, se->opaque, version_id);
   4.213 +            if (ret < 0)
   4.214 +                printk("warnings: loading state fail for device %s instance %d!\n",
   4.215 +                        idstr, instance_id);
   4.216 +        }
   4.217 +                    
   4.218 +
   4.219 +        /* make sure to jump end of record */
   4.220 +        if ( hvm_ctxt_tell(h) - rec_pos != rec_len) {
   4.221 +            printk("wrong hvm record size, maybe some dismatch between save&restore handler!\n");
   4.222 +        }
   4.223 +        hvm_ctxt_seek(h, rec_pos + rec_len);
   4.224 +    }
   4.225 +
   4.226 +    return 0;
   4.227 +}
   4.228 +
   4.229 +int arch_gethvm_ctxt(
   4.230 +    struct vcpu *v, struct hvm_domain_context *c)
   4.231 +{
   4.232 +    if ( !is_hvm_vcpu(v) )
   4.233 +        return -1;
   4.234 +
   4.235 +    return hvm_save(v, c);
   4.236 +
   4.237 +}
   4.238 +
   4.239 +int arch_sethvm_ctxt(
   4.240 +        struct vcpu *v, struct hvm_domain_context *c)
   4.241 +{
   4.242 +    return hvm_load(v, c);
   4.243 +}
   4.244 +
   4.245  int hvm_buffered_io_intercept(ioreq_t *p)
   4.246  {
   4.247      struct vcpu *v = current;
     5.1 --- a/xen/common/domctl.c	Thu Jan 18 16:48:03 2007 +0000
     5.2 +++ b/xen/common/domctl.c	Thu Jan 18 16:48:04 2007 +0000
     5.3 @@ -215,6 +215,39 @@ ret_t do_domctl(XEN_GUEST_HANDLE(xen_dom
     5.4      }
     5.5      break;
     5.6  
     5.7 +    case XEN_DOMCTL_sethvmcontext:
     5.8 +    { 
     5.9 +        struct hvm_domain_context *c;
    5.10 +        struct domain             *d;
    5.11 +        struct vcpu               *v;
    5.12 +
    5.13 +        ret = -ESRCH;
    5.14 +        if ( (d = find_domain_by_id(op->domain)) == NULL )
    5.15 +            break;
    5.16 +
    5.17 +        ret = -ENOMEM;
    5.18 +        if ( (c = xmalloc(struct hvm_domain_context)) == NULL )
    5.19 +            goto sethvmcontext_out;
    5.20 +
    5.21 +        v = d->vcpu[0];
    5.22 +        
    5.23 +        ret = -EFAULT;
    5.24 +
    5.25 +#ifndef CONFIG_COMPAT
    5.26 +        if ( copy_from_guest(c, op->u.hvmcontext.ctxt, 1) != 0 )
    5.27 +            goto sethvmcontext_out;
    5.28 +
    5.29 +        ret = arch_sethvm_ctxt(v, c);
    5.30 +#endif
    5.31 +
    5.32 +        xfree(c);
    5.33 +
    5.34 +    sethvmcontext_out:
    5.35 +        put_domain(d);
    5.36 +
    5.37 +    }
    5.38 +    break;
    5.39 +
    5.40      case XEN_DOMCTL_pausedomain:
    5.41      {
    5.42          struct domain *d = find_domain_by_id(op->domain);
    5.43 @@ -552,6 +585,46 @@ ret_t do_domctl(XEN_GUEST_HANDLE(xen_dom
    5.44      }
    5.45      break;
    5.46  
    5.47 +    case XEN_DOMCTL_gethvmcontext:
    5.48 +    { 
    5.49 +        struct hvm_domain_context *c;
    5.50 +        struct domain             *d;
    5.51 +        struct vcpu               *v;
    5.52 +
    5.53 +        ret = -ESRCH;
    5.54 +        if ( (d = find_domain_by_id(op->domain)) == NULL )
    5.55 +            break;
    5.56 +
    5.57 +        ret = -ENOMEM;
    5.58 +        if ( (c = xmalloc(struct hvm_domain_context)) == NULL )
    5.59 +            goto gethvmcontext_out;
    5.60 +
    5.61 +        v = d->vcpu[0];
    5.62 +
    5.63 +        ret = -ENODATA;
    5.64 +        if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
    5.65 +            goto gethvmcontext_out;
    5.66 +        
    5.67 +        ret = 0;
    5.68 +        if (arch_gethvm_ctxt(v, c) == -1)
    5.69 +            ret = -EFAULT;
    5.70 +
    5.71 +#ifndef CONFIG_COMPAT
    5.72 +        if ( copy_to_guest(op->u.hvmcontext.ctxt, c, 1) )
    5.73 +            ret = -EFAULT;
    5.74 +
    5.75 +        xfree(c);
    5.76 +#endif
    5.77 +
    5.78 +        if ( copy_to_guest(u_domctl, op, 1) )
    5.79 +            ret = -EFAULT;
    5.80 +
    5.81 +    gethvmcontext_out:
    5.82 +        put_domain(d);
    5.83 +
    5.84 +    }
    5.85 +    break;
    5.86 +
    5.87      case XEN_DOMCTL_getvcpuinfo:
    5.88      { 
    5.89          struct domain *d;
     6.1 --- a/xen/include/asm-x86/hvm/domain.h	Thu Jan 18 16:48:03 2007 +0000
     6.2 +++ b/xen/include/asm-x86/hvm/domain.h	Thu Jan 18 16:48:04 2007 +0000
     6.3 @@ -27,6 +27,20 @@
     6.4  #include <asm/hvm/io.h>
     6.5  #include <public/hvm/params.h>
     6.6  
     6.7 +typedef void SaveStateHandler(hvm_domain_context_t *h, void *opaque);
     6.8 +typedef int LoadStateHandler(hvm_domain_context_t *h, void *opaque, int version_id);
     6.9 +
    6.10 +#define HVM_SE_IDSTR_LEN 32
    6.11 +typedef struct HVMStateEntry {
    6.12 +    char idstr[HVM_SE_IDSTR_LEN];
    6.13 +    int instance_id;
    6.14 +    int version_id;
    6.15 +    SaveStateHandler *save_state;
    6.16 +    LoadStateHandler *load_state;
    6.17 +    void *opaque;
    6.18 +    struct HVMStateEntry *next;
    6.19 +} HVMStateEntry;
    6.20 +
    6.21  struct hvm_domain {
    6.22      unsigned long          shared_page_va;
    6.23      unsigned long          buffered_io_va;
    6.24 @@ -44,6 +58,9 @@ struct hvm_domain {
    6.25      spinlock_t             pbuf_lock;
    6.26  
    6.27      uint64_t               params[HVM_NR_PARAMS];
    6.28 +
    6.29 +    struct hvm_domain_context *hvm_ctxt;
    6.30 +    HVMStateEntry *first_se;
    6.31  };
    6.32  
    6.33  #endif /* __ASM_X86_HVM_DOMAIN_H__ */
     7.1 --- a/xen/include/asm-x86/hvm/support.h	Thu Jan 18 16:48:03 2007 +0000
     7.2 +++ b/xen/include/asm-x86/hvm/support.h	Thu Jan 18 16:48:04 2007 +0000
     7.3 @@ -121,6 +121,131 @@ extern unsigned int opt_hvm_debug_level;
     7.4  #define TRACE_VMEXIT(index, value)                              \
     7.5      current->arch.hvm_vcpu.hvm_trace_values[index] = (value)
     7.6  
     7.7 +/* save/restore support */
     7.8 +
     7.9 +//#define HVM_DEBUG_SUSPEND
    7.10 +
    7.11 +extern int hvm_register_savevm(struct domain *d,
    7.12 +                    const char *idstr,
    7.13 +                    int instance_id,
    7.14 +                    int version_id,
    7.15 +                    SaveStateHandler *save_state,
    7.16 +                    LoadStateHandler *load_state,
    7.17 +                    void *opaque);
    7.18 +
    7.19 +static inline void hvm_ctxt_seek(hvm_domain_context_t *h, unsigned int pos)
    7.20 +{
    7.21 +    h->cur = pos;
    7.22 +}
    7.23 +
    7.24 +static inline uint32_t hvm_ctxt_tell(hvm_domain_context_t *h)
    7.25 +{
    7.26 +    return h->cur;
    7.27 +}
    7.28 +
    7.29 +static inline int hvm_ctxt_end(hvm_domain_context_t *h)
    7.30 +{
    7.31 +    return (h->cur >= h->size || h->cur >= HVM_CTXT_SIZE);
    7.32 +}
    7.33 +
    7.34 +static inline void hvm_put_byte(hvm_domain_context_t *h, unsigned int i)
    7.35 +{
    7.36 +    if (h->cur >= HVM_CTXT_SIZE) {
    7.37 +        h->cur++;
    7.38 +        return;
    7.39 +    }
    7.40 +    h->data[h->cur++] = (char)i;
    7.41 +}
    7.42 +
    7.43 +static inline void hvm_put_8u(hvm_domain_context_t *h, uint8_t b)
    7.44 +{
    7.45 +    hvm_put_byte(h, b);
    7.46 +}
    7.47 +
    7.48 +static inline void hvm_put_16u(hvm_domain_context_t *h, uint16_t b)
    7.49 +{
    7.50 +    hvm_put_8u(h, b >> 8);
    7.51 +    hvm_put_8u(h, b);
    7.52 +}
    7.53 +
    7.54 +static inline void hvm_put_32u(hvm_domain_context_t *h, uint32_t b)
    7.55 +{
    7.56 +    hvm_put_16u(h, b >> 16);
    7.57 +    hvm_put_16u(h, b);
    7.58 +}
    7.59 +
    7.60 +static inline void hvm_put_64u(hvm_domain_context_t *h, uint64_t b)
    7.61 +{
    7.62 +    hvm_put_32u(h, b >> 32);
    7.63 +    hvm_put_32u(h, b);
    7.64 +}
    7.65 +
    7.66 +static inline void hvm_put_buffer(hvm_domain_context_t *h, const char *buf, int len)
    7.67 +{
    7.68 +    memcpy(&h->data[h->cur], buf, len);
    7.69 +    h->cur += len;
    7.70 +}
    7.71 +
    7.72 +
    7.73 +static inline char hvm_get_byte(hvm_domain_context_t *h)
    7.74 +{
    7.75 +    if (h->cur >= HVM_CTXT_SIZE) {
    7.76 +        printk("hvm_get_byte overflow.\n");
    7.77 +        return -1;
    7.78 +    }
    7.79 +
    7.80 +    if (h->cur >= h->size) {
    7.81 +        printk("hvm_get_byte exceed data area.\n");
    7.82 +        return -1;
    7.83 +    }
    7.84 +
    7.85 +    return h->data[h->cur++];
    7.86 +}
    7.87 +
    7.88 +static inline uint8_t hvm_get_8u(hvm_domain_context_t *h)
    7.89 +{
    7.90 +    return hvm_get_byte(h);
    7.91 +}
    7.92 +
    7.93 +static inline uint16_t hvm_get_16u(hvm_domain_context_t *h)
    7.94 +{
    7.95 +    uint16_t v;
    7.96 +    v =  hvm_get_8u(h) << 8;
    7.97 +    v |= hvm_get_8u(h);
    7.98 +
    7.99 +    return v;
   7.100 +}
   7.101 +
   7.102 +static inline uint32_t hvm_get_32u(hvm_domain_context_t *h)
   7.103 +{
   7.104 +    uint32_t v;
   7.105 +    v =  hvm_get_16u(h) << 16;
   7.106 +    v |= hvm_get_16u(h);
   7.107 +
   7.108 +    return v;
   7.109 +}
   7.110 +
   7.111 +static inline uint64_t hvm_get_64u(hvm_domain_context_t *h)
   7.112 +{
   7.113 +    uint64_t v;
   7.114 +    v =  (uint64_t)hvm_get_32u(h) << 32;
   7.115 +    v |= hvm_get_32u(h);
   7.116 +
   7.117 +    return v;
   7.118 +}
   7.119 +
   7.120 +static inline void hvm_get_buffer(hvm_domain_context_t *h, char *buf, int len)
   7.121 +{
   7.122 +    memcpy(buf, &h->data[h->cur], len);
   7.123 +    h->cur += len;
   7.124 +}
   7.125 +
   7.126 +extern int hvm_save(struct vcpu*, hvm_domain_context_t *h);
   7.127 +extern int hvm_load(struct vcpu*, hvm_domain_context_t *h);
   7.128 +
   7.129 +extern int arch_sethvm_ctxt(struct vcpu *v, struct hvm_domain_context *c);
   7.130 +extern int arch_gethvm_ctxt(struct vcpu *v, struct hvm_domain_context *c);
   7.131 +
   7.132  extern int hvm_enabled;
   7.133  
   7.134  int hvm_copy_to_guest_phys(paddr_t paddr, void *buf, int size);
     8.1 --- a/xen/include/public/domctl.h	Thu Jan 18 16:48:03 2007 +0000
     8.2 +++ b/xen/include/public/domctl.h	Thu Jan 18 16:48:04 2007 +0000
     8.3 @@ -386,6 +386,21 @@ struct xen_domctl_settimeoffset {
     8.4  };
     8.5  typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t;
     8.6  DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t);
     8.7 + 
     8.8 +#define HVM_CTXT_SIZE        6144
     8.9 +typedef struct hvm_domain_context {
    8.10 +    uint32_t cur;
    8.11 +    uint32_t size;
    8.12 +    uint8_t data[HVM_CTXT_SIZE];
    8.13 +} hvm_domain_context_t;
    8.14 +DEFINE_XEN_GUEST_HANDLE(hvm_domain_context_t);
    8.15 +
    8.16 +#define XEN_DOMCTL_gethvmcontext   33
    8.17 +#define XEN_DOMCTL_sethvmcontext   34
    8.18 +typedef struct xen_domctl_hvmcontext {
    8.19 +    XEN_GUEST_HANDLE(hvm_domain_context_t) ctxt;  /* IN/OUT */
    8.20 +} xen_domctl_hvmcontext_t;
    8.21 +DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_t);
    8.22  
    8.23  #define XEN_DOMCTL_real_mode_area     26
    8.24  struct xen_domctl_real_mode_area {
    8.25 @@ -423,6 +438,7 @@ struct xen_domctl {
    8.26          struct xen_domctl_arch_setup        arch_setup;
    8.27          struct xen_domctl_settimeoffset     settimeoffset;
    8.28          struct xen_domctl_real_mode_area    real_mode_area;
    8.29 +        struct xen_domctl_hvmcontext        hvmcontext;
    8.30          uint8_t                             pad[128];
    8.31      } u;
    8.32  };