ia64/xen-unstable

changeset 17771:fc89fb719214

[IA64] ia64 save/restore new formart. restore part.

Introduce ia64 save/restore new formart. restore part.
The formart twist is necessary for pv_ops linux support saving/restoring
all of the online vcpu context.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Isaku Yamahata <yamahata@valinux.co.jp>
date Tue Jun 10 15:58:09 2008 +0900 (2008-06-10)
parents 4af5059f4e0d
children 1201c7657832
files tools/libxc/ia64/xc_ia64_linux_restore.c tools/libxc/ia64/xc_ia64_save_restore.h
line diff
     1.1 --- a/tools/libxc/ia64/xc_ia64_linux_restore.c	Tue Jun 10 15:54:47 2008 +0900
     1.2 +++ b/tools/libxc/ia64/xc_ia64_linux_restore.c	Tue Jun 10 15:58:09 2008 +0900
     1.3 @@ -127,7 +127,7 @@ xc_ia64_recv_vcpu_context(int xc_handle,
     1.4      fprintf(stderr, "ip=%016lx, b0=%016lx\n", ctxt->regs.ip, ctxt->regs.b[0]);
     1.5  
     1.6      /* Initialize and set registers.  */
     1.7 -    ctxt->flags = VGCF_EXTRA_REGS | VGCF_SET_CR_IRR;
     1.8 +    ctxt->flags = VGCF_EXTRA_REGS | VGCF_SET_CR_IRR | VGCF_online;
     1.9      if (xc_vcpu_setcontext(xc_handle, dom, vcpu, ctxt) != 0) {
    1.10          ERROR("Couldn't set vcpu context");
    1.11          return -1;
    1.12 @@ -184,29 +184,57 @@ xc_ia64_recv_shared_info(int xc_handle, 
    1.13  }
    1.14  
    1.15  static int
    1.16 -xc_ia64_pv_recv_context(int xc_handle, int io_fd, uint32_t dom,
    1.17 -                        unsigned long shared_info_frame,
    1.18 -                        struct xen_ia64_p2m_table *p2m_table,
    1.19 -                        unsigned int store_evtchn, unsigned long *store_mfn,
    1.20 -                        unsigned int console_evtchn,
    1.21 -                        unsigned long *console_mfn)
    1.22 +xc_ia64_recv_vcpumap(const xc_dominfo_t *info, int io_fd, uint64_t **vcpumapp)
    1.23 +{
    1.24 +    uint64_t max_virt_cpus;
    1.25 +    unsigned long vcpumap_size;
    1.26 +    uint64_t *vcpumap = NULL;
    1.27 +
    1.28 +    *vcpumapp = NULL;
    1.29 +    
    1.30 +    if (read_exact(io_fd, &max_virt_cpus, sizeof(max_virt_cpus))) {
    1.31 +        ERROR("error reading max_virt_cpus");
    1.32 +        return -1;
    1.33 +    }
    1.34 +    if (max_virt_cpus < info->max_vcpu_id) {
    1.35 +        ERROR("too large max_virt_cpus %i < %i\n",
    1.36 +              max_virt_cpus, info->max_vcpu_id);
    1.37 +        return -1;
    1.38 +    }
    1.39 +    vcpumap_size = (max_virt_cpus + 1 + sizeof(vcpumap[0]) - 1) /
    1.40 +        sizeof(vcpumap[0]);
    1.41 +    vcpumap = malloc(vcpumap_size);
    1.42 +    if (vcpumap == NULL) {
    1.43 +        ERROR("memory alloc for vcpumap");
    1.44 +        return -1;
    1.45 +    }
    1.46 +    memset(vcpumap, 0, vcpumap_size);
    1.47 +    if (read_exact(io_fd, vcpumap, vcpumap_size)) {
    1.48 +        ERROR("read vcpumap");
    1.49 +        free(vcpumap);
    1.50 +        return -1;
    1.51 +    }
    1.52 +
    1.53 +    *vcpumapp = vcpumap;
    1.54 +    return 0;
    1.55 +}
    1.56 +
    1.57 +static int
    1.58 +xc_ia64_pv_recv_vcpu_context(int xc_handle, int io_fd, int32_t dom,
    1.59 +                             uint32_t vcpu)
    1.60  {
    1.61      int rc = -1;
    1.62 -    unsigned long gmfn;
    1.63  
    1.64      /* A copy of the CPU context of the guest. */
    1.65      vcpu_guest_context_t ctxt;
    1.66 -
    1.67 -    /* A temporary mapping of the guest's start_info page. */
    1.68 -    start_info_t *start_info;
    1.69 -
    1.70 +    
    1.71      if (lock_pages(&ctxt, sizeof(ctxt))) {
    1.72          /* needed for build domctl, but might as well do early */
    1.73          ERROR("Unable to lock_pages ctxt");
    1.74          return -1;
    1.75      }
    1.76  
    1.77 -    if (xc_ia64_recv_vcpu_context(xc_handle, io_fd, dom, 0, &ctxt))
    1.78 +    if (xc_ia64_recv_vcpu_context(xc_handle, io_fd, dom, vcpu, &ctxt))
    1.79          goto out;
    1.80  
    1.81      /* Then get privreg page.  */
    1.82 @@ -215,21 +243,42 @@ xc_ia64_pv_recv_context(int xc_handle, i
    1.83          goto out;
    1.84      }
    1.85  
    1.86 +    rc = 0;
    1.87 +
    1.88 + out:
    1.89 +    unlock_pages(&ctxt, sizeof(ctxt));
    1.90 +    return rc;
    1.91 +}
    1.92 +
    1.93 +static int
    1.94 +xc_ia64_pv_recv_shared_info(int xc_handle, int io_fd, int32_t dom, 
    1.95 +                            unsigned long shared_info_frame,
    1.96 +                            struct xen_ia64_p2m_table *p2m_table,
    1.97 +                            unsigned int store_evtchn,
    1.98 +                            unsigned long *store_mfn,
    1.99 +                            unsigned int console_evtchn,
   1.100 +                            unsigned long *console_mfn)
   1.101 +{
   1.102 +    unsigned long gmfn;
   1.103 +
   1.104 +    /* A temporary mapping of the guest's start_info page. */
   1.105 +    start_info_t *start_info;
   1.106 +    
   1.107      /* Read shared info.  */
   1.108      if (xc_ia64_recv_shared_info(xc_handle, io_fd, dom,
   1.109                                   shared_info_frame, &gmfn))
   1.110 -        goto out;
   1.111 +        return -1;
   1.112  
   1.113      /* Uncanonicalise the suspend-record frame number and poke resume rec. */
   1.114      if (populate_page_if_necessary(xc_handle, dom, gmfn, p2m_table)) {
   1.115          ERROR("cannot populate page 0x%lx", gmfn);
   1.116 -        goto out;
   1.117 +        return -1;
   1.118      }
   1.119      start_info = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
   1.120                                        PROT_READ | PROT_WRITE, gmfn);
   1.121      if (start_info == NULL) {
   1.122          ERROR("cannot map start_info page");
   1.123 -        goto out;
   1.124 +        return -1;
   1.125      }
   1.126      start_info->nr_pages = p2m_size;
   1.127      start_info->shared_info = shared_info_frame << PAGE_SHIFT;
   1.128 @@ -240,10 +289,109 @@ xc_ia64_pv_recv_context(int xc_handle, i
   1.129      start_info->console.domU.evtchn = console_evtchn;
   1.130      munmap(start_info, PAGE_SIZE);
   1.131  
   1.132 -    rc = 0;
   1.133 +    return 0;
   1.134 +}
   1.135 +
   1.136 +static int
   1.137 +xc_ia64_pv_recv_context_ver_one_or_two(int xc_handle, int io_fd, uint32_t dom,
   1.138 +                                       unsigned long shared_info_frame,
   1.139 +                                       struct xen_ia64_p2m_table *p2m_table,
   1.140 +                                       unsigned int store_evtchn,
   1.141 +                                       unsigned long *store_mfn,
   1.142 +                                       unsigned int console_evtchn,
   1.143 +                                       unsigned long *console_mfn)
   1.144 +{
   1.145 +    int rc;
   1.146 +
   1.147 +    /* vcpu 0 context */
   1.148 +    rc = xc_ia64_pv_recv_vcpu_context(xc_handle, io_fd, dom, 0);
   1.149 +    if (rc)
   1.150 +        return rc;
   1.151 +
   1.152 +
   1.153 +    /* shared_info */
   1.154 +    rc = xc_ia64_pv_recv_shared_info(xc_handle, io_fd, dom, shared_info_frame,
   1.155 +                                     p2m_table, store_evtchn, store_mfn,
   1.156 +                                     console_evtchn, console_mfn);
   1.157 +    return rc;
   1.158 +}
   1.159 +
   1.160 +static int
   1.161 +xc_ia64_pv_recv_context_ver_three(int xc_handle, int io_fd, uint32_t dom,
   1.162 +                                  unsigned long shared_info_frame,
   1.163 +                                  struct xen_ia64_p2m_table *p2m_table,
   1.164 +                                  unsigned int store_evtchn,
   1.165 +                                  unsigned long *store_mfn,
   1.166 +                                  unsigned int console_evtchn,
   1.167 +                                  unsigned long *console_mfn)
   1.168 +{
   1.169 +    int rc = -1;
   1.170 +    xc_dominfo_t info;
   1.171 +    unsigned int i;
   1.172 +    
   1.173 +    /* vcpu map */
   1.174 +    uint64_t *vcpumap = NULL;
   1.175 +    
   1.176 +    if (xc_domain_getinfo(xc_handle, dom, 1, &info) != 1) {
   1.177 +        ERROR("Could not get domain info");
   1.178 +        return -1;
   1.179 +    }
   1.180 +    rc = xc_ia64_recv_vcpumap(&info, io_fd, &vcpumap);
   1.181 +    if (rc != 0)
   1.182 +        goto out;
   1.183  
   1.184 +    /* vcpu context */
   1.185 +    for (i = 0; i <= info.max_vcpu_id; i++) {
   1.186 +        if (!__test_bit(i, vcpumap))
   1.187 +            continue;
   1.188 +
   1.189 +        rc = xc_ia64_pv_recv_vcpu_context(xc_handle, io_fd, dom, i);
   1.190 +        if (rc != 0)
   1.191 +            goto out;
   1.192 +    }    
   1.193 +
   1.194 +    /* shared_info */
   1.195 +    rc = xc_ia64_pv_recv_shared_info(xc_handle, io_fd, dom, shared_info_frame,
   1.196 +                                     p2m_table, store_evtchn, store_mfn,
   1.197 +                                     console_evtchn, console_mfn);
   1.198   out:
   1.199 -    unlock_pages(&ctxt, sizeof(ctxt));
   1.200 +    if (vcpumap != NULL)
   1.201 +        free(vcpumap);
   1.202 +    return rc;
   1.203 +}
   1.204 +
   1.205 +static int
   1.206 +xc_ia64_pv_recv_context(unsigned long format_version,
   1.207 +                        int xc_handle, int io_fd, uint32_t dom,
   1.208 +                        unsigned long shared_info_frame,
   1.209 +                        struct xen_ia64_p2m_table *p2m_table,
   1.210 +                        unsigned int store_evtchn,
   1.211 +                        unsigned long *store_mfn,
   1.212 +                        unsigned int console_evtchn,
   1.213 +                        unsigned long *console_mfn)
   1.214 +{
   1.215 +    int rc;
   1.216 +    switch (format_version) {
   1.217 +    case XC_IA64_SR_FORMAT_VER_ONE:
   1.218 +    case XC_IA64_SR_FORMAT_VER_TWO:
   1.219 +        rc = xc_ia64_pv_recv_context_ver_one_or_two(xc_handle, io_fd, dom,
   1.220 +                                                    shared_info_frame,
   1.221 +                                                    p2m_table, store_evtchn,
   1.222 +                                                    store_mfn, console_evtchn,
   1.223 +                                                    console_mfn);
   1.224 +        break;
   1.225 +    case XC_IA64_SR_FORMAT_VER_THREE:
   1.226 +        rc = xc_ia64_pv_recv_context_ver_three(xc_handle, io_fd, dom,
   1.227 +                                               shared_info_frame,
   1.228 +                                               p2m_table, store_evtchn,
   1.229 +                                               store_mfn, console_evtchn,
   1.230 +                                               console_mfn);
   1.231 +        break;
   1.232 +    default:
   1.233 +        ERROR("Unsupported format version");
   1.234 +        rc = -1;
   1.235 +        break;
   1.236 +    }
   1.237      return rc;
   1.238  }
   1.239  
   1.240 @@ -259,9 +407,7 @@ xc_ia64_hvm_recv_context(int xc_handle, 
   1.241      xc_dominfo_t info;
   1.242      unsigned int i;
   1.243      
   1.244 -    /* cpu */
   1.245 -    uint64_t max_virt_cpus;
   1.246 -    unsigned long vcpumap_size;
   1.247 +    /* cpumap */
   1.248      uint64_t *vcpumap = NULL;
   1.249  
   1.250      /* HVM: magic frames for ioreqs and xenstore comms */
   1.251 @@ -289,27 +435,8 @@ xc_ia64_hvm_recv_context(int xc_handle, 
   1.252          ERROR("Could not get domain info");
   1.253          goto out;
   1.254      }
   1.255 -    if (read_exact(io_fd, &max_virt_cpus, sizeof(max_virt_cpus))) {
   1.256 -        ERROR("error reading max_virt_cpus");
   1.257 -        goto out;
   1.258 -    }
   1.259 -    if (max_virt_cpus < info.max_vcpu_id) {
   1.260 -        ERROR("too large max_virt_cpus %i < %i\n",
   1.261 -              max_virt_cpus, info.max_vcpu_id);
   1.262 +    if (xc_ia64_recv_vcpumap(&info, io_fd, &vcpumap))
   1.263          goto out;
   1.264 -    }
   1.265 -    vcpumap_size = (max_virt_cpus + 1 + sizeof(vcpumap[0]) - 1) /
   1.266 -        sizeof(vcpumap[0]);
   1.267 -    vcpumap = malloc(vcpumap_size);
   1.268 -    if (vcpumap == NULL) {
   1.269 -        ERROR("memory alloc for vcpumap");
   1.270 -        goto out;
   1.271 -    }
   1.272 -    memset(vcpumap, 0, vcpumap_size);
   1.273 -    if (read_exact(io_fd, vcpumap, vcpumap_size)) {
   1.274 -        ERROR("read vcpumap");
   1.275 -        goto out;
   1.276 -    }
   1.277      
   1.278      /* vcpu context */
   1.279      for (i = 0; i <= info.max_vcpu_id; i++) {
   1.280 @@ -322,7 +449,7 @@ xc_ia64_hvm_recv_context(int xc_handle, 
   1.281          if (xc_ia64_recv_vcpu_context(xc_handle, io_fd, dom, i, &ctxt))
   1.282              goto out;
   1.283  
   1.284 -        // system context of vcpu is recieved as hvm context.
   1.285 +        /* system context of vcpu is recieved as hvm context. */
   1.286      }    
   1.287  
   1.288      /* Set HVM-specific parameters */
   1.289 @@ -350,6 +477,7 @@ xc_ia64_hvm_recv_context(int xc_handle, 
   1.290          ERROR("error setting HVM params: %i", rc);
   1.291          goto out;
   1.292      }
   1.293 +    rc = -1;
   1.294      *store_mfn = magic_pfns[0];
   1.295  
   1.296      /* Read HVM context */
   1.297 @@ -437,7 +565,9 @@ xc_domain_restore(int xc_handle, int io_
   1.298          ERROR("Error when reading version");
   1.299          goto out;
   1.300      }
   1.301 -    if (ver != XC_IA64_SR_FORMAT_VER_ONE && ver != XC_IA64_SR_FORMAT_VER_TWO) {
   1.302 +    if (ver != XC_IA64_SR_FORMAT_VER_ONE &&
   1.303 +        ver != XC_IA64_SR_FORMAT_VER_TWO &&
   1.304 +        ver != XC_IA64_SR_FORMAT_VER_THREE) {
   1.305          ERROR("version of save doesn't match");
   1.306          goto out;
   1.307      }
   1.308 @@ -468,7 +598,8 @@ xc_domain_restore(int xc_handle, int io_
   1.309      }
   1.310      shared_info_frame = domctl.u.getdomaininfo.shared_info_frame;
   1.311  
   1.312 -    if (ver == XC_IA64_SR_FORMAT_VER_TWO) {
   1.313 +    if (ver == XC_IA64_SR_FORMAT_VER_THREE ||
   1.314 +        ver == XC_IA64_SR_FORMAT_VER_TWO) {
   1.315          unsigned int memmap_info_num_pages;
   1.316          unsigned long memmap_size;
   1.317          xen_ia64_memmap_info_t *memmap_info;
   1.318 @@ -548,7 +679,8 @@ xc_domain_restore(int xc_handle, int io_
   1.319          goto out;
   1.320  
   1.321      if (!hvm)
   1.322 -        rc = xc_ia64_pv_recv_context(xc_handle, io_fd, dom, shared_info_frame,
   1.323 +        rc = xc_ia64_pv_recv_context(ver, 
   1.324 +                                     xc_handle, io_fd, dom, shared_info_frame,
   1.325                                       &p2m_table, store_evtchn, store_mfn,
   1.326                                       console_evtchn, console_mfn);
   1.327      else
     2.1 --- a/tools/libxc/ia64/xc_ia64_save_restore.h	Tue Jun 10 15:54:47 2008 +0900
     2.2 +++ b/tools/libxc/ia64/xc_ia64_save_restore.h	Tue Jun 10 15:58:09 2008 +0900
     2.3 @@ -27,7 +27,9 @@
     2.4  #define XC_IA64_SR_FORMAT_VER_ONE       1UL
     2.5          /* using foreign p2m exposure version */
     2.6  #define XC_IA64_SR_FORMAT_VER_TWO       2UL
     2.7 -#define XC_IA64_SR_FORMAT_VER_MAX       2UL
     2.8 +        /* only pv change: send vcpumap and all vcpu context */
     2.9 +#define XC_IA64_SR_FORMAT_VER_THREE     3UL
    2.10 +#define XC_IA64_SR_FORMAT_VER_MAX       3UL
    2.11  
    2.12  #define XC_IA64_SR_FORMAT_VER_CURRENT   XC_IA64_SR_FORMAT_VER_TWO
    2.13