# HG changeset patch # User Isaku Yamahata # Date 1213081233 -32400 # Node ID 1201c765783217371166062621e8926cb7643cfd # Parent fc89fb719214218c6245f632720f5105261539bd [IA64] ia64 save/restore new formart. save part. Introduce ia64 save/restore new formart. save part. The formart twist is necessary for pv_ops linux support saving/restoring all of the online vcpu context. Signed-off-by: Isaku Yamahata diff --git a/tools/libxc/ia64/xc_ia64_linux_save.c b/tools/libxc/ia64/xc_ia64_linux_save.c --- a/tools/libxc/ia64/xc_ia64_linux_save.c +++ b/tools/libxc/ia64/xc_ia64_linux_save.c @@ -207,68 +207,15 @@ } static int -xc_ia64_pv_send_context(int xc_handle, int io_fd, uint32_t dom, - shared_info_t *live_shinfo) -{ - /* A copy of the CPU context of the guest. */ - vcpu_guest_context_t ctxt; - char *mem; - - if (xc_ia64_send_vcpu_context(xc_handle, io_fd, dom, 0, &ctxt)) - return -1; - - mem = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, - PROT_READ|PROT_WRITE, ctxt.privregs_pfn); - if (mem == NULL) { - ERROR("cannot map privreg page"); - return -1; - } - if (write_exact(io_fd, mem, PAGE_SIZE)) { - ERROR("Error when writing privreg to state file (5)"); - munmap(mem, PAGE_SIZE); - return -1; - } - munmap(mem, PAGE_SIZE); - - if (xc_ia64_send_shared_info(xc_handle, io_fd, live_shinfo)) - return -1; - - return 0; -} - -static int -xc_ia64_hvm_send_context(int xc_handle, int io_fd, uint32_t dom, - const xc_dominfo_t *info, shared_info_t *live_shinfo) +xc_ia64_send_vcpumap(int xc_handle, int io_fd, uint32_t dom, + const xc_dominfo_t *info, uint64_t max_virt_cpus, + uint64_t **vcpumapp) { int rc = -1; unsigned int i; - - /* vcpu map */ - uint64_t max_virt_cpus; unsigned long vcpumap_size; uint64_t *vcpumap = NULL; - /* HVM: magic frames for ioreqs and xenstore comms */ - const int hvm_params[] = { - HVM_PARAM_STORE_PFN, - HVM_PARAM_IOREQ_PFN, - HVM_PARAM_BUFIOREQ_PFN, - HVM_PARAM_BUFPIOREQ_PFN, - }; - const int NR_PARAMS = sizeof(hvm_params) / sizeof(hvm_params[0]); - /* ioreq_pfn, bufioreq_pfn, store_pfn */ - uint64_t magic_pfns[NR_PARAMS]; - - /* HVM: a buffer for holding HVM contxt */ - uint64_t rec_size; - uint64_t hvm_buf_size = 0; - uint8_t *hvm_buf = NULL; - - if (xc_ia64_send_shared_info(xc_handle, io_fd, live_shinfo)) - return -1; - - /* vcpu map */ - max_virt_cpus = MAX_VIRT_CPUS; vcpumap_size = (max_virt_cpus + 1 + sizeof(vcpumap[0]) - 1) / sizeof(vcpumap[0]); vcpumap = malloc(vcpumap_size); @@ -294,6 +241,99 @@ goto out; } + rc = 0; + + out: + if (rc != 0 && vcpumap != NULL) { + free(vcpumap); + vcpumap = NULL; + } + *vcpumapp = vcpumap; + return rc; +} + + +static int +xc_ia64_pv_send_context(int xc_handle, int io_fd, uint32_t dom, + const xc_dominfo_t *info, shared_info_t *live_shinfo) +{ + int rc = -1; + unsigned int i; + + /* vcpu map */ + uint64_t *vcpumap = NULL; + if (xc_ia64_send_vcpumap(xc_handle, io_fd, dom, info, MAX_VIRT_CPUS, + &vcpumap)) + goto out; + + /* vcpu context */ + for (i = 0; i <= info->max_vcpu_id; i++) { + /* A copy of the CPU context of the guest. */ + vcpu_guest_context_t ctxt; + char *mem; + + if (!__test_bit(i, vcpumap)) + continue; + + if (xc_ia64_send_vcpu_context(xc_handle, io_fd, dom, i, &ctxt)) + goto out; + + mem = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, + PROT_READ|PROT_WRITE, ctxt.privregs_pfn); + if (mem == NULL) { + ERROR("cannot map privreg page"); + goto out; + } + if (write_exact(io_fd, mem, PAGE_SIZE)) { + ERROR("Error when writing privreg to state file (5)"); + munmap(mem, PAGE_SIZE); + goto out; + } + munmap(mem, PAGE_SIZE); + } + + rc = xc_ia64_send_shared_info(xc_handle, io_fd, live_shinfo); + + out: + if (vcpumap != NULL) + free(vcpumap); + return rc; +} + +static int +xc_ia64_hvm_send_context(int xc_handle, int io_fd, uint32_t dom, + const xc_dominfo_t *info, shared_info_t *live_shinfo) +{ + int rc = -1; + unsigned int i; + + /* vcpu map */ + uint64_t *vcpumap = NULL; + + /* HVM: magic frames for ioreqs and xenstore comms */ + const int hvm_params[] = { + HVM_PARAM_STORE_PFN, + HVM_PARAM_IOREQ_PFN, + HVM_PARAM_BUFIOREQ_PFN, + HVM_PARAM_BUFPIOREQ_PFN, + }; + const int NR_PARAMS = sizeof(hvm_params) / sizeof(hvm_params[0]); + /* ioreq_pfn, bufioreq_pfn, store_pfn */ + uint64_t magic_pfns[NR_PARAMS]; + + /* HVM: a buffer for holding HVM contxt */ + uint64_t rec_size; + uint64_t hvm_buf_size = 0; + uint8_t *hvm_buf = NULL; + + if (xc_ia64_send_shared_info(xc_handle, io_fd, live_shinfo)) + return -1; + + /* vcpu map */ + if (xc_ia64_send_vcpumap(xc_handle, io_fd, dom, info, MAX_VIRT_CPUS, + &vcpumap)) + goto out; + /* vcpu context */ for (i = 0; i <= info->max_vcpu_id; i++) { /* A copy of the CPU context of the guest. */ @@ -305,7 +345,7 @@ if (xc_ia64_send_vcpu_context(xc_handle, io_fd, dom, i, &ctxt)) goto out; - // system context of vcpu is sent as hvm context. + /* system context of vcpu is sent as hvm context. */ } /* Save magic-page locations. */ @@ -733,7 +773,8 @@ goto out; if (!hvm) - rc = xc_ia64_pv_send_context(xc_handle, io_fd, dom, live_shinfo); + rc = xc_ia64_pv_send_context(xc_handle, io_fd, + dom, &info, live_shinfo); else rc = xc_ia64_hvm_send_context(xc_handle, io_fd, dom, &info, live_shinfo); diff --git a/tools/libxc/ia64/xc_ia64_save_restore.h b/tools/libxc/ia64/xc_ia64_save_restore.h --- a/tools/libxc/ia64/xc_ia64_save_restore.h +++ b/tools/libxc/ia64/xc_ia64_save_restore.h @@ -31,7 +31,7 @@ #define XC_IA64_SR_FORMAT_VER_THREE 3UL #define XC_IA64_SR_FORMAT_VER_MAX 3UL -#define XC_IA64_SR_FORMAT_VER_CURRENT XC_IA64_SR_FORMAT_VER_TWO +#define XC_IA64_SR_FORMAT_VER_CURRENT XC_IA64_SR_FORMAT_VER_THREE /* ** During (live) save/migrate, we maintain a number of bitmaps to track