direct-io.hg

changeset 13818:710aec0abb61

[HVM] Save/restore: move save/restore routines out of intercept.c
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
author Tim Deegan <Tim.Deegan@xensource.com>
date Wed Feb 07 10:21:15 2007 +0000 (2007-02-07)
parents 67faf6c59bfa
children 4d7ee9f4336a
files xen/arch/x86/hvm/Makefile xen/arch/x86/hvm/intercept.c xen/arch/x86/hvm/save.c
line diff
     1.1 --- a/xen/arch/x86/hvm/Makefile	Wed Feb 07 12:25:18 2007 +0000
     1.2 +++ b/xen/arch/x86/hvm/Makefile	Wed Feb 07 10:21:15 2007 +0000
     1.3 @@ -15,3 +15,4 @@ obj-y += vpt.o
     1.4  obj-y += vioapic.o
     1.5  obj-y += vlapic.o
     1.6  obj-y += vpic.o
     1.7 +obj-y += save.o
     2.1 --- a/xen/arch/x86/hvm/intercept.c	Wed Feb 07 12:25:18 2007 +0000
     2.2 +++ b/xen/arch/x86/hvm/intercept.c	Wed Feb 07 10:21:15 2007 +0000
     2.3 @@ -29,8 +29,6 @@
     2.4  #include <asm/current.h>
     2.5  #include <io_ports.h>
     2.6  #include <xen/event.h>
     2.7 -#include <xen/compile.h>
     2.8 -#include <public/version.h>
     2.9  
    2.10  
    2.11  extern struct hvm_mmio_handler hpet_mmio_handler;
    2.12 @@ -157,180 +155,6 @@ static inline void hvm_mmio_access(struc
    2.13      }
    2.14  }
    2.15  
    2.16 -/* List of handlers for various HVM save and restore types */
    2.17 -static struct { 
    2.18 -    hvm_save_handler save;
    2.19 -    hvm_load_handler load; 
    2.20 -    const char *name;
    2.21 -} hvm_sr_handlers [HVM_SAVE_CODE_MAX + 1] = {{NULL, NULL, "<?>"},};
    2.22 -
    2.23 -/* Init-time function to add entries to that list */
    2.24 -void hvm_register_savevm(uint16_t typecode, 
    2.25 -                         const char *name,
    2.26 -                         hvm_save_handler save_state,
    2.27 -                         hvm_load_handler load_state)
    2.28 -{
    2.29 -    ASSERT(typecode <= HVM_SAVE_CODE_MAX);
    2.30 -    ASSERT(hvm_sr_handlers[typecode].save == NULL);
    2.31 -    ASSERT(hvm_sr_handlers[typecode].load == NULL);
    2.32 -    hvm_sr_handlers[typecode].save = save_state;
    2.33 -    hvm_sr_handlers[typecode].load = load_state;
    2.34 -    hvm_sr_handlers[typecode].name = name;
    2.35 -}
    2.36 -
    2.37 -
    2.38 -int hvm_save(struct domain *d, hvm_domain_context_t *h)
    2.39 -{
    2.40 -    uint32_t eax, ebx, ecx, edx;
    2.41 -    char *c;
    2.42 -    struct hvm_save_header hdr;
    2.43 -    struct hvm_save_end end;
    2.44 -    hvm_save_handler handler;
    2.45 -    uint16_t i;
    2.46 -
    2.47 -    hdr.magic = HVM_FILE_MAGIC;
    2.48 -    hdr.version = HVM_FILE_VERSION;
    2.49 -
    2.50 -    /* Save some CPUID bits */
    2.51 -    cpuid(1, &eax, &ebx, &ecx, &edx);
    2.52 -    hdr.cpuid = eax;
    2.53 -
    2.54 -    /* Save xen changeset */
    2.55 -    c = strrchr(XEN_CHANGESET, ':');
    2.56 -    if ( c )
    2.57 -        hdr.changeset = simple_strtoll(c, NULL, 16);
    2.58 -    else 
    2.59 -        hdr.changeset = -1ULL; /* Unknown */
    2.60 -
    2.61 -    if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 )
    2.62 -    {
    2.63 -        gdprintk(XENLOG_ERR, "HVM save: failed to write header\n");
    2.64 -        return -EFAULT;
    2.65 -    } 
    2.66 -
    2.67 -    /* Save all available kinds of state */
    2.68 -    for ( i = 0; i <= HVM_SAVE_CODE_MAX; i++ ) 
    2.69 -    {
    2.70 -        handler = hvm_sr_handlers[i].save;
    2.71 -        if ( handler != NULL ) 
    2.72 -        {
    2.73 -            gdprintk(XENLOG_INFO, "HVM save: %s\n",  hvm_sr_handlers[i].name);
    2.74 -            if ( handler(d, h) != 0 ) 
    2.75 -            {
    2.76 -                gdprintk(XENLOG_ERR, 
    2.77 -                         "HVM save: failed to save type %"PRIu16"\n", i);
    2.78 -                return -EFAULT;
    2.79 -            } 
    2.80 -        }
    2.81 -    }
    2.82 -
    2.83 -    /* Save an end-of-file marker */
    2.84 -    if ( hvm_save_entry(END, 0, h, &end) != 0 )
    2.85 -    {
    2.86 -        /* Run out of data */
    2.87 -        gdprintk(XENLOG_ERR, "HVM save: no room for end marker.\n");
    2.88 -        return -EFAULT;
    2.89 -    }
    2.90 -
    2.91 -    /* Save macros should not have let us overrun */
    2.92 -    ASSERT(h->cur <= h->size);
    2.93 -    return 0;
    2.94 -}
    2.95 -
    2.96 -int hvm_load(struct domain *d, hvm_domain_context_t *h)
    2.97 -{
    2.98 -    uint32_t eax, ebx, ecx, edx;
    2.99 -    char *c;
   2.100 -    uint64_t cset;
   2.101 -    struct hvm_save_header hdr;
   2.102 -    struct hvm_save_descriptor *desc;
   2.103 -    hvm_load_handler handler;
   2.104 -    struct vcpu *v;
   2.105 -    
   2.106 -    /* Read the save header, which must be first */
   2.107 -    if ( hvm_load_entry(HEADER, h, &hdr) != 0 ) 
   2.108 -        return -1;
   2.109 -
   2.110 -    if (hdr.magic != HVM_FILE_MAGIC) {
   2.111 -        gdprintk(XENLOG_ERR, 
   2.112 -                 "HVM restore: bad magic number %#"PRIx32"\n", hdr.magic);
   2.113 -        return -1;
   2.114 -    }
   2.115 -
   2.116 -    if (hdr.version != HVM_FILE_VERSION) {
   2.117 -        gdprintk(XENLOG_ERR, 
   2.118 -                 "HVM restore: unsupported version %u\n", hdr.version);
   2.119 -        return -1;
   2.120 -    }
   2.121 -
   2.122 -    cpuid(1, &eax, &ebx, &ecx, &edx);
   2.123 -    /*TODO: need to define how big a difference is acceptable */
   2.124 -    if (hdr.cpuid != eax)
   2.125 -        gdprintk(XENLOG_WARNING, "HVM restore: saved CPUID (%#"PRIx32") "
   2.126 -               "does not match host (%#"PRIx32").\n", hdr.cpuid, eax);
   2.127 -
   2.128 -
   2.129 -    c = strrchr(XEN_CHANGESET, ':');
   2.130 -    if ( hdr.changeset == -1ULL )
   2.131 -        gdprintk(XENLOG_WARNING, 
   2.132 -                 "HVM restore: Xen changeset was not saved.\n");
   2.133 -    else if ( c == NULL )
   2.134 -        gdprintk(XENLOG_WARNING, 
   2.135 -                 "HVM restore: Xen changeset is not available.\n");
   2.136 -    else
   2.137 -    {
   2.138 -        cset = simple_strtoll(c, NULL, 16);
   2.139 -        if ( hdr.changeset != cset )
   2.140 -        gdprintk(XENLOG_WARNING, "HVM restore: saved Xen changeset (%#"PRIx64
   2.141 -                 ") does not match host (%#"PRIx64").\n", hdr.changeset, cset);
   2.142 -    }
   2.143 -
   2.144 -    /* Down all the vcpus: we only re-enable the ones that had state saved. */
   2.145 -    for_each_vcpu(d, v) 
   2.146 -        if ( test_and_set_bit(_VCPUF_down, &v->vcpu_flags) )
   2.147 -            vcpu_sleep_nosync(v);
   2.148 -
   2.149 -    while(1) {
   2.150 -
   2.151 -        if ( h->size - h->cur < sizeof(struct hvm_save_descriptor) )
   2.152 -        {
   2.153 -            /* Run out of data */
   2.154 -            gdprintk(XENLOG_ERR, 
   2.155 -                     "HVM restore: save did not end with a null entry\n");
   2.156 -            return -1;
   2.157 -        }
   2.158 -        
   2.159 -        /* Read the typecode of the next entry  and check for the end-marker */
   2.160 -        desc = (struct hvm_save_descriptor *)(&h->data[h->cur]);
   2.161 -        if ( desc->typecode == 0 )
   2.162 -            return 0; 
   2.163 -        
   2.164 -        /* Find the handler for this entry */
   2.165 -        if ( desc->typecode > HVM_SAVE_CODE_MAX 
   2.166 -             || (handler = hvm_sr_handlers[desc->typecode].load) == NULL ) 
   2.167 -        {
   2.168 -            gdprintk(XENLOG_ERR, 
   2.169 -                     "HVM restore: unknown entry typecode %u\n", 
   2.170 -                     desc->typecode);
   2.171 -            return -1;
   2.172 -        }
   2.173 -
   2.174 -        /* Load the entry */
   2.175 -        gdprintk(XENLOG_INFO, "HVM restore: %s %"PRIu16"\n",  
   2.176 -                 hvm_sr_handlers[desc->typecode].name, desc->instance);
   2.177 -        if ( handler(d, h) != 0 ) 
   2.178 -        {
   2.179 -            gdprintk(XENLOG_ERR, 
   2.180 -                     "HVM restore: failed to load entry %u/%u\n", 
   2.181 -                     desc->typecode, desc->instance);
   2.182 -            return -1;
   2.183 -        }
   2.184 -    }
   2.185 -
   2.186 -    /* Not reached */
   2.187 -}
   2.188 -
   2.189 -
   2.190  int hvm_buffered_io_intercept(ioreq_t *p)
   2.191  {
   2.192      struct vcpu *v = current;
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xen/arch/x86/hvm/save.c	Wed Feb 07 10:21:15 2007 +0000
     3.3 @@ -0,0 +1,204 @@
     3.4 +/*
     3.5 + * hvm/save.c: Save and restore HVM guest's emulated hardware state.
     3.6 + *
     3.7 + * Copyright (c) 2004, Intel Corporation.
     3.8 + * Copyright (c) 2007, XenSource Inc.
     3.9 + *
    3.10 + * This program is free software; you can redistribute it and/or modify it
    3.11 + * under the terms and conditions of the GNU General Public License,
    3.12 + * version 2, as published by the Free Software Foundation.
    3.13 + *
    3.14 + * This program is distributed in the hope it will be useful, but WITHOUT
    3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    3.17 + * more details.
    3.18 + *
    3.19 + * You should have received a copy of the GNU General Public License along with
    3.20 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    3.21 + * Place - Suite 330, Boston, MA 02111-1307 USA.
    3.22 + */
    3.23 +
    3.24 +#include <xen/config.h>
    3.25 +#include <xen/compile.h>
    3.26 +#include <xen/lib.h>
    3.27 +#include <public/version.h>
    3.28 +#include <xen/sched.h>
    3.29 +
    3.30 +#include <asm/hvm/hvm.h>
    3.31 +#include <asm/hvm/support.h>
    3.32 +#include <asm/hvm/domain.h>
    3.33 +#include <asm/current.h>
    3.34 +
    3.35 +
    3.36 +/* List of handlers for various HVM save and restore types */
    3.37 +static struct { 
    3.38 +    hvm_save_handler save;
    3.39 +    hvm_load_handler load; 
    3.40 +    const char *name;
    3.41 +} hvm_sr_handlers [HVM_SAVE_CODE_MAX + 1] = {{NULL, NULL, "<?>"},};
    3.42 +
    3.43 +/* Init-time function to add entries to that list */
    3.44 +void hvm_register_savevm(uint16_t typecode, 
    3.45 +                         const char *name,
    3.46 +                         hvm_save_handler save_state,
    3.47 +                         hvm_load_handler load_state)
    3.48 +{
    3.49 +    ASSERT(typecode <= HVM_SAVE_CODE_MAX);
    3.50 +    ASSERT(hvm_sr_handlers[typecode].save == NULL);
    3.51 +    ASSERT(hvm_sr_handlers[typecode].load == NULL);
    3.52 +    hvm_sr_handlers[typecode].save = save_state;
    3.53 +    hvm_sr_handlers[typecode].load = load_state;
    3.54 +    hvm_sr_handlers[typecode].name = name;
    3.55 +}
    3.56 +
    3.57 +
    3.58 +int hvm_save(struct domain *d, hvm_domain_context_t *h)
    3.59 +{
    3.60 +    uint32_t eax, ebx, ecx, edx;
    3.61 +    char *c;
    3.62 +    struct hvm_save_header hdr;
    3.63 +    struct hvm_save_end end;
    3.64 +    hvm_save_handler handler;
    3.65 +    uint16_t i;
    3.66 +
    3.67 +    hdr.magic = HVM_FILE_MAGIC;
    3.68 +    hdr.version = HVM_FILE_VERSION;
    3.69 +
    3.70 +    /* Save some CPUID bits */
    3.71 +    cpuid(1, &eax, &ebx, &ecx, &edx);
    3.72 +    hdr.cpuid = eax;
    3.73 +
    3.74 +    /* Save xen changeset */
    3.75 +    c = strrchr(XEN_CHANGESET, ':');
    3.76 +    if ( c )
    3.77 +        hdr.changeset = simple_strtoll(c, NULL, 16);
    3.78 +    else 
    3.79 +        hdr.changeset = -1ULL; /* Unknown */
    3.80 +
    3.81 +    if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 )
    3.82 +    {
    3.83 +        gdprintk(XENLOG_ERR, "HVM save: failed to write header\n");
    3.84 +        return -EFAULT;
    3.85 +    } 
    3.86 +
    3.87 +    /* Save all available kinds of state */
    3.88 +    for ( i = 0; i <= HVM_SAVE_CODE_MAX; i++ ) 
    3.89 +    {
    3.90 +        handler = hvm_sr_handlers[i].save;
    3.91 +        if ( handler != NULL ) 
    3.92 +        {
    3.93 +            gdprintk(XENLOG_INFO, "HVM save: %s\n",  hvm_sr_handlers[i].name);
    3.94 +            if ( handler(d, h) != 0 ) 
    3.95 +            {
    3.96 +                gdprintk(XENLOG_ERR, 
    3.97 +                         "HVM save: failed to save type %"PRIu16"\n", i);
    3.98 +                return -EFAULT;
    3.99 +            } 
   3.100 +        }
   3.101 +    }
   3.102 +
   3.103 +    /* Save an end-of-file marker */
   3.104 +    if ( hvm_save_entry(END, 0, h, &end) != 0 )
   3.105 +    {
   3.106 +        /* Run out of data */
   3.107 +        gdprintk(XENLOG_ERR, "HVM save: no room for end marker.\n");
   3.108 +        return -EFAULT;
   3.109 +    }
   3.110 +
   3.111 +    /* Save macros should not have let us overrun */
   3.112 +    ASSERT(h->cur <= h->size);
   3.113 +    return 0;
   3.114 +}
   3.115 +
   3.116 +int hvm_load(struct domain *d, hvm_domain_context_t *h)
   3.117 +{
   3.118 +    uint32_t eax, ebx, ecx, edx;
   3.119 +    char *c;
   3.120 +    uint64_t cset;
   3.121 +    struct hvm_save_header hdr;
   3.122 +    struct hvm_save_descriptor *desc;
   3.123 +    hvm_load_handler handler;
   3.124 +    struct vcpu *v;
   3.125 +    
   3.126 +    /* Read the save header, which must be first */
   3.127 +    if ( hvm_load_entry(HEADER, h, &hdr) != 0 ) 
   3.128 +        return -1;
   3.129 +
   3.130 +    if (hdr.magic != HVM_FILE_MAGIC) {
   3.131 +        gdprintk(XENLOG_ERR, 
   3.132 +                 "HVM restore: bad magic number %#"PRIx32"\n", hdr.magic);
   3.133 +        return -1;
   3.134 +    }
   3.135 +
   3.136 +    if (hdr.version != HVM_FILE_VERSION) {
   3.137 +        gdprintk(XENLOG_ERR, 
   3.138 +                 "HVM restore: unsupported version %u\n", hdr.version);
   3.139 +        return -1;
   3.140 +    }
   3.141 +
   3.142 +    cpuid(1, &eax, &ebx, &ecx, &edx);
   3.143 +    /*TODO: need to define how big a difference is acceptable */
   3.144 +    if (hdr.cpuid != eax)
   3.145 +        gdprintk(XENLOG_WARNING, "HVM restore: saved CPUID (%#"PRIx32") "
   3.146 +               "does not match host (%#"PRIx32").\n", hdr.cpuid, eax);
   3.147 +
   3.148 +
   3.149 +    c = strrchr(XEN_CHANGESET, ':');
   3.150 +    if ( hdr.changeset == -1ULL )
   3.151 +        gdprintk(XENLOG_WARNING, 
   3.152 +                 "HVM restore: Xen changeset was not saved.\n");
   3.153 +    else if ( c == NULL )
   3.154 +        gdprintk(XENLOG_WARNING, 
   3.155 +                 "HVM restore: Xen changeset is not available.\n");
   3.156 +    else
   3.157 +    {
   3.158 +        cset = simple_strtoll(c, NULL, 16);
   3.159 +        if ( hdr.changeset != cset )
   3.160 +        gdprintk(XENLOG_WARNING, "HVM restore: saved Xen changeset (%#"PRIx64
   3.161 +                 ") does not match host (%#"PRIx64").\n", hdr.changeset, cset);
   3.162 +    }
   3.163 +
   3.164 +    /* Down all the vcpus: we only re-enable the ones that had state saved. */
   3.165 +    for_each_vcpu(d, v) 
   3.166 +        if ( test_and_set_bit(_VCPUF_down, &v->vcpu_flags) )
   3.167 +            vcpu_sleep_nosync(v);
   3.168 +
   3.169 +    while(1) {
   3.170 +
   3.171 +        if ( h->size - h->cur < sizeof(struct hvm_save_descriptor) )
   3.172 +        {
   3.173 +            /* Run out of data */
   3.174 +            gdprintk(XENLOG_ERR, 
   3.175 +                     "HVM restore: save did not end with a null entry\n");
   3.176 +            return -1;
   3.177 +        }
   3.178 +        
   3.179 +        /* Read the typecode of the next entry  and check for the end-marker */
   3.180 +        desc = (struct hvm_save_descriptor *)(&h->data[h->cur]);
   3.181 +        if ( desc->typecode == 0 )
   3.182 +            return 0; 
   3.183 +        
   3.184 +        /* Find the handler for this entry */
   3.185 +        if ( desc->typecode > HVM_SAVE_CODE_MAX 
   3.186 +             || (handler = hvm_sr_handlers[desc->typecode].load) == NULL ) 
   3.187 +        {
   3.188 +            gdprintk(XENLOG_ERR, 
   3.189 +                     "HVM restore: unknown entry typecode %u\n", 
   3.190 +                     desc->typecode);
   3.191 +            return -1;
   3.192 +        }
   3.193 +
   3.194 +        /* Load the entry */
   3.195 +        gdprintk(XENLOG_INFO, "HVM restore: %s %"PRIu16"\n",  
   3.196 +                 hvm_sr_handlers[desc->typecode].name, desc->instance);
   3.197 +        if ( handler(d, h) != 0 ) 
   3.198 +        {
   3.199 +            gdprintk(XENLOG_ERR, 
   3.200 +                     "HVM restore: failed to load entry %u/%u\n", 
   3.201 +                     desc->typecode, desc->instance);
   3.202 +            return -1;
   3.203 +        }
   3.204 +    }
   3.205 +
   3.206 +    /* Not reached */
   3.207 +}