ia64/xen-unstable

changeset 16154:9ea5f4c1feb5

hvm: Split save.c into arch generic/specific part.

struct hvm_save_header is arch specific so that arch specific part of
hvm_save()/hvm_load() are moved into arch_hvm_save()/acrh_hvm_load()

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Keir Fraser <keir@xensource.com>
date Thu Oct 18 11:11:40 2007 +0100 (2007-10-18)
parents a87d94be1172
children 789e4303b330
files xen/Rules.mk xen/arch/x86/hvm/save.c xen/common/Makefile xen/common/hvm/Makefile xen/common/hvm/save.c xen/include/xen/hvm/save.h
line diff
     1.1 --- a/xen/Rules.mk	Thu Oct 18 10:58:36 2007 +0100
     1.2 +++ b/xen/Rules.mk	Thu Oct 18 11:11:40 2007 +0100
     1.3 @@ -39,7 +39,9 @@ TARGET := $(BASEDIR)/xen
     1.4  
     1.5  HDRS := $(wildcard *.h)
     1.6  HDRS += $(wildcard $(BASEDIR)/include/xen/*.h)
     1.7 +HDRS := $(wildcard $(BASEDIR)/include/xen/hvm/*.h)
     1.8  HDRS += $(wildcard $(BASEDIR)/include/public/*.h)
     1.9 +HDRS += $(wildcard $(BASEDIR)/include/public/*/*.h)
    1.10  HDRS += $(wildcard $(BASEDIR)/include/compat/*.h)
    1.11  HDRS += $(wildcard $(BASEDIR)/include/asm-$(TARGET_ARCH)/*.h)
    1.12  HDRS += $(wildcard $(BASEDIR)/include/asm-$(TARGET_ARCH)/$(TARGET_SUBARCH)/*.h)
     2.1 --- a/xen/arch/x86/hvm/save.c	Thu Oct 18 10:58:36 2007 +0100
     2.2 +++ b/xen/arch/x86/hvm/save.c	Thu Oct 18 11:11:40 2007 +0100
     2.3 @@ -3,6 +3,9 @@
     2.4   *
     2.5   * Copyright (c) 2004, Intel Corporation.
     2.6   * Copyright (c) 2007, XenSource Inc.
     2.7 + * Copyright (c) 2007, Isaku Yamahata <yamahata at valinux co jp>
     2.8 + *                     VA Linux Systems Japan K.K.
     2.9 + *                     split x86 specific part
    2.10   *
    2.11   * This program is free software; you can redistribute it and/or modify it
    2.12   * under the terms and conditions of the GNU General Public License,
    2.13 @@ -18,212 +21,54 @@
    2.14   * Place - Suite 330, Boston, MA 02111-1307 USA.
    2.15   */
    2.16  
    2.17 -#include <xen/config.h>
    2.18 -#include <xen/lib.h>
    2.19 -#include <xen/version.h>
    2.20 -#include <public/version.h>
    2.21 -#include <xen/sched.h>
    2.22 -#include <asm/hvm/hvm.h>
    2.23  #include <asm/hvm/support.h>
    2.24 -#include <asm/hvm/domain.h>
    2.25 -#include <asm/current.h>
    2.26 -
    2.27 -/* List of handlers for various HVM save and restore types */
    2.28 -static struct { 
    2.29 -    hvm_save_handler save;
    2.30 -    hvm_load_handler load; 
    2.31 -    const char *name;
    2.32 -    size_t size;
    2.33 -    int kind;
    2.34 -} hvm_sr_handlers [HVM_SAVE_CODE_MAX + 1] = {{NULL, NULL, "<?>"},};
    2.35 +#include <public/hvm/save.h>
    2.36  
    2.37 -/* Init-time function to add entries to that list */
    2.38 -void hvm_register_savevm(uint16_t typecode, 
    2.39 -                         const char *name,
    2.40 -                         hvm_save_handler save_state,
    2.41 -                         hvm_load_handler load_state,
    2.42 -                         size_t size, int kind)
    2.43 -{
    2.44 -    ASSERT(typecode <= HVM_SAVE_CODE_MAX);
    2.45 -    ASSERT(hvm_sr_handlers[typecode].save == NULL);
    2.46 -    ASSERT(hvm_sr_handlers[typecode].load == NULL);
    2.47 -    hvm_sr_handlers[typecode].save = save_state;
    2.48 -    hvm_sr_handlers[typecode].load = load_state;
    2.49 -    hvm_sr_handlers[typecode].name = name;
    2.50 -    hvm_sr_handlers[typecode].size = size;
    2.51 -    hvm_sr_handlers[typecode].kind = kind;
    2.52 -}
    2.53 -
    2.54 -size_t hvm_save_size(struct domain *d) 
    2.55 -{
    2.56 -    struct vcpu *v;
    2.57 -    size_t sz;
    2.58 -    int i;
    2.59 -    
    2.60 -    /* Basic overhead for header and footer */
    2.61 -    sz = (2 * sizeof (struct hvm_save_descriptor)) + HVM_SAVE_LENGTH(HEADER);
    2.62 -
    2.63 -    /* Plus space for each thing we will be saving */
    2.64 -    for ( i = 0; i <= HVM_SAVE_CODE_MAX; i++ ) 
    2.65 -        if ( hvm_sr_handlers[i].kind == HVMSR_PER_VCPU )
    2.66 -            for_each_vcpu(d, v)
    2.67 -                sz += hvm_sr_handlers[i].size;
    2.68 -        else 
    2.69 -            sz += hvm_sr_handlers[i].size;
    2.70 -
    2.71 -    return sz;
    2.72 -}
    2.73 -
    2.74 -
    2.75 -int hvm_save(struct domain *d, hvm_domain_context_t *h)
    2.76 +void
    2.77 +arch_hvm_save(struct hvm_save_header *hdr)
    2.78  {
    2.79      uint32_t eax, ebx, ecx, edx;
    2.80 -    char *c;
    2.81 -    struct hvm_save_header hdr;
    2.82 -    struct hvm_save_end end;
    2.83 -    hvm_save_handler handler;
    2.84 -    uint16_t i;
    2.85 -
    2.86 -    hdr.magic = HVM_FILE_MAGIC;
    2.87 -    hdr.version = HVM_FILE_VERSION;
    2.88  
    2.89      /* Save some CPUID bits */
    2.90      cpuid(1, &eax, &ebx, &ecx, &edx);
    2.91 -    hdr.cpuid = eax;
    2.92 -
    2.93 -    /* Save xen changeset */
    2.94 -    c = strrchr(xen_changeset(), ':');
    2.95 -    if ( c )
    2.96 -        hdr.changeset = simple_strtoll(c, NULL, 16);
    2.97 -    else 
    2.98 -        hdr.changeset = -1ULL; /* Unknown */
    2.99 -
   2.100 -    hdr.pad0 = 0;
   2.101 -
   2.102 -    if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 )
   2.103 -    {
   2.104 -        gdprintk(XENLOG_ERR, "HVM save: failed to write header\n");
   2.105 -        return -EFAULT;
   2.106 -    } 
   2.107 +    hdr->cpuid = eax;
   2.108  
   2.109 -    /* Save all available kinds of state */
   2.110 -    for ( i = 0; i <= HVM_SAVE_CODE_MAX; i++ ) 
   2.111 -    {
   2.112 -        handler = hvm_sr_handlers[i].save;
   2.113 -        if ( handler != NULL ) 
   2.114 -        {
   2.115 -            gdprintk(XENLOG_INFO, "HVM save: %s\n",  hvm_sr_handlers[i].name);
   2.116 -            if ( handler(d, h) != 0 ) 
   2.117 -            {
   2.118 -                gdprintk(XENLOG_ERR, 
   2.119 -                         "HVM save: failed to save type %"PRIu16"\n", i);
   2.120 -                return -EFAULT;
   2.121 -            } 
   2.122 -        }
   2.123 -    }
   2.124 -
   2.125 -    /* Save an end-of-file marker */
   2.126 -    if ( hvm_save_entry(END, 0, h, &end) != 0 )
   2.127 -    {
   2.128 -        /* Run out of data */
   2.129 -        gdprintk(XENLOG_ERR, "HVM save: no room for end marker.\n");
   2.130 -        return -EFAULT;
   2.131 -    }
   2.132 -
   2.133 -    /* Save macros should not have let us overrun */
   2.134 -    ASSERT(h->cur <= h->size);
   2.135 -    return 0;
   2.136 +    hdr->pad0 = 0;
   2.137  }
   2.138  
   2.139 -int hvm_load(struct domain *d, hvm_domain_context_t *h)
   2.140 +int
   2.141 +arch_hvm_load(struct hvm_save_header *hdr)
   2.142  {
   2.143      uint32_t eax, ebx, ecx, edx;
   2.144 -    char *c;
   2.145 -    uint64_t cset;
   2.146 -    struct hvm_save_header hdr;
   2.147 -    struct hvm_save_descriptor *desc;
   2.148 -    hvm_load_handler handler;
   2.149 -    struct vcpu *v;
   2.150 -    
   2.151 -    /* Read the save header, which must be first */
   2.152 -    if ( hvm_load_entry(HEADER, h, &hdr) != 0 ) 
   2.153 -        return -1;
   2.154 -
   2.155 -    if (hdr.magic != HVM_FILE_MAGIC) {
   2.156 +    if ( hdr->magic != HVM_FILE_MAGIC )
   2.157 +    {
   2.158          gdprintk(XENLOG_ERR, 
   2.159 -                 "HVM restore: bad magic number %#"PRIx32"\n", hdr.magic);
   2.160 +                 "HVM restore: bad magic number %#"PRIx32"\n", hdr->magic);
   2.161          return -1;
   2.162      }
   2.163  
   2.164 -    if (hdr.version != HVM_FILE_VERSION) {
   2.165 +    if ( hdr->version != HVM_FILE_VERSION )
   2.166 +    {
   2.167          gdprintk(XENLOG_ERR, 
   2.168 -                 "HVM restore: unsupported version %u\n", hdr.version);
   2.169 +                 "HVM restore: unsupported version %u\n", hdr->version);
   2.170          return -1;
   2.171      }
   2.172  
   2.173      cpuid(1, &eax, &ebx, &ecx, &edx);
   2.174      /*TODO: need to define how big a difference is acceptable */
   2.175 -    if (hdr.cpuid != eax)
   2.176 +    if ( hdr->cpuid != eax )
   2.177          gdprintk(XENLOG_WARNING, "HVM restore: saved CPUID (%#"PRIx32") "
   2.178 -               "does not match host (%#"PRIx32").\n", hdr.cpuid, eax);
   2.179 -
   2.180 -
   2.181 -    c = strrchr(xen_changeset(), ':');
   2.182 -    if ( hdr.changeset == -1ULL )
   2.183 -        gdprintk(XENLOG_WARNING, 
   2.184 -                 "HVM restore: Xen changeset was not saved.\n");
   2.185 -    else if ( c == NULL )
   2.186 -        gdprintk(XENLOG_WARNING, 
   2.187 -                 "HVM restore: Xen changeset is not available.\n");
   2.188 -    else
   2.189 -    {
   2.190 -        cset = simple_strtoll(c, NULL, 16);
   2.191 -        if ( hdr.changeset != cset )
   2.192 -        gdprintk(XENLOG_WARNING, "HVM restore: saved Xen changeset (%#"PRIx64
   2.193 -                 ") does not match host (%#"PRIx64").\n", hdr.changeset, cset);
   2.194 -    }
   2.195 -
   2.196 -    /* Down all the vcpus: we only re-enable the ones that had state saved. */
   2.197 -    for_each_vcpu(d, v) 
   2.198 -        if ( test_and_set_bit(_VPF_down, &v->pause_flags) )
   2.199 -            vcpu_sleep_nosync(v);
   2.200 -
   2.201 -    while(1) {
   2.202 +               "does not match host (%#"PRIx32").\n", hdr->cpuid, eax);
   2.203  
   2.204 -        if ( h->size - h->cur < sizeof(struct hvm_save_descriptor) )
   2.205 -        {
   2.206 -            /* Run out of data */
   2.207 -            gdprintk(XENLOG_ERR, 
   2.208 -                     "HVM restore: save did not end with a null entry\n");
   2.209 -            return -1;
   2.210 -        }
   2.211 -        
   2.212 -        /* Read the typecode of the next entry  and check for the end-marker */
   2.213 -        desc = (struct hvm_save_descriptor *)(&h->data[h->cur]);
   2.214 -        if ( desc->typecode == 0 )
   2.215 -            return 0; 
   2.216 -        
   2.217 -        /* Find the handler for this entry */
   2.218 -        if ( desc->typecode > HVM_SAVE_CODE_MAX 
   2.219 -             || (handler = hvm_sr_handlers[desc->typecode].load) == NULL ) 
   2.220 -        {
   2.221 -            gdprintk(XENLOG_ERR, 
   2.222 -                     "HVM restore: unknown entry typecode %u\n", 
   2.223 -                     desc->typecode);
   2.224 -            return -1;
   2.225 -        }
   2.226 +    return 0;
   2.227 +}
   2.228  
   2.229 -        /* Load the entry */
   2.230 -        gdprintk(XENLOG_INFO, "HVM restore: %s %"PRIu16"\n",  
   2.231 -                 hvm_sr_handlers[desc->typecode].name, desc->instance);
   2.232 -        if ( handler(d, h) != 0 ) 
   2.233 -        {
   2.234 -            gdprintk(XENLOG_ERR, 
   2.235 -                     "HVM restore: failed to load entry %u/%u\n", 
   2.236 -                     desc->typecode, desc->instance);
   2.237 -            return -1;
   2.238 -        }
   2.239 -    }
   2.240 -
   2.241 -    /* Not reached */
   2.242 -}
   2.243 +/*
   2.244 + * Local variables:
   2.245 + * mode: C
   2.246 + * c-set-style: "BSD"
   2.247 + * c-basic-offset: 4
   2.248 + * tab-width: 4
   2.249 + * indent-tabs-mode: nil
   2.250 + * End:
   2.251 + */
     3.1 --- a/xen/common/Makefile	Thu Oct 18 10:58:36 2007 +0100
     3.2 +++ b/xen/common/Makefile	Thu Oct 18 11:11:40 2007 +0100
     3.3 @@ -35,6 +35,9 @@ obj-$(CONFIG_XENCOMM) += xencomm.o
     3.4  
     3.5  subdir-$(CONFIG_COMPAT) += compat
     3.6  
     3.7 +subdir-$(x86_32) += hvm
     3.8 +subdir-$(x86_64) += hvm
     3.9 +
    3.10  subdir-y += libelf
    3.11  
    3.12  # Object file contains changeset and compiler information.
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xen/common/hvm/Makefile	Thu Oct 18 11:11:40 2007 +0100
     4.3 @@ -0,0 +1,1 @@
     4.4 +obj-y += save.o
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/xen/common/hvm/save.c	Thu Oct 18 11:11:40 2007 +0100
     5.3 @@ -0,0 +1,218 @@
     5.4 +/*
     5.5 + * hvm/save.c: Save and restore HVM guest's emulated hardware state.
     5.6 + *
     5.7 + * Copyright (c) 2004, Intel Corporation.
     5.8 + * Copyright (c) 2007, XenSource Inc.
     5.9 + * Copyright (c) 2007, Isaku Yamahata <yamahata at valinux co jp>
    5.10 + *                     VA Linux Systems Japan K.K.
    5.11 + *                     split arch generic part
    5.12 + *
    5.13 + * This program is free software; you can redistribute it and/or modify it
    5.14 + * under the terms and conditions of the GNU General Public License,
    5.15 + * version 2, as published by the Free Software Foundation.
    5.16 + *
    5.17 + * This program is distributed in the hope it will be useful, but WITHOUT
    5.18 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.19 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    5.20 + * more details.
    5.21 + *
    5.22 + * You should have received a copy of the GNU General Public License along with
    5.23 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    5.24 + * Place - Suite 330, Boston, MA 02111-1307 USA.
    5.25 + */
    5.26 +
    5.27 +#include <xen/config.h>
    5.28 +#include <xen/lib.h>
    5.29 +#include <xen/version.h>
    5.30 +#include <public/version.h>
    5.31 +#include <xen/sched.h>
    5.32 +
    5.33 +#include <asm/hvm/support.h>
    5.34 +
    5.35 +/* List of handlers for various HVM save and restore types */
    5.36 +static struct { 
    5.37 +    hvm_save_handler save;
    5.38 +    hvm_load_handler load; 
    5.39 +    const char *name;
    5.40 +    size_t size;
    5.41 +    int kind;
    5.42 +} hvm_sr_handlers [HVM_SAVE_CODE_MAX + 1] = {{NULL, NULL, "<?>"},};
    5.43 +
    5.44 +/* Init-time function to add entries to that list */
    5.45 +void hvm_register_savevm(uint16_t typecode, 
    5.46 +                         const char *name,
    5.47 +                         hvm_save_handler save_state,
    5.48 +                         hvm_load_handler load_state,
    5.49 +                         size_t size, int kind)
    5.50 +{
    5.51 +    ASSERT(typecode <= HVM_SAVE_CODE_MAX);
    5.52 +    ASSERT(hvm_sr_handlers[typecode].save == NULL);
    5.53 +    ASSERT(hvm_sr_handlers[typecode].load == NULL);
    5.54 +    hvm_sr_handlers[typecode].save = save_state;
    5.55 +    hvm_sr_handlers[typecode].load = load_state;
    5.56 +    hvm_sr_handlers[typecode].name = name;
    5.57 +    hvm_sr_handlers[typecode].size = size;
    5.58 +    hvm_sr_handlers[typecode].kind = kind;
    5.59 +}
    5.60 +
    5.61 +size_t hvm_save_size(struct domain *d) 
    5.62 +{
    5.63 +    struct vcpu *v;
    5.64 +    size_t sz;
    5.65 +    int i;
    5.66 +    
    5.67 +    /* Basic overhead for header and footer */
    5.68 +    sz = (2 * sizeof (struct hvm_save_descriptor)) + HVM_SAVE_LENGTH(HEADER);
    5.69 +
    5.70 +    /* Plus space for each thing we will be saving */
    5.71 +    for ( i = 0; i <= HVM_SAVE_CODE_MAX; i++ ) 
    5.72 +        if ( hvm_sr_handlers[i].kind == HVMSR_PER_VCPU )
    5.73 +            for_each_vcpu(d, v)
    5.74 +                sz += hvm_sr_handlers[i].size;
    5.75 +        else 
    5.76 +            sz += hvm_sr_handlers[i].size;
    5.77 +
    5.78 +    return sz;
    5.79 +}
    5.80 +
    5.81 +
    5.82 +int hvm_save(struct domain *d, hvm_domain_context_t *h)
    5.83 +{
    5.84 +    char *c;
    5.85 +    struct hvm_save_header hdr;
    5.86 +    struct hvm_save_end end;
    5.87 +    hvm_save_handler handler;
    5.88 +    uint16_t i;
    5.89 +
    5.90 +    hdr.magic = HVM_FILE_MAGIC;
    5.91 +    hdr.version = HVM_FILE_VERSION;
    5.92 +
    5.93 +    /* Save xen changeset */
    5.94 +    c = strrchr(xen_changeset(), ':');
    5.95 +    if ( c )
    5.96 +        hdr.changeset = simple_strtoll(c, NULL, 16);
    5.97 +    else 
    5.98 +        hdr.changeset = -1ULL; /* Unknown */
    5.99 +
   5.100 +    arch_hvm_save(&hdr);
   5.101 +
   5.102 +    if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 )
   5.103 +    {
   5.104 +        gdprintk(XENLOG_ERR, "HVM save: failed to write header\n");
   5.105 +        return -EFAULT;
   5.106 +    } 
   5.107 +
   5.108 +    /* Save all available kinds of state */
   5.109 +    for ( i = 0; i <= HVM_SAVE_CODE_MAX; i++ ) 
   5.110 +    {
   5.111 +        handler = hvm_sr_handlers[i].save;
   5.112 +        if ( handler != NULL ) 
   5.113 +        {
   5.114 +            gdprintk(XENLOG_INFO, "HVM save: %s\n",  hvm_sr_handlers[i].name);
   5.115 +            if ( handler(d, h) != 0 ) 
   5.116 +            {
   5.117 +                gdprintk(XENLOG_ERR, 
   5.118 +                         "HVM save: failed to save type %"PRIu16"\n", i);
   5.119 +                return -EFAULT;
   5.120 +            } 
   5.121 +        }
   5.122 +    }
   5.123 +
   5.124 +    /* Save an end-of-file marker */
   5.125 +    if ( hvm_save_entry(END, 0, h, &end) != 0 )
   5.126 +    {
   5.127 +        /* Run out of data */
   5.128 +        gdprintk(XENLOG_ERR, "HVM save: no room for end marker.\n");
   5.129 +        return -EFAULT;
   5.130 +    }
   5.131 +
   5.132 +    /* Save macros should not have let us overrun */
   5.133 +    ASSERT(h->cur <= h->size);
   5.134 +    return 0;
   5.135 +}
   5.136 +
   5.137 +int hvm_load(struct domain *d, hvm_domain_context_t *h)
   5.138 +{
   5.139 +    char *c;
   5.140 +    uint64_t cset;
   5.141 +    struct hvm_save_header hdr;
   5.142 +    struct hvm_save_descriptor *desc;
   5.143 +    hvm_load_handler handler;
   5.144 +    struct vcpu *v;
   5.145 +    
   5.146 +    /* Read the save header, which must be first */
   5.147 +    if ( hvm_load_entry(HEADER, h, &hdr) != 0 ) 
   5.148 +        return -1;
   5.149 +
   5.150 +    if ( arch_hvm_load(&hdr) )
   5.151 +        return -1;
   5.152 +
   5.153 +    c = strrchr(xen_changeset(), ':');
   5.154 +    if ( hdr.changeset == -1ULL )
   5.155 +        gdprintk(XENLOG_WARNING, 
   5.156 +                 "HVM restore: Xen changeset was not saved.\n");
   5.157 +    else if ( c == NULL )
   5.158 +        gdprintk(XENLOG_WARNING, 
   5.159 +                 "HVM restore: Xen changeset is not available.\n");
   5.160 +    else
   5.161 +    {
   5.162 +        cset = simple_strtoll(c, NULL, 16);
   5.163 +        if ( hdr.changeset != cset )
   5.164 +        gdprintk(XENLOG_WARNING, "HVM restore: saved Xen changeset (%#"PRIx64
   5.165 +                 ") does not match host (%#"PRIx64").\n", hdr.changeset, cset);
   5.166 +    }
   5.167 +
   5.168 +    /* Down all the vcpus: we only re-enable the ones that had state saved. */
   5.169 +    for_each_vcpu(d, v) 
   5.170 +        if ( test_and_set_bit(_VPF_down, &v->pause_flags) )
   5.171 +            vcpu_sleep_nosync(v);
   5.172 +
   5.173 +    for ( ; ; )
   5.174 +    {
   5.175 +        if ( h->size - h->cur < sizeof(struct hvm_save_descriptor) )
   5.176 +        {
   5.177 +            /* Run out of data */
   5.178 +            gdprintk(XENLOG_ERR, 
   5.179 +                     "HVM restore: save did not end with a null entry\n");
   5.180 +            return -1;
   5.181 +        }
   5.182 +        
   5.183 +        /* Read the typecode of the next entry  and check for the end-marker */
   5.184 +        desc = (struct hvm_save_descriptor *)(&h->data[h->cur]);
   5.185 +        if ( desc->typecode == 0 )
   5.186 +            return 0; 
   5.187 +        
   5.188 +        /* Find the handler for this entry */
   5.189 +        if ( (desc->typecode > HVM_SAVE_CODE_MAX) ||
   5.190 +             ((handler = hvm_sr_handlers[desc->typecode].load) == NULL) )
   5.191 +        {
   5.192 +            gdprintk(XENLOG_ERR, 
   5.193 +                     "HVM restore: unknown entry typecode %u\n", 
   5.194 +                     desc->typecode);
   5.195 +            return -1;
   5.196 +        }
   5.197 +
   5.198 +        /* Load the entry */
   5.199 +        gdprintk(XENLOG_INFO, "HVM restore: %s %"PRIu16"\n",  
   5.200 +                 hvm_sr_handlers[desc->typecode].name, desc->instance);
   5.201 +        if ( handler(d, h) != 0 ) 
   5.202 +        {
   5.203 +            gdprintk(XENLOG_ERR, 
   5.204 +                     "HVM restore: failed to load entry %u/%u\n", 
   5.205 +                     desc->typecode, desc->instance);
   5.206 +            return -1;
   5.207 +        }
   5.208 +    }
   5.209 +
   5.210 +    /* Not reached */
   5.211 +}
   5.212 +
   5.213 +/*
   5.214 + * Local variables:
   5.215 + * mode: C
   5.216 + * c-set-style: "BSD"
   5.217 + * c-basic-offset: 4
   5.218 + * tab-width: 4
   5.219 + * indent-tabs-mode: nil
   5.220 + * End:
   5.221 + */
     6.1 --- a/xen/include/xen/hvm/save.h	Thu Oct 18 10:58:36 2007 +0100
     6.2 +++ b/xen/include/xen/hvm/save.h	Thu Oct 18 11:11:40 2007 +0100
     6.3 @@ -153,4 +153,9 @@ size_t hvm_save_size(struct domain *d);
     6.4  int hvm_save(struct domain *d, hvm_domain_context_t *h);
     6.5  int hvm_load(struct domain *d, hvm_domain_context_t *h);
     6.6  
     6.7 +/* Arch-specific definitions. */
     6.8 +struct hvm_save_header;
     6.9 +void arch_hvm_save(struct hvm_save_header *hdr);
    6.10 +int arch_hvm_load(struct hvm_save_header *hdr);
    6.11 +
    6.12  #endif /* __XEN_HVM_SAVE_H__ */